Summary of changes:
- updated copyright - several tempalate changes for the docs - added a config for grunt-contrib-watch - updated nock commit number - fixed the coverage script - removed the export_docs script - added error message for legacy "es" users who don't have a version locked and have not upgraded - host will now add auth to urls created with `#makeUrl()` - Log class no longer looks for `config.loggers` - The log class now properly escapes single quotes in trace logs - Removed compiled yaml_tests.js from the repo - Yaml suite will only log error and warning messages unless the VERBOSE env var is set - createDefer is now a global setting, changed by modifying Transport.createDefer fubction - wrote tests for Content-Type checking - callbacks will now return the body and status of the request (if the request has completed) when an error occurs - Stdio logger now adds "Elasticsearch " to the front of log messages to distinguish it from other output to stdout.
This commit is contained in:
@ -12,9 +12,8 @@ module.exports = function (grunt) {
|
|||||||
banner: '/*! <%= package.name %> - v<%= package.version %> - ' +
|
banner: '/*! <%= package.name %> - v<%= package.version %> - ' +
|
||||||
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
|
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
|
||||||
'<%= package.homepage ? " * " + package.homepage + "\\n" : "" %>' +
|
'<%= package.homepage ? " * " + package.homepage + "\\n" : "" %>' +
|
||||||
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= package.author.name %>;' +
|
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= package.author.company %>;' +
|
||||||
' Licensed <%= package.license %> */\n' +
|
' Licensed <%= package.license %> */\n'
|
||||||
' // built using browserify\n\n'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -27,7 +27,7 @@ We also provide builds of the elasticsearch.js client for use in the browser. If
|
|||||||
- [Quick Start](http://spenceralger.github.io/elasticsearch-js/index.html#quick-start)
|
- [Quick Start](http://spenceralger.github.io/elasticsearch-js/index.html#quick-start)
|
||||||
- [API](http://spenceralger.github.io/elasticsearch-js/api.html)
|
- [API](http://spenceralger.github.io/elasticsearch-js/api.html)
|
||||||
- [Configuration](http://spenceralger.github.io/elasticsearch-js/index.html#configuration)
|
- [Configuration](http://spenceralger.github.io/elasticsearch-js/index.html#configuration)
|
||||||
- [Development/Contributions](http://spenceralger.github.io/elasticsearch-js/index.html#dev)
|
- [Development/Contributing](http://spenceralger.github.io/elasticsearch-js/index.html#dev)
|
||||||
- [Extending Core Components](http://spenceralger.github.io/elasticsearch-js/index.html#extending)
|
- [Extending Core Components](http://spenceralger.github.io/elasticsearch-js/index.html#extending)
|
||||||
- [Logging](http://spenceralger.github.io/elasticsearch-js/index.html#logging)
|
- [Logging](http://spenceralger.github.io/elasticsearch-js/index.html#logging)
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
unit: {
|
|
||||||
src: ['test/unit/test_*.js'],
|
|
||||||
reporter: 'XUnit',
|
|
||||||
dest: './test-output-phantom-unit.xml',
|
|
||||||
run: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
15
grunt/config/watch.js
Normal file
15
grunt/config/watch.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module.exports = {
|
||||||
|
source: {
|
||||||
|
files: [
|
||||||
|
'src/**/*.js',
|
||||||
|
'test/unit/**/*.js',
|
||||||
|
'grunt/**/*.js',
|
||||||
|
'Gruntfile.js'
|
||||||
|
],
|
||||||
|
interrupt: true,
|
||||||
|
tasks: [
|
||||||
|
// 'jshint',
|
||||||
|
'run:unit_tests'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -37,7 +37,7 @@
|
|||||||
"mocha-lcov-reporter": "0.0.1",
|
"mocha-lcov-reporter": "0.0.1",
|
||||||
"blanket": "~1.1.5",
|
"blanket": "~1.1.5",
|
||||||
"sinon": "~1.7.3",
|
"sinon": "~1.7.3",
|
||||||
"nock": "git://github.com/spenceralger/nock.git#f28dc3c973651830b930793932b4006577260dc1",
|
"nock": "git://github.com/spenceralger/nock.git#5218548233983c594da5535bc07e7db36841987e",
|
||||||
"open": "0.0.4",
|
"open": "0.0.4",
|
||||||
"testling": "git://github.com/spenceralger/testling.git",
|
"testling": "git://github.com/spenceralger/testling.git",
|
||||||
"load-grunt-tasks": "~0.2.0",
|
"load-grunt-tasks": "~0.2.0",
|
||||||
@ -64,7 +64,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "grunt test",
|
"test": "grunt test",
|
||||||
"coverage": "mocha test/unit/test_*.js --require blanket -R html-cov > coverage.html && open -a \"Google Chrome\"./coverage.html",
|
"coverage": "mocha test/unit/test_*.js --require blanket -R html-cov > coverage.html && open -a \"Google Chrome\" ./coverage.html",
|
||||||
"blanket": {
|
"blanket": {
|
||||||
"pattern": "src"
|
"pattern": "src"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
var path = require('path');
|
|
||||||
|
|
||||||
var argv = require('optimist')
|
|
||||||
.default({
|
|
||||||
outputDir: '.',
|
|
||||||
verbose: false
|
|
||||||
})
|
|
||||||
.alias({
|
|
||||||
o: 'outputDir',
|
|
||||||
v: 'verbose'
|
|
||||||
})
|
|
||||||
.argv;
|
|
||||||
|
|
||||||
require('./_steps')(argv, [
|
|
||||||
['runInModule', {
|
|
||||||
cmd: 'node',
|
|
||||||
args: ['scripts/generate', '--force']
|
|
||||||
}],
|
|
||||||
['copy', {
|
|
||||||
from: path.join(__dirname, '../docs/_methods.jade'),
|
|
||||||
to: path.join(argv.outputDir, '_methods.jade')
|
|
||||||
}],
|
|
||||||
['copy', {
|
|
||||||
from: path.join(__dirname, '../docs/_method_list.jade'),
|
|
||||||
to: path.join(argv.outputDir, '_method_list.jade')
|
|
||||||
}]
|
|
||||||
]);
|
|
||||||
|
|
||||||
// function runInModule(cmd, args, exitCb) {
|
|
||||||
// log('running', cmd, args.join(' '));
|
|
||||||
|
|
||||||
// var proc = cp.spawn(cmd, args, {
|
|
||||||
// stdio: argv.verbose ? 'inherit' : 'ignore'
|
|
||||||
// });
|
|
||||||
|
|
||||||
// proc.on('error', function (err) {
|
|
||||||
// console.error('Error! --', err.message);
|
|
||||||
// process.exit(1);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// proc.on('exit', function (status) {
|
|
||||||
// if (status) {
|
|
||||||
// console.error('Error! --', cmd, 'exit status was', status);
|
|
||||||
// process.exit(1);
|
|
||||||
// } else {
|
|
||||||
// exitCb();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function copy(from, to, done) {
|
|
||||||
// log('copying', from, 'to', to);
|
|
||||||
|
|
||||||
// var read = fs.createReadStream(from);
|
|
||||||
// var write = fs.createWriteStream(to);
|
|
||||||
|
|
||||||
// read.pipe(write);
|
|
||||||
|
|
||||||
// read.on('error', function (err) {
|
|
||||||
// console.error('unable to read: ' + from);
|
|
||||||
// console.error(err.message);
|
|
||||||
// process.exit(1);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// write.on('error', function (err) {
|
|
||||||
// console.error('unable to write to: ' + to);
|
|
||||||
// console.error(err.message);
|
|
||||||
// process.exit(1);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// write.on('finish', function () {
|
|
||||||
// done();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
@ -7,14 +7,12 @@ var actionId = action.name.toLowerCase().replace(/[^\w]+/g, '-');
|
|||||||
h2#<%= actionId %>.fn
|
h2#<%= actionId %>.fn
|
||||||
span.name <%= action.name %>
|
span.name <%= action.name %>
|
||||||
span.args (params, [callback])
|
span.args (params, [callback])
|
||||||
a.perma(href="api.html#<%= actionId %>", title="Permalink")
|
include _descriptions/<%= action.name %>.jade
|
||||||
a.esdoc(href="<%= action.docUrl %>", title="Endpoint Docs")
|
a.esdoc(href="<%= action.docUrl %>", title="<%= action.name %> at elasticsearch.org").
|
||||||
//-
|
<%= action.docUrl %>
|
||||||
h4 Spec:
|
p.tight.
|
||||||
pre
|
The default method is <code><%= action.spec.method || 'GET' %></code> and
|
||||||
code <%= JSON.stringify(action, null, ' ').split('\n').map(function (line, i) {
|
the usual <a href="#api-conventions">params and return values</a> apply.
|
||||||
return (i > 0 ? ' | ' : '') + line;
|
|
||||||
}).join('\n') %>
|
|
||||||
|
|
||||||
<% if (_.size(action.allParams)) { %>
|
<% if (_.size(action.allParams)) { %>
|
||||||
h3 Params:
|
h3 Params:
|
||||||
@ -26,10 +24,6 @@ dl.params.api
|
|||||||
<%= indent(param.description || '', 4) %><%
|
<%= indent(param.description || '', 4) %><%
|
||||||
}); %>
|
}); %>
|
||||||
<% } %>
|
<% } %>
|
||||||
p.
|
|
||||||
Default method: <%= action.spec.method || 'GET' %><br>
|
|
||||||
Includes <a href="#api-conventions-return">the usual</a>
|
|
||||||
|
|
||||||
include _examples/<%= action.name %>.jade<%
|
include _examples/<%= action.name %>.jade<%
|
||||||
});
|
});
|
||||||
%>
|
%>
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# let the dust settle and ensure that es is ready for us.
|
||||||
|
sleep 15s
|
||||||
|
|
||||||
# generate the latest version of the yaml-tests
|
# generate the latest version of the yaml-tests
|
||||||
node scripts/generate/ --no-api 2>&1 > /dev/null
|
node scripts/generate/ --no-api 2>&1 > /dev/null
|
||||||
|
|
||||||
|
export VERBOSE="true"
|
||||||
|
|
||||||
# unit tests
|
# unit tests
|
||||||
./node_modules/.bin/mocha test/unit/test_*.js \
|
./node_modules/.bin/mocha test/unit/test_*.js \
|
||||||
--require should \
|
--require should \
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
* It will also instruct the client to use Angular's $http service for it's ajax requests
|
* It will also instruct the client to use Angular's $http service for it's ajax requests
|
||||||
*/
|
*/
|
||||||
var AngularConnector = require('./lib/connectors/angular');
|
var AngularConnector = require('./lib/connectors/angular');
|
||||||
|
var Transport = require('./lib/transport');
|
||||||
var Client = require('./lib/client');
|
var Client = require('./lib/client');
|
||||||
|
|
||||||
process.angular_build = true;
|
process.angular_build = true;
|
||||||
@ -16,12 +17,14 @@ angular.module('elasticsearch.client', [])
|
|||||||
AngularConnector.prototype.$http = $http;
|
AngularConnector.prototype.$http = $http;
|
||||||
AngularConnector.prototype.$q = $q;
|
AngularConnector.prototype.$q = $q;
|
||||||
|
|
||||||
|
// make the Transport return $q promisses instead
|
||||||
|
Transport.createDefer = function () {
|
||||||
|
return $q.defer();
|
||||||
|
};
|
||||||
|
|
||||||
var factory = function (config) {
|
var factory = function (config) {
|
||||||
config = config || {};
|
config = config || {};
|
||||||
config.connectionClass = AngularConnector;
|
config.connectionClass = AngularConnector;
|
||||||
config.createDefer = function () {
|
|
||||||
return $q.defer();
|
|
||||||
};
|
|
||||||
return new Client(config);
|
return new Client(config);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
var es = {
|
// In order to help people who were accidentally upgraded to this ES client,
|
||||||
Client: require('./lib/client'),
|
// throw an error when they try to instanciate the exported function.
|
||||||
ConnectionPool: require('./lib/connection_pool'),
|
// previous "elasticsearch" module -> https://github.com/ncb000gt/node-es
|
||||||
Transport: require('./lib/transport'),
|
function es() {
|
||||||
|
throw new Error('Looks like you are expecting the previous "elasticsearch" module. ' +
|
||||||
|
'It is now the "es" module. To create a client with this module use ' +
|
||||||
|
'`new es.Client(params)`.');
|
||||||
|
}
|
||||||
|
|
||||||
errors: require('./lib/errors')
|
es.Client = require('./lib/client');
|
||||||
};
|
es.ConnectionPool = require('./lib/connection_pool');
|
||||||
|
es.Transport = require('./lib/transport');
|
||||||
|
es.errors = require('./lib/errors');
|
||||||
|
|
||||||
module.exports = es;
|
module.exports = es;
|
||||||
|
|||||||
1
src/lib/connectors/angular.js
vendored
1
src/lib/connectors/angular.js
vendored
@ -36,4 +36,5 @@ AngularConnector.prototype.request = function (params, cb) {
|
|||||||
|
|
||||||
// must be overwritten before this connection can be used
|
// must be overwritten before this connection can be used
|
||||||
AngularConnector.prototype.$http = null;
|
AngularConnector.prototype.$http = null;
|
||||||
|
// required in order to provide abort functionality
|
||||||
AngularConnector.prototype.$q = null;
|
AngularConnector.prototype.$q = null;
|
||||||
|
|||||||
@ -128,7 +128,14 @@ Host.prototype.makeUrl = function (params) {
|
|||||||
query = qs.stringify(this.query);
|
query = qs.stringify(this.query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.protocol + '://' + this.host + port + path + (query ? '?' + query : '');
|
var auth = '';
|
||||||
|
if (params.auth) {
|
||||||
|
auth = params.auth + '@';
|
||||||
|
} else if (this.auth) {
|
||||||
|
auth = this.auth + '@';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.protocol + '://' + auth + this.host + port + path + (query ? '?' + query : '');
|
||||||
};
|
};
|
||||||
|
|
||||||
Host.prototype.toString = function () {
|
Host.prototype.toString = function () {
|
||||||
|
|||||||
@ -22,10 +22,6 @@ function Log(config) {
|
|||||||
var i;
|
var i;
|
||||||
var outputs;
|
var outputs;
|
||||||
|
|
||||||
if (config.loggers) {
|
|
||||||
config.log = config.loggers;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.log) {
|
if (config.log) {
|
||||||
if (_.isArrayOfStrings(config.log)) {
|
if (_.isArrayOfStrings(config.log)) {
|
||||||
outputs = [{
|
outputs = [{
|
||||||
@ -305,8 +301,7 @@ Log.prototype.trace = function (method, requestUrl, body, responseBody, response
|
|||||||
|
|
||||||
function prettyJSON(body) {
|
function prettyJSON(body) {
|
||||||
try {
|
try {
|
||||||
// TESTME
|
return JSON.stringify(JSON.parse(body), null, ' ').replace(/'/g, '\\u0027');
|
||||||
return JSON.stringify(JSON.parse(body), null, ' ').replace(/'/g, '\\\'');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return body || '';
|
return body || '';
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -68,8 +68,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
log: {
|
log: {
|
||||||
type: process.browser ? 'console' : 'stdio',
|
type: process.browser ? 'console' : 'stdio',
|
||||||
level: 'trace',
|
level: process.env.VERBOSE ? 'trace' : 'warning'
|
||||||
color: false
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -122,8 +122,9 @@ describe('Host class', function () {
|
|||||||
path: '/this and that',
|
path: '/this and that',
|
||||||
query: {
|
query: {
|
||||||
param: 1
|
param: 1
|
||||||
}
|
},
|
||||||
}).should.eql('http://localhost:9200/prefix/this and that?param=1&user_id=123');
|
auth: 'user:pass'
|
||||||
|
}).should.eql('http://user:pass@localhost:9200/prefix/this and that?param=1&user_id=123');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ensures that path starts with a forward-slash', function () {
|
it('ensures that path starts with a forward-slash', function () {
|
||||||
@ -148,8 +149,8 @@ describe('Host class', function () {
|
|||||||
host = new Host({ host: 'john', port: 80 });
|
host = new Host({ host: 'john', port: 80 });
|
||||||
host.makeUrl().should.eql('http://john/');
|
host.makeUrl().should.eql('http://john/');
|
||||||
|
|
||||||
host = new Host({ host: 'italy', path: '/pie' });
|
host = new Host({ host: 'italy', path: '/pie', auth: 'user:pass'});
|
||||||
host.makeUrl().should.eql('http://italy:9200/pie');
|
host.makeUrl().should.eql('http://user:pass@italy:9200/pie');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -188,7 +188,7 @@ describe('Http Connector', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs error events when an error occurs', function (done) {
|
it('does not log error events', function (done) {
|
||||||
var con = new HttpConnection(new Host('http://google.com'));
|
var con = new HttpConnection(new Host('http://google.com'));
|
||||||
|
|
||||||
stub(con.log, 'error');
|
stub(con.log, 'error');
|
||||||
@ -205,8 +205,8 @@ describe('Http Connector', function () {
|
|||||||
err.message.should.eql('actual error');
|
err.message.should.eql('actual error');
|
||||||
|
|
||||||
// logged the error and the trace log
|
// logged the error and the trace log
|
||||||
con.log.error.callCount.should.eql(1);
|
|
||||||
con.log.trace.callCount.should.eql(1);
|
con.log.trace.callCount.should.eql(1);
|
||||||
|
con.log.error.callCount.should.eql(0);
|
||||||
con.log.info.callCount.should.eql(0);
|
con.log.info.callCount.should.eql(0);
|
||||||
con.log.warning.callCount.should.eql(0);
|
con.log.warning.callCount.should.eql(0);
|
||||||
con.log.debug.callCount.should.eql(0);
|
con.log.debug.callCount.should.eql(0);
|
||||||
@ -227,9 +227,7 @@ describe('Http Connector', function () {
|
|||||||
err.message.should.eql('actual error');
|
err.message.should.eql('actual error');
|
||||||
|
|
||||||
// logged the error
|
// logged the error
|
||||||
con.log.error.callCount.should.eql(1);
|
con.log.error.callCount.should.eql(0);
|
||||||
con.log.error.lastCall.args[0].message.should.eql('actual error');
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -250,13 +248,13 @@ describe('Http Connector', function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
it('logs error event', function (done) {
|
it('does not log errors', function (done) {
|
||||||
var con = new HttpConnection(new Host('https://google.com'));
|
var con = new HttpConnection(new Host('https://google.com'));
|
||||||
stub(con.log, 'error');
|
stub(con.log, 'error');
|
||||||
stub(https, 'request', makeStubReqWithMsgWhichErrorsMidBody());
|
stub(https, 'request', makeStubReqWithMsgWhichErrorsMidBody());
|
||||||
|
|
||||||
con.request({}, function (err, resp, status) {
|
con.request({}, function (err, resp, status) {
|
||||||
con.log.error.callCount.should.eql(1);
|
con.log.error.callCount.should.eql(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -45,7 +45,7 @@ describe('Stdio Logger', function () {
|
|||||||
it('obeys the logger.color === false', function () {
|
it('obeys the logger.color === false', function () {
|
||||||
var logger = makeLogger();
|
var logger = makeLogger();
|
||||||
stub(process.stdout, 'write');
|
stub(process.stdout, 'write');
|
||||||
var withoutColor = 'INFO: ' + now + '\n something\n\n';
|
var withoutColor = 'Elasticsearch INFO: ' + now + '\n something\n\n';
|
||||||
|
|
||||||
logger.color = false;
|
logger.color = false;
|
||||||
logger.onInfo('something');
|
logger.onInfo('something');
|
||||||
@ -56,7 +56,7 @@ describe('Stdio Logger', function () {
|
|||||||
var logger = makeLogger();
|
var logger = makeLogger();
|
||||||
|
|
||||||
stub(process.stdout, 'write');
|
stub(process.stdout, 'write');
|
||||||
var withoutColor = 'TRACE: ' + now + '\n curl\n msg\n\n';
|
var withoutColor = 'Elasticsearch TRACE: ' + now + '\n curl\n msg\n\n';
|
||||||
|
|
||||||
logger.color = true;
|
logger.color = true;
|
||||||
logger.onTrace('msg', 'curl');
|
logger.onTrace('msg', 'curl');
|
||||||
|
|||||||
@ -33,20 +33,6 @@ describe('Transport Class', function () {
|
|||||||
trans.log.should.be.an.instanceOf(CustomLogClass);
|
trans.log.should.be.an.instanceOf(CustomLogClass);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Accepts a "createDefer" function, which can be used to tie into other promise libs.', function () {
|
|
||||||
function CustomPromise() {
|
|
||||||
this.then = function () {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var trans = new Transport({
|
|
||||||
createDefer: function () {
|
|
||||||
return new CustomPromise();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
trans.createDefer().should.be.an.instanceOf(CustomPromise);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Accepts a connection pool class and intanciates it at this.connectionPool', function () {
|
it('Accepts a connection pool class and intanciates it at this.connectionPool', function () {
|
||||||
function CustomConnectionPool() {}
|
function CustomConnectionPool() {}
|
||||||
var trans = new Transport({
|
var trans = new Transport({
|
||||||
@ -75,6 +61,33 @@ describe('Transport Class', function () {
|
|||||||
}).should.throw(/invalid connectionpool/i);
|
}).should.throw(/invalid connectionpool/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('calls sniff immediately if sniffOnStart is true', function () {
|
||||||
|
stub(Transport.prototype, 'sniff');
|
||||||
|
var trans = new Transport({
|
||||||
|
sniffOnStart: true
|
||||||
|
});
|
||||||
|
|
||||||
|
trans.sniff.callCount.should.eql(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('schedules a sniff when sniffInterval is set', function () {
|
||||||
|
var clock = sinon.useFakeTimers('setTimeout');
|
||||||
|
stub(Transport.prototype, 'sniff');
|
||||||
|
|
||||||
|
var trans = new Transport({
|
||||||
|
sniffInterval: 25000
|
||||||
|
});
|
||||||
|
|
||||||
|
_.size(clock.timeouts).should.eql(1);
|
||||||
|
var id = _.keys(clock.timeouts).pop();
|
||||||
|
clock.tick(25000);
|
||||||
|
trans.sniff.callCount.should.eql(1);
|
||||||
|
_.size(clock.timeouts).should.eql(1);
|
||||||
|
_.keys(clock.timeouts).pop().should.not.eql(id);
|
||||||
|
|
||||||
|
clock.restore();
|
||||||
|
});
|
||||||
|
|
||||||
describe('host config', function () {
|
describe('host config', function () {
|
||||||
it('rejects non-strings/objects', function () {
|
it('rejects non-strings/objects', function () {
|
||||||
(function () {
|
(function () {
|
||||||
@ -195,6 +208,14 @@ describe('Transport Class', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('::createDefer', function () {
|
||||||
|
it('returns a when.js promise by default', function () {
|
||||||
|
|
||||||
|
Transport.createDefer().constructor.should.be.exactly(when.defer().constructor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('#sniff', function () {
|
describe('#sniff', function () {
|
||||||
var trans;
|
var trans;
|
||||||
|
|
||||||
@ -275,27 +296,6 @@ describe('Transport Class', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#createDefer', function () {
|
|
||||||
it('returns a when.js promise by default', function () {
|
|
||||||
var trans = new Transport({
|
|
||||||
hosts: 'localhost'
|
|
||||||
});
|
|
||||||
|
|
||||||
trans.createDefer().constructor.should.be.exactly(when.defer().constructor);
|
|
||||||
});
|
|
||||||
it('is overridden by the createDefer option', function () {
|
|
||||||
var when = require('when');
|
|
||||||
var trans = new Transport({
|
|
||||||
hosts: 'localhost',
|
|
||||||
createDefer: function () {
|
|
||||||
return 'pasta';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
trans.createDefer().should.be.exactly('pasta');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#request', function () {
|
describe('#request', function () {
|
||||||
it('logs when it begins', function (done) {
|
it('logs when it begins', function (done) {
|
||||||
var trans = new Transport();
|
var trans = new Transport();
|
||||||
@ -445,48 +445,47 @@ describe('Transport Class', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('gets a connection err', function () {
|
describe('gets a connection err', function () {
|
||||||
function testRetries(retries, done) {
|
// create a test that checks N retries
|
||||||
var randomSelector = require('../../src/lib/selectors/random');
|
function testRetries(retries) {
|
||||||
var connections;
|
return function (done) {
|
||||||
var attempts = 0;
|
var randomSelector = require('../../src/lib/selectors/random');
|
||||||
function failRequest(params, cb) {
|
var connections;
|
||||||
attempts++;
|
var attempts = 0;
|
||||||
process.nextTick(function () {
|
function failRequest(params, cb) {
|
||||||
cb(new Error('Unable to do that thing you wanted'));
|
attempts++;
|
||||||
});
|
process.nextTick(function () {
|
||||||
}
|
cb(new Error('Unable to do that thing you wanted'));
|
||||||
|
});
|
||||||
var trans = new Transport({
|
|
||||||
hosts: _.map(new Array(retries + 1), function (i) {
|
|
||||||
return 'localhost/' + i;
|
|
||||||
}),
|
|
||||||
maxRetries: retries,
|
|
||||||
selector: function (_conns) {
|
|
||||||
connections = _conns;
|
|
||||||
return randomSelector(_conns);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// trigger a select so that we can harvest the connection list
|
var trans = new Transport({
|
||||||
trans.connectionPool.select(_.noop);
|
hosts: _.map(new Array(retries + 1), function (i) {
|
||||||
_.each(connections, function (conn) {
|
return 'localhost/' + i;
|
||||||
stub(conn, 'request', failRequest);
|
}),
|
||||||
});
|
maxRetries: retries,
|
||||||
|
selector: function (_conns) {
|
||||||
|
connections = _conns;
|
||||||
|
return randomSelector(_conns);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
trans.request({}, function (err, resp, body) {
|
// trigger a select so that we can harvest the connection list
|
||||||
attempts.should.eql(retries + 1);
|
trans.connectionPool.select(_.noop);
|
||||||
err.should.be.an.instanceOf(errors.ConnectionFault);
|
_.each(connections, function (conn) {
|
||||||
should.not.exist(resp);
|
stub(conn, 'request', failRequest);
|
||||||
should.not.exist(body);
|
});
|
||||||
done();
|
|
||||||
});
|
trans.request({}, function (err, resp, body) {
|
||||||
|
attempts.should.eql(retries + 1);
|
||||||
|
err.should.be.an.instanceOf(errors.ConnectionFault);
|
||||||
|
should.not.exist(resp);
|
||||||
|
should.not.exist(body);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
it('retries when there are retries remaining', function (done) {
|
it('retries when there are retries remaining', testRetries(_.random(25, 40)));
|
||||||
testRetries(30, done);
|
it('responds when there are no retries', testRetries(0));
|
||||||
});
|
|
||||||
it('responds when there are no retries', function (done) {
|
|
||||||
testRetries(0, done);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('server responds', function () {
|
describe('server responds', function () {
|
||||||
@ -505,16 +504,34 @@ describe('Transport Class', function () {
|
|||||||
.reply(500, 'ah shit')
|
.reply(500, 'ah shit')
|
||||||
|
|
||||||
.get('/exists?')
|
.get('/exists?')
|
||||||
.reply(200, '{"status":200}')
|
.reply(200, {
|
||||||
|
status: 200
|
||||||
|
})
|
||||||
|
|
||||||
.get('/give-me-someth')
|
.get('/give-me-someth')
|
||||||
.reply(200, '{"not":"valid')
|
.reply(200, '{"not":"valid', {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
})
|
||||||
|
|
||||||
.get('/')
|
.get('/')
|
||||||
.reply(200, '{"the answer":42}')
|
.reply(200, {
|
||||||
|
'the answer': 42
|
||||||
|
})
|
||||||
|
|
||||||
.get('/huh?')
|
.get('/huh?')
|
||||||
.reply(530, 'boo');
|
.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'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function () {
|
after(function () {
|
||||||
@ -532,8 +549,8 @@ describe('Transport Class', function () {
|
|||||||
}, function (err, body, status) {
|
}, function (err, body, status) {
|
||||||
err.should.be.an.instanceOf(errors[400]);
|
err.should.be.an.instanceOf(errors[400]);
|
||||||
err.should.be.an.instanceOf(errors.BadRequest);
|
err.should.be.an.instanceOf(errors.BadRequest);
|
||||||
should.not.exist(body);
|
body.should.eql('sorry bub');
|
||||||
should.not.exist(status);
|
status.should.eql(400);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -568,8 +585,8 @@ describe('Transport Class', function () {
|
|||||||
}, function (err, body, status) {
|
}, function (err, body, status) {
|
||||||
err.should.be.an.instanceOf(errors[404]);
|
err.should.be.an.instanceOf(errors[404]);
|
||||||
err.should.be.an.instanceOf(errors.NotFound);
|
err.should.be.an.instanceOf(errors.NotFound);
|
||||||
should.not.exist(body);
|
body.should.eql('nothing here');
|
||||||
should.not.exist(status);
|
status.should.eql(404);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -587,14 +604,14 @@ describe('Transport Class', function () {
|
|||||||
}, function (err, body, status) {
|
}, function (err, body, status) {
|
||||||
err.should.be.an.instanceOf(errors[500]);
|
err.should.be.an.instanceOf(errors[500]);
|
||||||
err.should.be.an.instanceOf(errors.InternalServerError);
|
err.should.be.an.instanceOf(errors.InternalServerError);
|
||||||
should.not.exist(body);
|
body.should.eql('ah shit');
|
||||||
should.not.exist(status);
|
status.should.eql(500);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with a 500 status code', function () {
|
describe('with a 530 status code', function () {
|
||||||
it('passes back a Generic error', function (done) {
|
it('passes back a Generic error', function (done) {
|
||||||
var trans = new Transport({
|
var trans = new Transport({
|
||||||
hosts: 'localhost'
|
hosts: 'localhost'
|
||||||
@ -604,8 +621,8 @@ describe('Transport Class', function () {
|
|||||||
path: '/huh?'
|
path: '/huh?'
|
||||||
}, function (err, body, status) {
|
}, function (err, body, status) {
|
||||||
err.should.be.an.instanceOf(errors.Generic);
|
err.should.be.an.instanceOf(errors.Generic);
|
||||||
should.not.exist(body);
|
body.should.eql('boo');
|
||||||
should.not.exist(status);
|
status.should.eql(530);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -639,8 +656,8 @@ describe('Transport Class', function () {
|
|||||||
path: '/give-me-someth',
|
path: '/give-me-someth',
|
||||||
}, function (err, body, status) {
|
}, function (err, body, status) {
|
||||||
err.should.be.an.instanceOf(errors.Serialization);
|
err.should.be.an.instanceOf(errors.Serialization);
|
||||||
should.not.exist(body);
|
body.should.eql('{"not":"valid');
|
||||||
should.not.exist(status);
|
status.should.eql(200);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -663,6 +680,22 @@ describe('Transport Class', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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, status) {
|
||||||
|
should.not.exist(err);
|
||||||
|
body.should.match(/s?he said/g);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('return value', function () {
|
describe('return value', function () {
|
||||||
@ -680,22 +713,44 @@ describe('Transport Class', function () {
|
|||||||
when.isPromise(ret).should.be.ok;
|
when.isPromise(ret).should.be.ok;
|
||||||
ret.abort.should.have.type('function');
|
ret.abort.should.have.type('function');
|
||||||
});
|
});
|
||||||
it('the promise is always pulled from the defer created by this.createDefer()', function () {
|
it('promise is always pulled from the defer created by this.createDefer()', function () {
|
||||||
var fakePromise = {};
|
var fakePromise = {};
|
||||||
var tran = new Transport({
|
var origCreate = Transport.createDefer;
|
||||||
createDefer: function () {
|
Transport.createDefer = function () {
|
||||||
return {
|
return {
|
||||||
resolve: _.noop,
|
resolve: _.noop,
|
||||||
reject: _.noop,
|
reject: _.noop,
|
||||||
promise: fakePromise
|
promise: fakePromise
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
});
|
var tran = new Transport({});
|
||||||
shortCircuitRequest(tran);
|
shortCircuitRequest(tran);
|
||||||
var ret = tran.request({});
|
var ret = tran.request({});
|
||||||
|
Transport.createDefer = origCreate;
|
||||||
ret.should.be.exactly(fakePromise);
|
ret.should.be.exactly(fakePromise);
|
||||||
ret.abort.should.have.type('function');
|
ret.abort.should.have.type('function');
|
||||||
});
|
});
|
||||||
|
it('resolves the promise it returns with an object containing status and body keys', function (done) {
|
||||||
|
var serverMock = nock('http://esbox.1.com')
|
||||||
|
.get('/')
|
||||||
|
.reply(200, {
|
||||||
|
good: 'day'
|
||||||
|
});
|
||||||
|
|
||||||
|
var tran = new Transport({
|
||||||
|
hosts: 'http://esbox.1.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
tran.request({}).then(function (resp) {
|
||||||
|
resp.should.eql({
|
||||||
|
body: {
|
||||||
|
good: 'day'
|
||||||
|
},
|
||||||
|
status: 200
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('aborting', function () {
|
describe('aborting', function () {
|
||||||
|
|||||||
@ -29,6 +29,7 @@ var suites = testXml.create('testsuites');
|
|||||||
var suiteCount = 0;
|
var suiteCount = 0;
|
||||||
var moment = require('moment');
|
var moment = require('moment');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
var chalk = require('chalk');
|
||||||
|
|
||||||
function makeJUnitXml(runnerName, testDetails) {
|
function makeJUnitXml(runnerName, testDetails) {
|
||||||
_.each(testDetails.suites, function serializeSuite(suiteInfo) {
|
_.each(testDetails.suites, function serializeSuite(suiteInfo) {
|
||||||
@ -78,10 +79,10 @@ function makeJUnitXml(runnerName, testDetails) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (suiteInfo.stdout.trim()) {
|
if (suiteInfo.stdout.trim()) {
|
||||||
suite.ele('system-out', {}).cdata(suiteInfo.stdout);
|
suite.ele('system-out', {}).cdata(chalk.stripColor(suiteInfo.stdout));
|
||||||
}
|
}
|
||||||
if (suiteInfo.stderr.trim()) {
|
if (suiteInfo.stderr.trim()) {
|
||||||
suite.ele('system-err', {}).cdata(suiteInfo.stderr);
|
suite.ele('system-err', {}).cdata(chalk.stripColor(suiteInfo.stderr));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user