diff --git a/CHANGES.md b/CHANGES.md index ffccb43..29f3199 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,8 @@ ## bunyan 0.5.2 (not yet released) +- [issue #3] More type checking of `new Logger(...)` and `log.child(...)` + options. - Start a test suite. diff --git a/TODO.md b/TODO.md index 09faeb9..e6bec49 100644 --- a/TODO.md +++ b/TODO.md @@ -42,7 +42,7 @@ logging, if helpful. - add option to "streams" to take the raw object, not serialized. It would be a good hook for people with custom needs that Bunyan doesn't - care about (e.g. log.ly or hook.io or whatever). + care about (e.g. http://loggly.com/ or hook.io or whatever). - split out `bunyan` cli to a "bunyan" or "bunyan-reader" or "node-bunyan-reader" as the basis for tools to consume bunyan logs. It can grow indep of node-bunyan for generating the logs. diff --git a/lib/bunyan.js b/lib/bunyan.js index 8fbce8f..63ad890 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -1,5 +1,7 @@ /* - * Copyright 2012 (c) Trent Mick. All rights reserved. + * Copyright (c) 2012 Trent Mick. All rights reserved. + * + * The bunyan logging library for node.js. */ var VERSION = "0.5.2"; @@ -215,12 +217,25 @@ function Logger(options, _childOptions, _childSimple) { if (!options) { throw new TypeError('options (object) is required'); } - if (!parent && !options.name) { - throw new TypeError('options.name (string) is required'); + if (!parent) { + if (!options.name) { + throw new TypeError('options.name (string) is required'); + } + } else { + if (options.name) { + throw new TypeError('invalid options.name: child cannot set logger name'); + } } if ((options.stream || options.level) && options.streams) { throw new TypeError('cannot mix "streams" with "stream" or "level" options'); } + if (options.streams && !Array.isArray(options.streams)) { + throw new TypeError('invalid options.streams: must be an array') + } + if (options.serializers && (typeof(options.serializers) !== 'object' + || Array.isArray(options.serializers))) { + throw new TypeError('invalid options.serializers: must be an object') + } // Fast path for simple child creation. if (parent && _childSimple) { diff --git a/test/ctor.test.js b/test/ctor.test.js index 81e9d9b..9abfe86 100644 --- a/test/ctor.test.js +++ b/test/ctor.test.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Trent Mick. All rights reserved. + * Copyright (c) 2012 Trent Mick. All rights reserved. * * Test type checking on creation of the Logger. */ @@ -8,8 +8,83 @@ var test = require('tap').test; var Logger = require('../lib/bunyan'); -test("douglas adams", function(t) { - t.ok(42, "the answer to life the universe and everything"); +test('ensure Logger creation options', function (t) { + t.throws(function () { new Logger(); }, + {name: 'TypeError', message: 'options (object) is required'}, + 'no options should throw'); + + t.throws(function () { new Logger({}); }, + {name: 'TypeError', message: 'options.name (string) is required'}, + 'no options.name should throw'); + + t.doesNotThrow(function () { new Logger({name: 'foo'}); }, + 'just options.name should be sufficient'); + + var options = {name: 'foo', stream: process.stdout, streams: []}; + t.throws(function () { new Logger(options); }, + 'cannot use "stream" and "streams"'); + + options = {name: 'foo', level: 'info', streams: []}; + t.throws(function () { new Logger(options); }, + 'cannot use "level" and "streams"'); + + // https://github.com/trentm/node-bunyan/issues/3 + options = {name: 'foo', streams: {}}; + t.throws(function () { new Logger(options); }, + {name: 'TypeError', message: 'invalid options.streams: must be an array'}, + '"streams" must be an array'); + + options = {name: 'foo', serializers: "a string"}; + t.throws(function () { new Logger(options); }, + {name: 'TypeError', message: 'invalid options.serializers: must be an object'}, + '"serializers" cannot be a string'); + + options = {name: 'foo', serializers: [1,2,3]}; + t.throws(function () { new Logger(options); }, + {name: 'TypeError', message: 'invalid options.serializers: must be an object'}, + '"serializers" cannot be an array'); + + t.end(); +}); + + +test('ensure Logger child() options', function (t) { + var log = new Logger({name: 'foo'}); + + t.doesNotThrow(function () { log.child(); }, + 'no options should be fine'); + + t.doesNotThrow(function () { log.child({}); }, + 'empty options should be fine too'); + + t.throws(function () { log.child({name: 'foo'}); }, + {name: 'TypeError', message: 'invalid options.name: child cannot set logger name'}, + 'child cannot change name'); + + var options = {stream: process.stdout, streams: []}; + t.throws(function () { log.child(options); }, + 'cannot use "stream" and "streams"'); + + options = {level: 'info', streams: []}; + t.throws(function () { log.child(options); }, + 'cannot use "level" and "streams"'); + + // https://github.com/trentm/node-bunyan/issues/3 + options = {streams: {}}; + t.throws(function () { log.child(options); }, + {name: 'TypeError', message: 'invalid options.streams: must be an array'}, + '"streams" must be an array'); + + options = {serializers: "a string"}; + t.throws(function () { log.child(options); }, + {name: 'TypeError', message: 'invalid options.serializers: must be an object'}, + '"serializers" cannot be a string'); + + options = {serializers: [1,2,3]}; + t.throws(function () { log.child(options); }, + {name: 'TypeError', message: 'invalid options.serializers: must be an object'}, + '"serializers" cannot be an array'); + t.end(); });