Merge pull request #159 from strongloop-forks/constructor-fix

Fix bad constructor guard
This commit is contained in:
Trent Mick 2014-08-25 00:10:41 -07:00
commit a051565ced
2 changed files with 41 additions and 16 deletions

View file

@ -233,7 +233,7 @@ function resolveLevel(nameOrNum) {
*/ */
function Logger(options, _childOptions, _childSimple) { function Logger(options, _childOptions, _childSimple) {
xxx('Logger start:', options) xxx('Logger start:', options)
if (! this instanceof Logger) { if (!(this instanceof Logger)) {
return new Logger(options, _childOptions); return new Logger(options, _childOptions);
} }
@ -242,7 +242,7 @@ function Logger(options, _childOptions, _childSimple) {
if (_childOptions !== undefined) { if (_childOptions !== undefined) {
parent = options; parent = options;
options = _childOptions; options = _childOptions;
if (! parent instanceof Logger) { if (!(parent instanceof Logger)) {
throw new TypeError( throw new TypeError(
'invalid Logger creation: do not pass a second arg'); 'invalid Logger creation: do not pass a second arg');
} }

View file

@ -19,11 +19,11 @@ var test = tap4nodeunit.test;
test('ensure Logger creation options', function (t) { test('ensure Logger creation options', function (t) {
t.throws(function () { new Logger(); }, t.throws(function () { new Logger(); },
'options (object) is required', /options \(object\) is required/,
'no options should throw'); 'no options should throw');
t.throws(function () { new Logger({}); }, t.throws(function () { new Logger({}); },
'options.name (string) is required', /options\.name \(string\) is required/,
'no options.name should throw'); 'no options.name should throw');
t.doesNotThrow(function () { new Logger({name: 'foo'}); }, t.doesNotThrow(function () { new Logger({name: 'foo'}); },
@ -31,35 +31,44 @@ test('ensure Logger creation options', function (t) {
var options = {name: 'foo', stream: process.stdout, streams: []}; var options = {name: 'foo', stream: process.stdout, streams: []};
t.throws(function () { new Logger(options); }, t.throws(function () { new Logger(options); },
/cannot mix "streams" and "stream" options/,
'cannot use "stream" and "streams"'); 'cannot use "stream" and "streams"');
// https://github.com/trentm/node-bunyan/issues/3 // https://github.com/trentm/node-bunyan/issues/3
options = {name: 'foo', streams: {}}; options = {name: 'foo', streams: {}};
t.throws(function () { new Logger(options); }, t.throws(function () { new Logger(options); },
'invalid options.streams: must be an array', /invalid options.streams: must be an array/,
'"streams" must be an array'); '"streams" must be an array');
options = {name: 'foo', serializers: 'a string'}; options = {name: 'foo', serializers: 'a string'};
t.throws(function () { new Logger(options); }, t.throws(function () { new Logger(options); },
'invalid options.serializers: must be an object', /invalid options.serializers: must be an object/,
'"serializers" cannot be a string'); '"serializers" cannot be a string');
options = {name: 'foo', serializers: [1, 2, 3]}; options = {name: 'foo', serializers: [1, 2, 3]};
t.throws(function () { new Logger(options); }, t.throws(function () { new Logger(options); },
'invalid options.serializers: must be an object', /invalid options.serializers: must be an object/,
'"serializers" cannot be an array'); '"serializers" cannot be an array');
t.end(); t.end();
}); });
test('ensure Logger constructor is safe without new', function (t) {
t.doesNotThrow(function () { Logger({name: 'foo'}); },
'constructor should call self with new if necessary');
t.end();
});
test('ensure Logger creation options (createLogger)', function (t) { test('ensure Logger creation options (createLogger)', function (t) {
t.throws(function () { bunyan.createLogger(); }, t.throws(function () { bunyan.createLogger(); },
'options (object) is required', /options \(object\) is required/,
'no options should throw'); 'no options should throw');
t.throws(function () { bunyan.createLogger({}); }, t.throws(function () { bunyan.createLogger({}); },
'options.name (string) is required', /options\.name \(string\) is required/,
'no options.name should throw'); 'no options.name should throw');
t.doesNotThrow(function () { bunyan.createLogger({name: 'foo'}); }, t.doesNotThrow(function () { bunyan.createLogger({name: 'foo'}); },
@ -67,22 +76,23 @@ test('ensure Logger creation options (createLogger)', function (t) {
var options = {name: 'foo', stream: process.stdout, streams: []}; var options = {name: 'foo', stream: process.stdout, streams: []};
t.throws(function () { bunyan.createLogger(options); }, t.throws(function () { bunyan.createLogger(options); },
/cannot mix "streams" and "stream" options/,
'cannot use "stream" and "streams"'); 'cannot use "stream" and "streams"');
// https://github.com/trentm/node-bunyan/issues/3 // https://github.com/trentm/node-bunyan/issues/3
options = {name: 'foo', streams: {}}; options = {name: 'foo', streams: {}};
t.throws(function () { bunyan.createLogger(options); }, t.throws(function () { bunyan.createLogger(options); },
'invalid options.streams: must be an array', /invalid options.streams: must be an array/,
'"streams" must be an array'); '"streams" must be an array');
options = {name: 'foo', serializers: 'a string'}; options = {name: 'foo', serializers: 'a string'};
t.throws(function () { bunyan.createLogger(options); }, t.throws(function () { bunyan.createLogger(options); },
'invalid options.serializers: must be an object', /invalid options.serializers: must be an object/,
'"serializers" cannot be a string'); '"serializers" cannot be a string');
options = {name: 'foo', serializers: [1, 2, 3]}; options = {name: 'foo', serializers: [1, 2, 3]};
t.throws(function () { bunyan.createLogger(options); }, t.throws(function () { bunyan.createLogger(options); },
'invalid options.serializers: must be an object', /invalid options.serializers: must be an object/,
'"serializers" cannot be an array'); '"serializers" cannot be an array');
t.end(); t.end();
@ -99,28 +109,43 @@ test('ensure Logger child() options', function (t) {
'empty options should be fine too'); 'empty options should be fine too');
t.throws(function () { log.child({name: 'foo'}); }, t.throws(function () { log.child({name: 'foo'}); },
'invalid options.name: child cannot set logger name', /invalid options.name: child cannot set logger name/,
'child cannot change name'); 'child cannot change name');
var options = {stream: process.stdout, streams: []}; var options = {stream: process.stdout, streams: []};
t.throws(function () { log.child(options); }, t.throws(function () { log.child(options); },
/cannot mix "streams" and "stream" options/,
'cannot use "stream" and "streams"'); 'cannot use "stream" and "streams"');
// https://github.com/trentm/node-bunyan/issues/3 // https://github.com/trentm/node-bunyan/issues/3
options = {streams: {}}; options = {streams: {}};
t.throws(function () { log.child(options); }, t.throws(function () { log.child(options); },
'invalid options.streams: must be an array', /invalid options.streams: must be an array/,
'"streams" must be an array'); '"streams" must be an array');
options = {serializers: 'a string'}; options = {serializers: 'a string'};
t.throws(function () { log.child(options); }, t.throws(function () { log.child(options); },
'invalid options.serializers: must be an object', /invalid options.serializers: must be an object/,
'"serializers" cannot be a string'); '"serializers" cannot be a string');
options = {serializers: [1, 2, 3]}; options = {serializers: [1, 2, 3]};
t.throws(function () { log.child(options); }, t.throws(function () { log.child(options); },
'invalid options.serializers: must be an object', /invalid options.serializers: must be an object/,
'"serializers" cannot be an array'); '"serializers" cannot be an array');
t.end(); t.end();
}); });
test('ensure Logger() rejects non-Logger parents', function (t) {
var dad = new Logger({name: 'dad', streams: []});
t.throws(function () { new Logger({}, {}); },
/invalid Logger creation: do not pass a second arg/,
'Logger arguments must be valid');
t.doesNotThrow(function () { new Logger(dad, {}); },
'Logger allows Logger instance as parent');
t.end();
});