Use standard and prettier (#10)

* switch from custom eslint config to standard + prettier

* fix new standard eslint violations

* add editorconfig file

* auto-fix all other violations

* update lint yarn script

* remove jshint comment
This commit is contained in:
Spencer
2019-07-09 13:24:13 -07:00
committed by GitHub
parent f69840c50f
commit 7c1573fb07
119 changed files with 4506 additions and 3521 deletions

View File

@ -3,43 +3,55 @@ var Client = require('../../src/elasticsearch').Client;
var _ = require('lodash');
var times = require('async').times;
process.once('message', function (port) {
process.once('message', function(port) {
var es = new Client({
host: 'http://127.0.0.1:' + port,
log: false
log: false,
});
times(1000, function (n, done) {
es.search({
body: {
query: {
match_all: {}
}
times(
1000,
function(n, done) {
es.search(
{
body: {
query: {
match_all: {},
},
},
},
done
);
clock.tick(10);
},
function(err) {
var conns = es.transport.connectionPool._conns;
var sockets = _([].concat(conns.dead, conns.alive))
.transform(function(sockets, conn) {
sockets.push(
_.values(conn.agent.sockets),
_.values(conn.agent.freeSockets)
);
}, [])
.flattenDeep()
.value();
es.close();
var out = {
socketCount: err || sockets.length,
remaining:
_.filter(sockets, { destroyed: true }).length - sockets.length,
timeouts:
_.size(clock.timers) && _.map(clock.timers, 'func').map(String),
};
clock.restore();
if (process.connected) {
process.send(out);
} else {
console.log(out);
}
}, done);
clock.tick(10);
}, function (err) {
var conns = es.transport.connectionPool._conns;
var sockets = _([].concat(conns.dead, conns.alive))
.transform(function (sockets, conn) {
sockets.push(_.values(conn.agent.sockets), _.values(conn.agent.freeSockets));
}, [])
.flattenDeep()
.value();
es.close();
var out = {
socketCount: err || sockets.length,
remaining: _.filter(sockets, { destroyed: true }).length - sockets.length,
timeouts: _.size(clock.timers) && _.map(clock.timers, 'func').map(String)
};
clock.restore();
if (process.connected) {
process.send(out)
} else {
console.log(out);
}
});
);
});

View File

@ -5,15 +5,15 @@
// timeouts aren't being left behind
var express = require('express');
var app = express().post('/_search', function (req, res) {
var app = express().post('/_search', function(req, res) {
res.json(200, { hits: { hits: [] } });
});
var server = require('http').createServer(app);
server.listen(function () {
server.listen(function() {
var port = server.address().port;
if (process.connected) {
process.send(port)
process.send(port);
} else {
console.log(port);
}

View File

@ -21,37 +21,52 @@ var client = null;
module.exports = {
create: function create(apiVersion, port, host, cb) {
// create a client and ping the server for up to 15 seconds
doCreateClient({
logConfig: null
}, function () {
var attemptsRemaining = 60;
var timeout = 500;
doCreateClient(
{
logConfig: null,
},
function() {
var attemptsRemaining = 60;
var timeout = 500;
(function ping() {
client.info({
maxRetries: 0,
requestTimeout: 100
}, function (err, resp) {
if (err && --attemptsRemaining) {
setTimeout(ping, timeout);
} else if (err) {
cb(new Error('unable to establish contact with ES at ' + JSON.stringify({
host: host,
port: port,
err: err
})));
} else if (resp.name !== 'elasticsearch_js_test_runner') {
console.log(resp);
cb(new Error('Almosted wiped out another es node. Shut-down all instances of ES and try again.'));
} else {
// create a new client
doCreateClient(function () {
cb(void 0, client);
});
}
});
}());
});
(function ping() {
client.info(
{
maxRetries: 0,
requestTimeout: 100,
},
function(err, resp) {
if (err && --attemptsRemaining) {
setTimeout(ping, timeout);
} else if (err) {
cb(
new Error(
'unable to establish contact with ES at ' +
JSON.stringify({
host: host,
port: port,
err: err,
})
)
);
} else if (resp.name !== 'elasticsearch_js_test_runner') {
console.log(resp);
cb(
new Error(
'Almosted wiped out another es node. Shut-down all instances of ES and try again.'
)
);
} else {
// create a new client
doCreateClient(function() {
cb(void 0, client);
});
}
}
);
})();
}
);
function doCreateClient(options, cb) {
if (typeof options === 'function') {
@ -90,50 +105,61 @@ module.exports = {
hosts: [
{
host: host,
port: port
}
port: port,
},
],
log: logConfig,
defer: function () {
defer: function() {
return Bluebird.defer();
}
},
});
client.clearEs = function () {
client.clearEs = function() {
return Bluebird.all([
client.indices.delete({ index: '*', ignore: 404 }),
client.indices.deleteTemplate({ name: '*', ignore: 404 }),
client.snapshot.getRepository()
.then(_.keys)
.map(function (repo) {
return client.snapshot.get({
repository: repo,
snapshot: '_all'
})
.then(function (resp) {
return _.map(resp.snapshots, 'snapshot');
}, function () {
return [];
})
.map(function (snapshot) {
return client.snapshot.delete({
repository: repo,
snapshot: snapshot
});
}, { concurrency: 1 })
.then(function () {
return client.snapshot.deleteRepository({
repository: repo
});
});
}, { concurrency: 1 })
client.snapshot
.getRepository()
.then(_.keys)
.map(
function(repo) {
return client.snapshot
.get({
repository: repo,
snapshot: '_all',
})
.then(
function(resp) {
return _.map(resp.snapshots, 'snapshot');
},
function() {
return [];
}
)
.map(
function(snapshot) {
return client.snapshot.delete({
repository: repo,
snapshot: snapshot,
});
},
{ concurrency: 1 }
)
.then(function() {
return client.snapshot.deleteRepository({
repository: repo,
});
});
},
{ concurrency: 1 }
),
]);
};
process.nextTick(cb);
}
},
get: function () {
get: function() {
return client;
}
},
};

View File

@ -1,8 +1,10 @@
module.exports = function (branch) {
module.exports = function(branch) {
var path = require('path');
var YamlFile = require('./yaml_file');
var root = require('find-root')(__dirname);
var rootReq = function (loc) { return require(path.join(root, loc)); };
var rootReq = function(loc) {
return require(path.join(root, loc));
};
var _ = require('lodash');
var utils = rootReq('src/lib/utils');
var clientManager = require('./client_manager');
@ -16,23 +18,25 @@ module.exports = function (branch) {
console.log(' port:', port);
console.log(' api version:', apiVersion);
describe('integration', function () {
describe('integration', function() {
this.timeout(30000);
// before running any tests...
before(function (done) {
before(function(done) {
this.timeout(5 * 60 * 1000);
clientManager.create(apiVersion, port, host, done);
});
before(function () {
before(function() {
// make sure ES is empty
return clientManager.get().clearEs();
});
_.map(require('./yaml_tests_' + utils.snakeCase(branch) + '.json'), function (docs, filename) {
return new YamlFile(filename, docs);
});
_.map(
require('./yaml_tests_' + utils.snakeCase(branch) + '.json'),
function(docs, filename) {
return new YamlFile(filename, docs);
}
);
});
};

View File

@ -14,7 +14,13 @@ var expect = require('expect.js');
var clientManager = require('./client_manager');
var inspect = require('util').inspect;
var implementedFeatures = ['gtelte', 'regex', 'benchmark', 'stash_in_path', 'groovy_scripting'];
var implementedFeatures = [
'gtelte',
'regex',
'benchmark',
'stash_in_path',
'groovy_scripting',
];
/**
* The version that ES is running, in comparable string form XXX-XXX-XXX, fetched when needed
@ -41,14 +47,16 @@ var versionRE = new RegExp('^(?:' + versionExp + ')$');
* Regular Expression to extract a version range from a string
* @type {RegExp}
*/
var versionRangeRE = new RegExp('^(?:' + versionExp + ')\\s*\\-\\s*(?:' + versionExp + ')$');
var versionRangeRE = new RegExp(
'^(?:' + versionExp + ')\\s*\\-\\s*(?:' + versionExp + ')$'
);
/**
* Fetches the client.info, and parses out the version number to a comparable string
* @param done {Function} - callback
*/
function getVersionFromES(done) {
clientManager.get().info({}, function (err, resp) {
clientManager.get().info({}, function(err, resp) {
if (err) {
throw new Error('unable to get info about ES');
}
@ -70,9 +78,9 @@ function versionToComparableString(version, def) {
return def;
}
var parts = _.map(version.split('.'), function (part) {
var parts = _.map(version.split('.'), function(part) {
part = '' + _.parseInt(part);
return (new Array(Math.max(4 - part.length, 0))).join('0') + part;
return new Array(Math.max(4 - part.length, 0)).join('0') + part;
});
while (parts.length < 3) {
@ -95,7 +103,7 @@ function rangeMatchesCurrentVersion(rangeString, done) {
}
if (!ES_VERSION) {
getVersionFromES(function () {
getVersionFromES(function() {
rangeMatchesCurrentVersion(rangeString, done);
});
return;
@ -104,7 +112,6 @@ function rangeMatchesCurrentVersion(rangeString, done) {
done(YamlDoc.compareRangeToVersion(rangeString, ES_VERSION));
}
function YamlDoc(doc, file) {
var self = this;
@ -114,66 +121,71 @@ function YamlDoc(doc, file) {
self._last_requests_response = null;
// setup the actions, creating a bound and testable method for each
self._actions = _.map(self.flattenTestActions(doc[self.description]), function (action) {
// get the method that will do the action
var method = self['do_' + action.name];
self._actions = _.map(
self.flattenTestActions(doc[self.description]),
function(action) {
// get the method that will do the action
var method = self['do_' + action.name];
// check that it's a function
expect(method || 'YamlDoc#' + action.name).to.be.a('function');
// check that it's a function
expect(method || 'YamlDoc#' + action.name).to.be.a('function');
if (_.isPlainObject(action.args)) {
action.name += '(' + JSON.stringify(action.args) + ')';
} else if (action.args) {
action.name += '(' + action.args + ')';
}
// wrap in a check for skipping
action.bound = _.bind(method, self, action.args);
// create a function that can be passed to mocha or async
action.testable = function (_cb) {
function done(err) {
process.nextTick(function () {
if (err) {
err.message += ' in ' + action.name;
}
_cb(err);
});
if (_.isPlainObject(action.args)) {
action.name += '(' + JSON.stringify(action.args) + ')';
} else if (action.args) {
action.name += '(' + action.args + ')';
}
if (self.skipping || self.file.skipping) {
return done();
}
if (method.length > 1) {
action.bound(done);
} else {
try {
action.bound();
process.nextTick(done);
} catch (err) {
done(err);
// wrap in a check for skipping
action.bound = _.bind(method, self, action.args);
// create a function that can be passed to mocha or async
action.testable = function(_cb) {
function done(err) {
process.nextTick(function() {
if (err) {
err.message += ' in ' + action.name;
}
_cb(err);
});
}
}
};
return action;
});
if (self.skipping || self.file.skipping) {
return done();
}
if (method.length > 1) {
action.bound(done);
} else {
try {
action.bound();
process.nextTick(done);
} catch (err) {
done(err);
}
}
};
self.getActionsRunners = function () {
return self._actions.map(function (action) {
return function (cb) {
clientManager.get().transport.log.debug(
'===========================\n' +
action.name +
'\n==========================='
);
return action;
}
);
self.getActionsRunners = function() {
return self._actions.map(function(action) {
return function(cb) {
clientManager
.get()
.transport.log.debug(
'===========================\n' +
action.name +
'\n==========================='
);
return action.testable(cb);
};
});
};
}
YamlDoc.compareRangeToVersion = function (range, version) {
YamlDoc.compareRangeToVersion = function(range, version) {
expect(range).to.match(versionRangeRE);
var rangeMatch = versionRangeRE.exec(range);
@ -184,11 +196,12 @@ YamlDoc.compareRangeToVersion = function (range, version) {
var max = versionToComparableString(rangeMatch[2], Infinity);
var comp = versionToComparableString(versionMatch[1], Infinity);
return (min === -Infinity || min <= comp) && (max === Infinity || max >= comp);
return (
(min === -Infinity || min <= comp) && (max === Infinity || max >= comp)
);
};
YamlDoc.prototype = {
/**
* convert tests actions
* from: [ {name:args, name:args}, {name:args}, ... ]
@ -196,20 +209,24 @@ YamlDoc.prototype = {
* so it's easier to work with
* @param {ArrayOfObjects} config - Actions to be taken as defined in the yaml specs
*/
flattenTestActions: function (config) {
flattenTestActions: function(config) {
// creates [ [ {name:"", args:"" }, ... ], ... ]
// from [ {name:args, name:args}, {name:args} ]
var actionSets = _.map(config, function (set) {
return _.map(_.toPairs(set), function (pair) {
var actionSets = _.map(config, function(set) {
return _.map(_.toPairs(set), function(pair) {
return { name: pair[0], args: pair[1] };
});
});
// do a single level flatten, merge=ing the nested arrays from step one
// into a master array, creating an array of action objects
return _.reduce(actionSets, function (note, set) {
return note.concat(set);
}, []);
return _.reduce(
actionSets,
function(note, set) {
return note.concat(set);
},
[]
);
},
/**
@ -218,7 +235,7 @@ YamlDoc.prototype = {
* @param {Function} ittr - The function to call for each action.
* @return {undefined}
*/
each: function (ittr) {
each: function(ittr) {
for (var i = 0; i < this._actions.length; i++) {
if (ittr(this._actions[i].testable, this._actions[i].name) === false) {
break;
@ -248,16 +265,17 @@ YamlDoc.prototype = {
* @param {string} path - The dot-notation path to the value needed.
* @return {*} - The value requested, or undefined if it was not found
*/
get: function (path, from) {
get: function(path, from) {
var self = this;
var log = process.env.LOG_GETS && !from ? console.log.bind(console) : function () {};
var log =
process.env.LOG_GETS && !from ? console.log.bind(console) : function() {};
var i;
if (path === '$body') {
// shortcut, the test just wants the whole body
return self._last_requests_response;
} else if (path) {
path = path.replace(/\.\$([a-zA-Z0-9_]+)/g, function (m, name) {
path = path.replace(/\.\$([a-zA-Z0-9_]+)/g, function(m, name) {
return '.' + self._stash[name];
});
}
@ -273,14 +291,20 @@ YamlDoc.prototype = {
log('getting', path, 'from', from);
var steps = _.map(path ? path.replace(/\\\./g, '\uffff').split('.') : [], function (step) {
return step.replace(/\uffff/g, '.');
});
var steps = _.map(
path ? path.replace(/\\\./g, '\uffff').split('.') : [],
function(step) {
return step.replace(/\uffff/g, '.');
}
);
var remainingSteps;
for (i = 0; from != null && i < steps.length; i++) {
if (from[steps[i]] === void 0) {
remainingSteps = steps.slice(i).join('.').replace(/\\\./g, '.');
remainingSteps = steps
.slice(i)
.join('.')
.replace(/\\\./g, '.');
from = from[remainingSteps];
break;
} else {
@ -299,36 +323,49 @@ YamlDoc.prototype = {
* @param args
* @param done
*/
do_skip: function (args, done) {
do_skip: function(args, done) {
if (args.version) {
return rangeMatchesCurrentVersion(args.version, _.bind(function (match) {
if (match) {
if (this.description === 'setup') {
this.file.skipping = true;
// console.log('skipping this file' + (args.reason ? ' because ' + args.reason : ''));
return rangeMatchesCurrentVersion(
args.version,
_.bind(function(match) {
if (match) {
if (this.description === 'setup') {
this.file.skipping = true;
// console.log('skipping this file' + (args.reason ? ' because ' + args.reason : ''));
} else {
this.skipping = true;
// console.log('skipping the rest of this doc' + (args.reason ? ' because ' + args.reason : ''));
}
} else {
this.skipping = true;
// console.log('skipping the rest of this doc' + (args.reason ? ' because ' + args.reason : ''));
this.skipping = false;
this.file.skipping = false;
}
} else {
this.skipping = false;
this.file.skipping = false;
}
done();
}, this));
done();
}, this)
);
}
if (args.features) {
var features = Array.isArray(args.features) ? args.features : [args.features];
var features = Array.isArray(args.features)
? args.features
: [args.features];
var notImplemented = _.difference(features, implementedFeatures);
if (notImplemented.length) {
if (this.description === 'setup') {
this.file.skipping = true;
console.log('skipping this file because ' + notImplemented.join(' & ') + ' are not implemented');
console.log(
'skipping this file because ' +
notImplemented.join(' & ') +
' are not implemented'
);
} else {
this.skipping = true;
console.log('skipping the rest of this doc because ' + notImplemented.join(' & ') + ' are not implemented');
console.log(
'skipping the rest of this doc because ' +
notImplemented.join(' & ') +
' are not implemented'
);
}
}
return done();
@ -342,12 +379,12 @@ YamlDoc.prototype = {
* @param {Function} done [description]
* @return {[type]} [description]
*/
do_do: function (args, done) {
do_do: function(args, done) {
var catcher;
if (process.env.LOG_DO) {
var __done = done;
done = function (err, resp) {
done = function(err, resp) {
console.log('doing', clientActionName, 'with', params);
console.log('got', resp);
__done(err, resp);
@ -399,7 +436,11 @@ YamlDoc.prototype = {
var otherKeys = _.keys(args);
var action = otherKeys.shift();
if (otherKeys.length) {
return done(new TypeError('Unexpected top-level args to "do": ' + otherKeys.join(', ')));
return done(
new TypeError(
'Unexpected top-level args to "do": ' + otherKeys.join(', ')
)
);
}
var client = clientManager.get();
@ -407,38 +448,47 @@ YamlDoc.prototype = {
var clientAction = this.get(clientActionName, client);
_.assign(inputParams, args[action]);
var params = _.transform(inputParams, _.bind(function (params, val, name) {
var camelName = _.camelCase(name);
var params = _.transform(
inputParams,
_.bind(function(params, val, name) {
var camelName = _.camelCase(name);
// search through the params and url peices to find this param name
var paramName = name;
var spec = clientAction && clientAction.spec;
var knownParam = spec && spec.params && spec.params[camelName];
var knownUrlParam = spec && !knownParam && !!_.find(spec.url ? [spec.url] : spec.urls, function (url) {
if ((url.opt && url.opt[camelName]) || (url.req && url.req[camelName])) {
return true;
}
});
// search through the params and url peices to find this param name
var paramName = name;
var spec = clientAction && clientAction.spec;
var knownParam = spec && spec.params && spec.params[camelName];
var knownUrlParam =
spec &&
!knownParam &&
!!_.find(spec.url ? [spec.url] : spec.urls, function(url) {
if (
(url.opt && url.opt[camelName]) ||
(url.req && url.req[camelName])
) {
return true;
}
});
// if we do know this param name, use the camelCase verison
if (knownParam || knownUrlParam) {
paramName = camelName;
}
// for ercursively traversing the params to replace '$stashed' vars
var transformObject = function (vals, val, i) {
if (_.isString(val)) {
val = (val[0] === '$') ? this.get(val) : val;
} else if (_.isPlainObject(val) || _.isArray(val)) {
val = _.transform(val, transformObject);
// if we do know this param name, use the camelCase verison
if (knownParam || knownUrlParam) {
paramName = camelName;
}
vals[i] = val;
}.bind(this);
// for ercursively traversing the params to replace '$stashed' vars
var transformObject = function(vals, val, i) {
if (_.isString(val)) {
val = val[0] === '$' ? this.get(val) : val;
} else if (_.isPlainObject(val) || _.isArray(val)) {
val = _.transform(val, transformObject);
}
transformObject(params, val, paramName);
}, this), {});
vals[i] = val;
}.bind(this);
transformObject(params, val, paramName);
}, this),
{}
);
expect(clientAction || clientActionName).to.be.a('function');
@ -448,7 +498,7 @@ YamlDoc.prototype = {
}
var timeoutId;
var cb = _.bind(function (error, body) {
var cb = _.bind(function(error, body) {
this._last_requests_response = body;
clearTimeout(timeoutId);
@ -474,13 +524,16 @@ YamlDoc.prototype = {
}, this);
var req = clientAction.call(client, params, cb);
timeoutId = setTimeout(function () {
// request timed out, so we will skip the rest of the tests and continue
req.abort();
this.skipping = true;
this._last_requests_response = {};
done();
}.bind(this), 20000);
timeoutId = setTimeout(
function() {
// request timed out, so we will skip the rest of the tests and continue
req.abort();
this.skipping = true;
this._last_requests_response = {};
done();
}.bind(this),
20000
);
},
/**
@ -493,10 +546,13 @@ YamlDoc.prototype = {
* @param {Object} args - The object set to the "set" key in the test
* @return {undefined}
*/
do_set: function (args) {
_.forOwn(args, _.bind(function (name, path) {
this._stash[name] = this.get(path);
}, this));
do_set: function(args) {
_.forOwn(
args,
_.bind(function(name, path) {
this._stash[name] = this.get(path);
}, this)
);
},
/**
@ -506,7 +562,7 @@ YamlDoc.prototype = {
* @param {string} path - Path to the response value to test
* @return {undefined}
*/
do_is_true: function (path) {
do_is_true: function(path) {
var val = this.get(path);
try {
expect(Boolean(val)).to.be(true, 'path: ' + path);
@ -522,12 +578,14 @@ YamlDoc.prototype = {
* @param {string} path - Path to the response value to test
* @return {undefined}
*/
do_is_false: function (path) {
do_is_false: function(path) {
var val = this.get(path);
try {
expect(Boolean(val)).to.be(false, 'path: ' + path);
} catch (e) {
throw new Error('expected path "' + path + '" to be false but got ' + val);
throw new Error(
'expected path "' + path + '" to be false but got ' + val
);
}
},
@ -562,7 +620,7 @@ YamlDoc.prototype = {
*
* @return {undefined}
*/
do_match: function (args) {
do_match: function(args) {
var self = this;
// recursively replace all $var within args
@ -572,80 +630,77 @@ YamlDoc.prototype = {
}
if (_.isString(val)) {
lvl[key] = val.replace(/\$[a-zA-Z0-9_]+/g, function (name) {
lvl[key] = val.replace(/\$[a-zA-Z0-9_]+/g, function(name) {
return self.get(name);
});
}
});
_.forOwn(args, _.bind(function (match, path) {
var origMatch = match;
_.forOwn(
args,
_.bind(function(match, path) {
var origMatch = match;
var maybeRE = false;
var usedRE = false;
var maybeRE = false;
var usedRE = false;
if (_.isString(match)) {
// convert the matcher into a compatible string for building a regexp
maybeRE = match
// replace comments, but allow the # to be escaped like \#
.replace(reCommentsRE, function (match, prevChar) {
if (prevChar === '\\') {
return match;
} else {
return prevChar + '\n';
}
})
// remove all whitespace from the expression, all meaningful
// whitespace is represented with \s
.replace(reWhitespaceRE, '');
if (_.isString(match)) {
// convert the matcher into a compatible string for building a regexp
maybeRE = match
// replace comments, but allow the # to be escaped like \#
.replace(reCommentsRE, function(match, prevChar) {
if (prevChar === '\\') {
return match;
} else {
return prevChar + '\n';
}
})
// remove all whitespace from the expression, all meaningful
// whitespace is represented with \s
.replace(reWhitespaceRE, '');
var startsWithSlash = maybeRE[0] === '/';
var endsWithSlash = maybeRE[maybeRE.length - 1] === '/';
var startsWithSlash = maybeRE[0] === '/';
var endsWithSlash = maybeRE[maybeRE.length - 1] === '/';
if (startsWithSlash && endsWithSlash) {
usedRE = true;
match = new RegExp(maybeRE.substr(1, maybeRE.length - 2));
}
}
var val = this.get(path);
var test = 'eql';
if (match instanceof RegExp) {
test = 'match';
// convert falsy values to an empty string so that regexp doesn't
// cast them to the strings "false", "undefined", etc.
val = val || '';
}
try {
expect(val).to[test](match);
} catch (e) {
var msg = [
'\nUnable to match',
inspect(match),
'with the path',
inspect(path),
'and value',
inspect(val)
];
if (usedRE) {
msg.push(
'and original matcher',
'|' + origMatch
);
if (startsWithSlash && endsWithSlash) {
usedRE = true;
match = new RegExp(maybeRE.substr(1, maybeRE.length - 2));
}
}
msg.push(
'original error',
e.message
);
var val = this.get(path);
var test = 'eql';
throw new Error(msg.join('\n'));
}
}, this));
if (match instanceof RegExp) {
test = 'match';
// convert falsy values to an empty string so that regexp doesn't
// cast them to the strings "false", "undefined", etc.
val = val || '';
}
try {
expect(val).to[test](match);
} catch (e) {
var msg = [
'\nUnable to match',
inspect(match),
'with the path',
inspect(path),
'and value',
inspect(val),
];
if (usedRE) {
msg.push('and original matcher', '|' + origMatch);
}
msg.push('original error', e.message);
throw new Error(msg.join('\n'));
}
}, this)
);
},
/**
@ -654,10 +709,13 @@ YamlDoc.prototype = {
* @param {Object} args - Hash of fields->values that need to be checked
* @return {undefined}
*/
do_lt: function (args) {
_.forOwn(args, _.bind(function (num, path) {
expect(this.get(path)).to.be.below(num, 'path: ' + path);
}, this));
do_lt: function(args) {
_.forOwn(
args,
_.bind(function(num, path) {
expect(this.get(path)).to.be.below(num, 'path: ' + path);
}, this)
);
},
/**
@ -666,10 +724,13 @@ YamlDoc.prototype = {
* @param {Object} args - Hash of fields->values that need to be checked
* @return {undefined}
*/
do_lte: function (args) {
_.forOwn(args, _.bind(function (num, path) {
expect(this.get(path) <= num).to.be.ok('path: ' + path);
}, this));
do_lte: function(args) {
_.forOwn(
args,
_.bind(function(num, path) {
expect(this.get(path) <= num).to.be.ok('path: ' + path);
}, this)
);
},
/**
@ -678,10 +739,13 @@ YamlDoc.prototype = {
* @param {Object} args - Hash of fields->values that need to be checked
* @return {undefined}
*/
do_gt: function (args) {
_.forOwn(args, _.bind(function (num, path) {
expect(this.get(path)).to.be.above(num, 'path: ' + path);
}, this));
do_gt: function(args) {
_.forOwn(
args,
_.bind(function(num, path) {
expect(this.get(path)).to.be.above(num, 'path: ' + path);
}, this)
);
},
/**
@ -690,10 +754,13 @@ YamlDoc.prototype = {
* @param {Object} args - Hash of fields->values that need to be checked
* @return {undefined}
*/
do_gte: function (args) {
_.forOwn(args, _.bind(function (num, path) {
expect(this.get(path) >= num).to.be.ok('path: ' + path);
}, this));
do_gte: function(args) {
_.forOwn(
args,
_.bind(function(num, path) {
expect(this.get(path) >= num).to.be.ok('path: ' + path);
}, this)
);
},
/**
@ -703,9 +770,12 @@ YamlDoc.prototype = {
* @param {Object} args - Hash of fields->values that need to be checked
* @return {undefined}
*/
do_length: function (args) {
_.forOwn(args, _.bind(function (len, path) {
expect(_.size(this.get(path))).to.eql(len, 'path: ' + path);
}, this));
}
do_length: function(args) {
_.forOwn(
args,
_.bind(function(len, path) {
expect(_.size(this.get(path))).to.eql(len, 'path: ' + path);
}, this)
);
},
};

View File

@ -17,28 +17,33 @@ function YamlFile(filename, docs) {
// file level skipping flag
file.skipping = false;
describe(filename, function () {
file.docs = _.map(docs, function (doc) {
describe(filename, function() {
file.docs = _.map(docs, function(doc) {
doc = new YamlDoc(doc, file);
if (doc.description === 'setup') {
beforeEach(/* doc */function (done) {
async.series(doc.getActionsRunners(), done);
});
beforeEach(
/* doc */ function(done) {
async.series(doc.getActionsRunners(), done);
}
);
} else {
it(doc.description, function (done) {
it(doc.description, function(done) {
async.series(doc.getActionsRunners(), done);
});
}
});
afterEach(/* doc */function () {
clientManager.get().transport.log.debug(
'===========================\n' +
'Cleanup\n' +
'==========================='
);
return clientManager.get().clearEs();
});
afterEach(
/* doc */ function() {
clientManager
.get()
.transport.log.debug(
'===========================\n' +
'Cleanup\n' +
'==========================='
);
return clientManager.get().clearEs();
}
);
});
}

View File

@ -5,11 +5,11 @@ var XhrServer = MockHttpRequest.MockHttpServer;
var parseUrl = MockHttpRequest.prototype.parseUri;
var _ = require('lodash');
var server = new XhrServer(function (request) {
var server = new XhrServer(function(request) {
var reqDetails = {
method: request.method,
host: request.urlParts.host,
path: request.urlParts.relative
path: request.urlParts.relative,
};
var response = _.find(interceptors, reqDetails);
@ -24,36 +24,38 @@ var server = new XhrServer(function (request) {
request.receive(response.status, response.body || void 0);
} else {
throw new Error('No known match for request: ' + JSON.stringify(reqDetails));
throw new Error(
'No known match for request: ' + JSON.stringify(reqDetails)
);
}
});
server.start();
var mockNock = module.exports = function (url) {
var mockNock = (module.exports = function(url) {
var parsedUrl = parseUrl(url);
var req = {
method: 'GET',
host: parsedUrl.host,
times: 1
times: 1,
};
var modifyReq = {
get: function (path) {
get: function(path) {
req.path = path;
req.method = 'GET';
return modifyReq;
},
port: function (path) {
port: function(path) {
req.path = path;
req.method = 'POST';
return modifyReq;
},
times: function (times) {
times: function(times) {
req.times = times;
return modifyReq;
},
reply: function (status, body) {
reply: function(status, body) {
req.status = status;
req.body = body;
switch (typeof req.body) {
@ -64,20 +66,22 @@ var mockNock = module.exports = function (url) {
try {
req.body = req.body && JSON.stringify(req.body);
} catch (e) {
req.body = req.body;
// noop
}
}
interceptors.push(req);
return mockNock(url);
},
done: mockNock.done
done: mockNock.done,
};
return modifyReq;
};
});
mockNock.done = function () {
mockNock.done = function() {
if (interceptors.length) {
throw new Error('Some interceptors were not called: ' + JSON.stringify(interceptors));
throw new Error(
'Some interceptors were not called: ' + JSON.stringify(interceptors)
);
}
};

View File

@ -19,7 +19,7 @@ function MockIncommingMessage() {
this.setEncoding = sinon.stub();
this.headers = {};
this._read = function () {};
this._read = function() {};
}
util.inherits(MockIncommingMessage, Readable);

View File

@ -7,32 +7,31 @@ var util = require('util');
var MockWritableStream; // defined simply for 0.10+, in detail for older versions
var Writable = require('stream').Writable;
if (Writable) {
// nice and simple for streams 2
MockWritableStream = module.exports = function (opts) {
MockWritableStream = module.exports = function(opts) {
Writable.call(this, opts);
this._write = function () {};
this._write = function() {};
};
util.inherits(MockWritableStream, Writable);
} else {
// Node < 0.10 did not provide a usefull stream abstract
var Stream = require('stream').Stream;
module.exports = MockWritableStream = function () {
module.exports = MockWritableStream = function() {
Stream.call(this);
this.writable = true;
};
util.inherits(MockWritableStream, Stream);
MockWritableStream.prototype.write = function () {
MockWritableStream.prototype.write = function() {
if (!this.writable) {
this.emit('error', new Error('stream not writable'));
return false;
}
var cb;
if (typeof(arguments[arguments.length - 1]) === 'function') {
if (typeof arguments[arguments.length - 1] === 'function') {
cb = arguments[arguments.length - 1];
}
@ -41,7 +40,7 @@ if (Writable) {
}
};
MockWritableStream.prototype.end = function (data, encoding) {
MockWritableStream.prototype.end = function(data, encoding) {
if (typeof data === 'function') {
// no callback support
} else if (typeof encoding === 'function') {
@ -53,18 +52,20 @@ if (Writable) {
this.writable = false;
};
MockWritableStream.prototype.destroy = function (cb) {
MockWritableStream.prototype.destroy = function(cb) {
var self = this;
if (!this.writable) {
if (cb) {
process.nextTick(function () { cb(null); });
process.nextTick(function() {
cb(null);
});
}
return;
}
this.writable = false;
process.nextTick(function () {
process.nextTick(function() {
if (cb) {
cb(null);
}
@ -74,5 +75,4 @@ if (Writable) {
// There is no shutdown() for files.
MockWritableStream.prototype.destroySoon = MockWritableStream.prototype.end;
}

View File

@ -3,8 +3,8 @@ var _ = require('lodash');
var expect = require('expect.js');
var Promise = require('bluebird');
describe('Angular esFactory', function () {
before(function () {
describe('Angular esFactory', function() {
before(function() {
require('../../../src/elasticsearch.angular.js');
});
@ -12,18 +12,18 @@ describe('Angular esFactory', function () {
var $rootScope;
function bootstrap(env) {
beforeEach(function () {
beforeEach(function() {
var promiseProvider = _.noop;
if (env.bluebirdPromises) {
promiseProvider = function ($provide) {
$provide.service('$q', function () {
promiseProvider = function($provide) {
$provide.service('$q', function() {
return {
defer: function () {
defer: function() {
return _.bindAll(Promise.defer(), ['resolve', 'reject']);
},
reject: Promise.reject,
when: Promise.resolve,
all: Promise.all
all: Promise.all,
};
});
};
@ -32,29 +32,31 @@ describe('Angular esFactory', function () {
angular.mock.module(promiseProvider, 'elasticsearch');
});
beforeEach(angular.mock.inject(function ($injector) {
esFactory = $injector.get('esFactory');
$rootScope = $injector.get('$rootScope');
}));
beforeEach(
angular.mock.inject(function($injector) {
esFactory = $injector.get('esFactory');
$rootScope = $injector.get('$rootScope');
})
);
}
describe('basic', function () {
describe('basic', function() {
bootstrap({
bluebirdPromises: true
bluebirdPromises: true,
});
it('is available in the elasticsearch module', function () {
it('is available in the elasticsearch module', function() {
expect(esFactory).to.be.a('function');
});
it('has Transport and ConnectionPool properties', function () {
it('has Transport and ConnectionPool properties', function() {
expect(esFactory).to.have.property('Transport');
expect(esFactory).to.have.property('ConnectionPool');
});
it('returns a new client when it is called', function () {
it('returns a new client when it is called', function() {
var client = esFactory({
hosts: null
hosts: null,
});
expect(client).to.have.keys('transport');
@ -62,15 +64,18 @@ describe('Angular esFactory', function () {
client.close();
});
it('returns an error created by calling a method incorrectly', function () {
it('returns an error created by calling a method incorrectly', function() {
var client = esFactory({ hosts: null });
var prom = client.get().then(function () {
throw new Error('expected request to fail');
}, function (err) {
expect(err).to.have.property('message');
expect(err.message).to.match(/unable/i);
});
var prom = client.get().then(
function() {
throw new Error('expected request to fail');
},
function(err) {
expect(err).to.have.property('message');
expect(err.message).to.match(/unable/i);
}
);
$rootScope.$apply();
return prom;

View File

@ -1,16 +1,16 @@
var expect = require('expect.js');
describe('elasticsearch namespace', function () {
describe('elasticsearch namespace', function() {
var es = window.elasticsearch;
it('is defined on the window', function () {
it('is defined on the window', function() {
expect(es).to.be.ok();
});
it('has Client, ConnectionPool, Transport, and errors keys', function () {
it('has Client, ConnectionPool, Transport, and errors keys', function() {
expect(es).to.have.keys('Client', 'ConnectionPool', 'Transport', 'errors');
});
it('can create a client', function () {
it('can create a client', function() {
var client = new es.Client({ hosts: null });
expect(client).to.have.keys('transport');
expect(client.transport).to.be.a(es.Transport);

View File

@ -1,16 +1,21 @@
/* global $ */
var expect = require('expect.js');
describe('jQuery.es namespace', function () {
it('is defined on the global jQuery', function () {
describe('jQuery.es namespace', function() {
it('is defined on the global jQuery', function() {
expect($.es).to.be.ok();
});
it('has Client, ConnectionPool, Transport, and errors keys', function () {
expect($.es).to.have.keys('Client', 'ConnectionPool', 'Transport', 'errors');
it('has Client, ConnectionPool, Transport, and errors keys', function() {
expect($.es).to.have.keys(
'Client',
'ConnectionPool',
'Transport',
'errors'
);
});
it('can create a client', function () {
it('can create a client', function() {
var client = new $.es.Client({ hosts: null });
expect(client).to.have.keys('transport');
expect(client.transport).to.be.a($.es.Transport);

View File

@ -1,17 +1,18 @@
module.exports = function (makeLogger) {
module.exports = function(makeLogger) {
var expect = require('expect.js');
var stub = require('../utils/auto_release_stub').make();
var fs = require('fs');
var once = require('events').EventEmitter.prototype.once;
var _ = require('lodash');
describe('buffer flush', function () {
describe('buffer flush', function() {
if (require('stream').Writable) {
it('writes everything in the buffer to console.error', function () {
var line = 'This string is written 10 times to create buffered output\n';
it('writes everything in the buffer to console.error', function() {
var line =
'This string is written 10 times to create buffered output\n';
var exitHandler;
stub(process, 'once', function (event, handler) {
stub(process, 'once', function(event, handler) {
if (event === 'exit') {
exitHandler = handler;
}
@ -21,13 +22,13 @@ module.exports = function (makeLogger) {
var logger = makeLogger();
// write the line 10 times
_.times(10, function () {
_.times(10, function() {
logger.onDebug(line);
});
// collect everything that is written to fs.appendFileSync
var flushedOutput = '';
stub(fs, 'appendFileSync', function (path, str) {
stub(fs, 'appendFileSync', function(path, str) {
flushedOutput += str;
});
@ -36,12 +37,15 @@ module.exports = function (makeLogger) {
// the first line is sent immediately to _write and there is nothing we can do about that
expect(flushedOutput).to.match(new RegExp(line));
expect(flushedOutput.match(new RegExp(line, 'g'))).to.have.property('length', 9);
expect(flushedOutput.match(new RegExp(line, 'g'))).to.have.property(
'length',
9
);
});
} else {
it('does not fall apart with non streams2 streams', function () {
it('does not fall apart with non streams2 streams', function() {
var exitHandler;
stub(process, 'once', function (event, handler) {
stub(process, 'once', function(event, handler) {
if (event === 'exit') {
exitHandler = handler;
}
@ -50,7 +54,7 @@ module.exports = function (makeLogger) {
makeLogger();
expect(function () {
expect(function() {
// call the event handler
exitHandler.call(process);
}).to.not.throwError();

View File

@ -1,5 +1,5 @@
require('blanket')({
pattern: require('path').join(__dirname, '../../src')
pattern: require('path').join(__dirname, '../../src'),
});
require('./index');

View File

@ -3,16 +3,16 @@ var Log = require('../../src/lib/log');
var now = new Date('2013-03-01T00:00:00Z');
var sinon = require('sinon');
module.exports = function (makeLogger) {
module.exports = function(makeLogger) {
var stub = require('../utils/auto_release_stub').make();
var parent = new Log();
afterEach(function () {
afterEach(function() {
parent.close();
});
describe('Constuctor', function () {
it('calls setupListeners, passes its new levels', function () {
describe('Constuctor', function() {
it('calls setupListeners, passes its new levels', function() {
var logger = makeLogger(parent);
stub(logger.constructor.prototype, 'setupListeners');
parent.close();
@ -21,21 +21,21 @@ module.exports = function (makeLogger) {
expect(logger.setupListeners).to.have.property('callCount', 1);
});
it('listens for the loggers\' "closing" event', function () {
it('listens for the loggers\' "closing" event', function() {
makeLogger(parent);
expect(parent.listenerCount('closing')).to.eql(1);
});
});
describe('listening levels', function () {
it('calls cleanUpListeners when the listeners are being setup', function () {
describe('listening levels', function() {
it('calls cleanUpListeners when the listeners are being setup', function() {
var logger = makeLogger();
stub(logger, 'cleanUpListeners');
logger.setupListeners([]);
expect(logger.cleanUpListeners).to.have.property('callCount', 1);
});
it('listens to just error when log is explicitly error', function () {
it('listens to just error when log is explicitly error', function() {
makeLogger(parent, 'error');
expect(parent.listenerCount('error')).to.eql(1);
expect(parent.listenerCount('warning')).to.eql(0);
@ -44,7 +44,7 @@ module.exports = function (makeLogger) {
expect(parent.listenerCount('trace')).to.eql(0);
});
it('listens for all the events when level is "trace"', function () {
it('listens for all the events when level is "trace"', function() {
makeLogger(parent, 'trace');
expect(parent.listenerCount('error')).to.eql(1);
expect(parent.listenerCount('warning')).to.eql(1);
@ -53,7 +53,7 @@ module.exports = function (makeLogger) {
expect(parent.listenerCount('trace')).to.eql(1);
});
it('listens for specific events when level is an array', function () {
it('listens for specific events when level is an array', function() {
makeLogger(parent, ['error', 'trace']);
expect(parent.listenerCount('error')).to.eql(1);
expect(parent.listenerCount('warning')).to.eql(0);
@ -62,29 +62,35 @@ module.exports = function (makeLogger) {
expect(parent.listenerCount('trace')).to.eql(1);
});
it('sets the logLevel property to the new levels', function () {
it('sets the logLevel property to the new levels', function() {
var logger = makeLogger();
var levels = ['error'];
logger.setupListeners(levels);
expect(logger.listeningLevels).to.eql(levels).and.not.be(levels);
expect(logger.listeningLevels)
.to.eql(levels)
.and.not.be(levels);
levels = ['warning', 'trace'];
logger.setupListeners(levels);
expect(logger.listeningLevels).to.eql(levels).and.not.be(levels);
expect(logger.listeningLevels)
.to.eql(levels)
.and.not.be(levels);
levels = ['debug', 'debug'];
logger.setupListeners(levels);
expect(logger.listeningLevels).to.eql(levels).and.not.be(levels);
expect(logger.listeningLevels)
.to.eql(levels)
.and.not.be(levels);
});
it('rejects listening levels it can not listen to', function () {
it('rejects listening levels it can not listen to', function() {
var logger = makeLogger();
expect(function () {
expect(function() {
logger.setupListeners(['scream']);
}).to.throwError(/unable to listen/i);
});
it('emits events because something is listening', function () {
it('emits events because something is listening', function() {
makeLogger(parent, 'trace');
stub(parent, 'emit');
@ -105,42 +111,40 @@ module.exports = function (makeLogger) {
});
});
describe('#timestamp', function () {
it('returns in the right format', function () {
describe('#timestamp', function() {
it('returns in the right format', function() {
stub.autoRelease(sinon.useFakeTimers(now.getTime()));
var logger = makeLogger();
expect(logger.timestamp()).to.eql('2013-03-01T00:00:00Z');
});
});
describe('#format', function () {
it('returns a single string with the message indented', function () {
describe('#format', function() {
it('returns a single string with the message indented', function() {
stub.autoRelease(sinon.useFakeTimers(now.getTime()));
var logger = makeLogger();
expect(logger.format('LABEL', 'MSG')).to.eql(
'LABEL: 2013-03-01T00:00:00Z\n' +
' MSG\n' +
'\n'
'LABEL: 2013-03-01T00:00:00Z\n' + ' MSG\n' + '\n'
);
});
it('properly indents multi-line messages', function () {
it('properly indents multi-line messages', function() {
stub.autoRelease(sinon.useFakeTimers(now.getTime()));
var logger = makeLogger();
expect(logger.format('LABEL', 'MSG\nwith\nseveral lines')).to.eql(
'LABEL: 2013-03-01T00:00:00Z\n' +
' MSG\n' +
' with\n' +
' several lines\n' +
'\n'
' MSG\n' +
' with\n' +
' several lines\n' +
'\n'
);
});
});
describe('#onError', function () {
it('uses the Error name when it is not just "Error"', function () {
describe('#onError', function() {
it('uses the Error name when it is not just "Error"', function() {
var logger = makeLogger();
stub(logger, 'write', function (label) {
stub(logger, 'write', function(label) {
expect(label).to.eql('TypeError');
});
@ -148,9 +152,9 @@ module.exports = function (makeLogger) {
expect(logger.write.callCount).to.eql(1);
});
it('uses "ERROR" when the error name is "Error"', function () {
it('uses "ERROR" when the error name is "Error"', function() {
var logger = makeLogger();
stub(logger, 'write', function (label) {
stub(logger, 'write', function(label) {
expect(label).to.eql('ERROR');
});
@ -159,19 +163,19 @@ module.exports = function (makeLogger) {
});
});
describe('#onWarning', function () {
it('uses the "WARNING" label', function () {
describe('#onWarning', function() {
it('uses the "WARNING" label', function() {
var logger = makeLogger();
stub(logger, 'write', function (label) {
stub(logger, 'write', function(label) {
expect(label).to.eql('WARNING');
});
logger.onWarning('message');
expect(logger.write.callCount).to.eql(1);
});
it('echos the message', function () {
it('echos the message', function() {
var logger = makeLogger();
stub(logger, 'write', function (label, msg) {
stub(logger, 'write', function(label, msg) {
expect(msg).to.eql('message');
});
@ -180,19 +184,19 @@ module.exports = function (makeLogger) {
});
});
describe('#onInfo', function () {
it('uses the "INFO" label', function () {
describe('#onInfo', function() {
it('uses the "INFO" label', function() {
var logger = makeLogger();
stub(logger, 'write', function (label) {
stub(logger, 'write', function(label) {
expect(label).to.eql('INFO');
});
logger.onInfo('message');
expect(logger.write.callCount).to.eql(1);
});
it('echos the message', function () {
it('echos the message', function() {
var logger = makeLogger();
stub(logger, 'write', function (label, msg) {
stub(logger, 'write', function(label, msg) {
expect(msg).to.eql('message');
});
@ -201,19 +205,19 @@ module.exports = function (makeLogger) {
});
});
describe('#onDebug', function () {
it('uses the "DEBUG" label', function () {
describe('#onDebug', function() {
it('uses the "DEBUG" label', function() {
var logger = makeLogger();
stub(logger, 'write', function (label) {
stub(logger, 'write', function(label) {
expect(label).to.eql('DEBUG');
});
logger.onDebug('message');
expect(logger.write.callCount).to.eql(1);
});
it('echos the message', function () {
it('echos the message', function() {
var logger = makeLogger();
stub(logger, 'write', function (label, msg) {
stub(logger, 'write', function(label, msg) {
expect(msg).to.eql('message');
});
@ -222,13 +226,21 @@ module.exports = function (makeLogger) {
});
});
describe('#onTrace', function () {
it('uses the "TRACE" label', function () {
describe('#onTrace', function() {
it('uses the "TRACE" label', function() {
var logger = makeLogger();
stub(logger, 'write', function (label) {
stub(logger, 'write', function(label) {
expect(label).to.eql('TRACE');
});
logger.onTrace(Log.normalizeTraceArgs('GET', 'http://place/thing?me=true', '{}', '{"ok": true}', 200));
logger.onTrace(
Log.normalizeTraceArgs(
'GET',
'http://place/thing?me=true',
'{}',
'{"ok": true}',
200
)
);
expect(logger.write.callCount).to.eql(1);
});
});

View File

@ -1,6 +1,9 @@
require('bluebird').longStackTraces();
const { resolve } = require('path');
var specDir = __dirname + '/specs';
require('fs').readdirSync(specDir).forEach(function (file) {
require(specDir + '/' + file);
});
var specDir = resolve(__dirname, 'specs');
require('fs')
.readdirSync(specDir)
.forEach(function(file) {
require(specDir + '/' + file);
});

View File

@ -1,4 +1,4 @@
describe('Logger Abstract', function () {
describe('Logger Abstract', function() {
var expect = require('expect.js');
var Log = require('../../../src/lib/log');
var LoggerAbstract = require('../../../src/lib/logger');
@ -7,21 +7,21 @@ describe('Logger Abstract', function () {
function makeLogger(parent, levels) {
return new LoggerAbstract(parent || parentLog, {
levels: Log.parseLevels(levels || [])
levels: Log.parseLevels(levels || []),
});
}
beforeEach(function () {
beforeEach(function() {
parentLog = new Log();
});
afterEach(function () {
afterEach(function() {
parentLog.close();
});
describe('#write', function () {
it('requires that it is overwritten', function () {
expect(function () {
describe('#write', function() {
it('requires that it is overwritten', function() {
expect(function() {
var logger = makeLogger();
logger.write();
}).to.throwError(/overwritten/);
@ -29,5 +29,4 @@ describe('Logger Abstract', function () {
});
require('../generic_logger_tests')(makeLogger);
});

View File

@ -1,58 +1,62 @@
describe('Client instances creation', function () {
describe('Client instances creation', function() {
var stream = require('stream');
var util = require('util');
var es = require('../../../src/elasticsearch');
var apis = require('../../../src/lib/apis');
var expect = require('expect.js');
var stub = require('../../utils/auto_release_stub').make();
var client;
describe('', function () {
beforeEach(function () {
describe('', function() {
beforeEach(function() {
client = new es.Client();
});
afterEach(function () {
afterEach(function() {
client.close();
});
it('throws an error linking to the es module when you try to instanciate the exports', function () {
it('throws an error linking to the es module when you try to instanciate the exports', function() {
var Es = es;
expect(function () {
expect(function() {
var c = new Es();
return c
return c;
}).to.throwError(/previous "elasticsearch" module/);
});
var pkg = require('../../../package.json');
var def = pkg.config.default_api_branch;
var prev = pkg.config.supported_es_branches[pkg.config.supported_es_branches.indexOf(def) + 1];
var prev =
pkg.config.supported_es_branches[
pkg.config.supported_es_branches.indexOf(def) + 1
];
it('inherits the ' + def + ' API by default', function () {
it('inherits the ' + def + ' API by default', function() {
expect(client.bulk).to.be(apis[def].bulk);
expect(client.nodes.stats).to.be(apis[def].nodes.prototype.stats);
});
it('inherits the ' + prev + ' API when specified', function () {
it('inherits the ' + prev + ' API when specified', function() {
client.close();
client = es.Client({
apiVersion: prev
apiVersion: prev,
});
expect(client.bulk).to.be(apis[prev].bulk);
expect(client.cluster.nodeStats).to.be(apis[prev].cluster.prototype.nodeStats);
expect(client.cluster.nodeStats).to.be(
apis[prev].cluster.prototype.nodeStats
);
});
it('closing the client causes it\'s transport to be closed', function () {
it("closing the client causes it's transport to be closed", function() {
var called = false;
client.transport.close = function () {
client.transport.close = function() {
called = true;
};
client.close();
expect(called).to.be(true);
});
it('creates a warning level logger by default', function () {
it('creates a warning level logger by default', function() {
expect(client.transport.log.listenerCount('error')).to.eql(1);
expect(client.transport.log.listenerCount('warning')).to.eql(1);
expect(client.transport.log.listenerCount('info')).to.eql(0);
@ -61,21 +65,19 @@ describe('Client instances creation', function () {
});
});
describe('config', function () {
it('accepts a stream type logger', function (done) {
describe('config', function() {
it('accepts a stream type logger', function(done) {
function NullStream() {
stream.Writable.call(this);
}
util.inherits(NullStream, stream.Writable);
NullStream.prototype._write = function (/* chunk, encoding, next */) {
NullStream.prototype._write = function(/* chunk, encoding, next */) {
done();
};
client = new es.Client({
log: [
{ type: 'stream', stream: new NullStream() }
]
log: [{ type: 'stream', stream: new NullStream() }],
});
client.transport.log.error(new Error());

File diff suppressed because it is too large Load Diff

View File

@ -7,45 +7,45 @@ var errors = require('../../../src/lib/errors');
var stub = require('../../utils/auto_release_stub').make();
describe('Connection Abstract', function () {
describe('Connection Abstract', function() {
var host = new Host('localhost:9200');
it('constructs with defaults for host, and bound', function () {
it('constructs with defaults for host, and bound', function() {
var conn = new ConnectionAbstract(host);
expect(conn.host).to.be(host);
});
it('requires a valid host', function () {
expect(function () {
it('requires a valid host', function() {
expect(function() {
// eslint-disable-next-line no-new
new ConnectionAbstract();
}).to.throwError(TypeError);
expect(function () {
expect(function() {
// eslint-disable-next-line no-new
new ConnectionAbstract({});
}).to.throwError(TypeError);
});
it('required that the request method is overridden', function () {
expect(function () {
it('required that the request method is overridden', function() {
expect(function() {
var conn = new ConnectionAbstract(host);
conn.request();
}).to.throwError(/overwrit/);
});
describe('#ping', function () {
it('accpets just a callback', function () {
describe('#ping', function() {
it('accpets just a callback', function() {
var conn = new ConnectionAbstract(host);
stub(conn, 'request');
var cb = function () {};
var cb = function() {};
conn.ping(cb);
expect(conn.request.callCount).to.eql(1);
expect(conn.request.lastCall.args[0]).to.be.a('object');
expect(conn.request.lastCall.args[1]).to.be.a('function');
});
it('accpets just params', function () {
it('accpets just params', function() {
var conn = new ConnectionAbstract(host);
stub(conn, 'request');
conn.ping({});
@ -54,13 +54,13 @@ describe('Connection Abstract', function () {
expect(conn.request.lastCall.args[1]).to.be.a('function');
});
it('allows overriding the requestTimeout, method, and path', function () {
it('allows overriding the requestTimeout, method, and path', function() {
var conn = new ConnectionAbstract(host);
stub(conn, 'request');
var params = {
method: 'HEAD',
path: '/',
requestTimeout: 10000
requestTimeout: 10000,
};
conn.ping(params);
expect(conn.request.callCount).to.eql(1);
@ -68,7 +68,7 @@ describe('Connection Abstract', function () {
expect(conn.request.lastCall.args[1]).to.be.a('function');
});
it('defaults to the pingTimeout in the config', function () {
it('defaults to the pingTimeout in the config', function() {
var conn = new ConnectionAbstract(host, { pingTimeout: 5000 });
var clock = sinon.useFakeTimers('setTimeout', 'clearTimeout');
stub.autoRelease(clock);
@ -81,64 +81,70 @@ describe('Connection Abstract', function () {
expect(clock.timers[_.keys(clock.timers).shift()].delay).to.eql(5000);
});
it('calls it\'s own request method', function () {
it("calls it's own request method", function() {
var conn = new ConnectionAbstract(host);
stub(conn, 'request');
conn.ping();
expect(conn.request.callCount).to.eql(1);
});
it('sets a timer for the request', function (done) {
it('sets a timer for the request', function(done) {
var conn = new ConnectionAbstract(host);
var clock = sinon.useFakeTimers('setTimeout', 'clearTimeout');
stub.autoRelease(clock);
var order = 0;
stub(conn, 'request', function (params, cb) {
setTimeout(function () {
stub(conn, 'request', function(params, cb) {
setTimeout(function() {
expect(++order).to.eql(2);
cb();
}, 10001);
});
conn.ping({
requestTimeout: 100
}, function (err) {
expect(++order).to.eql(1);
expect(err).to.be.an(errors.RequestTimeout);
});
conn.ping(
{
requestTimeout: 100,
},
function(err) {
expect(++order).to.eql(1);
expect(err).to.be.an(errors.RequestTimeout);
}
);
process.nextTick(function () {
process.nextTick(function() {
clock.tick(1000);
clock.tick(10000);
done();
});
});
it('calls the requestAborter if req takes too long', function (done) {
it('calls the requestAborter if req takes too long', function(done) {
var conn = new ConnectionAbstract(host);
var clock = sinon.useFakeTimers('setTimeout', 'clearTimeout');
stub.autoRelease(clock);
var order = 0;
stub(conn, 'request', function (params, cb) {
setTimeout(function () {
stub(conn, 'request', function(params, cb) {
setTimeout(function() {
expect(++order).to.eql(3);
cb();
}, 10001);
return function () {
return function() {
expect(++order).to.eql(1);
};
});
conn.ping({
requestTimeout: 100
}, function (err) {
expect(++order).to.eql(2);
expect(err).to.be.an(errors.RequestTimeout);
});
conn.ping(
{
requestTimeout: 100,
},
function(err) {
expect(++order).to.eql(2);
expect(err).to.be.an(errors.RequestTimeout);
}
);
process.nextTick(function () {
process.nextTick(function() {
clock.tick(1000);
clock.tick(10000);
done();
@ -148,15 +154,15 @@ describe('Connection Abstract', function () {
// it('ignores the response from the request if it already aborted');
});
describe('#setStatus', function () {
it('emits the "status set" event with `new`, `old` & `conn` args', function () {
describe('#setStatus', function() {
it('emits the "status set" event with `new`, `old` & `conn` args', function() {
var conn = new ConnectionAbstract(host);
var emitted = false;
conn.emit = function (eventName) {
conn.emit = function(eventName) {
emitted = {
name: eventName,
args: Array.prototype.slice.call(arguments, 1)
args: Array.prototype.slice.call(arguments, 1),
};
};
@ -165,7 +171,7 @@ describe('Connection Abstract', function () {
expect(emitted.args).to.eql(['closed', undefined, conn]);
});
it('stores the status in this.status', function () {
it('stores the status in this.status', function() {
var conn = new ConnectionAbstract(host);
conn.setStatus('closed');

View File

@ -17,25 +17,25 @@ function listenerCount(emitter, event) {
}
}
describe('Connection Pool', function () {
describe('Adding/Removing/Syncing Connections', function () {
describe('Connection Pool', function() {
describe('Adding/Removing/Syncing Connections', function() {
var pool, host, connection, host2, connection2;
beforeEach(function () {
beforeEach(function() {
pool = new ConnectionPool({});
host = new Host({
port: 999
port: 999,
});
connection = new ConnectionAbstract(host);
host2 = new Host({
port: 2222
port: 2222,
});
connection2 = new ConnectionAbstract(host2);
});
it('#addConnection only adds the connection if it doesn\'t already exist', function () {
it("#addConnection only adds the connection if it doesn't already exist", function() {
expect(_.keys(pool.index).length).to.eql(0);
pool.addConnection(connection);
@ -45,8 +45,8 @@ describe('Connection Pool', function () {
expect(pool._conns.dead).to.eql([]);
});
describe('#removeConnection', function () {
it('removes the connection if it exist', function () {
describe('#removeConnection', function() {
it('removes the connection if it exist', function() {
pool.addConnection(connection);
pool.removeConnection(connection2);
@ -55,7 +55,7 @@ describe('Connection Pool', function () {
expect(_.keys(pool.index).length).to.eql(1);
});
it('closes the connection when it removes it', function () {
it('closes the connection when it removes it', function() {
pool.addConnection(connection);
expect(connection.status).to.eql('alive');
expect(listenerCount(connection, 'status set')).to.eql(1);
@ -67,7 +67,7 @@ describe('Connection Pool', function () {
});
});
it('#setHosts syncs the list of Hosts with the connections in the index', function () {
it('#setHosts syncs the list of Hosts with the connections in the index', function() {
// there should now be two connections
pool.setHosts([host, host2]);
expect(pool._conns.alive.length).to.eql(2);
@ -92,53 +92,56 @@ describe('Connection Pool', function () {
});
});
describe('Connection selection', function () {
describe('Connection selection', function() {
var pool, host, host2;
beforeEach(function () {
beforeEach(function() {
pool = new ConnectionPool({});
host = new Host('localhost:9200');
host2 = new Host('localhost:9201');
pool.setHosts([
host,
host2
]);
pool.setHosts([host, host2]);
});
it('detects if the selector is async', function (done) {
pool.selector = function (list, cb) {
it('detects if the selector is async', function(done) {
pool.selector = function(list, cb) {
expect(cb).to.be.a('function');
cb();
};
pool.select(function (err) {
if (err) { throw err; }
pool.select(function(err) {
if (err) {
throw err;
}
done();
});
});
it('detects if the selector is not async', function (done) {
pool.selector = function () {
it('detects if the selector is not async', function(done) {
pool.selector = function() {
expect(arguments.length).to.be(1);
};
pool.select(function (err) {
if (err) { throw err; }
pool.select(function(err) {
if (err) {
throw err;
}
done();
});
});
it('sync selectors should still return async', function (done) {
pool.selector = function (list) {
it('sync selectors should still return async', function(done) {
pool.selector = function(list) {
return list[0];
};
var selected = null;
pool.select(function (err, selection) {
if (err) { throw err; }
pool.select(function(err, selection) {
if (err) {
throw err;
}
expect(selection.host).to.be(host);
selected = selection;
done();
@ -147,51 +150,49 @@ describe('Connection Pool', function () {
expect(selected).to.be(null);
});
it('should catch errors in sync selectors', function (done) {
pool.selector = function () {
it('should catch errors in sync selectors', function(done) {
pool.selector = function() {
return JSON.notAMethod();
};
pool.select(function (err) {
pool.select(function(err) {
expect(err).be.an(Error);
done();
});
});
});
describe('Connection selection with no living nodes', function () {
it('should ping all of the dead nodes, in order of oldest timeout, and return the first that\'s okay',
function (done) {
describe('Connection selection with no living nodes', function() {
it("should ping all of the dead nodes, in order of oldest timeout, and return the first that's okay", function(done) {
var clock = sinon.useFakeTimers('setTimeout', 'clearTimeout');
stub.autoRelease(clock);
var pool = new ConnectionPool({
deadTimeout: 10000
deadTimeout: 10000,
});
var connections = [
new ConnectionAbstract(new Host('http://localhost:9200')),
new ConnectionAbstract(new Host('http://localhost:9201')),
new ConnectionAbstract(new Host('http://localhost:9202')),
new ConnectionAbstract(new Host('http://localhost:9203'))
new ConnectionAbstract(new Host('http://localhost:9203')),
];
var pingQueue = _.shuffle(connections);
var expectedSelection = pingQueue[pingQueue.length - 1];
_.each(pingQueue, function (conn) {
_.each(pingQueue, function(conn) {
pool.addConnection(conn);
stub(conn, 'ping', function (params, cb) {
stub(conn, 'ping', function(params, cb) {
if (typeof params === 'function') {
cb = params;
}
var expectedConn = pingQueue.shift();
expect(conn).to.be(expectedConn);
if (pingQueue.length) {
process.nextTick(function () {
process.nextTick(function() {
cb(new Error('keep trying'));
});
} else {
process.nextTick(function () {
process.nextTick(function() {
cb(null, true);
});
}
@ -200,7 +201,7 @@ describe('Connection Pool', function () {
clock.tick(500);
});
pool.select(function (err, selection) {
pool.select(function(err, selection) {
expect(selection).to.be(expectedSelection);
expect(pingQueue.length).to.be(0);
pool.setHosts([]);
@ -210,19 +211,16 @@ describe('Connection Pool', function () {
});
});
describe('Connection state management', function () {
describe('Connection state management', function() {
var pool, host, host2, connection, connection2;
beforeEach(function () {
beforeEach(function() {
pool = new ConnectionPool({});
host = new Host('localhost:9200');
host2 = new Host('localhost:9201');
pool.setHosts([
host,
host2
]);
pool.setHosts([host, host2]);
connection = pool.index[host.toString()];
connection2 = pool.index[host2.toString()];
@ -231,32 +229,38 @@ describe('Connection Pool', function () {
expect(pool._conns.dead.length).to.be(0);
});
afterEach(function () {
afterEach(function() {
pool.close();
});
it('moves an alive connection to dead', function () {
it('moves an alive connection to dead', function() {
connection.setStatus('dead');
expect(pool._conns.alive.length).to.be(1);
expect(pool._conns.dead.length).to.be(1);
});
it('clears and resets the timeout when a connection redies', function () {
it('clears and resets the timeout when a connection redies', function() {
var clock = sinon.useFakeTimers();
stub.autoRelease(clock);
connection.setStatus('dead');
expect(_.size(clock.timers)).to.eql(1);
var id = _(clock.timers).keys().head();
var id = _(clock.timers)
.keys()
.head();
// it re-dies
connection.setStatus('dead');
expect(_.size(clock.timers)).to.eql(1);
expect(_(clock.timers).keys().head()).to.not.eql(id);
expect(
_(clock.timers)
.keys()
.head()
).to.not.eql(id);
});
it('does nothing when a connection is re-alive', function () {
it('does nothing when a connection is re-alive', function() {
var last = pool._conns.alive[pool._conns.alive.length - 1];
var first = pool._conns.alive[0];
@ -273,7 +277,7 @@ describe('Connection Pool', function () {
expect(pool._conns.alive[pool._conns.alive.length - 1]).to.be(last);
});
it('removes all its connection when it closes, causing them to be closed', function () {
it('removes all its connection when it closes, causing them to be closed', function() {
pool.close();
expect(pool._conns.alive.length).to.be(0);
expect(pool._conns.dead.length).to.be(0);
@ -281,11 +285,10 @@ describe('Connection Pool', function () {
expect(connection.status).to.eql('closed');
expect(connection2.status).to.eql('closed');
});
});
describe('#getConnections', function () {
it('will return all values from the alive list by default', function () {
describe('#getConnections', function() {
it('will return all values from the alive list by default', function() {
var pool = new ConnectionPool({});
pool._conns.alive = new Array(1000);
var length = pool._conns.alive.length;
@ -295,50 +298,58 @@ describe('Connection Pool', function () {
var result = pool.getConnections();
expect(result.length).to.be(1000);
expect(_.reduce(result, function (sum, num) {
sum += num
return sum;
}, 0)).to.eql(499500);
expect(
_.reduce(
result,
function(sum, num) {
sum += num;
return sum;
},
0
)
).to.eql(499500);
});
});
describe('#calcDeadTimeout', function () {
it('should be configurable via config.calcDeadTimeout', function () {
describe('#calcDeadTimeout', function() {
it('should be configurable via config.calcDeadTimeout', function() {
var pool = new ConnectionPool({
calcDeadTimeout: 'flat'
calcDeadTimeout: 'flat',
});
expect(pool.calcDeadTimeout).to.be(ConnectionPool.calcDeadTimeoutOptions.flat);
expect(pool.calcDeadTimeout).to.be(
ConnectionPool.calcDeadTimeoutOptions.flat
);
pool.close();
});
it('"flat" always returns the base timeout', function () {
it('"flat" always returns the base timeout', function() {
var pool = new ConnectionPool({
calcDeadTimeout: 'flat'
calcDeadTimeout: 'flat',
});
expect(pool.calcDeadTimeout(0, 1000)).to.eql(1000);
expect(pool.calcDeadTimeout(10, 5000)).to.eql(5000);
expect(pool.calcDeadTimeout(25, 10000)).to.eql(10000);
});
it('"exponential" always increases the timeout based on the attempts', function () {
it('"exponential" always increases the timeout based on the attempts', function() {
var pool = new ConnectionPool({
calcDeadTimeout: 'exponential'
calcDeadTimeout: 'exponential',
});
expect(pool.calcDeadTimeout(0, 1000)).to.eql(1000);
expect(pool.calcDeadTimeout(10, 5000)).to.be.greaterThan(5000);
expect(pool.calcDeadTimeout(25, 10000)).to.be.greaterThan(10000);
});
it('"exponential" produces predicatable results', function () {
it('"exponential" produces predicatable results', function() {
var pool = new ConnectionPool({
calcDeadTimeout: 'exponential'
calcDeadTimeout: 'exponential',
});
expect(pool.calcDeadTimeout(0, 1000)).to.eql(1000);
expect(pool.calcDeadTimeout(4, 10000)).to.eql(40000);
// maxes out at 30 minutes by default
expect(pool.calcDeadTimeout(25, 30000)).to.eql(18e5);
});
it('"exponential" repects config.maxDeadtimeout', function () {
it('"exponential" repects config.maxDeadtimeout', function() {
var pool = new ConnectionPool({
calcDeadTimeout: 'exponential',
maxDeadTimeout: 10000
maxDeadTimeout: 10000,
});
expect(pool.calcDeadTimeout(0, 1000)).to.eql(1000);
expect(pool.calcDeadTimeout(10, 1000)).to.eql(10000);

View File

@ -4,29 +4,28 @@ var sinon = require('sinon');
var expect = require('expect.js');
var parentLog;
beforeEach(function () {
beforeEach(function() {
parentLog = new Log();
});
afterEach(function () {
afterEach(function() {
parentLog.close();
});
function makeLogger(parent, levels) {
parent = parent || parentLog;
var config = {
levels: Log.parseLevels(levels || 'trace')
levels: Log.parseLevels(levels || 'trace'),
};
return new ConsoleLogger(parent, config);
}
require('../../utils/auto_release_stub').make();
describe('Console Logger', function () {
describe('Console Logger', function() {
require('../generic_logger_tests')(makeLogger);
it('checks before using unique logging functions, falls back to #log()', function () {
it('checks before using unique logging functions, falls back to #log()', function() {
var _warning = console.warn;
console.warn = null;
sinon.stub(console, 'log');
@ -39,5 +38,4 @@ describe('Console Logger', function () {
console.warn = _warning;
console.log.restore();
});
});

View File

@ -2,10 +2,10 @@ var errors = require('../../../src/lib/errors');
var expect = require('expect.js');
var _ = require('lodash');
_.each(errors, function (CustomError, name) {
_.each(errors, function(CustomError, name) {
if (name.charAt(0) !== '_') {
describe(name, function () {
it('extend the ErrorAbstract and Error classes', function () {
describe(name, function() {
it('extend the ErrorAbstract and Error classes', function() {
var err = new CustomError();
expect(err).to.be.an(Error);
expect(err).to.be.an(errors._Abstract);
@ -14,8 +14,8 @@ _.each(errors, function (CustomError, name) {
}
});
describe('Error Abstract', function () {
it('provides a stack property in the browser', function () {
describe('Error Abstract', function() {
it('provides a stack property in the browser', function() {
var isBrowser = process.browser;
process.browser = true;
var err = new errors._Abstract();
@ -25,8 +25,8 @@ describe('Error Abstract', function () {
});
});
describe('StatusCodeError', function () {
it('exposes status code as a number', function () {
describe('StatusCodeError', function() {
it('exposes status code as a number', function() {
var err = new errors['404']();
expect(err.status).to.be(404);
expect(err.status).to.not.be('404');

View File

@ -1,4 +1,4 @@
describe('File Logger', function () {
describe('File Logger', function() {
var Log = require('../../../src/lib/log');
var FileLogger = require('../../../src/lib/loggers/file');
var once = require('events').EventEmitter.prototype.once;
@ -10,11 +10,11 @@ describe('File Logger', function () {
var fs = require('fs');
var stub = require('../../utils/auto_release_stub').make();
beforeEach(function () {
beforeEach(function() {
parentLog = new Log();
});
afterEach(function () {
afterEach(function() {
parentLog.close();
if (logger) {
utils.clearWriteStreamBuffer(logger.stream);
@ -25,24 +25,25 @@ describe('File Logger', function () {
parent = parent || parentLog;
logger = new FileLogger(parent, {
levels: Log.parseLevels(levels || 'trace'),
path: 'test.log'
path: 'test.log',
});
return logger;
}
after(function () {
after(function() {
fs.unlinkSync('test.log');
});
require('../generic_logger_tests')(makeLogger);
describe('buffer flush', function () {
describe('buffer flush', function() {
if (require('stream').Writable) {
it('writes everything in the buffer to console.error', function () {
var line = 'This string is written 10 times to create buffered output\n';
it('writes everything in the buffer to console.error', function() {
var line =
'This string is written 10 times to create buffered output\n';
var exitHandler;
stub(process, 'once', function (event, handler) {
stub(process, 'once', function(event, handler) {
if (event === 'exit') {
exitHandler = handler;
}
@ -52,13 +53,13 @@ describe('File Logger', function () {
var logger = makeLogger();
// write the line 10 times
_.times(10, function () {
_.times(10, function() {
logger.onDebug(line);
});
// collect everything that is written to fs.appendFileSync
var flushedOutput = '';
stub(fs, 'appendFileSync', function (path, str) {
stub(fs, 'appendFileSync', function(path, str) {
flushedOutput += str;
});
@ -70,9 +71,9 @@ describe('File Logger', function () {
expect(flushedOutput.match(new RegExp(line, 'g')).length).to.be(9);
});
} else {
it('does not fall apart with non streams2 streams', function () {
it('does not fall apart with non streams2 streams', function() {
var exitHandler;
stub(process, 'once', function (event, handler) {
stub(process, 'once', function(event, handler) {
if (event === 'exit') {
exitHandler = handler;
}
@ -81,7 +82,7 @@ describe('File Logger', function () {
makeLogger();
expect(function () {
expect(function() {
// call the event handler
exitHandler.call(process);
}).to.not.throwError();

View File

@ -19,40 +19,42 @@ var hostDefaults = {
ca: null,
ciphers: null,
rejectUnauthorized: false,
secureProtocol: null
}
secureProtocol: null,
},
};
var base64 = function (str) {
var buffer = Buffer.from ? Buffer.from(str, 'utf8') : new Buffer(str, 'utf8')
return buffer.toString('base64')
}
var base64 = function(str) {
var buffer = Buffer.from ? Buffer.from(str, 'utf8') : new Buffer(str, 'utf8');
return buffer.toString('base64');
};
describe('Host class', function () {
describe('construction', function () {
it('properly sets the defaults', function () {
describe('Host class', function() {
describe('construction', function() {
it('properly sets the defaults', function() {
var host = new Host();
expect(host).to.eql(hostDefaults);
});
it('accepts a string for query', function () {
it('accepts a string for query', function() {
var host = new Host({ query: 'beep=boop' });
expect(host.query).to.eql({
beep: 'boop'
beep: 'boop',
});
});
it('accepts other generic params', function () {
it('accepts other generic params', function() {
var headers = { 'X-Special-Routing-Header': 'pie' };
var host = new Host({ headers: headers });
expect(host.headers).to.eql(headers);
});
describe('from a string', function () {
it('accepts a string for the entire url', function () {
var host = new Host('john:dude@pizza.com:420/pizza/cheese?shrooms=true');
describe('from a string', function() {
it('accepts a string for the entire url', function() {
var host = new Host(
'john:dude@pizza.com:420/pizza/cheese?shrooms=true'
);
expectSubObject(host, {
protocol: 'http',
@ -60,12 +62,12 @@ describe('Host class', function () {
port: 420,
path: '/pizza/cheese',
query: {
shrooms: 'true'
}
shrooms: 'true',
},
});
});
it('uses the default port based on the protocol', function () {
it('uses the default port based on the protocol', function() {
var host;
host = new Host('https://google.com');
@ -80,7 +82,7 @@ describe('Host class', function () {
delete Host.defaultPorts.trift;
});
it('parses simple urls properly', function () {
it('parses simple urls properly', function() {
var host;
host = new Host('localhost');
@ -105,8 +107,8 @@ describe('Host class', function () {
});
});
describe('based on the output from url.parse', function () {
it('might cause weird things to happen', function () {
describe('based on the output from url.parse', function() {
it('might cause weird things to happen', function() {
var parsedUrl = url.parse('pizza.com:888');
// I imagine most people don't expect
@ -118,69 +120,80 @@ describe('Host class', function () {
expect(host.host).to.eql('888');
});
it('will cause extra properties', function () {
var host = new Host(url.parse('https://joe:diner@pizza.com:888/path?query=yes#section'));
it('will cause extra properties', function() {
var host = new Host(
url.parse('https://joe:diner@pizza.com:888/path?query=yes#section')
);
expect(host.protocol).to.eql('https');
expect(host.host).to.eql('pizza.com');
expect(host.port).to.eql(888);
expect(host.path).to.eql('/path');
expect(host.headers).to.eql({ Authorization: 'Basic ' + base64('joe:diner') });
expect(host.headers).to.eql({
Authorization: 'Basic ' + base64('joe:diner'),
});
expect(host.query).to.eql({
query: 'yes'
query: 'yes',
});
expect(host).to.include.keys('slashes', 'hash', 'href', 'search');
});
});
it('ignores anything that\'s not a string or object-y', function () {
it("ignores anything that's not a string or object-y", function() {
var host = new Host(1234);
expect(host).to.eql(hostDefaults);
});
it('defaults auth values from the `httpAuth` setting', function () {
it('defaults auth values from the `httpAuth` setting', function() {
var host = new Host('http://localhost:9200', {
httpAuth: 'username:password'
httpAuth: 'username:password',
});
expect(host.headers).to.have.property('Authorization', 'Basic ' + base64('username:password'));
expect(host.headers).to.have.property(
'Authorization',
'Basic ' + base64('username:password')
);
});
});
describe('#makeUrl', function () {
it('merges parameters', function () {
describe('#makeUrl', function() {
it('merges parameters', function() {
var host = new Host({
path: '/prefix',
query: {
user_id: 123
}
user_id: 123,
},
});
expect(host.makeUrl({
path: '/this and that',
query: {
param: 1
}
})).to.be('http://localhost:9200/prefix/this and that?user_id=123&param=1');
expect(
host.makeUrl({
path: '/this and that',
query: {
param: 1,
},
})
).to.be('http://localhost:9200/prefix/this and that?user_id=123&param=1');
});
it('ensures that path starts with a forward-slash', function () {
it('ensures that path starts with a forward-slash', function() {
var host = new Host();
host.path = 'prefix';
expect(host.makeUrl({ path: '/this and that' }))
.to.be('http://localhost:9200/prefix/this and that');
expect(host.makeUrl({ path: '/this and that' })).to.be(
'http://localhost:9200/prefix/this and that'
);
});
it('does not try to prevent double forward-slashes', function () {
it('does not try to prevent double forward-slashes', function() {
var host = new Host({ path: 'prefix/' });
expect(host.makeUrl({ path: '/this and that' }))
.to.be('http://localhost:9200/prefix//this and that');
expect(host.makeUrl({ path: '/this and that' })).to.be(
'http://localhost:9200/prefix//this and that'
);
});
it('creates proper url without any params', function () {
it('creates proper url without any params', function() {
var host = new Host({});
expect(host.makeUrl()).to.be('http://localhost:9200/');
@ -191,58 +204,61 @@ describe('Host class', function () {
expect(host.makeUrl()).to.be('http://italy:9200/pie');
});
it('outputs valid relative urls when the host is empty', function () {
it('outputs valid relative urls when the host is empty', function() {
var host = new Host({
host: false,
path: '/path',
query: { this: 'that' }
query: { this: 'that' },
});
expect(host + '').to.be('/path?this=that');
});
});
describe('#toString', function () {
it('produces the same output as makeUrl when it is called without params', function () {
describe('#toString', function() {
it('produces the same output as makeUrl when it is called without params', function() {
var host = new Host({
path: '/pasta',
host: 'google.com'
host: 'google.com',
});
expect(host.toString()).to.eql(host.makeUrl());
});
});
describe('#getHeaders', function () {
it('merges the passed in headers with the default headers', function () {
describe('#getHeaders', function() {
it('merges the passed in headers with the default headers', function() {
var host = new Host({ headers: { 'Joe-Smith': 'present' } });
expect(host.getHeaders({
'John-Smith': 'present'
})).to.eql({
expect(
host.getHeaders({
'John-Smith': 'present',
})
).to.eql({
'John-Smith': 'present',
'Joe-Smith': 'present'
'Joe-Smith': 'present',
});
});
it('overrides the default headers with the passed in headers', function () {
it('overrides the default headers with the passed in headers', function() {
var host = new Host({ headers: { 'Joe-Smith': 'present' } });
expect(host.getHeaders({
expect(
host.getHeaders({
'John-Smith': 'present',
'Joe-Smith': 'absent',
})
).to.eql({
'John-Smith': 'present',
'Joe-Smith': 'absent'
})).to.eql({
'John-Smith': 'present',
'Joe-Smith': 'absent'
'Joe-Smith': 'absent',
});
});
it('adds Accept-Encoding header when the suggestCompression setting is true', function () {
it('adds Accept-Encoding header when the suggestCompression setting is true', function() {
var host = new Host({ suggestCompression: true });
expect(host.getHeaders()).to.eql({
'Accept-Encoding': 'gzip,deflate'
'Accept-Encoding': 'gzip,deflate',
});
});
});
});

View File

@ -1,5 +1,4 @@
describe('Http Connector', function () {
describe('Http Connector', function() {
var _ = require('lodash');
var expect = require('expect.js');
var nock = require('nock');
@ -22,7 +21,7 @@ describe('Http Connector', function () {
var stub = require('../../utils/auto_release_stub').make();
function makeStubReqMethod(prep) {
return function (params, cb) {
return function(params, cb) {
var req = new MockRequest();
if (prep) {
prep(req, params, cb);
@ -32,21 +31,21 @@ describe('Http Connector', function () {
}
function whereReqDies(withErr) {
return function (req) {
process.nextTick(function () {
return function(req) {
process.nextTick(function() {
// causes the request to quit and callback
req.emit('error', withErr || void 0);
});
};
}
describe('Constructor', function () {
it('creates an object that extends ConnectionAbstract', function () {
describe('Constructor', function() {
it('creates an object that extends ConnectionAbstract', function() {
var con = new HttpConnection(new Host());
expect(con).to.be.a(ConnectionAbstract);
});
it('sets certain defaults', function () {
it('sets certain defaults', function() {
var con = new HttpConnection(new Host());
expect(con.hand).to.be(require('http'));
@ -57,27 +56,31 @@ describe('Http Connector', function () {
// requestTimeout
});
it('expects the host to have a protocol of http or https', function () {
expect(function () {
it('expects the host to have a protocol of http or https', function() {
expect(function() {
// eslint-disable-next-line no-new
new HttpConnection(new Host('thrifty://es.com/stuff'));
}).to.throwError(/invalid protocol/i);
});
it('allows defining a custom agent', function () {
it('allows defining a custom agent', function() {
var football = {};
var con = new HttpConnection(new Host(), { createNodeAgent: _.constant(football) });
var con = new HttpConnection(new Host(), {
createNodeAgent: _.constant(football),
});
expect(con.agent).to.be(football);
});
it('allows setting agent to false', function () {
var con = new HttpConnection(new Host(), { createNodeAgent: _.constant(false) });
it('allows setting agent to false', function() {
var con = new HttpConnection(new Host(), {
createNodeAgent: _.constant(false),
});
expect(con.agent).to.be(false);
});
});
describe('#makeReqParams', function () {
it('properly reads the host object', function () {
describe('#makeReqParams', function() {
it('properly reads the host object', function() {
var host = new Host('john:dude@pizza.com:9200/pizza/cheese?shrooms=true');
var con = new HttpConnection(host, {});
var reqParams = con.makeReqParams();
@ -90,34 +93,38 @@ describe('Http Connector', function () {
port: 9200,
path: '/pizza/cheese?shrooms=true',
headers: host.headers,
agent: con.agent
agent: con.agent,
});
});
it('merges a query object with the hosts\'', function () {
var con = new HttpConnection(new Host({
query: {
user_id: 123
}
}));
it("merges a query object with the hosts'", function() {
var con = new HttpConnection(
new Host({
query: {
user_id: 123,
},
})
);
var reqParams = con.makeReqParams({
query: {
jvm: 'yes'
}
jvm: 'yes',
},
});
expect(reqParams.path).to.eql('/?user_id=123&jvm=yes');
});
it('merges the path prefix', function () {
var con = new HttpConnection(new Host('https://google.com/path/prefix/for/user/1'));
it('merges the path prefix', function() {
var con = new HttpConnection(
new Host('https://google.com/path/prefix/for/user/1')
);
var reqParams = con.makeReqParams({
method: 'GET',
path: '/items',
query: {
q: 'pizza'
}
q: 'pizza',
},
});
expectSubObject(reqParams, {
@ -125,15 +132,17 @@ describe('Http Connector', function () {
});
});
it('merges the query', function () {
var con = new HttpConnection(new Host('http://google.com/pref-x?userId=12345&token=42069'));
it('merges the query', function() {
var con = new HttpConnection(
new Host('http://google.com/pref-x?userId=12345&token=42069')
);
var reqParams = con.makeReqParams({
method: 'PUT',
path: '/stuff',
query: {
q: 'pizza'
}
q: 'pizza',
},
});
expectSubObject(reqParams, {
@ -141,12 +150,12 @@ describe('Http Connector', function () {
});
});
it('Works well with minimum params', function () {
it('Works well with minimum params', function() {
var con = new HttpConnection(new Host('http://google.com'));
var reqParams = con.makeReqParams({
method: 'PUT',
path: '/stuff'
path: '/stuff',
});
expect(reqParams).to.eql({
@ -156,20 +165,20 @@ describe('Http Connector', function () {
port: 80,
path: '/stuff',
headers: null,
agent: con.agent
agent: con.agent,
});
});
});
describe('#request', function () {
beforeEach(function () {
describe('#request', function() {
beforeEach(function() {
stub(http, 'request', makeStubReqMethod(whereReqDies()));
stub(https, 'request', makeStubReqMethod(whereReqDies()));
});
it('calls http based on the host', function (done) {
it('calls http based on the host', function(done) {
var con = new HttpConnection(new Host('http://google.com'));
con.request({}, function () {
con.request({}, function() {
expect(http.request.callCount).to.be(1);
expect(https.request.callCount).to.be(0);
expect(http.request.lastCall.args[0].agent).to.be.a(AgentKeepAlive);
@ -177,17 +186,19 @@ describe('Http Connector', function () {
});
});
it('calls https based on the host', function (done) {
it('calls https based on the host', function(done) {
var con = new HttpConnection(new Host('https://google.com'));
con.request({}, function () {
con.request({}, function() {
expect(http.request.callCount).to.be(0);
expect(https.request.callCount).to.be(1);
expect(https.request.lastCall.args[0].agent).to.be.a(AgentKeepAlive.HttpsAgent);
expect(https.request.lastCall.args[0].agent).to.be.a(
AgentKeepAlive.HttpsAgent
);
done();
});
});
it('does not log error events', function (done) {
it('does not log error events', function(done) {
var con = new HttpConnection(new Host('http://google.com'));
stub(con.log, 'error');
@ -197,9 +208,13 @@ describe('Http Connector', function () {
stub(con.log, 'debug');
http.request.restore();
stub(http, 'request', makeStubReqMethod(whereReqDies(new Error('actual error'))));
stub(
http,
'request',
makeStubReqMethod(whereReqDies(new Error('actual error')))
);
con.request({}, function (err) {
con.request({}, function(err) {
// error should have been sent to the
expect(err.message).to.eql('actual error');
@ -214,14 +229,16 @@ describe('Http Connector', function () {
});
});
it('logs error events', function (done) {
it('logs error events', function(done) {
var con = new HttpConnection(new Host('http://google.com'));
stub(con.log, 'error');
http.request.func = makeStubReqMethod(whereReqDies(new Error('actual error')));
http.request.func = makeStubReqMethod(
whereReqDies(new Error('actual error'))
);
con.request({}, function (err) {
con.request({}, function(err) {
// error should have been sent to the
expect(err.message).to.eql('actual error');
@ -231,25 +248,29 @@ describe('Http Connector', function () {
});
});
it('calls back with error when http.request throws an error', function (done) {
var con = new HttpConnection(new Host('http://google.com/thisisinvalid\uffe2'));
it('calls back with error when http.request throws an error', function(done) {
var con = new HttpConnection(
new Host('http://google.com/thisisinvalid\uffe2')
);
stub(con.log, 'error');
con.request({}, function (err) {
expect(err.message).to.eql('ERR_UNESCAPED_CHARACTERS: /thisisinvalid\uffe2');
con.request({}, function(err) {
expect(err.message).to.eql(
'ERR_UNESCAPED_CHARACTERS: /thisisinvalid\uffe2'
);
done();
});
});
});
describe('#request with incomming message error', function () {
describe('#request with incomming message error', function() {
function makeStubReqWithMsgWhichErrorsMidBody(err) {
return makeStubReqMethod(function (req, params, cb) {
process.nextTick(function () {
return makeStubReqMethod(function(req, params, cb) {
process.nextTick(function() {
var incom = new MockIncommingMessage();
incom.statusCode = 200;
setTimeout(function () {
setTimeout(function() {
incom.emit('data', '{ "not json"');
incom.emit('error', err || new Error('Socket is dead now...'));
}, 20);
@ -258,72 +279,77 @@ describe('Http Connector', function () {
});
}
it('does not log errors', function (done) {
it('does not log errors', function(done) {
var con = new HttpConnection(new Host('https://google.com'));
stub(con.log, 'error');
stub(https, 'request', makeStubReqWithMsgWhichErrorsMidBody());
con.request({}, function () {
con.request({}, function() {
expect(con.log.error.callCount).to.eql(0);
done();
});
});
it('passes the original error on', function (done) {
it('passes the original error on', function(done) {
var con = new HttpConnection(new Host('https://google.com'));
stub(https, 'request', makeStubReqWithMsgWhichErrorsMidBody(new Error('no more message :(')));
stub(
https,
'request',
makeStubReqWithMsgWhichErrorsMidBody(new Error('no more message :('))
);
con.request({}, function (err) {
con.request({}, function(err) {
expect(err).to.be.an(Error);
expect(err.message).to.eql('no more message :(');
done();
});
});
it('does not pass the partial body along', function (done) {
it('does not pass the partial body along', function(done) {
var con = new HttpConnection(new Host('https://google.com'));
stub(https, 'request', makeStubReqWithMsgWhichErrorsMidBody());
con.request({}, function (err, resp) {
con.request({}, function(err, resp) {
expect(resp).to.be(undefined);
done();
});
});
it('does not pass the status code along', function (done) {
it('does not pass the status code along', function(done) {
var con = new HttpConnection(new Host('https://google.com'));
stub(https, 'request', makeStubReqWithMsgWhichErrorsMidBody());
con.request({}, function (err, resp, status) {
con.request({}, function(err, resp, status) {
expect(status).to.be(undefined);
done();
});
});
});
describe('#request\'s responder', function () {
it('collects the whole request body', function (done) {
describe("#request's responder", function() {
it('collects the whole request body', function(done) {
var server = nock('http://esjs.com:9200');
var con = new HttpConnection(new Host('http://esjs.com:9200'));
var body = '{ "USER": "doc" }';
server
.get('/users/1')
.reply(200, body);
server.get('/users/1').reply(200, body);
con.request({
method: 'GET',
path: '/users/1'
}, function (err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
server.done();
done();
});
con.request(
{
method: 'GET',
path: '/users/1',
},
function(err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
server.done();
done();
}
);
});
it('collects the whole request body (gzip compressed)', function (done) {
it('collects the whole request body (gzip compressed)', function(done) {
var server = nock('http://esjs.com:9200');
var con = new HttpConnection(new Host('http://esjs.com:9200'));
var elements = [];
@ -331,25 +357,28 @@ describe('Http Connector', function () {
elements.push({ USER: 'doc' });
}
var body = JSON.stringify(elements);
zlib.gzip(body, function (err, compressedBody) {
zlib.gzip(body, function(err, compressedBody) {
server
.get('/users/1')
.reply(200, compressedBody, { 'Content-Encoding': 'gzip' });
con.request({
method: 'GET',
path: '/users/1'
}, function (err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
server.done();
done();
});
con.request(
{
method: 'GET',
path: '/users/1',
},
function(err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
server.done();
done();
}
);
});
});
it('collects the whole request body (deflate compressed)', function (done) {
it('collects the whole request body (deflate compressed)', function(done) {
var server = nock('http://esjs.com:9200');
var con = new HttpConnection(new Host('http://esjs.com:9200'));
var elements = [];
@ -357,127 +386,144 @@ describe('Http Connector', function () {
elements.push({ USER: 'doc' });
}
var body = JSON.stringify(elements);
zlib.deflate(body, function (err, compressedBody) {
zlib.deflate(body, function(err, compressedBody) {
server
.get('/users/1')
.reply(200, compressedBody, { 'Content-Encoding': 'deflate' });
con.request({
method: 'GET',
path: '/users/1'
}, function (err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
server.done();
done();
});
con.request(
{
method: 'GET',
path: '/users/1',
},
function(err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
server.done();
done();
}
);
});
});
it('Can handle decompression errors', function (done) {
it('Can handle decompression errors', function(done) {
var server = nock('http://esjs.com:9200');
var con = new HttpConnection(new Host('http://esjs.com:9200'));
var body = 'blah';
server
.get('/users/1')
.reply(200, body, { 'Content-Encoding': 'gzip' });
server.get('/users/1').reply(200, body, { 'Content-Encoding': 'gzip' });
con.request({
method: 'GET',
path: '/users/1'
}, function (err, resp, status) {
expect(err).to.be.an(Error);
expect(resp).to.eql(undefined);
expect(status).to.eql(undefined);
server.done();
done();
});
con.request(
{
method: 'GET',
path: '/users/1',
},
function(err, resp, status) {
expect(err).to.be.an(Error);
expect(resp).to.eql(undefined);
expect(status).to.eql(undefined);
server.done();
done();
}
);
});
it('Ignores serialization errors', function (done) {
it('Ignores serialization errors', function(done) {
var server = nock('http://esjs.com:9200');
var con = new HttpConnection(new Host('http://esjs.com:9200'));
var body = '{ "USER":';
// partial body
server
.get('/users/1')
.reply(200, body);
server.get('/users/1').reply(200, body);
con.request({
method: 'GET',
path: '/users/1'
}, function (err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
done();
});
con.request(
{
method: 'GET',
path: '/users/1',
},
function(err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql(body);
expect(status).to.eql(200);
done();
}
);
});
});
describe('HTTP specifics', function () {
it('uses TCP no delay', function (done) {
describe('HTTP specifics', function() {
it('uses TCP no delay', function(done) {
var con = new HttpConnection(new Host('localhost'));
stub(http.ClientRequest.prototype, 'setNoDelay');
var server = nock('http://localhost').get('/').reply(200);
var server = nock('http://localhost')
.get('/')
.reply(200);
con.request({}, function () {
con.request({}, function() {
expect(http.ClientRequest.prototype.setNoDelay.callCount).to.eql(1);
expect(http.ClientRequest.prototype.setNoDelay.lastCall.args[0]).to.eql(true);
expect(http.ClientRequest.prototype.setNoDelay.lastCall.args[0]).to.eql(
true
);
server.done();
done();
});
});
it('sets the Content-Length header properly', function (done) {
it('sets the Content-Length header properly', function(done) {
var con = new HttpConnection(new Host('localhost'));
stub(http.ClientRequest.prototype, 'setHeader');
var server = nock('http://localhost').get('/').reply(200);
var server = nock('http://localhost')
.get('/')
.reply(200);
var body = 'pasta and 𝄞';
expect(body.length).to.eql(12); // nope
expect(Buffer.byteLength(body, 'utf8')).to.eql(14); // yep
con.request({
body: body
}, function () {
expect(http.ClientRequest.prototype.setHeader.args.find((arg) => arg[0] === 'Content-Length')).to.eql(['Content-Length', 14]);
server.done();
done();
});
con.request(
{
body: body,
},
function() {
expect(
http.ClientRequest.prototype.setHeader.args.find(
arg => arg[0] === 'Content-Length'
)
).to.eql(['Content-Length', 14]);
server.done();
done();
}
);
});
it('does not set the Accept-Encoding header by default', function (done) {
it('does not set the Accept-Encoding header by default', function(done) {
var con = new HttpConnection(new Host());
var respBody = 'i should not be encoded';
var server = nock('http://localhost:9200')
.matchHeader('Accept-Encoding', function (v) {
.matchHeader('Accept-Encoding', function(v) {
return v === undefined;
})
.get('/')
.once()
.reply(200, respBody);
return v === undefined;
})
.get('/')
.once()
.reply(200, respBody);
con.request({}, function (err, resp) {
con.request({}, function(err, resp) {
expect(resp).to.be(respBody);
server.done();
done();
});
});
it('sets the Accept-Encoding header when specified', function (done) {
it('sets the Accept-Encoding header when specified', function(done) {
var con = new HttpConnection(new Host({ suggestCompression: true }));
var respBody = 'i should be encoded';
var server = nock('http://localhost:9200')
.matchHeader('Accept-Encoding', 'gzip,deflate')
.get('/')
.once()
.reply(200, respBody);
.matchHeader('Accept-Encoding', 'gzip,deflate')
.get('/')
.once()
.reply(200, respBody);
con.request({}, function (err, resp) {
con.request({}, function(err, resp) {
expect(resp).to.be(respBody);
server.done();
done();
@ -485,21 +531,23 @@ describe('Http Connector', function () {
});
});
describe('Connection cleanup', function () {
it('destroys any connections created', function (done) {
describe('Connection cleanup', function() {
it('destroys any connections created', function(done) {
this.timeout(5 * 60 * 1000);
var cp = require('child_process');
var path = require('path');
var fixture = _.partial(path.join, __dirname, '../../fixtures');
var timeout; // start the timeout once we hear back from the client
var server = cp.fork(fixture('keepalive_server.js'))
.on('message', function (port) {
var server = cp
.fork(fixture('keepalive_server.js'))
.on('message', function(port) {
client.send(port);
});
var client = cp.fork(fixture('keepalive.js'))
.on('message', function (output) {
var client = cp
.fork(fixture('keepalive.js'))
.on('message', function(output) {
expect(output).to.have.property('remaining', 0);
expect(output).to.have.property('timeouts', 0);
server.kill('SIGKILL');
@ -507,30 +555,30 @@ describe('Http Connector', function () {
client.disconnect();
}
timeout = setTimeout(function () {
timeout = setTimeout(function() {
client.removeListener('exit');
done(new Error('process should have closed by now'));
}, 2000);
})
.on('exit', function () {
.on('exit', function() {
clearTimeout(timeout);
done();
});
});
it('properly removes all elements from the socket', function () {
it('properly removes all elements from the socket', function() {
var con = new HttpConnection(new Host('localhost'));
var sockets = [
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} },
{ destroy: function () {} }
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
{ destroy: function() {} },
];
var name = con.agent.getName(parseUrl('http://localhost/'));
con.agent.sockets[name] = sockets;
@ -538,5 +586,4 @@ describe('Http Connector', function () {
expect(sockets).to.eql([]);
});
});
});

View File

@ -1,4 +1,4 @@
describe('JSON serializer', function () {
describe('JSON serializer', function() {
var JsonSerializer = require('../../../src/lib/serializers/json');
var expect = require('expect.js');
var sinon = require('sinon');
@ -8,8 +8,8 @@ describe('JSON serializer', function () {
return new JsonSerializer();
}
describe('#serialize', function () {
it('defers to JSON.stringify', function () {
describe('#serialize', function() {
it('defers to JSON.stringify', function() {
var stub = sinon.stub(JSON, 'stringify');
var ser = makeSerializer();
ser.serialize({ some: 'object' });
@ -17,30 +17,30 @@ describe('JSON serializer', function () {
stub.restore();
});
it('does not modify strings', function () {
it('does not modify strings', function() {
var ser = makeSerializer();
var thing = 'pretend that I am serialized';
expect(ser.serialize(thing)).to.be(thing);
});
it('returns nothing for invalid values', function () {
it('returns nothing for invalid values', function() {
var ser = makeSerializer();
expect(ser.serialize(null)).to.be(undefined);
expect(ser.serialize(false)).to.be(undefined);
});
it('throws serialization errors', function () {
it('throws serialization errors', function() {
var ser = makeSerializer();
var thing = { name: 'thing' };
thing.self = thing;
expect(function () {
expect(function() {
ser.serialize(thing);
}).to.throwError();
});
it('utilizes replacer or spaces if passed', function () {
it('utilizes replacer or spaces if passed', function() {
sinon.spy(JSON, 'stringify');
var ser = makeSerializer();
var thing = { name: 'thing' };
@ -49,7 +49,7 @@ describe('JSON serializer', function () {
JSON.stringify.restore();
});
it('should call JSON.stringify with value only', function () {
it('should call JSON.stringify with value only', function() {
sinon.spy(JSON, 'stringify');
var ser = makeSerializer();
var thing = { name: 'thing' };
@ -59,15 +59,15 @@ describe('JSON serializer', function () {
});
});
describe('#deserialize', function () {
it('defers to JSON.parse', function () {
describe('#deserialize', function() {
it('defers to JSON.parse', function() {
stub(JSON, 'parse');
var ser = makeSerializer();
ser.deserialize('{ "some": "JSON" }');
expect(JSON.parse.callCount).to.eql(1);
});
it('ignores non string values', function () {
it('ignores non string values', function() {
var ser = makeSerializer();
var thing = ['pretend that I am not here'];
expect(ser.deserialize(thing)).to.be(undefined);
@ -75,42 +75,39 @@ describe('JSON serializer', function () {
expect(ser.deserialize(false)).to.be(undefined);
});
it('catches serialization errors, returns nothing', function () {
it('catches serialization errors, returns nothing', function() {
var ser = makeSerializer();
var thing = '{ name: \'thing\' }';
var thing = "{ name: 'thing' }";
expect(ser.deserialize(thing)).to.be(undefined);
});
});
describe('#bulkBody', function () {
var body = [
{ index: 'thing' },
{ document: 'hi' }
];
describe('#bulkBody', function() {
var body = [{ index: 'thing' }, { document: 'hi' }];
var bulk = '{"index":"thing"}\n{"document":"hi"}\n';
it('creates a string out of an array of obejcts', function () {
it('creates a string out of an array of obejcts', function() {
var ser = makeSerializer();
expect(ser.bulkBody(body)).to.eql(bulk);
});
it('adds a newline to the end of strings', function () {
it('adds a newline to the end of strings', function() {
var ser = makeSerializer();
expect(ser.bulkBody(bulk.substr(0, bulk.length - 1))).to.eql(bulk);
});
it('throws an error for anything else', function () {
it('throws an error for anything else', function() {
var ser = makeSerializer();
expect(function () {
expect(function() {
ser.bulkBody({});
}).to.throwError();
expect(function () {
expect(function() {
ser.bulkBody(null);
}).to.throwError();
expect(function () {
expect(function() {
ser.bulkBody(false);
}).to.throwError();
});

View File

@ -2,119 +2,110 @@ var Log = require('../../../src/lib/log');
var _ = require('lodash');
var expect = require('expect.js');
describe('Log class', function () {
describe('::parseLevels', function () {
it('accepts a string and returns it and the other levels below it', function () {
describe('Log class', function() {
describe('::parseLevels', function() {
it('accepts a string and returns it and the other levels below it', function() {
expect(Log.parseLevels('trace')).to.eql([
'error',
'warning',
'info',
'debug',
'trace'
'trace',
]);
});
it('accepts and validates an array of levels', function () {
it('accepts and validates an array of levels', function() {
expect(Log.parseLevels(['warning', 'info'])).to.eql(['warning', 'info']);
});
it('throws an error when an invalid string is supplied', function () {
expect(function () {
it('throws an error when an invalid string is supplied', function() {
expect(function() {
Log.parseLevels('INVALID');
}).to.throwError(/invalid logging level/);
});
it('throws an error when an invalid string is supplied in side an array', function () {
expect(function () {
it('throws an error when an invalid string is supplied in side an array', function() {
expect(function() {
Log.parseLevels(['error', 'INVALID']);
}).to.throwError(/invalid logging level/);
});
});
describe('#addOutput', function () {
describe('#addOutput', function() {
var log;
Log.loggers.stub = function (log, config) {
Log.loggers.stub = function(log, config) {
this.config = config;
};
beforeEach(function () {
beforeEach(function() {
log = new Log();
});
it('returns the newly created logger', function () {
it('returns the newly created logger', function() {
expect(log.addOutput({ type: 'stub' })).to.be.a(Log.loggers.stub);
});
it('Accepts a config object with `level: "{{level}}"`', function () {
it('Accepts a config object with `level: "{{level}}"`', function() {
var logger = log.addOutput({
type: 'stub',
level: 'warning'
level: 'warning',
});
expect(logger.config.levels).to.eql([
'error', 'warning'
]);
expect(logger.config.levels).to.eql(['error', 'warning']);
});
it('Accepts a config object with `level: ["{{level}}"]`', function () {
it('Accepts a config object with `level: ["{{level}}"]`', function() {
var logger = log.addOutput({
type: 'stub',
level: ['warning']
level: ['warning'],
});
expect(logger.config.levels).to.eql([
'warning'
]);
expect(logger.config.levels).to.eql(['warning']);
});
it('Accepts a config object with `levels: "{{level}}"`', function () {
it('Accepts a config object with `levels: "{{level}}"`', function() {
var logger = log.addOutput({
type: 'stub',
levels: 'warning'
levels: 'warning',
});
expect(logger.config.levels).to.eql([
'error', 'warning'
]);
expect(logger.config.levels).to.eql(['error', 'warning']);
});
it('Accepts a config object with `levels: ["{{level}}"]`', function () {
it('Accepts a config object with `levels: ["{{level}}"]`', function() {
var logger = log.addOutput({
type: 'stub',
level: ['warning']
level: ['warning'],
});
expect(logger.config.levels).to.eql([
'warning'
]);
expect(logger.config.levels).to.eql(['warning']);
});
});
describe('#join', function () {
it('joins strings together with spaces', function () {
describe('#join', function() {
it('joins strings together with spaces', function() {
expect(Log.join(['foo', 'bar'])).to.eql('foo bar');
});
it('stringifies objects', function () {
it('stringifies objects', function() {
expect(Log.join([{ foo: 'bar' }])).to.eql('{\n "foo": "bar"\n}\n');
});
it('fully stringifies deeply nested objects', function () {
it('fully stringifies deeply nested objects', function() {
var object = { foo: { bar: { baz: 'value' } } };
var expected = '{\n "bar": {\n "baz": "value"\n }\n}\n';
expect(Log.join(object)).to.eql(expected);
});
});
describe('instance without any outputs', function () {
describe('instance without any outputs', function() {
var log;
beforeEach(function () {
beforeEach(function() {
log = new Log();
});
it('should not emit any events', function () {
log.emit = function () {
it('should not emit any events', function() {
log.emit = function() {
throw new Error('Emit should not be called');
};
@ -123,37 +114,36 @@ describe('Log class', function () {
log.warning();
log.debug();
log.trace();
});
});
describe('instance without one output listening to all events', function () {
describe('instance without one output listening to all events', function() {
var log, call;
beforeEach(function () {
beforeEach(function() {
call = void 0;
log = new Log({
log: [
{
type: function (log) {
type: function(log) {
log.on('error', _.noop);
log.on('warning', _.noop);
log.on('info', _.noop);
log.on('debug', _.noop);
log.on('trace', _.noop);
}
}
]
},
},
],
});
log.emit = function (eventName) {
log.emit = function(eventName) {
call = {
event: eventName,
args: Array.prototype.slice.call(arguments, 1)
args: Array.prototype.slice.call(arguments, 1),
};
};
});
it('should emit an "error" event with an Error object arg', function () {
it('should emit an "error" event with an Error object arg', function() {
var err = new Error('error');
log.error(err);
expect(call.event).to.eql('error');
@ -167,40 +157,45 @@ describe('Log class', function () {
expect(call.args[0].message).to.eql('error');
});
it('should emit a "warning" event with a single message arg for #warning calls', function () {
it('should emit a "warning" event with a single message arg for #warning calls', function() {
log.warning('shit!');
expect(call.event).to.eql('warning');
expect(call.args.length).to.be(1);
expect(call.args[0]).to.eql('shit!');
});
it('should emit a "info" event with a single message arg for #info calls', function () {
it('should emit a "info" event with a single message arg for #info calls', function() {
log.info('look out!');
expect(call.event).to.eql('info');
expect(call.args.length).to.be(1);
expect(call.args[0]).to.eql('look out!');
});
it('should emit a "debug" event with a single message arg for #debug calls', function () {
it('should emit a "debug" event with a single message arg for #debug calls', function() {
log.debug('here');
expect(call.event).to.eql('debug');
expect(call.args.length).to.be(1);
expect(call.args[0]).to.eql('here');
});
it('should emit a trace event for trace events, with normalized request details arg', function () {
it('should emit a trace event for trace events, with normalized request details arg', function() {
log.trace('GET', 'http://localhost:9200/_cluster/nodes', '', '', 200);
expect(call.event).to.eql('trace');
expect(call.args.length).to.be(1);
expect(call.args[0]).to.have.property('method', 'GET');
expect(call.args[0]).to.have.property('url', 'http://localhost:9200/_cluster/nodes');
expect(call.args[0]).to.have.property(
'url',
'http://localhost:9200/_cluster/nodes'
);
expect(call.args[0]).to.have.property('status', 200);
});
});
describe('constructor', function () {
it('looks for output config options at config.log', function () {
var log = new Log({ log: { type: process.browser ? 'console' : 'stdio', level: 'error' } });
describe('constructor', function() {
it('looks for output config options at config.log', function() {
var log = new Log({
log: { type: process.browser ? 'console' : 'stdio', level: 'error' },
});
expect(log.listenerCount('error')).to.eql(1);
expect(log.listenerCount('warning')).to.eql(0);
expect(log.listenerCount('info')).to.eql(0);
@ -208,7 +203,7 @@ describe('Log class', function () {
expect(log.listenerCount('trace')).to.eql(0);
});
it('accepts a string and treat it as a log level', function () {
it('accepts a string and treat it as a log level', function() {
var log = new Log({ log: 'error' });
expect(log.listenerCount('error')).to.eql(1);
expect(log.listenerCount('warning')).to.eql(0);
@ -217,7 +212,7 @@ describe('Log class', function () {
expect(log.listenerCount('trace')).to.eql(0);
});
it('accepts an array of strings and treat it as a log level config', function () {
it('accepts an array of strings and treat it as a log level config', function() {
var log = new Log({ log: ['error', 'trace'] });
expect(log.listenerCount('error')).to.eql(1);
expect(log.listenerCount('warning')).to.eql(0);
@ -226,7 +221,7 @@ describe('Log class', function () {
expect(log.listenerCount('trace')).to.eql(1);
});
it('accepts an array of output config objects', function () {
it('accepts an array of output config objects', function() {
var log = new Log({ log: [{ level: 'error' }, { level: 'trace' }] });
expect(log.listenerCount('error')).to.eql(2);
expect(log.listenerCount('warning')).to.eql(1);
@ -235,28 +230,28 @@ describe('Log class', function () {
expect(log.listenerCount('trace')).to.eql(1);
});
it('rejects numbers and other truthy data-types', function () {
expect(function () {
it('rejects numbers and other truthy data-types', function() {
expect(function() {
// eslint-disable-next-line no-new
new Log({ log: 1515 });
}).to.throwError(/invalid logging output config/i);
expect(function () {
expect(function() {
// eslint-disable-next-line no-new
new Log({ log: /regexp/ });
}).to.throwError(/invalid logging output config/i);
expect(function () {
expect(function() {
// eslint-disable-next-line no-new
new Log({ log: new Date() });
}).to.throwError(/invalid logging output config/i);
expect(function () {
expect(function() {
// eslint-disable-next-line no-new
new Log({ log: [1515] });
}).to.throwError(/invalid logging output config/i);
expect(function () {
expect(function() {
// eslint-disable-next-line no-new
new Log({ log: [/regexp/] });
}).to.throwError(/invalid logging output config/i);
expect(function () {
expect(function() {
// eslint-disable-next-line no-new
new Log({ log: [new Date()] });
}).to.throwError(/invalid logging output config/i);

View File

@ -1,4 +1,4 @@
describe('Nodes to host callback', function () {
describe('Nodes to host callback', function() {
var callback = require('../../../src/lib/nodes_to_host');
var expect = require('expect.js');
@ -7,8 +7,8 @@ describe('Nodes to host callback', function () {
var nodes20 = require('../../fixtures/short_node_list.2.0.json');
var nodes50 = require('../../fixtures/short_node_list.5.0.json');
context('0.x style', function () {
it('properly creates host objects', function () {
context('0.x style', function() {
it('properly creates host objects', function() {
expect(callback(nodes90)).to.eql([
{
host: '192.168.1.1',
@ -16,8 +16,8 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id1',
name: 'name1',
version: '0.90.14-SNAPSHOT'
}
version: '0.90.14-SNAPSHOT',
},
},
{
host: 'localhost',
@ -25,15 +25,15 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id2',
name: 'name2',
version: '0.90.14-SNAPSHOT'
}
}
version: '0.90.14-SNAPSHOT',
},
},
]);
});
});
context('1.0 nodes style', function () {
it('properly creates host objects', function () {
context('1.0 nodes style', function() {
it('properly creates host objects', function() {
expect(callback(nodes10)).to.eql([
{
host: '10.10.10.100',
@ -41,8 +41,8 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id1',
name: 'name1',
version: '1.0.4-SNAPSHOT'
}
version: '1.0.4-SNAPSHOT',
},
},
{
host: 'published.hostname',
@ -50,15 +50,15 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id2',
name: 'name2',
version: '1.0.4-SNAPSHOT'
}
}
version: '1.0.4-SNAPSHOT',
},
},
]);
});
});
context('2.0 nodes style', function () {
it('properly creates host objects', function () {
context('2.0 nodes style', function() {
it('properly creates host objects', function() {
expect(callback(nodes20)).to.eql([
{
host: '127.0.0.1',
@ -66,8 +66,8 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id1',
name: 'name1',
version: '2.0.3-SNAPSHOT'
}
version: '2.0.3-SNAPSHOT',
},
},
{
host: 'published.hostname',
@ -75,15 +75,15 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id2',
name: 'name2',
version: '2.0.3-SNAPSHOT'
}
}
version: '2.0.3-SNAPSHOT',
},
},
]);
});
});
context('5.0 nodes style', function () {
it('properly creates host objects', function () {
context('5.0 nodes style', function() {
it('properly creates host objects', function() {
expect(callback(nodes50)).to.eql([
{
host: '127.0.0.1',
@ -91,8 +91,8 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id1',
name: 'name1',
version: '5.0.3'
}
version: '5.0.3',
},
},
{
host: 'published.hostname',
@ -100,34 +100,32 @@ describe('Nodes to host callback', function () {
_meta: {
id: 'id2',
name: 'name2',
version: '5.0.3'
}
}
version: '5.0.3',
},
},
]);
});
});
it('ignores hosts that don\'t have an http_host property', function () {
it("ignores hosts that don't have an http_host property", function() {
var hosts = callback({
node_id: {
not: 'much of a node'
}
not: 'much of a node',
},
});
expect(hosts.length).to.be(0);
});
it('throws an error when the host property is not formatted properly', function () {
expect(function () {
it('throws an error when the host property is not formatted properly', function() {
expect(function() {
callback({
node_id: {
http: {
publish_address: 'not actually an http host'
}
}
publish_address: 'not actually an http host',
},
},
});
}).to.throwException(/^Malformed http.publish_address/);
});
});

View File

@ -1,20 +1,21 @@
describe('Random Selector', function () {
describe('Random Selector', function() {
var randomSelector = require('../../../src/lib/selectors/random');
var _ = require('lodash');
var expect = require('expect.js');
it('chooses a selection by random', function () {
it('chooses a selection by random', function() {
var log = { a: 0, b: 0, c: 0 };
var choices = _.keys(log);
_.times(1000, function () {
_.times(1000, function() {
var choice = randomSelector(choices);
log[choice]++;
});
expect(_.filter(log, function (count) {
return count < 200 || count > 400;
})).to.have.length(0);
expect(
_.filter(log, function(count) {
return count < 200 || count > 400;
})
).to.have.length(0);
});
});

View File

@ -1,14 +1,14 @@
describe('Round Robin Selector', function () {
describe('Round Robin Selector', function() {
var selector = require('../../../src/lib/selectors/round_robin');
var _ = require('lodash');
var expect = require('expect.js');
it('chooses options in order', function () {
it('chooses options in order', function() {
var options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
var expected = _.clone(options);
var selections = [];
_.times(options.length, function () {
_.times(options.length, function() {
selections.push(selector(options));
});

View File

@ -1,23 +1,22 @@
describe('Stdio Logger', function () {
describe('Stdio Logger', function() {
var Log = require('../../../src/lib/log');
var StdioLogger = require('../../../src/lib/loggers/stdio');
var expect = require('expect.js');
var sinon = require('sinon');
var parentLog;
beforeEach(function () {
beforeEach(function() {
parentLog = new Log();
});
afterEach(function () {
afterEach(function() {
parentLog.close();
});
function makeLogger(parent, levels) {
parent = parent || parentLog;
var config = {
levels: Log.parseLevels(levels || 'trace')
levels: Log.parseLevels(levels || 'trace'),
};
return new StdioLogger(parent, config);
}
@ -26,23 +25,23 @@ describe('Stdio Logger', function () {
require('../generic_logger_tests')(makeLogger);
describe('colorizing', function () {
describe('colorizing', function() {
var chalk = require('chalk');
var now = '2013-01-01T00:00:00Z';
var nowDate = new Date(now);
var nowTime = nowDate.getTime();
beforeEach(function () {
beforeEach(function() {
stub.autoRelease(sinon.useFakeTimers(nowTime));
});
it('uses colors when it\'s supported', function () {
it("uses colors when it's supported", function() {
var logger = makeLogger();
var hasColor = require('chalk').supportsColor;
expect(logger.color).to.be(hasColor);
});
it('obeys the logger.color === false', function () {
it('obeys the logger.color === false', function() {
var logger = makeLogger();
stub(process.stdout, 'write');
var withoutColor = 'Elasticsearch INFO: ' + now + '\n something\n\n';
@ -52,7 +51,7 @@ describe('Stdio Logger', function () {
expect(process.stdout.write.lastCall.args[0]).to.eql(withoutColor);
});
it('obeys the logger.color === true', function () {
it('obeys the logger.color === true', function() {
var logger = makeLogger();
stub(process.stdout, 'write');
@ -61,8 +60,9 @@ describe('Stdio Logger', function () {
logger.color = true;
logger.onDebug('be weary');
expect(process.stdout.write.lastCall.args[0]).to.not.eql(withoutColor);
expect(chalk.stripColor(process.stdout.write.lastCall.args[0])).to.eql(withoutColor);
expect(chalk.stripColor(process.stdout.write.lastCall.args[0])).to.eql(
withoutColor
);
});
});
});

View File

@ -1,4 +1,4 @@
describe('Stream Logger', function () {
describe('Stream Logger', function() {
var Log = require('../../../src/lib/log');
var StreamLogger = require('../../../src/lib/loggers/stream');
var MockWritableStream = require('../../mocks/writable_stream');
@ -11,14 +11,14 @@ describe('Stream Logger', function () {
var stub = require('../../utils/auto_release_stub').make();
beforeEach(function () {
beforeEach(function() {
stub(stream, 'write');
stub(stream, 'end');
parentLog = new Log();
});
afterEach(function () {
afterEach(function() {
parentLog.close();
utils.clearWriteStreamBuffer(stream);
});
@ -27,34 +27,37 @@ describe('Stream Logger', function () {
parent = parent || parentLog;
var config = {
levels: Log.parseLevels(levels || 'trace'),
stream: stream
stream: stream,
};
return new StreamLogger(parent, config);
}
require('../generic_logger_tests')(makeLogger);
describe('buffer flush', function () {
describe('buffer flush', function() {
if (require('stream').Writable) {
it('writes everything in the buffer to console.error', function () {
it('writes everything in the buffer to console.error', function() {
var logger = makeLogger();
var line = 'This string is written 10 times to create buffered output\n';
var line =
'This string is written 10 times to create buffered output\n';
// get the last handler for process's "exit" event
var exitHandlers = process._events.exit;
var exitHandler = _.isArray(exitHandlers) ? _.last(exitHandlers) : exitHandlers;
var exitHandler = _.isArray(exitHandlers)
? _.last(exitHandlers)
: exitHandlers;
// allow the logger to acctually write to the stream
stream.write.restore();
// write the line 10 times
_.times(10, function () {
_.times(10, function() {
logger.onDebug(line);
});
// collect everything that is written to console.error
var flushedOutput = '';
stub(console, 'error', function (str) {
stub(console, 'error', function(str) {
flushedOutput += str;
});
@ -69,9 +72,9 @@ describe('Stream Logger', function () {
expect(flushedOutput.match(new RegExp(line, 'g'))).to.have.length(9);
});
} else {
it('does not fall apart with non streams2 streams', function () {
it('does not fall apart with non streams2 streams', function() {
var exitHandler;
stub(process, 'once', function (event, handler) {
stub(process, 'once', function(event, handler) {
if (event === 'exit') {
exitHandler = handler;
}
@ -80,12 +83,11 @@ describe('Stream Logger', function () {
makeLogger();
expect(function () {
expect(function() {
// call the event handler
exitHandler.call(process);
}).to.not.throwError();
});
}
});
});

View File

@ -1,22 +1,21 @@
describe('Tracer Logger', function () {
describe('Tracer Logger', function() {
var Log = require('../../../src/lib/log');
var TracerLogger = require('../../../src/lib/loggers/tracer');
var expect = require('expect.js');
var parentLog;
beforeEach(function () {
beforeEach(function() {
parentLog = new Log();
});
afterEach(function () {
afterEach(function() {
parentLog.close();
});
function makeLogger(parent, levels) {
parent = parent || parentLog;
var config = {
levels: Log.parseLevels(levels || 'trace')
levels: Log.parseLevels(levels || 'trace'),
};
return new TracerLogger(parent, config);
}
@ -25,8 +24,8 @@ describe('Tracer Logger', function () {
// require('../generic_logger_tests')(makeLogger);
describe('#formatTraceMessage', function () {
it('includes the original host', function () {
describe('#formatTraceMessage', function() {
it('includes the original host', function() {
var logger = makeLogger();
var formatted = logger._formatTraceMessage({
@ -34,37 +33,41 @@ describe('Tracer Logger', function () {
url: 'https://originalHost.com:9522/path/to/thing?qs=100',
body: '{ "yes": true }',
status: 333,
response: '{ "ok": false }'
response: '{ "ok": false }',
});
expect(formatted.curl).to.match(/-XDELETE/);
expect(formatted.curl).to.match(/https:\/\/originalHost\.com:9522\/?\s+/i);
expect(formatted.curl).to.match(/https:\/\/localhost:9200\/path\/to\/thing\?(pretty=true|qs=100|&){3}/);
expect(formatted.curl).to.match(
/https:\/\/originalHost\.com:9522\/?\s+/i
);
expect(formatted.curl).to.match(
/https:\/\/localhost:9200\/path\/to\/thing\?(pretty=true|qs=100|&){3}/
);
});
});
describe('#write', function () {
describe('#write', function() {
var logger;
beforeEach(function () {
beforeEach(function() {
logger = makeLogger();
stub(logger.stream, 'write');
});
it('detects tracer logs by listening messages wrapped in objects', function () {
it('detects tracer logs by listening messages wrapped in objects', function() {
logger.write('TRACE', { msg: 'msgtext', curl: 'curlcall' });
expect(logger.stream.write.callCount).to.be(1);
expect(logger.stream.write.lastCall.args[0]).to.contain('msgtext');
expect(logger.stream.write.lastCall.args[0]).to.contain('curlcall');
});
it('comments everthing except the curl call', function () {
it('comments everthing except the curl call', function() {
logger.write('TRACE', { msg: 'comment me', curl: 'no comment' });
expect(logger.stream.write.callCount).to.be(1);
expect(logger.stream.write.lastCall.args[0]).to.match(/^# +comment me/m);
expect(logger.stream.write.lastCall.args[0]).to.match(/^no comment/m);
});
it('just comments when it gets a string', function () {
it('just comments when it gets a string', function() {
logger.write('TRACE', 'log me');
expect(logger.stream.write.callCount).to.be(1);
expect(logger.stream.write.lastCall.args[0]).to.match(/^# +log me/m);

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,12 @@ var through2 = require('through2');
var _ = require('lodash');
var stub = require('../../utils/auto_release_stub').make();
describe('Transport + Mock server', function () {
describe('#request', function () {
describe('server responds', function () {
describe('Transport + Mock server', function() {
describe('#request', function() {
describe('server responds', function() {
var serverMock;
before(function () {
before(function() {
serverMock = nock('http://localhost')
.get('/give-me-400')
.reply(400, 'sorry bub')
@ -28,235 +28,266 @@ describe('Transport + Mock server', function () {
.get('/exists?')
.reply(200, {
status: 200
status: 200,
})
.get('/give-me-someth')
.reply(200, '{"not":"valid', {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
})
.get('/')
.reply(200, {
'the answer': 42
'the answer': 42,
})
.get('/huh?')
.reply(530, 'boo')
.get('/hottie-threads')
.reply(200, [
'he said',
'she said',
'he said',
'she said',
'he said',
'she said'
].join('\n'), {
'Content-Type': 'text/plain'
});
.reply(
200,
[
'he said',
'she said',
'he said',
'she said',
'he said',
'she said',
].join('\n'),
{
'Content-Type': 'text/plain',
}
);
});
after(function () {
after(function() {
serverMock.done();
});
describe('with a 400 status code', function () {
it('passes back a 400/BadRequest error', function (done) {
describe('with a 400 status code', function() {
it('passes back a 400/BadRequest error', function(done) {
var trans = new Transport({
hosts: 'localhost'
hosts: 'localhost',
});
trans.request({
path: '/give-me-400'
}, function (err, body, status) {
expect(err).to.be.a(errors[400]);
expect(err).to.be.a(errors.BadRequest);
expect(body).to.eql('sorry bub');
expect(status).to.eql(400);
done();
trans.request(
{
path: '/give-me-400',
},
function(err, body, status) {
expect(err).to.be.a(errors[400]);
expect(err).to.be.a(errors.BadRequest);
expect(body).to.eql('sorry bub');
expect(status).to.eql(400);
done();
}
);
});
});
describe('with a 404 status code', function() {
describe('and castExists is set', function() {
it('sends back false', function(done) {
var trans = new Transport({
hosts: 'localhost',
});
trans.request(
{
path: '/give-me-404',
castExists: true,
},
function(err, body, status) {
expect(err).to.be(undefined);
expect(body).to.eql(false);
expect(status).to.eql(404);
done();
}
);
});
});
describe('and the castExists param is not set', function() {
it('sends back a 404/NotFound error', function(done) {
var trans = new Transport({
hosts: 'localhost',
});
trans.request(
{
path: '/give-me-404',
},
function(err, body, status) {
expect(err).to.be.a(errors[404]);
expect(err).to.be.a(errors.NotFound);
expect(body).to.eql('nothing here');
expect(status).to.eql(404);
done();
}
);
});
});
});
describe('with a 404 status code', function () {
describe('and castExists is set', function () {
it('sends back false', function (done) {
describe('with a 500 status code', function() {
it('passes back a 500/InternalServerError error', function(done) {
var trans = new Transport({
hosts: 'localhost',
});
trans.request(
{
path: '/give-me-500',
},
function(err, body, status) {
expect(err).to.be.a(errors[500]);
expect(err).to.be.a(errors.InternalServerError);
expect(body).to.eql('ah shit');
expect(status).to.eql(500);
done();
}
);
});
});
describe('with a 530 status code', function() {
it('passes back a Generic error', function(done) {
var trans = new Transport({
hosts: 'localhost',
});
trans.request(
{
path: '/huh?',
},
function(err, body, status) {
expect(err).to.be.a(errors.Generic);
expect(body).to.eql('boo');
expect(status).to.eql(530);
done();
}
);
});
});
describe('with a 200 status code', function() {
describe('and the castExists param is set', function() {
it('sends back true', function(done) {
var trans = new Transport({
hosts: 'localhost'
hosts: 'localhost',
});
trans.request({
path: '/give-me-404',
castExists: true
}, function (err, body, status) {
trans.request(
{
path: '/exists?',
castExists: true,
},
function(err, body, status) {
expect(err).to.be(undefined);
expect(body).to.eql(true);
expect(status).to.eql(200);
done();
}
);
});
});
describe('with a partial response body', function() {
it('sends back a serialization error', function(done) {
var trans = new Transport({
hosts: 'localhost',
});
trans.request(
{
path: '/give-me-someth',
},
function(err, body, status) {
expect(err).to.be.a(errors.Serialization);
expect(body).to.eql('{"not":"valid');
expect(status).to.eql(200);
done();
}
);
});
});
describe('with a valid response body', function() {
it('sends back the body and status code with no error', function(done) {
var trans = new Transport({
hosts: 'localhost',
});
trans.request(
{
path: '/',
},
function(err, body) {
expect(err).to.be(undefined);
expect(body).to.eql({
'the answer': 42,
});
done();
}
);
});
});
});
describe('with plain text', function() {
it('notices the content-type header and returns the text', function(done) {
var trans = new Transport({
hosts: 'localhost',
});
trans.request(
{
path: '/hottie-threads',
},
function(err, body) {
expect(err).to.be(undefined);
expect(body).to.eql(false);
expect(status).to.eql(404);
expect(body).to.match(/s?he said/g);
done();
});
});
});
describe('and the castExists param is not set', function () {
it('sends back a 404/NotFound error', function (done) {
var trans = new Transport({
hosts: 'localhost'
});
trans.request({
path: '/give-me-404'
}, function (err, body, status) {
expect(err).to.be.a(errors[404]);
expect(err).to.be.a(errors.NotFound);
expect(body).to.eql('nothing here');
expect(status).to.eql(404);
done();
});
});
});
});
describe('with a 500 status code', function () {
it('passes back a 500/InternalServerError error', function (done) {
var trans = new Transport({
hosts: 'localhost'
});
trans.request({
path: '/give-me-500'
}, function (err, body, status) {
expect(err).to.be.a(errors[500]);
expect(err).to.be.a(errors.InternalServerError);
expect(body).to.eql('ah shit');
expect(status).to.eql(500);
done();
});
});
});
describe('with a 530 status code', function () {
it('passes back a Generic error', function (done) {
var trans = new Transport({
hosts: 'localhost'
});
trans.request({
path: '/huh?'
}, function (err, body, status) {
expect(err).to.be.a(errors.Generic);
expect(body).to.eql('boo');
expect(status).to.eql(530);
done();
});
});
});
describe('with a 200 status code', function () {
describe('and the castExists param is set', function () {
it('sends back true', function (done) {
var trans = new Transport({
hosts: 'localhost'
});
trans.request({
path: '/exists?',
castExists: true
}, function (err, body, status) {
expect(err).to.be(undefined);
expect(body).to.eql(true);
expect(status).to.eql(200);
done();
});
});
});
describe('with a partial response body', function () {
it('sends back a serialization error', function (done) {
var trans = new Transport({
hosts: 'localhost'
});
trans.request({
path: '/give-me-someth',
}, function (err, body, status) {
expect(err).to.be.a(errors.Serialization);
expect(body).to.eql('{"not":"valid');
expect(status).to.eql(200);
done();
});
});
});
describe('with a valid response body', function () {
it('sends back the body and status code with no error', function (done) {
var trans = new Transport({
hosts: 'localhost'
});
trans.request({
path: '/',
}, function (err, body) {
expect(err).to.be(undefined);
expect(body).to.eql({
'the answer': 42
});
done();
});
});
});
});
describe('with plain text', function () {
it('notices the content-type header and returns the text', function (done) {
var trans = new Transport({
hosts: 'localhost'
});
trans.request({
path: '/hottie-threads',
}, function (err, body) {
expect(err).to.be(undefined);
expect(body).to.match(/s?he said/g);
done();
});
}
);
});
});
});
describe('return value', function () {
it('resolves the promise it with the response body', function (done) {
describe('return value', function() {
it('resolves the promise it with the response body', function(done) {
nock('http://esbox.1.com')
.get('/')
.reply(200, {
good: 'day'
good: 'day',
});
var tran = new Transport({
hosts: 'http://esbox.1.com'
hosts: 'http://esbox.1.com',
});
tran.request({}).then(function (resp) {
tran.request({}).then(function(resp) {
expect(resp).to.eql({
good: 'day'
good: 'day',
});
done();
}, done);
});
});
describe('timeout', function () {
it('clears the timeout when the request is complete', function () {
describe('timeout', function() {
it('clears the timeout when the request is complete', function() {
var clock = sinon.useFakeTimers('setTimeout', 'clearTimeout');
stub.autoRelease(clock);
var tran = new Transport({
host: 'http://localhost:9200'
host: 'http://localhost:9200',
});
nock('http://localhost:9200')
.get('/')
.reply(200, {
i: 'am here'
i: 'am here',
});
tran.request({}, function (err, resp, status) {
tran.request({}, function(err, resp, status) {
expect(err).to.be(undefined);
expect(resp).to.eql({ i: 'am here' });
expect(status).to.eql(200);
@ -265,44 +296,47 @@ describe('Transport + Mock server', function () {
});
});
it('timeout responds with a requestTimeout error', function (done) {
it('timeout responds with a requestTimeout error', function(done) {
var tran = new Transport({
host: 'http://localhost:9200'
host: 'http://localhost:9200',
});
nock('http://localhost:9200')
.get('/')
.delay(1000)
.reply(200, {
i: 'am here'
i: 'am here',
});
tran.request({
requestTimeout: 25
}, function (err) {
expect(err).to.be.a(errors.RequestTimeout);
done();
});
tran.request(
{
requestTimeout: 25,
},
function(err) {
expect(err).to.be.a(errors.RequestTimeout);
done();
}
);
});
});
describe('sniffOnConnectionFault', function () {
it('schedules a sniff when sniffOnConnectionFault is set and a connection failes', function () {
describe('sniffOnConnectionFault', function() {
it('schedules a sniff when sniffOnConnectionFault is set and a connection failes', function() {
var clock = sinon.useFakeTimers('setTimeout');
stub.autoRelease(clock);
nock('http://esbox.1.com')
.get('/')
.reply(200, function () {
var str = through2(function (chunk, enc, cb) {
.reply(200, function() {
var str = through2(function(chunk, enc, cb) {
cb(new Error('force error'));
});
setTimeout(function () {
setTimeout(function() {
str.write('');
}, 10);
str.setEncoding = function () {}; // force nock's isStream detection
str.setEncoding = function() {}; // force nock's isStream detection
return str;
});
@ -311,26 +345,31 @@ describe('Transport + Mock server', function () {
var tran = new Transport({
hosts: 'http://esbox.1.com',
sniffOnConnectionFault: true,
maxRetries: 0
maxRetries: 0,
});
expect(tran.connectionPool._onConnectionDied).to.not.be(ConnectionPool.prototype._onConnectionDied);
expect(tran.connectionPool._onConnectionDied).to.not.be(
ConnectionPool.prototype._onConnectionDied
);
tran.request({
requestTimeout: Infinity
})
.then(function () {
throw new Error('expected the request to fail');
})
.catch(function () {
expect(ConnectionPool.prototype._onConnectionDied.callCount).to.eql(1);
expect(tran.sniff.callCount).to.eql(0);
expect(_.size(clock.timers)).to.eql(1);
tran
.request({
requestTimeout: Infinity,
})
.then(function() {
throw new Error('expected the request to fail');
})
.catch(function() {
expect(ConnectionPool.prototype._onConnectionDied.callCount).to.eql(
1
);
expect(tran.sniff.callCount).to.eql(0);
expect(_.size(clock.timers)).to.eql(1);
var timeout = _.values(clock.timers).pop();
timeout.func();
expect(tran.sniff.callCount).to.eql(1);
});
var timeout = _.values(clock.timers).pop();
timeout.func();
expect(tran.sniff.callCount).to.eql(1);
});
});
});
});

View File

@ -4,28 +4,27 @@ var expect = require('expect.js');
var stub = require('../../utils/auto_release_stub').make();
describe('Utils', function () {
describe('Additional Type Checkers', function () {
describe('#isArrayOfStrings', function () {
describe('Utils', function() {
describe('Additional Type Checkers', function() {
describe('#isArrayOfStrings', function() {
const thing = {
is: ['creamy', 'poop'],
not: {}
not: {},
};
it('likes arrays of strings', function () {
it('likes arrays of strings', function() {
expect(utils.isArrayOfStrings(thing.is)).to.be(true);
});
it('dislikes when there is even one non string', function () {
it('dislikes when there is even one non string', function() {
// notice a string in the array
thing.is.push(thing.not || ' not ');
expect(utils.isArrayOfStrings(thing.is)).to.be(false);
});
});
describe('#isNumeric', function () {
it('likes integer literals', function () {
describe('#isNumeric', function() {
it('likes integer literals', function() {
expect(utils.isNumeric('-10')).to.be(true);
expect(utils.isNumeric('0')).to.be(true);
expect(utils.isNumeric('5')).to.be(true);
@ -34,10 +33,10 @@ describe('Utils', function () {
expect(utils.isNumeric(32)).to.be(true);
expect(utils.isNumeric('040')).to.be(true);
expect(utils.isNumeric('0xFF')).to.be(true);
expect(utils.isNumeric(0xFFF)).to.be(true);
expect(utils.isNumeric(0xfff)).to.be(true);
});
it('likes float literals', function () {
it('likes float literals', function() {
expect(utils.isNumeric('-1.6')).to.be(true);
expect(utils.isNumeric('4.536')).to.be(true);
expect(utils.isNumeric(-2.6)).to.be(true);
@ -46,7 +45,7 @@ describe('Utils', function () {
expect(utils.isNumeric('123e-2')).to.be(true);
});
it('dislikes non-numeric stuff', function () {
it('dislikes non-numeric stuff', function() {
expect(utils.isNumeric('')).to.be(false);
expect(utils.isNumeric(' ')).to.be(false);
expect(utils.isNumeric('\t\t')).to.be(false);
@ -66,219 +65,238 @@ describe('Utils', function () {
expect(utils.isNumeric([])).to.be(false);
expect(utils.isNumeric([1, 2, 3, 4])).to.be(false);
expect(utils.isNumeric({})).to.be(false);
expect(utils.isNumeric(function () {})).to.be(false);
expect(utils.isNumeric(function() {})).to.be(false);
});
});
describe('#isInterval', function() {
_.forEach(
{
M: 'months',
w: 'weeks',
d: 'days',
h: 'hours',
m: 'minutes',
s: 'seconds',
y: 'years',
},
function(name, unit) {
it('likes ' + name, function() {
expect(utils.isInterval('1' + unit)).to.be(true);
});
describe('#isInterval', function () {
_.forEach({
M: 'months',
w: 'weeks',
d: 'days',
h: 'hours',
m: 'minutes',
s: 'seconds',
y: 'years'
},
function (name, unit) {
it('likes ' + name, function () {
expect(utils.isInterval('1' + unit)).to.be(true);
});
it('likes decimal ' + name, function() {
expect(utils.isInterval('1.5' + unit)).to.be(true);
});
}
);
it('likes decimal ' + name, function () {
expect(utils.isInterval('1.5' + unit)).to.be(true);
});
});
it('dislikes more than one unit', function () {
it('dislikes more than one unit', function() {
expect(utils.isInterval('1my')).to.be(false);
});
it('dislikes spaces', function () {
it('dislikes spaces', function() {
expect(utils.isInterval('1 m')).to.be(false);
});
});
});
describe('String Transformers', function () {
describe('#camelCase', function () {
it('find spaces, underscores, and other natural word breaks', function () {
expect(utils.camelCase('Neil Patrick.Harris-is_a.dog')).to.eql('neilPatrickHarrisIsADog');
describe('String Transformers', function() {
describe('#camelCase', function() {
it('find spaces, underscores, and other natural word breaks', function() {
expect(utils.camelCase('Neil Patrick.Harris-is_a.dog')).to.eql(
'neilPatrickHarrisIsADog'
);
});
it('ignores abreviations', function () {
it('ignores abreviations', function() {
expect(utils.camelCase('Json_parser')).to.eql('jsonParser');
});
it('handles leading _', function () {
it('handles leading _', function() {
expect(utils.camelCase('_thing_one_')).to.eql('_thingOne');
});
it('works on numbers', function () {
it('works on numbers', function() {
expect(utils.camelCase('version 1.0')).to.eql('version10');
});
});
describe('#studlyCase', function () {
it('find spaces, underscores, and other natural word breaks', function () {
expect(utils.studlyCase('Neil Patrick.Harris-is_a.dog')).to.eql('NeilPatrickHarrisIsADog');
describe('#studlyCase', function() {
it('find spaces, underscores, and other natural word breaks', function() {
expect(utils.studlyCase('Neil Patrick.Harris-is_a.dog')).to.eql(
'NeilPatrickHarrisIsADog'
);
});
it('ignores abreviations', function () {
it('ignores abreviations', function() {
expect(utils.studlyCase('Json_parser')).to.eql('JsonParser');
});
it('handles leading _', function () {
it('handles leading _', function() {
expect(utils.studlyCase('_thing_one_')).to.eql('_ThingOne');
});
it('works on numbers', function () {
it('works on numbers', function() {
expect(utils.studlyCase('version 1.0')).to.eql('Version10');
});
});
describe('#snakeCase', function () {
it('find spaces, underscores, and other natural word breaks', function () {
expect(utils.snakeCase('Neil Patrick.Harris-is_a.dog')).to.eql('neil_patrick_harris_is_a_dog');
describe('#snakeCase', function() {
it('find spaces, underscores, and other natural word breaks', function() {
expect(utils.snakeCase('Neil Patrick.Harris-is_a.dog')).to.eql(
'neil_patrick_harris_is_a_dog'
);
});
it('ignores abreviations', function () {
it('ignores abreviations', function() {
expect(utils.snakeCase('Json_parser')).to.eql('json_parser');
});
it('handles leading _', function () {
it('handles leading _', function() {
expect(utils.snakeCase('_thing_one_')).to.eql('_thing_one');
});
it('works on numbers', function () {
it('works on numbers', function() {
expect(utils.snakeCase('version 1.0')).to.eql('version_1_0');
});
});
describe('#toUpperString', function () {
it('transforms normal strings', function () {
describe('#toUpperString', function() {
it('transforms normal strings', function() {
expect(utils.toUpperString('PASTA')).to.eql('PASTA');
});
it('ignores long form empty vals (null, false, undef)', function () {
it('ignores long form empty vals (null, false, undef)', function() {
expect(utils.toUpperString(null)).to.eql('');
expect(utils.toUpperString(false)).to.eql('');
expect(utils.toUpperString(void 0)).to.eql('');
});
it('uses the objects own toString', function () {
it('uses the objects own toString', function() {
expect(utils.toUpperString(['A', 'B'])).to.eql('A,B');
});
it('sorta kinda works on objects', function () {
it('sorta kinda works on objects', function() {
expect(utils.toUpperString({ a: 'thing' })).to.eql('[OBJECT OBJECT]');
});
});
describe('#repeat', function () {
it('repeats strings', function () {
describe('#repeat', function() {
it('repeats strings', function() {
expect(utils.repeat(' ', 5)).to.eql(' ');
expect(utils.repeat('foobar', 2)).to.eql('foobarfoobar');
});
});
describe('#ucfirst', function () {
it('only capitalized the first letter, lowercases everything else', function () {
describe('#ucfirst', function() {
it('only capitalized the first letter, lowercases everything else', function() {
expect(utils.ucfirst('ALGER')).to.eql('Alger');
});
});
});
describe('#createArray', function () {
it('accepts an array of things and simply returns a copy of it', function () {
describe('#createArray', function() {
it('accepts an array of things and simply returns a copy of it', function() {
var inp = [{ a: 1 }, 'pizza'];
var out = utils.createArray(inp);
expect(out).to.eql(inp);
expect(out).to.not.be(inp);
});
it('accepts a primitive value and calls the the transform function', function (done) {
utils.createArray('str', function (val) {
it('accepts a primitive value and calls the the transform function', function(done) {
utils.createArray('str', function(val) {
expect(val).to.be('str');
done();
});
});
it('wraps any non-array in an array', function () {
it('wraps any non-array in an array', function() {
expect(utils.createArray({})).to.eql([{}]);
expect(utils.createArray('')).to.eql(['']);
expect(utils.createArray(123)).to.eql([123]);
expect(utils.createArray(/abc/)).to.eql([/abc/]);
expect(utils.createArray(false)).to.eql([false]);
});
it('returns false when the transform function returns undefined', function () {
expect(utils.createArray(['str', 1], function (val) {
if (_.isString(val)) {
return {
val: val
};
}
})).to.be(false);
it('returns false when the transform function returns undefined', function() {
expect(
utils.createArray(['str', 1], function(val) {
if (_.isString(val)) {
return {
val: val,
};
}
})
).to.be(false);
});
});
describe('#funcEnum', function () {
describe('#funcEnum', function() {
/*
* _.funcEnum(object, key, opts, default);
*/
it('tests if the value at key in object is a function, returns it if so', function () {
it('tests if the value at key in object is a function, returns it if so', function() {
var config = {
func: function () {}
func: function() {},
};
expect(utils.funcEnum(config, 'func', {}, 'toString'))
.to.be(config.func);
expect(utils.funcEnum(config, 'func', {}, 'toString')).to.be(config.func);
});
it('tests if the value at key in object is undefined, returns the option at key default if so', function () {
it('tests if the value at key in object is undefined, returns the option at key default if so', function() {
var config = {
func: undefined
func: undefined,
};
expect(utils.funcEnum(config, 'func', {}, 'toString'))
.to.be(Object.prototype.toString);
expect(utils.funcEnum(config, 'func', {}, 'toString')).to.be(
Object.prototype.toString
);
});
it('tests if the value at key in object is a string, returns the option at that key if so', function () {
it('tests if the value at key in object is a string, returns the option at that key if so', function() {
var config = {
'config key name': 'toString'
'config key name': 'toString',
};
expect(utils.funcEnum(config, 'config key name', { toString: 'pizza' }, 'toJSON'))
.to.be('pizza');
expect(
utils.funcEnum(
config,
'config key name',
{ toString: 'pizza' },
'toJSON'
)
).to.be('pizza');
});
it('throws an informative error if the selection if invalid', function () {
it('throws an informative error if the selection if invalid', function() {
var config = {
'config': 'val'
config: 'val',
};
expect(function () {
expect(function() {
utils.funcEnum(config, 'config', {});
}).to.throwError(/expected a function/i);
expect(function () {
expect(function() {
utils.funcEnum(config, 'config', { main: 'default' }, 'main');
}).to.throwError(/expected a function or main/i);
expect(function () {
utils.funcEnum(config, 'config', { main: 'default', other: 'default' }, 'main');
expect(function() {
utils.funcEnum(
config,
'config',
{ main: 'default', other: 'default' },
'main'
);
}).to.throwError(/expected a function or one of main, other/i);
});
});
describe('#applyArgs', function () {
_.times(10, function (i) {
describe('#applyArgs', function() {
_.times(10, function(i) {
var method = i > 5 ? 'apply' : 'call';
var argCount = i + 1;
var slice = 1;
it('uses ' + method + ' with ' + i + ' args', function () {
var func = function () {};
it('uses ' + method + ' with ' + i + ' args', function() {
var func = function() {};
stub(func, method);
var args = _.map(new Array(i), function (val, i) { return i; });
var args = _.map(new Array(i), function(val, i) {
return i;
});
utils.applyArgs(func, null, args);
expect(func[method].callCount).to.eql(1);
@ -289,27 +307,36 @@ describe('Utils', function () {
}
});
it('slices the arguments properly before calling ' + method + ' with ' + argCount + ' args sliced at ' + slice,
function () {
var func = function () {};
stub(func, method);
it(
'slices the arguments properly before calling ' +
method +
' with ' +
argCount +
' args sliced at ' +
slice,
function() {
var func = function() {};
stub(func, method);
var args = _.map(new Array(argCount), function (val, i) { return i; });
var expected = args.slice(slice);
utils.applyArgs(func, null, args, slice);
var args = _.map(new Array(argCount), function(val, i) {
return i;
});
var expected = args.slice(slice);
utils.applyArgs(func, null, args, slice);
expect(func[method].callCount).to.eql(1);
if (method === 'apply') {
expect(func.apply.lastCall.args[1]).to.eql(expected);
} else {
expect(func.call.lastCall.args.splice(1)).to.eql(expected);
expect(func[method].callCount).to.eql(1);
if (method === 'apply') {
expect(func.apply.lastCall.args[1]).to.eql(expected);
} else {
expect(func.call.lastCall.args.splice(1)).to.eql(expected);
}
}
});
);
});
});
describe('#getUnwrittenFromStream', function () {
it('ignores things that do not have writableState', function () {
describe('#getUnwrittenFromStream', function() {
it('ignores things that do not have writableState', function() {
expect(utils.getUnwrittenFromStream()).to.be(undefined);
expect(utils.getUnwrittenFromStream(false)).to.be(undefined);
expect(utils.getUnwrittenFromStream([])).to.be(undefined);
@ -318,12 +345,12 @@ describe('Utils', function () {
if (require('stream').Writable) {
var MockWritableStream = require('../../mocks/writable_stream');
it('ignores empty stream', function () {
it('ignores empty stream', function() {
var stream = new MockWritableStream();
expect(utils.getUnwrittenFromStream(stream)).to.be('');
});
it('returns only what is in the buffer', function () {
it('returns only what is in the buffer', function() {
var stream = new MockWritableStream();
stream.write('hot');
stream.write('dog');
@ -331,5 +358,4 @@ describe('Utils', function () {
});
}
});
});

View File

@ -1,16 +1,16 @@
describe('Yaml Test Reader', function () {
describe('Yaml Test Reader', function() {
var YamlDoc = require('../../integration/yaml_suite/yaml_doc');
var compare = YamlDoc.compareRangeToVersion;
var expect = require('expect.js');
describe('version range comparison', function () {
it('supports unbounded ranges', function () {
describe('version range comparison', function() {
it('supports unbounded ranges', function() {
expect(compare(' - ', '999999999999999999')).to.be(true);
expect(compare('0 - ', '999999999999999999')).to.be(true);
expect(compare(' - 1', '999999999999999999')).to.be(false);
});
it('supports bound ranges', function () {
it('supports bound ranges', function() {
expect(compare('1.4 - 1.5', '1.4.4')).to.be(true);
expect(compare('1.4.4 - 1.5', '1.4.4')).to.be(true);
expect(compare('1.4 - 1.4.4', '1.4.4')).to.be(true);

View File

@ -1,19 +1,18 @@
var sinon = require('sinon');
exports.make = function () {
exports.make = function() {
var log = [];
afterEach(function () {
var stub;
while (stub = log.pop()) {
afterEach(function() {
for (const stub of log) {
stub.restore();
}
log.length = 0;
});
var stubber = function () {
var stubber = function() {
log.push(sinon.stub.apply(sinon, arguments));
};
stubber.autoRelease = function (item) {
stubber.autoRelease = function(item) {
log.push(item);
};

View File

@ -1,10 +1,13 @@
var _ = require('lodash');
var expect = require('expect.js');
module.exports = function expectSubObject(obj, subObj) {
_.forOwn(subObj, function (val, prop) {
_.forOwn(subObj, function(val, prop) {
if (typeof obj[prop] === 'object') {
// non-strict equals
expect(obj[prop]).to.eql(val, 'Expected property' + prop + ' of object to equal ' + val);
expect(obj[prop]).to.eql(
val,
'Expected property' + prop + ' of object to equal ' + val
);
} else {
expect(obj).property(prop, val);
}

View File

@ -14,18 +14,22 @@ var fs = require('fs');
var path = require('path');
var inspect = require('util').inspect;
var log = (function () {
var log = (function() {
var locked = _.bind(process.stdout.write, process.stdout);
return function (str) {
return function(str) {
if (typeof str !== 'string') {
str = inspect(str);
}
locked(str);
};
}());
})();
var integration = _.find(process.argv, function (arg) { return arg.indexOf('test/integration') > -1; });
var unit = _.find(process.argv, function (arg) { return arg.indexOf('test/unit') > -1; });
var integration = _.find(process.argv, function(arg) {
return arg.indexOf('test/integration') > -1;
});
var unit = _.find(process.argv, function(arg) {
return arg.indexOf('test/unit') > -1;
});
var output;
if (unit) {
@ -40,21 +44,18 @@ function JenkinsReporter(runner) {
Base.call(this, runner);
var stats = this.stats;
var pass = 0;
var pending = 0;
var fail = 0;
var rootSuite = {
results: [],
suites: []
suites: [],
};
var stack = [rootSuite];
function indt() {
return (new Array(stack.length + 1)).join(' ');
return new Array(stack.length + 1).join(' ');
}
runner.on('suite', function (suite) {
runner.on('suite', function(suite) {
if (suite.root) {
return;
}
@ -65,7 +66,7 @@ function JenkinsReporter(runner) {
results: [],
start: Date.now(),
stdout: '',
stderr: ''
stderr: '',
};
// append to the previous stack leader
@ -78,7 +79,7 @@ function JenkinsReporter(runner) {
stack.unshift(suite);
});
runner.on('suite end', function (suite) {
runner.on('suite end', function(suite) {
if (suite.root) {
return;
}
@ -86,22 +87,19 @@ function JenkinsReporter(runner) {
stack.shift();
});
runner.on('fail', function (test) {
if ('hook' === test.type) {
runner.on('fail', function(test) {
if (test.type === 'hook') {
runner.emit('test end', test);
}
});
runner.on('test end', function (test) {
runner.on('test end', function(test) {
if (test.state === 'passed') {
pass++;
log(chalk.green('.'));
} else if (test.pending) {
pending++;
log(chalk.grey('.'));
return;
} else {
fail++;
log(chalk.red('x'));
}
@ -117,18 +115,24 @@ function JenkinsReporter(runner) {
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
// check for the result of the stringifying.
if ('[object Error]' === errMsg) {
if (errMsg === '[object Error]') {
errMsg = test.err.message;
}
// Safari doesn't give you a stack. Let's at least provide a source line.
if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
if (
!test.err.stack &&
test.err.sourceURL &&
test.err.line !== undefined
) {
errMsg += '\n(' + test.err.sourceURL + ':' + test.err.line + ')';
}
console.error(_.map(errMsg.split('\n'), function (line) {
return indt() + ' ' + line;
}).join('\n'));
console.error(
_.map(errMsg.split('\n'), function(line) {
return indt() + ' ' + line;
}).join('\n')
);
}
if (stack[0]) {
@ -138,14 +142,18 @@ function JenkinsReporter(runner) {
pass: test.state === 'passed',
test: test,
stdout: stack[0].stdout,
stderr: stack[0].stderr
stderr: stack[0].stderr,
});
stack[0].stdout = stack[0].stderr = '';
}
});
runner.on('hook end', function (hook) {
if (hook.title.indexOf('"after each"') > -1 && stack[0] && stack[0].results.length) {
runner.on('hook end', function(hook) {
if (
hook.title.indexOf('"after each"') > -1 &&
stack[0] &&
stack[0].results.length
) {
var result = _.last(stack[0].results);
result.stdout += stack[0].stdout;
result.stderr += stack[0].stderr;
@ -153,7 +161,7 @@ function JenkinsReporter(runner) {
}
});
runner.on('end', function () {
runner.on('end', function() {
restoreStdio();
var xml = makeJUnitXml('node ' + process.version, {
stats: stats,
@ -164,38 +172,43 @@ function JenkinsReporter(runner) {
time: suite.time || 0,
results: suite.results,
stdout: suite.stdout,
stderr: suite.stderr
stderr: suite.stderr,
};
if (suite.suites) {
s.suites = _.map(suite.suites, removeElements);
}
return s;
})
}),
});
fs.writeFileSync(output, xml, 'utf8');
console.log('\n' + [
'tests complete in ' + (Math.round(stats.duration / 10) / 100) + ' seconds',
' fail: ' + chalk.red(stats.failures),
' pass: ' + chalk.green(stats.passes),
' pending: ' + chalk.grey(stats.pending)
].join('\n'));
console.log(
'\n' +
[
'tests complete in ' +
Math.round(stats.duration / 10) / 100 +
' seconds',
' fail: ' + chalk.red(stats.failures),
' pass: ' + chalk.green(stats.passes),
' pending: ' + chalk.grey(stats.pending),
].join('\n')
);
});
// overload the write methods on stdout and stderr
['stdout', 'stderr'].forEach(function (name) {
['stdout', 'stderr'].forEach(function(name) {
var obj = process[name];
var orig = obj.write;
obj.write = function (chunk) {
obj.write = function(chunk) {
if (stack[0]) {
stack[0][name] = (stack[0][name] || '') + chunk;
}
// orig.apply(obj, arguments);
};
obj.__restore = function () {
obj.__restore = function() {
this.write = orig;
};
});
@ -204,5 +217,4 @@ function JenkinsReporter(runner) {
process.stdout.__restore();
process.stderr.__restore();
}
}

View File

@ -33,7 +33,6 @@ var chalk = require('chalk');
function makeJUnitXml(runnerName, testDetails) {
_.each(testDetails.suites, function serializeSuite(suiteInfo) {
var suite = suites.ele('testsuite', {
package: 'elasticsearch-js',
id: suiteCount++,
@ -43,15 +42,19 @@ function makeJUnitXml(runnerName, testDetails) {
tests: (suiteInfo.results && suiteInfo.results.length) || 0,
failures: _.filter(suiteInfo.results, { pass: false }).length,
errors: 0,
time: suiteInfo.time / 1000
time: suiteInfo.time / 1000,
});
_.each(suiteInfo.results, function (testInfo) {
_.each(suiteInfo.results, function(testInfo) {
var section;
var integration = false;
if (suiteInfo.name.match(/\/.*\.yaml$/)) {
section = suiteInfo.name.split('/').slice(0, -1).join('/').replace(/\./g, '/');
section = suiteInfo.name
.split('/')
.slice(0, -1)
.join('/')
.replace(/\./g, '/');
} else {
section = suiteInfo.name.replace(/\./g, ',');
}
@ -64,18 +67,19 @@ function makeJUnitXml(runnerName, testDetails) {
var testcase = suite.ele('testcase', {
name: testInfo.name,
time: (testInfo.time || 0) / 1000,
classname: runnerName + (integration ? ' - integration' : '') + '.' + section
classname:
runnerName + (integration ? ' - integration' : '') + '.' + section,
});
if (testInfo.errMsg) {
testcase.ele('failure', {
message: testInfo.errMsg,
type: 'AssertError'
type: 'AssertError',
});
} else if (!testInfo.pass) {
testcase.ele('error', {
message: 'Unknown Error',
type: 'TestError'
type: 'TestError',
});
}

View File

@ -20,20 +20,21 @@ testFiles.unit = _(fs.readdirSync(unitSpecDir))
'console_logger.js',
'stream_logger.js',
'tracer_logger.js',
'transport_with_server.js'
'transport_with_server.js',
])
.map(function (file) {
.map(function(file) {
return unitSpecDir + '/' + file;
})
.value();
testFiles.build = fs.readdirSync(browserBuildsDir)
.map(function (file) {
testFiles.build = fs
.readdirSync(browserBuildsDir)
.map(function(file) {
if (file.substr(-3) === '.js') {
return browserBuildsDir + '/' + file;
}
return null
return null;
})
.filter(Boolean);
@ -42,27 +43,29 @@ var aliasify = require('aliasify').configure({
aliases: pkg.browser,
excludeExtensions: 'json',
// verbose: false,
configDir: root
configDir: root,
});
// queue for bundle requests, two at a time
var bundleQueue = async.queue(function (task, done) {
var bundleQueue = async.queue(function(task, done) {
task(done);
}, 2);
// create a route that bundles a file list, based on the patterns defined in testFiles
function bundleTests(name) {
return function (req, res, next) {
bundleQueue.push(function (_cb) {
var done = function (err) {
if (err) { return next(err); }
return function(req, res, next) {
bundleQueue.push(function(_cb) {
var done = function(err) {
if (err) {
return next(err);
}
_cb(err);
};
res.set('Content-Type', 'application/javascript');
var b = browserify(testFiles[name], {
insertGlobals: true
insertGlobals: true,
});
b.transform(aliasify);
var str = b.bundle();
@ -76,7 +79,7 @@ function bundleTests(name) {
// create a route that just rends a specific file (like a symlink or something)
function sendFile(file) {
return function (req, res) {
return function(req, res) {
res.sendfile(file);
};
}
@ -93,25 +96,42 @@ app
.get('/expect.js', sendFile(root + '/node_modules/expect.js/index.js'))
.get('/mocha.css', sendFile(root + '/node_modules/mocha/mocha.css'))
.get('/mocha.js', sendFile(root + '/node_modules/mocha/mocha.js'))
.get('/screencast-reporter.css', sendFile(root + '/node_modules/mocha-screencast-reporter/screencast-reporter.css'))
.get('/screencast-reporter.js', sendFile(root + '/node_modules/mocha-screencast-reporter/screencast-reporter.js'))
.get(
'/screencast-reporter.css',
sendFile(
root + '/node_modules/mocha-screencast-reporter/screencast-reporter.css'
)
)
.get(
'/screencast-reporter.js',
sendFile(
root + '/node_modules/mocha-screencast-reporter/screencast-reporter.js'
)
)
// libs
.get('/angular.js', sendFile(root + '/bower_components/angular/angular.js'))
.get('/angular-mocks.js', sendFile(root + '/bower_components/angular-mocks/angular-mocks.js'))
.get(
'/angular-mocks.js',
sendFile(root + '/bower_components/angular-mocks/angular-mocks.js')
)
.get('/jquery.js', sendFile(root + '/node_modules/jquery/dist/jquery.js'))
// builds
.get('/elasticsearch.js', sendFile(root + '/dist/elasticsearch.js'))
.get('/elasticsearch.angular.js', sendFile(root + '/dist/elasticsearch.angular.js'))
.get('/elasticsearch.jquery.js', sendFile(root + '/dist/elasticsearch.jquery.js'))
.get(
'/elasticsearch.angular.js',
sendFile(root + '/dist/elasticsearch.angular.js')
)
.get(
'/elasticsearch.jquery.js',
sendFile(root + '/dist/elasticsearch.jquery.js')
)
// bundles
.get('/unit_tests.js', bundleTests('unit'))
.get('/build_tests.js', bundleTests('build'))
.get('/build_tests.js', bundleTests('build'));
;
http.createServer(app).listen(8000, function () {
http.createServer(app).listen(8000, function() {
console.log('listening on port 8000');
});

View File

@ -1,6 +1,8 @@
// I know this is horrible
// I just don't want the keys searchable on github
module.exports = JSON.parse(new Buffer(
'eyJ1c2VyIjoiZWxhc3RpY3NlYXJjaC1qcyIsImtleSI6IjI0ZjQ5ZTA3LWQ4MmYtNDA2Ny04NTRlLWQ4MTVlYmQxNWU0NiJ9',
'base64'
).toString('utf8'));
module.exports = JSON.parse(
new Buffer(
'eyJ1c2VyIjoiZWxhc3RpY3NlYXJjaC1qcyIsImtleSI6IjI0ZjQ5ZTA3LWQ4MmYtNDA2Ny04NTRlLWQ4MTVlYmQxNWU0NiJ9',
'base64'
).toString('utf8')
);