From e2d44024f8596a572370ce94544bfaa8a370e280 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 29 Jan 2022 15:33:52 -0700 Subject: [PATCH 01/39] chore: wrap logger tests in top-level describe --- test/logger.test.js | 1689 ++++++++++++++++++++++--------------------- 1 file changed, 852 insertions(+), 837 deletions(-) diff --git a/test/logger.test.js b/test/logger.test.js index 2618d1d60..2d1b47125 100755 --- a/test/logger.test.js +++ b/test/logger.test.js @@ -22,1060 +22,1075 @@ const format = require('../lib/winston').format; const helpers = require('./helpers'); const mockTransport = require('./helpers/mocks/mock-transport'); -describe('Logger', function () { - it('new Logger()', function () { - var logger = winston.createLogger(); - assume(logger).is.an('object'); - assume(isStream(logger.format)); - assume(logger.level).equals('info'); - assume(logger.exitOnError).equals(true); - }); - - it('new Logger({ parameters })', function () { - var myFormat = format(function (info, opts) { - return info; - })(); - var logger = winston.createLogger({ - format: myFormat, - level: 'error', - exitOnError: false, - transports: [] +describe('Logger', function () { + describe('Logger', function () { + it('new Logger()', function () { + var logger = winston.createLogger(); + assume(logger).is.an('object'); + assume(isStream(logger.format)); + assume(logger.level).equals('info'); + assume(logger.exitOnError).equals(true); }); - assume(logger.format).equals(myFormat); - assume(logger.level).equals('error'); - assume(logger.exitOnError).equals(false); - assume(logger._readableState.pipesCount).equals(0); - }); + it('new Logger({ parameters })', function () { + var myFormat = format(function (info, opts) { + return info; + })(); - it('new Logger({ levels }) defines custom methods', function () { - var myFormat = format(function (info, opts) { - return info; - })(); - - var logger = winston.createLogger({ - levels: winston.config.syslog.levels, - format: myFormat, - level: 'error', - exitOnError: false, - transports: [] + var logger = winston.createLogger({ + format: myFormat, + level: 'error', + exitOnError: false, + transports: [] + }); + + assume(logger.format).equals(myFormat); + assume(logger.level).equals('error'); + assume(logger.exitOnError).equals(false); + assume(logger._readableState.pipesCount).equals(0); }); - Object.keys(winston.config.syslog.levels).forEach(level => { - assume(logger[level]).is.a('function'); - }) - }); + it('new Logger({ levels }) defines custom methods', function () { + var myFormat = format(function (info, opts) { + return info; + })(); + + var logger = winston.createLogger({ + levels: winston.config.syslog.levels, + format: myFormat, + level: 'error', + exitOnError: false, + transports: [] + }); - it('new Logger({ levels }) custom methods are not bound to instance', function (done) { - var logger = winston.createLogger({ - level: 'error', - exitOnError: false, - transports: [] + Object.keys(winston.config.syslog.levels).forEach(level => { + assume(logger[level]).is.a('function'); + }) }); - let logs = []; - let extendedLogger = Object.create(logger, { - write: { - value: function(...args) { - logs.push(args); - if (logs.length === 4) { - assume(logs.length).is.eql(4); - assume(logs[0]).is.eql([{ test: 1, level: 'info' }]); - assume(logs[1]).is.eql([{ test: 2, level: 'warn' }]); - assume(logs[2]).is.eql([{ message: 'test3', level: 'info' }]) - assume(logs[3]).is.eql([{ with: 'meta', - test: 4, - level: 'warn', - message: 'a warning' - }]); + it('new Logger({ levels }) custom methods are not bound to instance', function (done) { + var logger = winston.createLogger({ + level: 'error', + exitOnError: false, + transports: [] + }); - done(); + let logs = []; + let extendedLogger = Object.create(logger, { + write: { + value: function (...args) { + logs.push(args); + if (logs.length === 4) { + assume(logs.length).is.eql(4); + assume(logs[0]).is.eql([{test: 1, level: 'info'}]); + assume(logs[1]).is.eql([{test: 2, level: 'warn'}]); + assume(logs[2]).is.eql([{message: 'test3', level: 'info'}]) + assume(logs[3]).is.eql([{ + with: 'meta', + test: 4, + level: 'warn', + message: 'a warning' + }]); + + done(); + } } } - } + }); + + extendedLogger.log('info', {test: 1}); + extendedLogger.log('warn', {test: 2}); + extendedLogger.info('test3'); + extendedLogger.warn('a warning', {with: 'meta', test: 4}); }); - extendedLogger.log('info', { test: 1 }); - extendedLogger.log('warn', { test: 2 }); - extendedLogger.info('test3'); - extendedLogger.warn('a warning', { with: 'meta', test: 4 }); - }); + it('.add({ invalid Transport })', function () { + var logger = winston.createLogger(); + assume(function () { + logger.add(5); + }).throws(/invalid transport/i); + }); - it('.add({ invalid Transport })', function () { - var logger = winston.createLogger(); - assume(function () { - logger.add(5); - }).throws(/invalid transport/i); - }); + it('.add(TransportStream)', function (done) { + var logger = winston.createLogger(); + var expected = {message: 'foo', level: 'info'}; + var transport = new TransportStream({ + log: function (info) { + assume(info.message).equals('foo'); + assume(info.level).equals('info'); + assume(JSON.parse(info[MESSAGE])).deep.equals({level: 'info', message: 'foo'}); + done(); + } + }); - it('.add(TransportStream)', function (done) { - var logger = winston.createLogger(); - var expected = { message: 'foo', level: 'info' }; - var transport = new TransportStream({ - log: function (info) { - assume(info.message).equals('foo'); - assume(info.level).equals('info'); - assume(JSON.parse(info[MESSAGE])).deep.equals({ level: 'info', message: 'foo' }); - done(); - } + logger.add(transport); + logger.log(expected); }); - logger.add(transport); - logger.log(expected); - }); + it('.stream()', function () { + var logger = winston.createLogger(); + var outStream = logger.stream(); - it('.stream()', function () { - var logger = winston.createLogger(); - var outStream = logger.stream(); + assume(isStream(outStream)).true(); + }); - assume(isStream(outStream)).true(); - }); + it('.configure()', function () { + var logger = winston.createLogger({ + transports: [new winston.transports.Console()] + }); - it('.configure()', function () { - var logger = winston.createLogger({ - transports: [new winston.transports.Console()] - }); + assume(logger.transports.length).equals(1); + assume(logger.transports[0].name).equals('console'); - assume(logger.transports.length).equals(1); - assume(logger.transports[0].name).equals('console'); + logger.configure(); - logger.configure(); + assume(logger.transports.length).equals(0); + }); - assume(logger.transports.length).equals(0); - }); + it('.configure({ transports })', function () { + var logger = winston.createLogger(); - it('.configure({ transports })', function () { - var logger = winston.createLogger(); + assume(logger.transports.length).equals(0); - assume(logger.transports.length).equals(0); + logger.configure({ + transports: [new winston.transports.Console()] + }); - logger.configure({ - transports: [new winston.transports.Console()] + assume(logger.transports.length).equals(1); + assume(logger.transports[0].name).equals('console'); }); - assume(logger.transports.length).equals(1); - assume(logger.transports[0].name).equals('console'); - }); + it('.configure({ transports, format })', function () { + var logger = winston.createLogger(), + format = logger.format; - it('.configure({ transports, format })', function () { - var logger = winston.createLogger(), - format = logger.format; + assume(logger.transports.length).equals(0); - assume(logger.transports.length).equals(0); + logger.configure({ + transports: [new winston.transports.Console()], + format: winston.format.json() + }); - logger.configure({ - transports: [new winston.transports.Console()], - format: winston.format.json() + assume(logger.transports.length).equals(1); + assume(logger.transports[0].name).equals('console'); + assume(logger.format).not.equals(format); }); - assume(logger.transports.length).equals(1); - assume(logger.transports[0].name).equals('console'); - assume(logger.format).not.equals(format); - }); + it('.remove() [transport not added]', function () { + var transports = [ + new winston.transports.Console(), + new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) + ]; - it('.remove() [transport not added]', function () { - var transports = [ - new winston.transports.Console(), - new winston.transports.File({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log' )}) - ]; + var logger = winston.createLogger({transports: transports}) + .remove(new winston.transports.Console()); - var logger = winston.createLogger({ transports: transports }) - .remove(new winston.transports.Console()); + assume(logger.transports.length).equals(2); + assume(logger.transports.map(function (wrap) { + // Unwrap LegacyTransportStream instances + return wrap.transport || wrap; + })).deep.equals(transports); + }); - assume(logger.transports.length).equals(2); - assume(logger.transports.map(function (wrap) { - // Unwrap LegacyTransportStream instances - return wrap.transport || wrap; - })).deep.equals(transports); - }); + it('.remove() [TransportStream]', function () { + var transports = [ + new winston.transports.Console(), + new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) + ]; - it('.remove() [TransportStream]', function () { - var transports = [ - new winston.transports.Console(), - new winston.transports.File({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log' )}) - ]; + var logger = winston.createLogger({transports: transports}); - var logger = winston.createLogger({ transports: transports }); + assume(logger.transports.length).equals(2); + logger.remove(transports[0]); + assume(logger.transports.length).equals(1); + assume(logger.transports[0]).equals(transports[1]); + }); - assume(logger.transports.length).equals(2); - logger.remove(transports[0]); - assume(logger.transports.length).equals(1); - assume(logger.transports[0]).equals(transports[1]); - }); + it('.clear() [no transports]', function () { + var logger = winston.createLogger(); + assume(logger.transports.length).equals(0); + logger.clear(); + assume(logger.transports.length).equals(0); + }); - it('.clear() [no transports]', function () { - var logger = winston.createLogger(); - assume(logger.transports.length).equals(0); - logger.clear(); - assume(logger.transports.length).equals(0); - }); + it('.clear() [transports]', function () { + var logger = winston.createLogger({ + transports: [new winston.transports.Console()] + }); - it ('.clear() [transports]', function () { - var logger = winston.createLogger({ - transports: [new winston.transports.Console()] + assume(logger.transports.length).equals(1); + logger.clear(); + assume(logger.transports.length).equals(0); }); - assume(logger.transports.length).equals(1); - logger.clear(); - assume(logger.transports.length).equals(0); - }); + it('{ silent: true }', function (done) { + const neverLogTo = new TransportStream({ + log: function (info) { + assume(false).true('TransportStream was improperly written to'); + } + }); - it('{ silent: true }', function (done) { - const neverLogTo = new TransportStream({ - log: function (info) { - assume(false).true('TransportStream was improperly written to'); - } - }); + var logger = winston.createLogger({ + transports: [neverLogTo], + silent: true + }); - var logger = winston.createLogger({ - transports: [neverLogTo], - silent: true - }); + logger.log({ + level: 'info', + message: 'This should be ignored' + }); - logger.log({ - level: 'info', - message: 'This should be ignored' + setImmediate(() => done()); }); - - setImmediate(() => done()); }); -}); -describe('Logger (multiple transports of the same type)', function () { - var logger, transports; - - before(function () { - transports = [ - new winston.transports.File({ - name: 'filelog-info.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'), - level: 'info' - }), - new winston.transports.File({ - name: 'filelog-error.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'), - level: 'error' - }) - ]; + describe('Logger (multiple transports of the same type)', function () { + var logger, transports; + + before(function () { + transports = [ + new winston.transports.File({ + name: 'filelog-info.log', + filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'), + level: 'info' + }), + new winston.transports.File({ + name: 'filelog-error.log', + filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'), + level: 'error' + }) + ]; + + logger = winston.createLogger({ + transports: transports + }); + }); - logger = winston.createLogger({ - transports: transports + it('should have both transports', function () { + assume(logger.transports.length).equals(2); + assume(logger.transports.map(function (wrap) { + return wrap.transport || wrap; + })).deep.equals(transports); }); - }); - it('should have both transports', function () { - assume(logger.transports.length).equals(2); - assume(logger.transports.map(function (wrap) { - return wrap.transport || wrap; - })).deep.equals(transports); + it('.remove() of one transport', function () { + logger.remove(transports[0]); + assume(logger.transports.length).equals(1); + assume(logger.transports[0]).equals(transports[1]); + }); }); - it('.remove() of one transport', function () { - logger.remove(transports[0]); - assume(logger.transports.length).equals(1); - assume(logger.transports[0]).equals(transports[1]); - }); -}); + describe('Logger (levels)', function () { + it('report unknown levels', function (done) { + stdMocks.use(); + var logger = helpers.createLogger(function (info) { + }); + var expected = {message: 'foo', level: 'bar'}; + logger.log(expected); -describe('Logger (levels)', function () { - it('report unknown levels', function (done) { - stdMocks.use(); - var logger = helpers.createLogger(function (info) {}); - var expected = { message: 'foo', level: 'bar' }; - logger.log(expected); + stdMocks.restore(); + var output = stdMocks.flush(); - stdMocks.restore(); - var output = stdMocks.flush(); + assume(output.stderr).deep.equals(['[winston] Unknown logger level: bar\n']); + done(); + }); - assume(output.stderr).deep.equals(['[winston] Unknown logger level: bar\n']); - done(); - }); + it('.()', function (done) { + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).is.a('string'); + assume(info[MESSAGE]).is.a('string'); + assume(info.message).equals(''); + assume(JSON.parse(info[MESSAGE])).deep.equals({ + level: 'info', + message: '' + }); - it('.()', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).is.a('string'); - assume(info[MESSAGE]).is.a('string'); - assume(info.message).equals(''); - assume(JSON.parse(info[MESSAGE])).deep.equals({ - level: 'info', - message: '' + done(); }); - done(); + logger.info(); + logger.info(''); }); - logger.info(); - logger.info(''); - }); + it('default levels', function (done) { + var logger = winston.createLogger(); + var expected = {message: 'foo', level: 'debug'}; + + function logLevelTransport(level) { + return new TransportStream({ + level: level, + log: function (obj) { + if (level === 'info') { + assume(obj).equals(undefined, 'Transport on level info should never be called'); + } + + assume(obj.message).equals('foo'); + assume(obj.level).equals('debug'); + assume(JSON.parse(obj[MESSAGE])).deep.equals({level: 'debug', message: 'foo'}); + done(); + } + }); + } - it('default levels', function (done) { - var logger = winston.createLogger(); - var expected = { message: 'foo', level: 'debug' }; + assume(logger.info).is.a('function'); + assume(logger.debug).is.a('function'); - function logLevelTransport(level) { - return new TransportStream({ - level: level, - log: function (obj) { - if (level === 'info') { - assume(obj).equals(undefined, 'Transport on level info should never be called'); - } + logger + .add(logLevelTransport('info')) + .add(logLevelTransport('debug')) + .log(expected); + }); - assume(obj.message).equals('foo'); - assume(obj.level).equals('debug'); - assume(JSON.parse(obj[MESSAGE])).deep.equals({ level: 'debug', message: 'foo' }); - done(); + it('custom levels', function (done) { + var logger = winston.createLogger({ + levels: { + bad: 0, + test: 1, + ok: 2 } }); - } - assume(logger.info).is.a('function'); - assume(logger.debug).is.a('function'); + var expected = {message: 'foo', level: 'test'}; - logger - .add(logLevelTransport('info')) - .add(logLevelTransport('debug')) - .log(expected); - }); + function filterLevelTransport(level) { + return new TransportStream({ + level: level, + log: function (obj) { + if (level === 'bad') { + assume(obj).equals(undefined, 'transport on level "bad" should never be called'); + } - it('custom levels', function (done) { - var logger = winston.createLogger({ - levels: { - bad: 0, - test: 1, - ok: 2 + assume(obj.message).equals('foo'); + assume(obj.level).equals('test'); + assume(JSON.parse(obj[MESSAGE])).deep.equals({level: 'test', message: 'foo'}); + done(); + } + }); } + + assume(logger.bad).is.a('function'); + assume(logger.test).is.a('function'); + assume(logger.ok).is.a('function'); + + logger + .add(filterLevelTransport('bad')) + .add(filterLevelTransport('ok')) + .log(expected); }); - var expected = { message: 'foo', level: 'test' }; - function filterLevelTransport(level) { - return new TransportStream({ - level: level, - log: function (obj) { - if (level === 'bad') { - assume(obj).equals(undefined, 'transport on level "bad" should never be called'); + it('sets transports levels', done => { + let logger; + const transport = new TransportStream({ + log(obj) { + if (obj.level === 'info') { + assume(obj).equals(undefined, 'Transport on level info should never be called'); } assume(obj.message).equals('foo'); - assume(obj.level).equals('test'); - assume(JSON.parse(obj[MESSAGE])).deep.equals({ level: 'test', message: 'foo' }); + assume(obj.level).equals('error'); + assume(JSON.parse(obj[MESSAGE])).deep.equals({level: 'error', message: 'foo'}); done(); } }); - } - assume(logger.bad).is.a('function'); - assume(logger.test).is.a('function'); - assume(logger.ok).is.a('function'); + // Begin our test in the next tick after the pipe event is + // emitted from the transport. + transport.once('pipe', () => setImmediate(() => { + const expectedError = {message: 'foo', level: 'error'}; + const expectedInfo = {message: 'bar', level: 'info'}; - logger - .add(filterLevelTransport('bad')) - .add(filterLevelTransport('ok')) - .log(expected); - }); + assume(logger.error).is.a('function'); + assume(logger.info).is.a('function'); - it('sets transports levels', done => { - let logger; - const transport = new TransportStream({ - log(obj) { - if (obj.level === 'info') { - assume(obj).equals(undefined, 'Transport on level info should never be called'); - } + // Set the level + logger.level = 'error'; - assume(obj.message).equals('foo'); - assume(obj.level).equals('error'); - assume(JSON.parse(obj[MESSAGE])).deep.equals({ level: 'error', message: 'foo' }); - done(); - } + // Log the messages. "info" should never arrive. + logger + .log(expectedInfo) + .log(expectedError); + })); + + logger = winston.createLogger({ + transports: [transport] + }); }); + }); - // Begin our test in the next tick after the pipe event is - // emitted from the transport. - transport.once('pipe', () => setImmediate(() => { - const expectedError = { message: 'foo', level: 'error' }; - const expectedInfo = { message: 'bar', level: 'info' }; + describe('Logger (level enabled/disabled)', function () { + it('default levels', function () { + var logger = winston.createLogger({ + level: 'verbose', + levels: winston.config.npm.levels, + transports: [new winston.transports.Console()] + }); - assume(logger.error).is.a('function'); - assume(logger.info).is.a('function'); + assume(logger.isLevelEnabled).is.a('function'); + + assume(logger.isErrorEnabled).is.a('function'); + assume(logger.isWarnEnabled).is.a('function'); + assume(logger.isInfoEnabled).is.a('function'); + assume(logger.isVerboseEnabled).is.a('function'); + assume(logger.isDebugEnabled).is.a('function'); + assume(logger.isSillyEnabled).is.a('function'); + + assume(logger.isLevelEnabled('error')).true(); + assume(logger.isLevelEnabled('warn')).true(); + assume(logger.isLevelEnabled('info')).true(); + assume(logger.isLevelEnabled('verbose')).true(); + assume(logger.isLevelEnabled('debug')).false(); + assume(logger.isLevelEnabled('silly')).false(); + + assume(logger.isErrorEnabled()).true(); + assume(logger.isWarnEnabled()).true(); + assume(logger.isInfoEnabled()).true(); + assume(logger.isVerboseEnabled()).true(); + assume(logger.isDebugEnabled()).false(); + assume(logger.isSillyEnabled()).false(); + }); - // Set the level - logger.level = 'error'; + it('default levels, transport override', function () { + var transport = new winston.transports.Console(); + transport.level = 'debug'; - // Log the messages. "info" should never arrive. - logger - .log(expectedInfo) - .log(expectedError); - })); + var logger = winston.createLogger({ + level: 'info', + levels: winston.config.npm.levels, + transports: [transport] + }); - logger = winston.createLogger({ - transports: [transport] + assume(logger.isLevelEnabled).is.a('function'); + + assume(logger.isErrorEnabled).is.a('function'); + assume(logger.isWarnEnabled).is.a('function'); + assume(logger.isInfoEnabled).is.a('function'); + assume(logger.isVerboseEnabled).is.a('function'); + assume(logger.isDebugEnabled).is.a('function'); + assume(logger.isSillyEnabled).is.a('function'); + + assume(logger.isLevelEnabled('error')).true(); + assume(logger.isLevelEnabled('warn')).true(); + assume(logger.isLevelEnabled('info')).true(); + assume(logger.isLevelEnabled('verbose')).true(); + assume(logger.isLevelEnabled('debug')).true(); + assume(logger.isLevelEnabled('silly')).false(); + + assume(logger.isErrorEnabled()).true(); + assume(logger.isWarnEnabled()).true(); + assume(logger.isInfoEnabled()).true(); + assume(logger.isVerboseEnabled()).true(); + assume(logger.isDebugEnabled()).true(); + assume(logger.isSillyEnabled()).false(); }); - }); -}); -describe('Logger (level enabled/disabled)', function () { - it('default levels', function () { - var logger = winston.createLogger({ - level: 'verbose', - levels: winston.config.npm.levels, - transports: [new winston.transports.Console()] + it('default levels, no transports', function () { + var logger = winston.createLogger({ + level: 'verbose', + levels: winston.config.npm.levels, + transports: [] + }); + + assume(logger.isLevelEnabled).is.a('function'); + + assume(logger.isErrorEnabled).is.a('function'); + assume(logger.isWarnEnabled).is.a('function'); + assume(logger.isInfoEnabled).is.a('function'); + assume(logger.isVerboseEnabled).is.a('function'); + assume(logger.isDebugEnabled).is.a('function'); + assume(logger.isSillyEnabled).is.a('function'); + + assume(logger.isLevelEnabled('error')).true(); + assume(logger.isLevelEnabled('warn')).true(); + assume(logger.isLevelEnabled('info')).true(); + assume(logger.isLevelEnabled('verbose')).true(); + assume(logger.isLevelEnabled('debug')).false(); + assume(logger.isLevelEnabled('silly')).false(); + + assume(logger.isErrorEnabled()).true(); + assume(logger.isWarnEnabled()).true(); + assume(logger.isInfoEnabled()).true(); + assume(logger.isVerboseEnabled()).true(); + assume(logger.isDebugEnabled()).false(); + assume(logger.isSillyEnabled()).false(); }); - assume(logger.isLevelEnabled).is.a('function'); - - assume(logger.isErrorEnabled).is.a('function'); - assume(logger.isWarnEnabled).is.a('function'); - assume(logger.isInfoEnabled).is.a('function'); - assume(logger.isVerboseEnabled).is.a('function'); - assume(logger.isDebugEnabled).is.a('function'); - assume(logger.isSillyEnabled).is.a('function'); - - assume(logger.isLevelEnabled('error')).true(); - assume(logger.isLevelEnabled('warn')).true(); - assume(logger.isLevelEnabled('info')).true(); - assume(logger.isLevelEnabled('verbose')).true(); - assume(logger.isLevelEnabled('debug')).false(); - assume(logger.isLevelEnabled('silly')).false(); - - assume(logger.isErrorEnabled()).true(); - assume(logger.isWarnEnabled()).true(); - assume(logger.isInfoEnabled()).true(); - assume(logger.isVerboseEnabled()).true(); - assume(logger.isDebugEnabled()).false(); - assume(logger.isSillyEnabled()).false(); - }); + it('custom levels', function () { + var logger = winston.createLogger({ + level: 'test', + levels: { + bad: 0, + test: 1, + ok: 2 + }, + transports: [new winston.transports.Console()] + }); - it('default levels, transport override', function () { - var transport = new winston.transports.Console(); - transport.level = 'debug'; + assume(logger.isLevelEnabled).is.a('function'); - var logger = winston.createLogger({ - level: 'info', - levels: winston.config.npm.levels, - transports: [transport] - }); + assume(logger.isBadEnabled).is.a('function'); + assume(logger.isTestEnabled).is.a('function'); + assume(logger.isOkEnabled).is.a('function'); - assume(logger.isLevelEnabled).is.a('function'); - - assume(logger.isErrorEnabled).is.a('function'); - assume(logger.isWarnEnabled).is.a('function'); - assume(logger.isInfoEnabled).is.a('function'); - assume(logger.isVerboseEnabled).is.a('function'); - assume(logger.isDebugEnabled).is.a('function'); - assume(logger.isSillyEnabled).is.a('function'); - - assume(logger.isLevelEnabled('error')).true(); - assume(logger.isLevelEnabled('warn')).true(); - assume(logger.isLevelEnabled('info')).true(); - assume(logger.isLevelEnabled('verbose')).true(); - assume(logger.isLevelEnabled('debug')).true(); - assume(logger.isLevelEnabled('silly')).false(); - - assume(logger.isErrorEnabled()).true(); - assume(logger.isWarnEnabled()).true(); - assume(logger.isInfoEnabled()).true(); - assume(logger.isVerboseEnabled()).true(); - assume(logger.isDebugEnabled()).true(); - assume(logger.isSillyEnabled()).false(); - }); + assume(logger.isLevelEnabled('bad')).true(); + assume(logger.isLevelEnabled('test')).true(); + assume(logger.isLevelEnabled('ok')).false(); - it('default levels, no transports', function () { - var logger = winston.createLogger({ - level: 'verbose', - levels: winston.config.npm.levels, - transports: [] + assume(logger.isBadEnabled()).true(); + assume(logger.isTestEnabled()).true(); + assume(logger.isOkEnabled()).false(); }); - assume(logger.isLevelEnabled).is.a('function'); - - assume(logger.isErrorEnabled).is.a('function'); - assume(logger.isWarnEnabled).is.a('function'); - assume(logger.isInfoEnabled).is.a('function'); - assume(logger.isVerboseEnabled).is.a('function'); - assume(logger.isDebugEnabled).is.a('function'); - assume(logger.isSillyEnabled).is.a('function'); - - assume(logger.isLevelEnabled('error')).true(); - assume(logger.isLevelEnabled('warn')).true(); - assume(logger.isLevelEnabled('info')).true(); - assume(logger.isLevelEnabled('verbose')).true(); - assume(logger.isLevelEnabled('debug')).false(); - assume(logger.isLevelEnabled('silly')).false(); - - assume(logger.isErrorEnabled()).true(); - assume(logger.isWarnEnabled()).true(); - assume(logger.isInfoEnabled()).true(); - assume(logger.isVerboseEnabled()).true(); - assume(logger.isDebugEnabled()).false(); - assume(logger.isSillyEnabled()).false(); - }); + it('custom levels, no transports', function () { + var logger = winston.createLogger({ + level: 'test', + levels: { + bad: 0, + test: 1, + ok: 2 + }, + transports: [] + }); - it('custom levels', function () { - var logger = winston.createLogger({ - level: 'test', - levels: { - bad: 0, - test: 1, - ok: 2 - }, - transports: [new winston.transports.Console()] + assume(logger.isLevelEnabled).is.a('function'); + + assume(logger.isBadEnabled).is.a('function'); + assume(logger.isTestEnabled).is.a('function'); + assume(logger.isOkEnabled).is.a('function'); + + assume(logger.isLevelEnabled('bad')).true(); + assume(logger.isLevelEnabled('test')).true(); + assume(logger.isLevelEnabled('ok')).false(); + + assume(logger.isBadEnabled()).true(); + assume(logger.isTestEnabled()).true(); + assume(logger.isOkEnabled()).false(); }); - assume(logger.isLevelEnabled).is.a('function'); + it('custom levels, transport override', function () { + var transport = new winston.transports.Console(); + transport.level = 'ok'; + + var logger = winston.createLogger({ + level: 'bad', + levels: { + bad: 0, + test: 1, + ok: 2 + }, + transports: [transport] + }); - assume(logger.isBadEnabled).is.a('function'); - assume(logger.isTestEnabled).is.a('function'); - assume(logger.isOkEnabled).is.a('function'); + assume(logger.isLevelEnabled).is.a('function'); - assume(logger.isLevelEnabled('bad')).true(); - assume(logger.isLevelEnabled('test')).true(); - assume(logger.isLevelEnabled('ok')).false(); + assume(logger.isBadEnabled).is.a('function'); + assume(logger.isTestEnabled).is.a('function'); + assume(logger.isOkEnabled).is.a('function'); - assume(logger.isBadEnabled()).true(); - assume(logger.isTestEnabled()).true(); - assume(logger.isOkEnabled()).false(); - }); + assume(logger.isLevelEnabled('bad')).true(); + assume(logger.isLevelEnabled('test')).true(); + assume(logger.isLevelEnabled('ok')).true(); - it('custom levels, no transports', function () { - var logger = winston.createLogger({ - level: 'test', - levels: { - bad: 0, - test: 1, - ok: 2 - }, - transports: [] + assume(logger.isBadEnabled()).true(); + assume(logger.isTestEnabled()).true(); + assume(logger.isOkEnabled()).true(); }); + }); + + describe('Logger (stream semantics)', function () { + it(`'finish' event awaits transports to emit 'finish'`, function (done) { + const transports = [ + new TransportStream({ + log: function () { + } + }), + new TransportStream({ + log: function () { + } + }), + new TransportStream({ + log: function () { + } + }) + ]; - assume(logger.isLevelEnabled).is.a('function'); + const finished = []; + const logger = winston.createLogger({transports}); - assume(logger.isBadEnabled).is.a('function'); - assume(logger.isTestEnabled).is.a('function'); - assume(logger.isOkEnabled).is.a('function'); + // Assert each transport emits finish + transports.forEach((transport, i) => { + transport.on('finish', () => finished[i] = true); + }); - assume(logger.isLevelEnabled('bad')).true(); - assume(logger.isLevelEnabled('test')).true(); - assume(logger.isLevelEnabled('ok')).false(); + // Manually end the last transport to simulate mixed + // finished state + transports[2].end(); - assume(logger.isBadEnabled()).true(); - assume(logger.isTestEnabled()).true(); - assume(logger.isOkEnabled()).false(); - }); + // Assert that all transport 'finish' events have been + // emitted when the logger emits 'finish'. + logger.on('finish', function () { + assume(finished[0]).true(); + assume(finished[1]).true(); + assume(finished[2]).true(); + done(); + }); - it('custom levels, transport override', function () { - var transport = new winston.transports.Console(); - transport.level = 'ok'; - - var logger = winston.createLogger({ - level: 'bad', - levels: { - bad: 0, - test: 1, - ok: 2 - }, - transports: [transport] + setImmediate(() => logger.end()); }); - assume(logger.isLevelEnabled).is.a('function'); - - assume(logger.isBadEnabled).is.a('function'); - assume(logger.isTestEnabled).is.a('function'); - assume(logger.isOkEnabled).is.a('function'); + it(`rethrows errors from user-defined formats`, function () { + stdMocks.use(); + const logger = winston.createLogger({ + transports: [new winston.transports.Console()], + format: winston.format.printf((info) => { + // Set a trap. + if (info.message === 'ENDOR') { + throw new Error('ITS A TRAP!'); + } - assume(logger.isLevelEnabled('bad')).true(); - assume(logger.isLevelEnabled('test')).true(); - assume(logger.isLevelEnabled('ok')).true(); + return info.message; + }) + }); - assume(logger.isBadEnabled()).true(); - assume(logger.isTestEnabled()).true(); - assume(logger.isOkEnabled()).true(); - }); -}); + // Trigger the trap. Swallow the error so processing continues. + try { + logger.info('ENDOR'); + } catch (err) { + assume(err.message).equals('ITS A TRAP!'); + } -describe('Logger (stream semantics)', function () { - it(`'finish' event awaits transports to emit 'finish'`, function (done) { - const transports = [ - new TransportStream({ log: function () {} }), - new TransportStream({ log: function () {} }), - new TransportStream({ log: function () {} }) - ]; + const expected = [ + 'Now witness the power of the fully armed and operational logger', + 'Consider the philosophical and metaphysical – BANANA BANANA BANANA', + 'I was god once. I saw – you were doing well until everyone died.' + ]; - const finished = []; - const logger = winston.createLogger({ transports }); + expected.forEach(msg => logger.info(msg)); - // Assert each transport emits finish - transports.forEach((transport, i) => { - transport.on('finish', () => finished[i] = true); + stdMocks.restore(); + const actual = stdMocks.flush(); + assume(actual.stdout).deep.equals(expected.map(msg => `${msg}${EOL}`)); + assume(actual.stderr).deep.equals([]); }); + }); - // Manually end the last transport to simulate mixed - // finished state - transports[2].end(); + describe('Logger (winston@2 logging API)', function () { + it('.log(level, message)', function (done) { + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('Some super awesome log message'); + assume(info[MESSAGE]).is.a('string'); + done(); + }); - // Assert that all transport 'finish' events have been - // emitted when the logger emits 'finish'. - logger.on('finish', function () { - assume(finished[0]).true(); - assume(finished[1]).true(); - assume(finished[2]).true(); - done(); + logger.log('info', 'Some super awesome log message') }); - setImmediate(() => logger.end()); - }); - - it(`rethrows errors from user-defined formats`, function () { - stdMocks.use(); - const logger = winston.createLogger( { - transports: [new winston.transports.Console()], - format: winston.format.printf((info) => { - // Set a trap. - if (info.message === 'ENDOR') { - throw new Error('ITS A TRAP!'); - } + it(`.log(level, undefined) creates info with { message: undefined }`, function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(undefined); + done(); + }); - return info.message; - }) + logger.log('info', undefined); }); - // Trigger the trap. Swallow the error so processing continues. - try { - logger.info('ENDOR'); - } catch (err) { - assume(err.message).equals('ITS A TRAP!'); - } - - const expected = [ - 'Now witness the power of the fully armed and operational logger', - 'Consider the philosophical and metaphysical – BANANA BANANA BANANA', - 'I was god once. I saw – you were doing well until everyone died.' - ]; - - expected.forEach(msg => logger.info(msg)); - - stdMocks.restore(); - const actual = stdMocks.flush(); - assume(actual.stdout).deep.equals(expected.map(msg => `${msg}${EOL}`)); - assume(actual.stderr).deep.equals([]); - }); -}); + it(`.log(level, null) creates info with { message: null }`, function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(null); + done(); + }); -describe('Logger (winston@2 logging API)', function () { - it('.log(level, message)', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('Some super awesome log message'); - assume(info[MESSAGE]).is.a('string'); - done(); + logger.log('info', null); }); - logger.log('info', 'Some super awesome log message') - }); + it(`.log(level, new Error()) uses Error instance as info`, function (done) { + const err = new Error('test'); + const logger = helpers.createLogger(function (info) { + assume(info).instanceOf(Error); + assume(info).equals(err); + done(); + }); - it(`.log(level, undefined) creates info with { message: undefined }`, function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(undefined); - done(); + logger.log('info', err); }); - logger.log('info', undefined); - }); + it('.log(level, message, meta)', function (done) { + var meta = {one: 2}; + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('Some super awesome log message'); + assume(info.one).equals(2); + assume(info[MESSAGE]).is.a('string'); + done(); + }); - it(`.log(level, null) creates info with { message: null }`, function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(null); - done(); + logger.log('info', 'Some super awesome log message', meta); }); - logger.log('info', null); - }); + it('.log(level, formatStr, ...splat)', function (done) { + const format = winston.format.combine( + winston.format.splat(), + winston.format.printf(info => `${info.level}: ${info.message}`) + ); - it(`.log(level, new Error()) uses Error instance as info`, function (done) { - const err = new Error('test'); - const logger = helpers.createLogger(function (info) { - assume(info).instanceOf(Error); - assume(info).equals(err); - done(); + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('100% such wow {"much":"javascript"}'); + assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); + assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"}'); + done(); + }, format); + + logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}); }); - logger.log('info', err); - }); + it('.log(level, formatStr, ...splat, meta)', function (done) { + const format = winston.format.combine( + winston.format.splat(), + winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({thisIsMeta: info.thisIsMeta})}`) + ); - it('.log(level, message, meta)', function (done) { - var meta = { one: 2 }; - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('Some super awesome log message'); - assume(info.one).equals(2); - assume(info[MESSAGE]).is.a('string'); - done(); - }); + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('100% such wow {"much":"javascript"}'); + assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); + assume(info.thisIsMeta).true(); + assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"} {"thisIsMeta":true}'); + done(); + }, format); - logger.log('info', 'Some super awesome log message', meta); + logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}, {thisIsMeta: true}); + }); }); - it('.log(level, formatStr, ...splat)', function (done) { - const format = winston.format.combine( - winston.format.splat(), - winston.format.printf(info => `${info.level}: ${info.message}`) - ); - - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('100% such wow {"much":"javascript"}'); - assume(info[SPLAT]).deep.equals([100, 'wow', { much: 'javascript' }]); - assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"}'); - done(); - }, format); + describe('Logger (logging exotic data types)', function () { + describe('.log', function () { + it(`.log(new Error()) uses Error instance as info`, function (done) { + const err = new Error('test'); + err.level = 'info'; - logger.log('info', '%d%% such %s %j', 100, 'wow', { much: 'javascript' }); - }); + const logger = helpers.createLogger(function (info) { + assume(info).instanceOf(Error); + assume(info).equals(err); + done(); + }); - it('.log(level, formatStr, ...splat, meta)', function (done) { - const format = winston.format.combine( - winston.format.splat(), - winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({ thisIsMeta: info.thisIsMeta })}`) - ); - - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('100% such wow {"much":"javascript"}'); - assume(info[SPLAT]).deep.equals([100, 'wow', { much: 'javascript' }]); - assume(info.thisIsMeta).true(); - assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"} {"thisIsMeta":true}'); - done(); - }, format); + logger.log(err); + }); - logger.log('info', '%d%% such %s %j', 100, 'wow', { much: 'javascript' }, { thisIsMeta: true }); - }); -}); + it(`.info('Hello') preserve meta without splat format`, function (done) { + const logged = []; + const logger = helpers.createLogger(function (info, enc, next) { + logged.push(info); + assume(info.label).equals('world'); + next(); -describe('Logger (logging exotic data types)', function () { - describe('.log', function () { - it(`.log(new Error()) uses Error instance as info`, function (done) { - const err = new Error('test'); - err.level = 'info'; + if (logged.length === 1) done(); + }); - const logger = helpers.createLogger(function (info) { - assume(info).instanceOf(Error); - assume(info).equals(err); - done(); + logger.info('Hello', {label: 'world'}); }); - logger.log(err); - }); + it(`.info('Hello %d') does not mutate unnecessarily with string interpolation tokens`, function (done) { + const logged = []; + const logger = helpers.createLogger(function (info, enc, next) { + logged.push(info); + assume(info.label).equals(undefined); + next(); - it(`.info('Hello') preserve meta without splat format`, function (done) { - const logged = []; - const logger = helpers.createLogger(function (info, enc, next) { - logged.push(info); - assume(info.label).equals('world'); - next(); + if (logged.length === 1) done(); + }); - if (logged.length === 1) done(); + logger.info('Hello %j', {label: 'world'}, {extra: true}); }); - logger.info('Hello', { label: 'world' }); - }); + it(`.info('Hello') and .info('Hello %d') preserve meta with splat format`, function (done) { + const logged = []; + const logger = helpers.createLogger(function (info, enc, next) { + logged.push(info); + assume(info.label).equals('world'); + next(); - it(`.info('Hello %d') does not mutate unnecessarily with string interpolation tokens`, function (done) { - const logged = []; - const logger = helpers.createLogger(function (info, enc, next) { - logged.push(info); - assume(info.label).equals(undefined); - next(); + if (logged.length === 2) done(); + }, format.splat()); - if (logged.length === 1) done(); + logger.info('Hello', {label: 'world'}); + logger.info('Hello %d', 100, {label: 'world'}); }); - - logger.info('Hello %j', { label: 'world' }, { extra: true }); }); - it(`.info('Hello') and .info('Hello %d') preserve meta with splat format`, function (done) { - const logged = []; - const logger = helpers.createLogger(function (info, enc, next) { - logged.push(info); - assume(info.label).equals('world'); - next(); + describe('.info', function () { + it('.info(undefined) creates info with { message: undefined }', function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(undefined); + done(); + }); - if (logged.length === 2) done(); - }, format.splat()); + logger.info(undefined); + }); - logger.info('Hello', { label: 'world' }); - logger.info('Hello %d', 100, { label: 'world' }); - }); - }); + it('.info(null) creates info with { message: null }', function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(null); + done(); + }); - describe('.info', function () { - it('.info(undefined) creates info with { message: undefined }', function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(undefined); - done(); + logger.info(null); }); - logger.info(undefined); - }); + it('.info(new Error()) uses Error instance as info', function (done) { + const err = new Error('test'); + const logger = helpers.createLogger(function (info) { + assume(info).instanceOf(Error); + assume(info).equals(err); + done(); + }); - it('.info(null) creates info with { message: null }', function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(null); - done(); + logger.info(err); }); - logger.info(null); + it.skip(`.info('any string', new Error())`, function (done) { + const err = new Error('test'); + const logger = helpers.createLogger(function (info) { + // TODO (indexzero): assert this works. + done(); + }); + + logger.info(err); + }); }); + }); - it('.info(new Error()) uses Error instance as info', function (done) { - const err = new Error('test'); - const logger = helpers.createLogger(function (info) { - assume(info).instanceOf(Error); - assume(info).equals(err); + describe('Logger (profile, startTimer)', function (done) { + it('profile(id, info)', function (done) { + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'), + assume(info.something).equals('ok'); + assume(info.level).equals('info'); + assume(info.durationMs).is.a('number'); + assume(info.message).equals('testing1'); + assume(info[MESSAGE]).is.a('string'); done(); }); - logger.info(err); + logger.profile('testing1'); + setTimeout(function () { + logger.profile('testing1', { + something: 'ok', + level: 'info' + }) + }, 100); }); - it.skip(`.info('any string', new Error())`, function (done) { - const err = new Error('test'); - const logger = helpers.createLogger(function (info) { - // TODO (indexzero): assert this works. + it('profile(id, callback) ignores callback', function (done) { + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'), + assume(info.something).equals('ok'); + assume(info.level).equals('info'); + assume(info.durationMs).is.a('number'); + assume(info.message).equals('testing2'); + assume(info[MESSAGE]).is.a('string'); done(); }); - logger.info(err); - }); - }); -}); + logger.profile('testing2', function () { + done(new Error('Unexpected callback invoked')); + }); -describe('Logger (profile, startTimer)', function (done) { - it('profile(id, info)', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); - assume(info.level).equals('info'); - assume(info.durationMs).is.a('number'); - assume(info.message).equals('testing1'); - assume(info[MESSAGE]).is.a('string'); - done(); + setTimeout(function () { + logger.profile('testing2', { + something: 'ok', + level: 'info' + }) + }, 100); }); - logger.profile('testing1'); - setTimeout(function () { - logger.profile('testing1', { - something: 'ok', - level: 'info' - }) - }, 100); - }); - - it('profile(id, callback) ignores callback', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); - assume(info.level).equals('info'); - assume(info.durationMs).is.a('number'); - assume(info.message).equals('testing2'); - assume(info[MESSAGE]).is.a('string'); - done(); - }); + it('startTimer()', function (done) { + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'), + assume(info.something).equals('ok'); + assume(info.level).equals('info'); + assume(info.durationMs).is.a('number'); + assume(info.message).equals('testing1'); + assume(info[MESSAGE]).is.a('string'); + done(); + }); - logger.profile('testing2', function () { - done(new Error('Unexpected callback invoked')); + var timer = logger.startTimer(); + setTimeout(function () { + timer.done({ + message: 'testing1', + something: 'ok', + level: 'info' + }); + }, 100); }); - - setTimeout(function () { - logger.profile('testing2', { - something: 'ok', - level: 'info' - }) - }, 100); }); - it('startTimer()', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); - assume(info.level).equals('info'); - assume(info.durationMs).is.a('number'); - assume(info.message).equals('testing1'); - assume(info[MESSAGE]).is.a('string'); - done(); - }); - - var timer = logger.startTimer(); - setTimeout(function () { - timer.done({ - message: 'testing1', - something: 'ok', - level: 'info' + describe('Should bubble transport events', () => { + it('error', (done) => { + const consoleTransport = new winston.transports.Console(); + const logger = winston.createLogger({ + transports: [consoleTransport] }); - }, 100); - }); -}); - -describe('Should bubble transport events', () => { - it('error', (done) => { - const consoleTransport = new winston.transports.Console(); - const logger = winston.createLogger({ - transports: [consoleTransport] - }); - logger.on('error', (err, transport) => { - assume(err).instanceOf(Error); - assume(transport).is.an('object'); - done(); + logger.on('error', (err, transport) => { + assume(err).instanceOf(Error); + assume(transport).is.an('object'); + done(); + }); + consoleTransport.emit('error', new Error()); }); - consoleTransport.emit('error', new Error()); - }); - it('warn', (done) => { - const consoleTransport = new winston.transports.Console(); - const logger = winston.createLogger({ - transports: [consoleTransport] - }); + it('warn', (done) => { + const consoleTransport = new winston.transports.Console(); + const logger = winston.createLogger({ + transports: [consoleTransport] + }); - logger.on('warn', (err, transport) => { - assume(err).instanceOf(Error); - assume(transport).is.an('object'); - done(); + logger.on('warn', (err, transport) => { + assume(err).instanceOf(Error); + assume(transport).is.an('object'); + done(); + }); + consoleTransport.emit('warn', new Error()); }); - consoleTransport.emit('warn', new Error()); }); -}); -describe('Should support child loggers & defaultMeta', () => { - it('sets child meta for text messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.requestId).equals('451'); - done(); - }); + describe('Should support child loggers & defaultMeta', () => { + it('sets child meta for text messages correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.requestId).equals('451'); + done(); + }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({requestId: '451'}); + childLogger.info('dummy message'); }); - const childLogger = logger.child({ requestId: '451' }); - childLogger.info('dummy message'); - }); + it('sets child meta for json messages correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message.text).equals('dummy'); + assume(msg.requestId).equals('451'); + done(); + }); - it('sets child meta for json messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message.text).equals('dummy'); - assume(msg.requestId).equals('451'); - done(); - }); + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + const childLogger = logger.child({requestId: '451'}); + childLogger.info({text: 'dummy'}); }); - const childLogger = logger.child({ requestId: '451' }); - childLogger.info({ text: 'dummy' }); - }); + it('merges child and provided meta correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('user-service'); + assume(msg.requestId).equals('451'); + done(); + }); - it('merges child and provided meta correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('user-service'); - assume(msg.requestId).equals('451'); - done(); - }); + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + const childLogger = logger.child({service: 'user-service'}); + childLogger.info('dummy message', {requestId: '451'}); }); - const childLogger = logger.child({ service: 'user-service' }); - childLogger.info('dummy message', { requestId: '451' }); - }); + it('provided meta take precedence over defaultMeta', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('audit-service'); + assume(msg.requestId).equals('451'); + done(); + }); - it('provided meta take precedence over defaultMeta', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('audit-service'); - assume(msg.requestId).equals('451'); - done(); - }); + const logger = winston.createLogger({ + defaultMeta: {service: 'user-service'}, + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); - const logger = winston.createLogger({ - defaultMeta: { service: 'user-service' }, - transports: [ - mockTransport.createMockTransport(assertFn) - ] + logger.info('dummy message', { + requestId: '451', + service: 'audit-service' + }); }); - logger.info('dummy message', { - requestId: '451', - service: 'audit-service' - }); - }); + it('provided meta take precedence over child meta', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('audit-service'); + assume(msg.requestId).equals('451'); + done(); + }); - it('provided meta take precedence over child meta', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('audit-service'); - assume(msg.requestId).equals('451'); - done(); - }); + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + const childLogger = logger.child({service: 'user-service'}); + childLogger.info('dummy message', { + requestId: '451', + service: 'audit-service' + }); }); - const childLogger = logger.child({ service: 'user-service' }); - childLogger.info('dummy message', { - requestId: '451', - service: 'audit-service' - }); - }); + it('handles error stack traces in child loggers correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('error'); + assume(msg.message).equals('dummy error'); + assume(msg.stack).includes('logger.test.js'); + assume(msg.service).equals('user-service'); + done(); + }); - it('handles error stack traces in child loggers correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('error'); - assume(msg.message).equals('dummy error'); - assume(msg.stack).includes('logger.test.js'); - assume(msg.service).equals('user-service'); - done(); - }); + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + const childLogger = logger.child({service: 'user-service'}); + childLogger.error(Error('dummy error')); }); - const childLogger = logger.child({ service: 'user-service' }); - childLogger.error(Error('dummy error')); - }); + it('defaultMeta() autobinds correctly', (done) => { + const logger = helpers.createLogger(info => { + assume(info.message).equals('test'); + done(); + }); - it('defaultMeta() autobinds correctly', (done) => { - const logger = helpers.createLogger(info => { - assume(info.message).equals('test'); - done(); + const log = logger.info; + log('test'); }); - - const log = logger.info; - log('test'); }); }); From 29a9ff72eab00bdfa2ea54cf2d128d2e05b4d33b Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 29 Jan 2022 16:22:40 -0700 Subject: [PATCH 02/39] chore: restructure tests directory --- lib/winston/transports/http.js | 2 +- package.json | 4 +- test/fixtures/file/simple-stream.log | 0 {test => tests}/fixtures/.gitkeep | 0 {test => tests}/fixtures/keys/agent2-cert.pem | 0 {test => tests}/fixtures/keys/agent2-key.pem | 0 {test => tests}/fixtures/logs/.gitkeep | 0 {test => tests}/helpers/index.js | 0 .../helpers/mocks/legacy-mixed-transport.js | 0 .../helpers/mocks/legacy-transport.js | 0 .../helpers/mocks/mock-transport.js | 0 {test => tests}/helpers/scripts/colorize.js | 0 .../helpers/scripts/default-exceptions.js | 0 .../helpers/scripts/default-rejections.js | 0 .../helpers/scripts/exit-on-error.js | 0 .../helpers/scripts/log-exceptions.js | 0 .../helpers/scripts/log-rejections.js | 0 .../helpers/scripts/log-string-exception.js | 0 .../helpers/scripts/unhandle-exceptions.js | 0 .../helpers/scripts/unhandle-rejections.js | 0 {test => tests}/integration/formats.test.js | 0 {test => tests}/tsconfig.json | 0 {test => tests}/typescript-definitions.ts | 0 {test => tests/unit}/formats/errors.test.js | 4 +- .../unit/winston/config}/config.test.js | 4 +- .../unit/winston}/container.test.js | 2 +- tests/unit/winston/create-logger.test.js | 86 +++++++++++++++++++ .../unit/winston}/exception-handler.test.js | 4 +- .../unit/winston}/exception-stream.test.js | 4 +- .../unit/winston}/log-exception.test.js | 4 +- .../unit/winston}/logger-legacy.test.js | 8 +- {test => tests/unit/winston}/logger.test.js | 12 +-- {test => tests/unit/winston}/profiler.test.js | 2 +- .../unit/winston}/rejection-handler.test.js | 4 +- .../unit/winston}/tail-file.test.js | 4 +- .../transports/00-file-stress.test.js | 4 +- .../transports/01-file-maxsize.test.js | 2 +- .../unit/winston}/transports/console.test.js | 4 +- .../unit/winston}/transports/error.test.js | 2 +- .../winston}/transports/file-archive.test.js | 2 +- .../transports/file-create-dir-test.js | 2 +- .../winston}/transports/file-maxfiles-test.js | 4 +- .../transports/file-tailrolling.test.js | 2 +- .../unit/winston}/transports/file.test.js | 4 +- .../unit/winston}/transports/http.test.js | 2 +- .../unit/winston}/transports/stream.test.js | 4 +- {test => tests}/winston.test.js | 0 47 files changed, 131 insertions(+), 45 deletions(-) delete mode 100644 test/fixtures/file/simple-stream.log rename {test => tests}/fixtures/.gitkeep (100%) rename {test => tests}/fixtures/keys/agent2-cert.pem (100%) rename {test => tests}/fixtures/keys/agent2-key.pem (100%) rename {test => tests}/fixtures/logs/.gitkeep (100%) rename {test => tests}/helpers/index.js (100%) rename {test => tests}/helpers/mocks/legacy-mixed-transport.js (100%) rename {test => tests}/helpers/mocks/legacy-transport.js (100%) rename {test => tests}/helpers/mocks/mock-transport.js (100%) rename {test => tests}/helpers/scripts/colorize.js (100%) rename {test => tests}/helpers/scripts/default-exceptions.js (100%) rename {test => tests}/helpers/scripts/default-rejections.js (100%) rename {test => tests}/helpers/scripts/exit-on-error.js (100%) rename {test => tests}/helpers/scripts/log-exceptions.js (100%) rename {test => tests}/helpers/scripts/log-rejections.js (100%) rename {test => tests}/helpers/scripts/log-string-exception.js (100%) rename {test => tests}/helpers/scripts/unhandle-exceptions.js (100%) rename {test => tests}/helpers/scripts/unhandle-rejections.js (100%) rename {test => tests}/integration/formats.test.js (100%) rename {test => tests}/tsconfig.json (100%) rename {test => tests}/typescript-definitions.ts (100%) rename {test => tests/unit}/formats/errors.test.js (98%) rename {test => tests/unit/winston/config}/config.test.js (83%) rename {test => tests/unit/winston}/container.test.js (97%) create mode 100644 tests/unit/winston/create-logger.test.js rename {test => tests/unit/winston}/exception-handler.test.js (97%) rename {test => tests/unit/winston}/exception-stream.test.js (89%) rename {test => tests/unit/winston}/log-exception.test.js (97%) rename {test => tests/unit/winston}/logger-legacy.test.js (92%) rename {test => tests/unit/winston}/logger.test.js (99%) rename {test => tests/unit/winston}/profiler.test.js (93%) rename {test => tests/unit/winston}/rejection-handler.test.js (97%) rename {test => tests/unit/winston}/tail-file.test.js (95%) rename {test => tests/unit/winston}/transports/00-file-stress.test.js (97%) rename {test => tests/unit/winston}/transports/01-file-maxsize.test.js (98%) rename {test => tests/unit/winston}/transports/console.test.js (98%) rename {test => tests/unit/winston}/transports/error.test.js (98%) rename {test => tests/unit/winston}/transports/file-archive.test.js (97%) rename {test => tests/unit/winston}/transports/file-create-dir-test.js (95%) rename {test => tests/unit/winston}/transports/file-maxfiles-test.js (97%) rename {test => tests/unit/winston}/transports/file-tailrolling.test.js (98%) rename {test => tests/unit/winston}/transports/file.test.js (97%) rename {test => tests/unit/winston}/transports/http.test.js (97%) rename {test => tests/unit/winston}/transports/stream.test.js (92%) rename {test => tests}/winston.test.js (100%) diff --git a/lib/winston/transports/http.js b/lib/winston/transports/http.js index bcace8341..90f270338 100644 --- a/lib/winston/transports/http.js +++ b/lib/winston/transports/http.js @@ -263,4 +263,4 @@ module.exports = class Http extends TransportStream { )); req.end(Buffer.from(JSON.stringify(options), 'utf8')); } -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index a11ba097f..773247867 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,8 @@ "scripts": { "lint": "populist lib/*.js lib/winston/*.js lib/winston/**/*.js", "pretest": "npm run lint", - "test": "nyc --reporter=text --reporter lcov npm run test:mocha", - "test:mocha": "mocha test/*.test.js test/**/*.test.js --exit", + "test:coverage": "nyc --reporter=text --reporter lcov npm run test", + "test": "mocha tests/*.test.js tests/**/*.test.js --exit", "build": "rimraf dist && babel lib -d dist", "prepublishOnly": "npm run build" }, diff --git a/test/fixtures/file/simple-stream.log b/test/fixtures/file/simple-stream.log deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/fixtures/.gitkeep b/tests/fixtures/.gitkeep similarity index 100% rename from test/fixtures/.gitkeep rename to tests/fixtures/.gitkeep diff --git a/test/fixtures/keys/agent2-cert.pem b/tests/fixtures/keys/agent2-cert.pem similarity index 100% rename from test/fixtures/keys/agent2-cert.pem rename to tests/fixtures/keys/agent2-cert.pem diff --git a/test/fixtures/keys/agent2-key.pem b/tests/fixtures/keys/agent2-key.pem similarity index 100% rename from test/fixtures/keys/agent2-key.pem rename to tests/fixtures/keys/agent2-key.pem diff --git a/test/fixtures/logs/.gitkeep b/tests/fixtures/logs/.gitkeep similarity index 100% rename from test/fixtures/logs/.gitkeep rename to tests/fixtures/logs/.gitkeep diff --git a/test/helpers/index.js b/tests/helpers/index.js similarity index 100% rename from test/helpers/index.js rename to tests/helpers/index.js diff --git a/test/helpers/mocks/legacy-mixed-transport.js b/tests/helpers/mocks/legacy-mixed-transport.js similarity index 100% rename from test/helpers/mocks/legacy-mixed-transport.js rename to tests/helpers/mocks/legacy-mixed-transport.js diff --git a/test/helpers/mocks/legacy-transport.js b/tests/helpers/mocks/legacy-transport.js similarity index 100% rename from test/helpers/mocks/legacy-transport.js rename to tests/helpers/mocks/legacy-transport.js diff --git a/test/helpers/mocks/mock-transport.js b/tests/helpers/mocks/mock-transport.js similarity index 100% rename from test/helpers/mocks/mock-transport.js rename to tests/helpers/mocks/mock-transport.js diff --git a/test/helpers/scripts/colorize.js b/tests/helpers/scripts/colorize.js similarity index 100% rename from test/helpers/scripts/colorize.js rename to tests/helpers/scripts/colorize.js diff --git a/test/helpers/scripts/default-exceptions.js b/tests/helpers/scripts/default-exceptions.js similarity index 100% rename from test/helpers/scripts/default-exceptions.js rename to tests/helpers/scripts/default-exceptions.js diff --git a/test/helpers/scripts/default-rejections.js b/tests/helpers/scripts/default-rejections.js similarity index 100% rename from test/helpers/scripts/default-rejections.js rename to tests/helpers/scripts/default-rejections.js diff --git a/test/helpers/scripts/exit-on-error.js b/tests/helpers/scripts/exit-on-error.js similarity index 100% rename from test/helpers/scripts/exit-on-error.js rename to tests/helpers/scripts/exit-on-error.js diff --git a/test/helpers/scripts/log-exceptions.js b/tests/helpers/scripts/log-exceptions.js similarity index 100% rename from test/helpers/scripts/log-exceptions.js rename to tests/helpers/scripts/log-exceptions.js diff --git a/test/helpers/scripts/log-rejections.js b/tests/helpers/scripts/log-rejections.js similarity index 100% rename from test/helpers/scripts/log-rejections.js rename to tests/helpers/scripts/log-rejections.js diff --git a/test/helpers/scripts/log-string-exception.js b/tests/helpers/scripts/log-string-exception.js similarity index 100% rename from test/helpers/scripts/log-string-exception.js rename to tests/helpers/scripts/log-string-exception.js diff --git a/test/helpers/scripts/unhandle-exceptions.js b/tests/helpers/scripts/unhandle-exceptions.js similarity index 100% rename from test/helpers/scripts/unhandle-exceptions.js rename to tests/helpers/scripts/unhandle-exceptions.js diff --git a/test/helpers/scripts/unhandle-rejections.js b/tests/helpers/scripts/unhandle-rejections.js similarity index 100% rename from test/helpers/scripts/unhandle-rejections.js rename to tests/helpers/scripts/unhandle-rejections.js diff --git a/test/integration/formats.test.js b/tests/integration/formats.test.js similarity index 100% rename from test/integration/formats.test.js rename to tests/integration/formats.test.js diff --git a/test/tsconfig.json b/tests/tsconfig.json similarity index 100% rename from test/tsconfig.json rename to tests/tsconfig.json diff --git a/test/typescript-definitions.ts b/tests/typescript-definitions.ts similarity index 100% rename from test/typescript-definitions.ts rename to tests/typescript-definitions.ts diff --git a/test/formats/errors.test.js b/tests/unit/formats/errors.test.js similarity index 98% rename from test/formats/errors.test.js rename to tests/unit/formats/errors.test.js index c3ff7bdcf..400de910a 100644 --- a/test/formats/errors.test.js +++ b/tests/unit/formats/errors.test.js @@ -10,9 +10,9 @@ const assume = require('assume'); const { LEVEL, MESSAGE, SPLAT } = require('triple-beam'); -const winston = require('../../lib/winston'); +const winston = require('../../../lib/winston'); const { format } = winston; -const helpers = require('../helpers'); +const helpers = require('../../helpers'); function assumeExpectedInfo(info, target = {}) { const expected = Object.assign({}, { diff --git a/test/config.test.js b/tests/unit/winston/config/config.test.js similarity index 83% rename from test/config.test.js rename to tests/unit/winston/config/config.test.js index a25c63a8c..1925921d9 100644 --- a/test/config.test.js +++ b/tests/unit/winston/config/config.test.js @@ -7,8 +7,8 @@ */ const assume = require('assume'); -const winston = require('../lib/winston'); -const helpers = require('./helpers'); +const winston = require('../../../../lib/winston'); +const helpers = require('../../../helpers'); describe('winston.config', function () { it('should have expected methods', function () { diff --git a/test/container.test.js b/tests/unit/winston/container.test.js similarity index 97% rename from test/container.test.js rename to tests/unit/winston/container.test.js index f122c7650..ab587d7e2 100644 --- a/test/container.test.js +++ b/tests/unit/winston/container.test.js @@ -7,7 +7,7 @@ */ const assume = require('assume'); -const winston = require('../lib/winston'); +const winston = require('../../../lib/winston'); describe('Container', function () { describe('no transports', function () { diff --git a/tests/unit/winston/create-logger.test.js b/tests/unit/winston/create-logger.test.js new file mode 100644 index 000000000..50b04df53 --- /dev/null +++ b/tests/unit/winston/create-logger.test.js @@ -0,0 +1,86 @@ +const winston = require("../../../lib/winston"); +const assume = require("assume"); +const isStream = require("is-stream"); +const {format} = require("../../../lib/winston"); + +describe('Create Logger', function () { + it('should build a logger with default values', function () { + let logger = winston.createLogger(); + assume(logger).is.an('object'); + assume(isStream(logger.format)); + assume(logger.level).equals('info'); + assume(logger.exitOnError).equals(true); + }); + + it('new Logger({ parameters })', function () { + let myFormat = format(function (info, opts) { + return info; + })(); + + let logger = winston.createLogger({ + format: myFormat, + level: 'error', + exitOnError: false, + transports: [] + }); + + assume(logger.format).equals(myFormat); + assume(logger.level).equals('error'); + assume(logger.exitOnError).equals(false); + assume(logger._readableState.pipesCount).equals(0); + }); + + it('new Logger({ levels }) defines custom methods', function () { + let myFormat = format(function (info, opts) { + return info; + })(); + + let logger = winston.createLogger({ + levels: winston.config.syslog.levels, + format: myFormat, + level: 'error', + exitOnError: false, + transports: [] + }); + + Object.keys(winston.config.syslog.levels).forEach(level => { + assume(logger[level]).is.a('function'); + }) + }); + + it('new Logger({ levels }) custom methods are not bound to instance', function (done) { + let logger = winston.createLogger({ + level: 'error', + exitOnError: false, + transports: [] + }); + + let logs = []; + let extendedLogger = Object.create(logger, { + write: { + value: function (...args) { + logs.push(args); + if (logs.length === 4) { + assume(logs.length).is.eql(4); + assume(logs[0]).is.eql([{test: 1, level: 'info'}]); + assume(logs[1]).is.eql([{test: 2, level: 'warn'}]); + assume(logs[2]).is.eql([{message: 'test3', level: 'info'}]) + assume(logs[3]).is.eql([{ + with: 'meta', + test: 4, + level: 'warn', + message: 'a warning' + }]); + + done(); + } + } + } + }); + + extendedLogger.log('info', {test: 1}); + extendedLogger.log('warn', {test: 2}); + extendedLogger.info('test3'); + extendedLogger.warn('a warning', {with: 'meta', test: 4}); + }); +}); \ No newline at end of file diff --git a/test/exception-handler.test.js b/tests/unit/winston/exception-handler.test.js similarity index 97% rename from test/exception-handler.test.js rename to tests/unit/winston/exception-handler.test.js index 9a2286c7b..8ddb12dcc 100644 --- a/test/exception-handler.test.js +++ b/tests/unit/winston/exception-handler.test.js @@ -9,8 +9,8 @@ const stream = require('stream'); const assume = require('assume'); const mocha = require('mocha'); -const winston = require('../lib/winston'); -const helpers = require('./helpers'); +const winston = require('../../../lib/winston'); +const helpers = require('../../helpers'); // // This is an awful and fragile hack that diff --git a/test/exception-stream.test.js b/tests/unit/winston/exception-stream.test.js similarity index 89% rename from test/exception-stream.test.js rename to tests/unit/winston/exception-stream.test.js index 328680209..8883f03a9 100644 --- a/test/exception-stream.test.js +++ b/tests/unit/winston/exception-stream.test.js @@ -9,8 +9,8 @@ const assume = require('assume'); const { Writable } = require('readable-stream'); const path = require('path'); -const winston = require('../lib/winston'); -const ExceptionStream = require('../lib/winston/exception-stream'); +const winston = require('../../../lib/winston'); +const ExceptionStream = require('../../../lib/winston/exception-stream'); describe('ExceptionStream', function () { it('has expected methods', function () { diff --git a/test/log-exception.test.js b/tests/unit/winston/log-exception.test.js similarity index 97% rename from test/log-exception.test.js rename to tests/unit/winston/log-exception.test.js index 3abd2d8f2..b0ed146e0 100644 --- a/test/log-exception.test.js +++ b/tests/unit/winston/log-exception.test.js @@ -10,8 +10,8 @@ const assume = require('assume'); const fs = require('fs'); const path = require('path'); const { spawn } = require('child_process'); -const winston = require('../lib/winston'); -const helpers = require('./helpers'); +const winston = require('../../../lib/winston'); +const helpers = require('../../helpers'); describe('Logger, ExceptionHandler', function () { this.timeout(5000); diff --git a/test/logger-legacy.test.js b/tests/unit/winston/logger-legacy.test.js similarity index 92% rename from test/logger-legacy.test.js rename to tests/unit/winston/logger-legacy.test.js index 2dbb5b4d2..c30d99257 100644 --- a/test/logger-legacy.test.js +++ b/tests/unit/winston/logger-legacy.test.js @@ -15,11 +15,11 @@ const util = require('util'); const isStream = require('is-stream'); const stdMocks = require('std-mocks'); const { MESSAGE } = require('triple-beam'); -const winston = require('../lib/winston'); -const LegacyTransport = require('./helpers/mocks/legacy-transport'); -const LegacyMixedTransport = require('./helpers/mocks/legacy-mixed-transport'); +const winston = require('../../../lib/winston'); +const LegacyTransport = require('../../helpers/mocks/legacy-transport'); +const LegacyMixedTransport = require('../../helpers/mocks/legacy-mixed-transport'); const TransportStream = require('winston-transport'); -const helpers = require('./helpers'); +const helpers = require('../../helpers'); /* * Assumes that the `TransportClass` with the given { name, displayName } diff --git a/test/logger.test.js b/tests/unit/winston/logger.test.js similarity index 99% rename from test/logger.test.js rename to tests/unit/winston/logger.test.js index 2d1b47125..9aa742537 100755 --- a/test/logger.test.js +++ b/tests/unit/winston/logger.test.js @@ -16,16 +16,16 @@ const { EOL } = require('os'); const isStream = require('is-stream'); const stdMocks = require('std-mocks'); const { MESSAGE, SPLAT } = require('triple-beam'); -const winston = require('../lib/winston'); +const winston = require('../../../lib/winston'); const TransportStream = require('winston-transport'); -const format = require('../lib/winston').format; -const helpers = require('./helpers'); -const mockTransport = require('./helpers/mocks/mock-transport'); +const format = require('../../../lib/winston').format; +const helpers = require('../../helpers'); +const mockTransport = require('../../helpers/mocks/mock-transport'); describe('Logger', function () { - describe('Logger', function () { - it('new Logger()', function () { + describe('createLogger()', function () { + it('should build a logger with default values', function () { var logger = winston.createLogger(); assume(logger).is.an('object'); assume(isStream(logger.format)); diff --git a/test/profiler.test.js b/tests/unit/winston/profiler.test.js similarity index 93% rename from test/profiler.test.js rename to tests/unit/winston/profiler.test.js index 6983e0af4..6ca38db0c 100644 --- a/test/profiler.test.js +++ b/tests/unit/winston/profiler.test.js @@ -7,7 +7,7 @@ */ const assume = require('assume'); -const Profiler = require('../lib/winston/profiler'); +const Profiler = require('../../../lib/winston/profiler'); describe('Profiler', function () { it('new Profiler()', function () { diff --git a/test/rejection-handler.test.js b/tests/unit/winston/rejection-handler.test.js similarity index 97% rename from test/rejection-handler.test.js rename to tests/unit/winston/rejection-handler.test.js index aef41b1aa..dd2147d8a 100644 --- a/test/rejection-handler.test.js +++ b/tests/unit/winston/rejection-handler.test.js @@ -9,8 +9,8 @@ const stream = require('stream'); const assume = require('assume'); const mocha = require('mocha'); -const winston = require('../lib/winston'); -const helpers = require('./helpers'); +const winston = require('../../../lib/winston'); +const helpers = require('../../helpers'); // // This is an awful and fragile hack that diff --git a/test/tail-file.test.js b/tests/unit/winston/tail-file.test.js similarity index 95% rename from test/tail-file.test.js rename to tests/unit/winston/tail-file.test.js index a007d35f8..cf8d9923e 100644 --- a/test/tail-file.test.js +++ b/tests/unit/winston/tail-file.test.js @@ -9,8 +9,8 @@ const assume = require('assume'); const fs = require('fs'); const path = require('path'); -const winston = require('../lib/winston'); -const tailFile = require('../lib/winston/tail-file'); +const winston = require('../../../lib/winston'); +const tailFile = require('../../../lib/winston/tail-file'); const { Stream } = require('readable-stream'); // diff --git a/test/transports/00-file-stress.test.js b/tests/unit/winston/transports/00-file-stress.test.js similarity index 97% rename from test/transports/00-file-stress.test.js rename to tests/unit/winston/transports/00-file-stress.test.js index e8740d571..e1552833f 100644 --- a/test/transports/00-file-stress.test.js +++ b/tests/unit/winston/transports/00-file-stress.test.js @@ -12,9 +12,9 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); const assume = require('assume'); -const helpers = require('../helpers'); +const helpers = require('../../../helpers'); const split = require('split2'); -const winston = require('../../lib/winston'); +const winston = require('../../../../lib/winston'); describe('File (stress)', function () { this.timeout(30 * 1000); diff --git a/test/transports/01-file-maxsize.test.js b/tests/unit/winston/transports/01-file-maxsize.test.js similarity index 98% rename from test/transports/01-file-maxsize.test.js rename to tests/unit/winston/transports/01-file-maxsize.test.js index f098e9c96..1f0bf7f3c 100644 --- a/test/transports/01-file-maxsize.test.js +++ b/tests/unit/winston/transports/01-file-maxsize.test.js @@ -9,7 +9,7 @@ const rimraf = require('rimraf'); const fs = require('fs'); const path = require('path'); const assume = require('assume'); -const winston = require('../../'); +const winston = require('../../../../index'); const MESSAGE = Symbol.for('message'); diff --git a/test/transports/console.test.js b/tests/unit/winston/transports/console.test.js similarity index 98% rename from test/transports/console.test.js rename to tests/unit/winston/transports/console.test.js index 61b5bccd3..c25bae9af 100644 --- a/test/transports/console.test.js +++ b/tests/unit/winston/transports/console.test.js @@ -11,8 +11,8 @@ const path = require('path'); const assume = require('assume'); const { LEVEL, MESSAGE } = require('triple-beam'); -const winston = require('../../lib/winston'); -const helpers = require('../helpers'); +const winston = require('../../../../lib/winston'); +const helpers = require('../../../helpers'); const stdMocks = require('std-mocks'); const defaultLevels = winston.config.npm.levels; diff --git a/test/transports/error.test.js b/tests/unit/winston/transports/error.test.js similarity index 98% rename from test/transports/error.test.js rename to tests/unit/winston/transports/error.test.js index b1c3f54c9..05468a3bf 100644 --- a/test/transports/error.test.js +++ b/tests/unit/winston/transports/error.test.js @@ -1,4 +1,4 @@ -const winston = require('../../lib/winston'); +const winston = require('../../../../lib/winston'); const assume = require('assume'); // https://github.com/winstonjs/winston/issues/1364 diff --git a/test/transports/file-archive.test.js b/tests/unit/winston/transports/file-archive.test.js similarity index 97% rename from test/transports/file-archive.test.js rename to tests/unit/winston/transports/file-archive.test.js index 801432775..2c5266d91 100644 --- a/test/transports/file-archive.test.js +++ b/tests/unit/winston/transports/file-archive.test.js @@ -11,7 +11,7 @@ const assert = require('assert'); const rimraf = require('rimraf'); const fs = require('fs'); const path = require('path'); -const winston = require('../../lib/winston'); +const winston = require('../../../../lib/winston'); const { MESSAGE } = require('triple-beam'); diff --git a/test/transports/file-create-dir-test.js b/tests/unit/winston/transports/file-create-dir-test.js similarity index 95% rename from test/transports/file-create-dir-test.js rename to tests/unit/winston/transports/file-create-dir-test.js index 82407ce33..eecde1eb7 100644 --- a/test/transports/file-create-dir-test.js +++ b/tests/unit/winston/transports/file-create-dir-test.js @@ -3,7 +3,7 @@ const fs = require('fs'); const assert = require('assert'); const path = require('path'); -const winston = require('../../lib/winston'); +const winston = require('../../../../lib/winston'); /* eslint-disable no-sync */ diff --git a/test/transports/file-maxfiles-test.js b/tests/unit/winston/transports/file-maxfiles-test.js similarity index 97% rename from test/transports/file-maxfiles-test.js rename to tests/unit/winston/transports/file-maxfiles-test.js index b7448b5c3..7d37ecdd5 100644 --- a/test/transports/file-maxfiles-test.js +++ b/tests/unit/winston/transports/file-maxfiles-test.js @@ -13,8 +13,8 @@ var assert = require('assert'), fs = require('fs'), path = require('path'), vows = require('vows'), - winston = require('../../lib/winston'), - helpers = require('../helpers'); + winston = require('../../../../lib/winston'), + helpers = require('../../../helpers'); var maxfilesTransport = new winston.transports.File({ timestamp: false, diff --git a/test/transports/file-tailrolling.test.js b/tests/unit/winston/transports/file-tailrolling.test.js similarity index 98% rename from test/transports/file-tailrolling.test.js rename to tests/unit/winston/transports/file-tailrolling.test.js index f07e33a67..25e88a814 100644 --- a/test/transports/file-tailrolling.test.js +++ b/tests/unit/winston/transports/file-tailrolling.test.js @@ -3,7 +3,7 @@ const assert = require('assert'); const rimraf = require('rimraf'); const fs = require('fs'); const path = require('path'); -const winston = require('../../lib/winston'); +const winston = require('../../../../lib/winston'); const { MESSAGE } = require('triple-beam'); diff --git a/test/transports/file.test.js b/tests/unit/winston/transports/file.test.js similarity index 97% rename from test/transports/file.test.js rename to tests/unit/winston/transports/file.test.js index 3847cd0ad..18838bc64 100644 --- a/test/transports/file.test.js +++ b/tests/unit/winston/transports/file.test.js @@ -1,8 +1,8 @@ 'use strict'; const path = require('path'); -const winston = require('../../'); -const helpers = require('../helpers'); +const winston = require('../../../../index'); +const helpers = require('../../../helpers'); const fs = require('fs'); const { MESSAGE } = require('triple-beam'); const split = require('split2'); diff --git a/test/transports/http.test.js b/tests/unit/winston/transports/http.test.js similarity index 97% rename from test/transports/http.test.js rename to tests/unit/winston/transports/http.test.js index 696b86c99..3e52123f7 100644 --- a/test/transports/http.test.js +++ b/tests/unit/winston/transports/http.test.js @@ -7,7 +7,7 @@ const http = require('http'); const hock = require('hock'); const assume = require('assume'); -const Http = require('../../lib/winston/transports/http'); +const Http = require('../../../../lib/winston/transports/http'); const host = '127.0.0.1'; const port = 0; diff --git a/test/transports/stream.test.js b/tests/unit/winston/transports/stream.test.js similarity index 92% rename from test/transports/stream.test.js rename to tests/unit/winston/transports/stream.test.js index e0efbd2fd..b21de661d 100644 --- a/test/transports/stream.test.js +++ b/tests/unit/winston/transports/stream.test.js @@ -1,10 +1,10 @@ 'use strict'; const path = require('path'); -const writeable = require('../helpers').writeable; +const writeable = require('../../../helpers').writeable; const { MESSAGE } = require('triple-beam'); const os = require('os'); -const winston = require('../../'); +const winston = require('../../../../index'); const split = require('split2'); const assume = require('assume'); diff --git a/test/winston.test.js b/tests/winston.test.js similarity index 100% rename from test/winston.test.js rename to tests/winston.test.js From 23d9036e45d26397519245b25bc5e888ed39def9 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 29 Jan 2022 22:07:27 -0700 Subject: [PATCH 03/39] chore: restructure logger tests --- tests/unit/winston/create-logger.test.js | 21 + tests/unit/winston/logger.test.js | 1123 ++++++++++------------ 2 files changed, 545 insertions(+), 599 deletions(-) diff --git a/tests/unit/winston/create-logger.test.js b/tests/unit/winston/create-logger.test.js index 50b04df53..b4e0c44b7 100644 --- a/tests/unit/winston/create-logger.test.js +++ b/tests/unit/winston/create-logger.test.js @@ -2,6 +2,7 @@ const winston = require("../../../lib/winston"); const assume = require("assume"); const isStream = require("is-stream"); const {format} = require("../../../lib/winston"); +const TransportStream = require("winston-transport"); describe('Create Logger', function () { it('should build a logger with default values', function () { @@ -12,6 +13,26 @@ describe('Create Logger', function () { assume(logger.exitOnError).equals(true); }); + it('new Logger({ silent: true })', function (done) { + const neverLogTo = new TransportStream({ + log: function (info) { + assume(false).true('TransportStream was improperly written to'); + } + }); + + var logger = winston.createLogger({ + transports: [neverLogTo], + silent: true + }); + + logger.log({ + level: 'info', + message: 'This should be ignored' + }); + + setImmediate(() => done()); + }); + it('new Logger({ parameters })', function () { let myFormat = format(function (info, opts) { return info; diff --git a/tests/unit/winston/logger.test.js b/tests/unit/winston/logger.test.js index 9aa742537..730682c2f 100755 --- a/tests/unit/winston/logger.test.js +++ b/tests/unit/winston/logger.test.js @@ -23,118 +23,8 @@ const helpers = require('../../helpers'); const mockTransport = require('../../helpers/mocks/mock-transport'); -describe('Logger', function () { - describe('createLogger()', function () { - it('should build a logger with default values', function () { - var logger = winston.createLogger(); - assume(logger).is.an('object'); - assume(isStream(logger.format)); - assume(logger.level).equals('info'); - assume(logger.exitOnError).equals(true); - }); - - it('new Logger({ parameters })', function () { - var myFormat = format(function (info, opts) { - return info; - })(); - - var logger = winston.createLogger({ - format: myFormat, - level: 'error', - exitOnError: false, - transports: [] - }); - - assume(logger.format).equals(myFormat); - assume(logger.level).equals('error'); - assume(logger.exitOnError).equals(false); - assume(logger._readableState.pipesCount).equals(0); - }); - - it('new Logger({ levels }) defines custom methods', function () { - var myFormat = format(function (info, opts) { - return info; - })(); - - var logger = winston.createLogger({ - levels: winston.config.syslog.levels, - format: myFormat, - level: 'error', - exitOnError: false, - transports: [] - }); - - Object.keys(winston.config.syslog.levels).forEach(level => { - assume(logger[level]).is.a('function'); - }) - }); - - it('new Logger({ levels }) custom methods are not bound to instance', function (done) { - var logger = winston.createLogger({ - level: 'error', - exitOnError: false, - transports: [] - }); - - let logs = []; - let extendedLogger = Object.create(logger, { - write: { - value: function (...args) { - logs.push(args); - if (logs.length === 4) { - assume(logs.length).is.eql(4); - assume(logs[0]).is.eql([{test: 1, level: 'info'}]); - assume(logs[1]).is.eql([{test: 2, level: 'warn'}]); - assume(logs[2]).is.eql([{message: 'test3', level: 'info'}]) - assume(logs[3]).is.eql([{ - with: 'meta', - test: 4, - level: 'warn', - message: 'a warning' - }]); - - done(); - } - } - } - }); - - extendedLogger.log('info', {test: 1}); - extendedLogger.log('warn', {test: 2}); - extendedLogger.info('test3'); - extendedLogger.warn('a warning', {with: 'meta', test: 4}); - }); - - it('.add({ invalid Transport })', function () { - var logger = winston.createLogger(); - assume(function () { - logger.add(5); - }).throws(/invalid transport/i); - }); - - it('.add(TransportStream)', function (done) { - var logger = winston.createLogger(); - var expected = {message: 'foo', level: 'info'}; - var transport = new TransportStream({ - log: function (info) { - assume(info.message).equals('foo'); - assume(info.level).equals('info'); - assume(JSON.parse(info[MESSAGE])).deep.equals({level: 'info', message: 'foo'}); - done(); - } - }); - - logger.add(transport); - logger.log(expected); - }); - - it('.stream()', function () { - var logger = winston.createLogger(); - var outStream = logger.stream(); - - assume(isStream(outStream)).true(); - }); - +describe('Logger Instance', function () { + describe('Configuration', function () { it('.configure()', function () { var logger = winston.createLogger({ transports: [new winston.transports.Console()] @@ -176,112 +66,141 @@ describe('Logger', function () { assume(logger.transports[0].name).equals('console'); assume(logger.format).not.equals(format); }); + }); - it('.remove() [transport not added]', function () { - var transports = [ - new winston.transports.Console(), - new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) - ]; - - var logger = winston.createLogger({transports: transports}) - .remove(new winston.transports.Console()); - - assume(logger.transports.length).equals(2); - assume(logger.transports.map(function (wrap) { - // Unwrap LegacyTransportStream instances - return wrap.transport || wrap; - })).deep.equals(transports); - }); - - it('.remove() [TransportStream]', function () { - var transports = [ - new winston.transports.Console(), - new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) - ]; - - var logger = winston.createLogger({transports: transports}); + describe('Transports', function() { + describe('add', function () { + it('should throw error when adding an invalid transport', function () { + var logger = winston.createLogger(); + assume(function () { + logger.add(5); + }).throws(/invalid transport/i); + }); + + it('should add the expected transport', function (done) { + var logger = winston.createLogger(); + var expected = {message: 'foo', level: 'info'}; + var transport = new TransportStream({ + log: function (info) { + assume(info.message).equals('foo'); + assume(info.level).equals('info'); + assume(JSON.parse(info[MESSAGE])).deep.equals({level: 'info', message: 'foo'}); + done(); + } + }); - assume(logger.transports.length).equals(2); - logger.remove(transports[0]); - assume(logger.transports.length).equals(1); - assume(logger.transports[0]).equals(transports[1]); - }); + logger.add(transport); + logger.log(expected); + }); + + it('should allow adding multiple transports', function () { + let transports = [ + new winston.transports.File({ + name: 'filelog-info.log', + filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'), + level: 'info' + }), + new winston.transports.File({ + name: 'filelog-error.log', + filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'), + level: 'error' + }) + ]; + let logger = winston.createLogger({ + transports: transports + }); - it('.clear() [no transports]', function () { - var logger = winston.createLogger(); - assume(logger.transports.length).equals(0); - logger.clear(); - assume(logger.transports.length).equals(0); - }); + assume(logger.transports.length).equals(2); + assume(logger.transports.map(function (wrap) { + return wrap.transport || wrap; + })).deep.equals(transports); + }); + }); + + describe('remove', function () { + it('should do nothing if transport was not added', function () { + var transports = [ + new winston.transports.Console(), + new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) + ]; + + var logger = winston.createLogger({transports: transports}) + .remove(new winston.transports.Console()); + + assume(logger.transports.length).equals(2); + assume(logger.transports.map(function (wrap) { + // Unwrap LegacyTransportStream instances + return wrap.transport || wrap; + })).deep.equals(transports); + }); + + it('should remove transport when matching one is found', function () { + var transports = [ + new winston.transports.Console(), + new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) + ]; + + var logger = winston.createLogger({transports: transports}); + + assume(logger.transports.length).equals(2); + logger.remove(transports[0]); + assume(logger.transports.length).equals(1); + assume(logger.transports[0]).equals(transports[1]); + }); + + it('should remove specified logger even when duplicate exists', function () { + let transports = [ + new winston.transports.File({ + name: 'filelog-info.log', + filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'), + level: 'info' + }), + new winston.transports.File({ + name: 'filelog-error.log', + filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'), + level: 'error' + }) + ]; + let logger = winston.createLogger({ + transports: transports + }); - it('.clear() [transports]', function () { - var logger = winston.createLogger({ - transports: [new winston.transports.Console()] + logger.remove(transports[0]); + assume(logger.transports.length).equals(1); + assume(logger.transports[0]).equals(transports[1]); }); - - assume(logger.transports.length).equals(1); - logger.clear(); - assume(logger.transports.length).equals(0); }); - it('{ silent: true }', function (done) { - const neverLogTo = new TransportStream({ - log: function (info) { - assume(false).true('TransportStream was improperly written to'); - } + describe('clear', function () { + it('should do nothing when no transports exist', function () { + var logger = winston.createLogger(); + assume(logger.transports.length).equals(0); + logger.clear(); + assume(logger.transports.length).equals(0); }); - var logger = winston.createLogger({ - transports: [neverLogTo], - silent: true - }); + it('should remove all transports', function () { + var logger = winston.createLogger({ + transports: [new winston.transports.Console()] + }); - logger.log({ - level: 'info', - message: 'This should be ignored' + assume(logger.transports.length).equals(1); + logger.clear(); + assume(logger.transports.length).equals(0); }); - - setImmediate(() => done()); }); - }); - - describe('Logger (multiple transports of the same type)', function () { - var logger, transports; - before(function () { - transports = [ - new winston.transports.File({ - name: 'filelog-info.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'), - level: 'info' - }), - new winston.transports.File({ - name: 'filelog-error.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'), - level: 'error' - }) - ]; + describe('stream', function () { + it('should return a log stream for all transports', function () { + var logger = winston.createLogger(); + var outStream = logger.stream(); - logger = winston.createLogger({ - transports: transports + assume(isStream(outStream)).true(); }); }); - - it('should have both transports', function () { - assume(logger.transports.length).equals(2); - assume(logger.transports.map(function (wrap) { - return wrap.transport || wrap; - })).deep.equals(transports); - }); - - it('.remove() of one transport', function () { - logger.remove(transports[0]); - assume(logger.transports.length).equals(1); - assume(logger.transports[0]).equals(transports[1]); - }); }); - describe('Logger (levels)', function () { + describe('Log Levels', function () { it('report unknown levels', function (done) { stdMocks.use(); var logger = helpers.createLogger(function (info) { @@ -418,188 +337,188 @@ describe('Logger', function () { transports: [transport] }); }); - }); - - describe('Logger (level enabled/disabled)', function () { - it('default levels', function () { - var logger = winston.createLogger({ - level: 'verbose', - levels: winston.config.npm.levels, - transports: [new winston.transports.Console()] - }); - assume(logger.isLevelEnabled).is.a('function'); - - assume(logger.isErrorEnabled).is.a('function'); - assume(logger.isWarnEnabled).is.a('function'); - assume(logger.isInfoEnabled).is.a('function'); - assume(logger.isVerboseEnabled).is.a('function'); - assume(logger.isDebugEnabled).is.a('function'); - assume(logger.isSillyEnabled).is.a('function'); - - assume(logger.isLevelEnabled('error')).true(); - assume(logger.isLevelEnabled('warn')).true(); - assume(logger.isLevelEnabled('info')).true(); - assume(logger.isLevelEnabled('verbose')).true(); - assume(logger.isLevelEnabled('debug')).false(); - assume(logger.isLevelEnabled('silly')).false(); - - assume(logger.isErrorEnabled()).true(); - assume(logger.isWarnEnabled()).true(); - assume(logger.isInfoEnabled()).true(); - assume(logger.isVerboseEnabled()).true(); - assume(logger.isDebugEnabled()).false(); - assume(logger.isSillyEnabled()).false(); - }); + describe('Log Levels Enabled', function () { + it('default levels', function () { + var logger = winston.createLogger({ + level: 'verbose', + levels: winston.config.npm.levels, + transports: [new winston.transports.Console()] + }); - it('default levels, transport override', function () { - var transport = new winston.transports.Console(); - transport.level = 'debug'; + assume(logger.isLevelEnabled).is.a('function'); - var logger = winston.createLogger({ - level: 'info', - levels: winston.config.npm.levels, - transports: [transport] - }); + assume(logger.isErrorEnabled).is.a('function'); + assume(logger.isWarnEnabled).is.a('function'); + assume(logger.isInfoEnabled).is.a('function'); + assume(logger.isVerboseEnabled).is.a('function'); + assume(logger.isDebugEnabled).is.a('function'); + assume(logger.isSillyEnabled).is.a('function'); - assume(logger.isLevelEnabled).is.a('function'); - - assume(logger.isErrorEnabled).is.a('function'); - assume(logger.isWarnEnabled).is.a('function'); - assume(logger.isInfoEnabled).is.a('function'); - assume(logger.isVerboseEnabled).is.a('function'); - assume(logger.isDebugEnabled).is.a('function'); - assume(logger.isSillyEnabled).is.a('function'); - - assume(logger.isLevelEnabled('error')).true(); - assume(logger.isLevelEnabled('warn')).true(); - assume(logger.isLevelEnabled('info')).true(); - assume(logger.isLevelEnabled('verbose')).true(); - assume(logger.isLevelEnabled('debug')).true(); - assume(logger.isLevelEnabled('silly')).false(); - - assume(logger.isErrorEnabled()).true(); - assume(logger.isWarnEnabled()).true(); - assume(logger.isInfoEnabled()).true(); - assume(logger.isVerboseEnabled()).true(); - assume(logger.isDebugEnabled()).true(); - assume(logger.isSillyEnabled()).false(); - }); + assume(logger.isLevelEnabled('error')).true(); + assume(logger.isLevelEnabled('warn')).true(); + assume(logger.isLevelEnabled('info')).true(); + assume(logger.isLevelEnabled('verbose')).true(); + assume(logger.isLevelEnabled('debug')).false(); + assume(logger.isLevelEnabled('silly')).false(); - it('default levels, no transports', function () { - var logger = winston.createLogger({ - level: 'verbose', - levels: winston.config.npm.levels, - transports: [] + assume(logger.isErrorEnabled()).true(); + assume(logger.isWarnEnabled()).true(); + assume(logger.isInfoEnabled()).true(); + assume(logger.isVerboseEnabled()).true(); + assume(logger.isDebugEnabled()).false(); + assume(logger.isSillyEnabled()).false(); }); - assume(logger.isLevelEnabled).is.a('function'); - - assume(logger.isErrorEnabled).is.a('function'); - assume(logger.isWarnEnabled).is.a('function'); - assume(logger.isInfoEnabled).is.a('function'); - assume(logger.isVerboseEnabled).is.a('function'); - assume(logger.isDebugEnabled).is.a('function'); - assume(logger.isSillyEnabled).is.a('function'); - - assume(logger.isLevelEnabled('error')).true(); - assume(logger.isLevelEnabled('warn')).true(); - assume(logger.isLevelEnabled('info')).true(); - assume(logger.isLevelEnabled('verbose')).true(); - assume(logger.isLevelEnabled('debug')).false(); - assume(logger.isLevelEnabled('silly')).false(); - - assume(logger.isErrorEnabled()).true(); - assume(logger.isWarnEnabled()).true(); - assume(logger.isInfoEnabled()).true(); - assume(logger.isVerboseEnabled()).true(); - assume(logger.isDebugEnabled()).false(); - assume(logger.isSillyEnabled()).false(); - }); + it('default levels, transport override', function () { + var transport = new winston.transports.Console(); + transport.level = 'debug'; - it('custom levels', function () { - var logger = winston.createLogger({ - level: 'test', - levels: { - bad: 0, - test: 1, - ok: 2 - }, - transports: [new winston.transports.Console()] - }); + var logger = winston.createLogger({ + level: 'info', + levels: winston.config.npm.levels, + transports: [transport] + }); - assume(logger.isLevelEnabled).is.a('function'); + assume(logger.isLevelEnabled).is.a('function'); + + assume(logger.isErrorEnabled).is.a('function'); + assume(logger.isWarnEnabled).is.a('function'); + assume(logger.isInfoEnabled).is.a('function'); + assume(logger.isVerboseEnabled).is.a('function'); + assume(logger.isDebugEnabled).is.a('function'); + assume(logger.isSillyEnabled).is.a('function'); + + assume(logger.isLevelEnabled('error')).true(); + assume(logger.isLevelEnabled('warn')).true(); + assume(logger.isLevelEnabled('info')).true(); + assume(logger.isLevelEnabled('verbose')).true(); + assume(logger.isLevelEnabled('debug')).true(); + assume(logger.isLevelEnabled('silly')).false(); + + assume(logger.isErrorEnabled()).true(); + assume(logger.isWarnEnabled()).true(); + assume(logger.isInfoEnabled()).true(); + assume(logger.isVerboseEnabled()).true(); + assume(logger.isDebugEnabled()).true(); + assume(logger.isSillyEnabled()).false(); + }); + + it('default levels, no transports', function () { + var logger = winston.createLogger({ + level: 'verbose', + levels: winston.config.npm.levels, + transports: [] + }); - assume(logger.isBadEnabled).is.a('function'); - assume(logger.isTestEnabled).is.a('function'); - assume(logger.isOkEnabled).is.a('function'); + assume(logger.isLevelEnabled).is.a('function'); + + assume(logger.isErrorEnabled).is.a('function'); + assume(logger.isWarnEnabled).is.a('function'); + assume(logger.isInfoEnabled).is.a('function'); + assume(logger.isVerboseEnabled).is.a('function'); + assume(logger.isDebugEnabled).is.a('function'); + assume(logger.isSillyEnabled).is.a('function'); + + assume(logger.isLevelEnabled('error')).true(); + assume(logger.isLevelEnabled('warn')).true(); + assume(logger.isLevelEnabled('info')).true(); + assume(logger.isLevelEnabled('verbose')).true(); + assume(logger.isLevelEnabled('debug')).false(); + assume(logger.isLevelEnabled('silly')).false(); + + assume(logger.isErrorEnabled()).true(); + assume(logger.isWarnEnabled()).true(); + assume(logger.isInfoEnabled()).true(); + assume(logger.isVerboseEnabled()).true(); + assume(logger.isDebugEnabled()).false(); + assume(logger.isSillyEnabled()).false(); + }); + + it('custom levels', function () { + var logger = winston.createLogger({ + level: 'test', + levels: { + bad: 0, + test: 1, + ok: 2 + }, + transports: [new winston.transports.Console()] + }); - assume(logger.isLevelEnabled('bad')).true(); - assume(logger.isLevelEnabled('test')).true(); - assume(logger.isLevelEnabled('ok')).false(); + assume(logger.isLevelEnabled).is.a('function'); - assume(logger.isBadEnabled()).true(); - assume(logger.isTestEnabled()).true(); - assume(logger.isOkEnabled()).false(); - }); + assume(logger.isBadEnabled).is.a('function'); + assume(logger.isTestEnabled).is.a('function'); + assume(logger.isOkEnabled).is.a('function'); - it('custom levels, no transports', function () { - var logger = winston.createLogger({ - level: 'test', - levels: { - bad: 0, - test: 1, - ok: 2 - }, - transports: [] - }); + assume(logger.isLevelEnabled('bad')).true(); + assume(logger.isLevelEnabled('test')).true(); + assume(logger.isLevelEnabled('ok')).false(); - assume(logger.isLevelEnabled).is.a('function'); + assume(logger.isBadEnabled()).true(); + assume(logger.isTestEnabled()).true(); + assume(logger.isOkEnabled()).false(); + }); - assume(logger.isBadEnabled).is.a('function'); - assume(logger.isTestEnabled).is.a('function'); - assume(logger.isOkEnabled).is.a('function'); + it('custom levels, no transports', function () { + var logger = winston.createLogger({ + level: 'test', + levels: { + bad: 0, + test: 1, + ok: 2 + }, + transports: [] + }); - assume(logger.isLevelEnabled('bad')).true(); - assume(logger.isLevelEnabled('test')).true(); - assume(logger.isLevelEnabled('ok')).false(); + assume(logger.isLevelEnabled).is.a('function'); - assume(logger.isBadEnabled()).true(); - assume(logger.isTestEnabled()).true(); - assume(logger.isOkEnabled()).false(); - }); + assume(logger.isBadEnabled).is.a('function'); + assume(logger.isTestEnabled).is.a('function'); + assume(logger.isOkEnabled).is.a('function'); - it('custom levels, transport override', function () { - var transport = new winston.transports.Console(); - transport.level = 'ok'; + assume(logger.isLevelEnabled('bad')).true(); + assume(logger.isLevelEnabled('test')).true(); + assume(logger.isLevelEnabled('ok')).false(); - var logger = winston.createLogger({ - level: 'bad', - levels: { - bad: 0, - test: 1, - ok: 2 - }, - transports: [transport] + assume(logger.isBadEnabled()).true(); + assume(logger.isTestEnabled()).true(); + assume(logger.isOkEnabled()).false(); }); - assume(logger.isLevelEnabled).is.a('function'); + it('custom levels, transport override', function () { + var transport = new winston.transports.Console(); + transport.level = 'ok'; + + var logger = winston.createLogger({ + level: 'bad', + levels: { + bad: 0, + test: 1, + ok: 2 + }, + transports: [transport] + }); - assume(logger.isBadEnabled).is.a('function'); - assume(logger.isTestEnabled).is.a('function'); - assume(logger.isOkEnabled).is.a('function'); + assume(logger.isLevelEnabled).is.a('function'); - assume(logger.isLevelEnabled('bad')).true(); - assume(logger.isLevelEnabled('test')).true(); - assume(logger.isLevelEnabled('ok')).true(); + assume(logger.isBadEnabled).is.a('function'); + assume(logger.isTestEnabled).is.a('function'); + assume(logger.isOkEnabled).is.a('function'); - assume(logger.isBadEnabled()).true(); - assume(logger.isTestEnabled()).true(); - assume(logger.isOkEnabled()).true(); - }); + assume(logger.isLevelEnabled('bad')).true(); + assume(logger.isLevelEnabled('test')).true(); + assume(logger.isLevelEnabled('ok')).true(); + + assume(logger.isBadEnabled()).true(); + assume(logger.isTestEnabled()).true(); + assume(logger.isOkEnabled()).true(); + }); + }) }); - describe('Logger (stream semantics)', function () { + describe('Transport Events', function () { it(`'finish' event awaits transports to emit 'finish'`, function (done) { const transports = [ new TransportStream({ @@ -640,6 +559,36 @@ describe('Logger', function () { setImmediate(() => logger.end()); }); + it('error', (done) => { + const consoleTransport = new winston.transports.Console(); + const logger = winston.createLogger({ + transports: [consoleTransport] + }); + + logger.on('error', (err, transport) => { + assume(err).instanceOf(Error); + assume(transport).is.an('object'); + done(); + }); + consoleTransport.emit('error', new Error()); + }); + + it('warn', (done) => { + const consoleTransport = new winston.transports.Console(); + const logger = winston.createLogger({ + transports: [consoleTransport] + }); + + logger.on('warn', (err, transport) => { + assume(err).instanceOf(Error); + assume(transport).is.an('object'); + done(); + }); + consoleTransport.emit('warn', new Error()); + }); + }) + + describe('Formats', function () { it(`rethrows errors from user-defined formats`, function () { stdMocks.use(); const logger = winston.createLogger({ @@ -674,103 +623,79 @@ describe('Logger', function () { assume(actual.stdout).deep.equals(expected.map(msg => `${msg}${EOL}`)); assume(actual.stderr).deep.equals([]); }); - }); + }) - describe('Logger (winston@2 logging API)', function () { - it('.log(level, message)', function (done) { + describe('Profiling', function () { + // todo(maverick1872): refine tests + it('profile(id, info)', function (done) { var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); + assume(info).is.an('object'), + assume(info.something).equals('ok'); assume(info.level).equals('info'); - assume(info.message).equals('Some super awesome log message'); + assume(info.durationMs).is.a('number'); + assume(info.message).equals('testing1'); assume(info[MESSAGE]).is.a('string'); done(); }); - logger.log('info', 'Some super awesome log message') - }); - - it(`.log(level, undefined) creates info with { message: undefined }`, function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(undefined); - done(); - }); - - logger.log('info', undefined); - }); - - it(`.log(level, null) creates info with { message: null }`, function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(null); - done(); - }); - - logger.log('info', null); - }); - - it(`.log(level, new Error()) uses Error instance as info`, function (done) { - const err = new Error('test'); - const logger = helpers.createLogger(function (info) { - assume(info).instanceOf(Error); - assume(info).equals(err); - done(); - }); - - logger.log('info', err); + logger.profile('testing1'); + setTimeout(function () { + logger.profile('testing1', { + something: 'ok', + level: 'info' + }) + }, 100); }); - it('.log(level, message, meta)', function (done) { - var meta = {one: 2}; + it('profile(id, callback) ignores callback', function (done) { var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); + assume(info).is.an('object'), + assume(info.something).equals('ok'); assume(info.level).equals('info'); - assume(info.message).equals('Some super awesome log message'); - assume(info.one).equals(2); + assume(info.durationMs).is.a('number'); + assume(info.message).equals('testing2'); assume(info[MESSAGE]).is.a('string'); done(); }); - logger.log('info', 'Some super awesome log message', meta); - }); - - it('.log(level, formatStr, ...splat)', function (done) { - const format = winston.format.combine( - winston.format.splat(), - winston.format.printf(info => `${info.level}: ${info.message}`) - ); - - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('100% such wow {"much":"javascript"}'); - assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); - assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"}'); - done(); - }, format); + logger.profile('testing2', function () { + done(new Error('Unexpected callback invoked')); + }); - logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}); + setTimeout(function () { + logger.profile('testing2', { + something: 'ok', + level: 'info' + }) + }, 100); }); + }); - it('.log(level, formatStr, ...splat, meta)', function (done) { - const format = winston.format.combine( - winston.format.splat(), - winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({thisIsMeta: info.thisIsMeta})}`) - ); - + describe('Start Timer', function () { + // todo(maverick1872): refine tests + it('startTimer()', function (done) { var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); + assume(info).is.an('object'), + assume(info.something).equals('ok'); assume(info.level).equals('info'); - assume(info.message).equals('100% such wow {"much":"javascript"}'); - assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); - assume(info.thisIsMeta).true(); - assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"} {"thisIsMeta":true}'); + assume(info.durationMs).is.a('number'); + assume(info.message).equals('testing1'); + assume(info[MESSAGE]).is.a('string'); done(); - }, format); + }); - logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}, {thisIsMeta: true}); + var timer = logger.startTimer(); + setTimeout(function () { + timer.done({ + message: 'testing1', + something: 'ok', + level: 'info' + }); + }, 100); }); }); - describe('Logger (logging exotic data types)', function () { + describe('Logging non-primitive data types', function () { describe('.log', function () { it(`.log(new Error()) uses Error instance as info`, function (done) { const err = new Error('test'); @@ -868,229 +793,229 @@ describe('Logger', function () { }); }); - describe('Logger (profile, startTimer)', function (done) { - it('profile(id, info)', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); - assume(info.level).equals('info'); - assume(info.durationMs).is.a('number'); - assume(info.message).equals('testing1'); - assume(info[MESSAGE]).is.a('string'); - done(); - }); + describe('Child Loggers', function () { + describe('Should support child loggers & defaultMeta', () => { + it('sets child meta for text messages correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.requestId).equals('451'); + done(); + }); - logger.profile('testing1'); - setTimeout(function () { - logger.profile('testing1', { - something: 'ok', - level: 'info' - }) - }, 100); - }); + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); - it('profile(id, callback) ignores callback', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); - assume(info.level).equals('info'); - assume(info.durationMs).is.a('number'); - assume(info.message).equals('testing2'); - assume(info[MESSAGE]).is.a('string'); - done(); + const childLogger = logger.child({requestId: '451'}); + childLogger.info('dummy message'); }); - logger.profile('testing2', function () { - done(new Error('Unexpected callback invoked')); + it('sets child meta for json messages correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message.text).equals('dummy'); + assume(msg.requestId).equals('451'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({requestId: '451'}); + childLogger.info({text: 'dummy'}); }); - setTimeout(function () { - logger.profile('testing2', { - something: 'ok', - level: 'info' - }) - }, 100); - }); + it('merges child and provided meta correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('user-service'); + assume(msg.requestId).equals('451'); + done(); + }); - it('startTimer()', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); - assume(info.level).equals('info'); - assume(info.durationMs).is.a('number'); - assume(info.message).equals('testing1'); - assume(info[MESSAGE]).is.a('string'); - done(); + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({service: 'user-service'}); + childLogger.info('dummy message', {requestId: '451'}); }); - var timer = logger.startTimer(); - setTimeout(function () { - timer.done({ - message: 'testing1', - something: 'ok', - level: 'info' + it('provided meta take precedence over defaultMeta', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('audit-service'); + assume(msg.requestId).equals('451'); + done(); }); - }, 100); - }); - }); - describe('Should bubble transport events', () => { - it('error', (done) => { - const consoleTransport = new winston.transports.Console(); - const logger = winston.createLogger({ - transports: [consoleTransport] + const logger = winston.createLogger({ + defaultMeta: {service: 'user-service'}, + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + logger.info('dummy message', { + requestId: '451', + service: 'audit-service' + }); }); - logger.on('error', (err, transport) => { - assume(err).instanceOf(Error); - assume(transport).is.an('object'); - done(); + it('provided meta take precedence over child meta', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('info'); + assume(msg.message).equals('dummy message'); + assume(msg.service).equals('audit-service'); + assume(msg.requestId).equals('451'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({service: 'user-service'}); + childLogger.info('dummy message', { + requestId: '451', + service: 'audit-service' + }); }); - consoleTransport.emit('error', new Error()); - }); - it('warn', (done) => { - const consoleTransport = new winston.transports.Console(); - const logger = winston.createLogger({ - transports: [consoleTransport] + it('handles error stack traces in child loggers correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('error'); + assume(msg.message).equals('dummy error'); + assume(msg.stack).includes('logger.test.js'); + assume(msg.service).equals('user-service'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransport.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({service: 'user-service'}); + childLogger.error(Error('dummy error')); }); - logger.on('warn', (err, transport) => { - assume(err).instanceOf(Error); - assume(transport).is.an('object'); - done(); + it('defaultMeta() autobinds correctly', (done) => { + const logger = helpers.createLogger(info => { + assume(info.message).equals('test'); + done(); + }); + + const log = logger.info; + log('test'); }); - consoleTransport.emit('warn', new Error()); }); }); - describe('Should support child loggers & defaultMeta', () => { - it('sets child meta for text messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.requestId).equals('451'); + describe('Winston V2 usage API', function () { + it('.log(level, message)', function (done) { + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('Some super awesome log message'); + assume(info[MESSAGE]).is.a('string'); done(); }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({requestId: '451'}); - childLogger.info('dummy message'); + logger.log('info', 'Some super awesome log message') }); - it('sets child meta for json messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message.text).equals('dummy'); - assume(msg.requestId).equals('451'); + it(`.log(level, undefined) creates info with { message: undefined }`, function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(undefined); done(); }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({requestId: '451'}); - childLogger.info({text: 'dummy'}); + logger.log('info', undefined); }); - it('merges child and provided meta correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('user-service'); - assume(msg.requestId).equals('451'); + it(`.log(level, null) creates info with { message: null }`, function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(null); done(); }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({service: 'user-service'}); - childLogger.info('dummy message', {requestId: '451'}); + logger.log('info', null); }); - it('provided meta take precedence over defaultMeta', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('audit-service'); - assume(msg.requestId).equals('451'); + it(`.log(level, new Error()) uses Error instance as info`, function (done) { + const err = new Error('test'); + const logger = helpers.createLogger(function (info) { + assume(info).instanceOf(Error); + assume(info).equals(err); done(); }); - const logger = winston.createLogger({ - defaultMeta: {service: 'user-service'}, - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - logger.info('dummy message', { - requestId: '451', - service: 'audit-service' - }); + logger.log('info', err); }); - it('provided meta take precedence over child meta', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('audit-service'); - assume(msg.requestId).equals('451'); + it('.log(level, message, meta)', function (done) { + var meta = {one: 2}; + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('Some super awesome log message'); + assume(info.one).equals(2); + assume(info[MESSAGE]).is.a('string'); done(); }); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); - - const childLogger = logger.child({service: 'user-service'}); - childLogger.info('dummy message', { - requestId: '451', - service: 'audit-service' - }); + logger.log('info', 'Some super awesome log message', meta); }); - it('handles error stack traces in child loggers correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('error'); - assume(msg.message).equals('dummy error'); - assume(msg.stack).includes('logger.test.js'); - assume(msg.service).equals('user-service'); - done(); - }); + it('.log(level, formatStr, ...splat)', function (done) { + const format = winston.format.combine( + winston.format.splat(), + winston.format.printf(info => `${info.level}: ${info.message}`) + ); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] - }); + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('100% such wow {"much":"javascript"}'); + assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); + assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"}'); + done(); + }, format); - const childLogger = logger.child({service: 'user-service'}); - childLogger.error(Error('dummy error')); + logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}); }); - it('defaultMeta() autobinds correctly', (done) => { - const logger = helpers.createLogger(info => { - assume(info.message).equals('test'); + it('.log(level, formatStr, ...splat, meta)', function (done) { + const format = winston.format.combine( + winston.format.splat(), + winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({thisIsMeta: info.thisIsMeta})}`) + ); + + var logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('100% such wow {"much":"javascript"}'); + assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); + assume(info.thisIsMeta).true(); + assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"} {"thisIsMeta":true}'); done(); - }); + }, format); - const log = logger.info; - log('test'); + logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}, {thisIsMeta: true}); }); }); }); From 5df578638cc141b59fa19d0d2d16e3c6f1d42f47 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 29 Jan 2022 23:42:56 -0700 Subject: [PATCH 04/39] chore: cleanup test descriptions --- tests/unit/winston/logger.test.js | 244 ++++++++++++++-------------- tests/unit/winston/profiler.test.js | 2 +- 2 files changed, 123 insertions(+), 123 deletions(-) diff --git a/tests/unit/winston/logger.test.js b/tests/unit/winston/logger.test.js index 730682c2f..8041cc333 100755 --- a/tests/unit/winston/logger.test.js +++ b/tests/unit/winston/logger.test.js @@ -26,7 +26,7 @@ const mockTransport = require('../../helpers/mocks/mock-transport'); describe('Logger Instance', function () { describe('Configuration', function () { it('.configure()', function () { - var logger = winston.createLogger({ + let logger = winston.createLogger({ transports: [new winston.transports.Console()] }); @@ -39,7 +39,7 @@ describe('Logger Instance', function () { }); it('.configure({ transports })', function () { - var logger = winston.createLogger(); + let logger = winston.createLogger(); assume(logger.transports.length).equals(0); @@ -52,7 +52,7 @@ describe('Logger Instance', function () { }); it('.configure({ transports, format })', function () { - var logger = winston.createLogger(), + let logger = winston.createLogger(), format = logger.format; assume(logger.transports.length).equals(0); @@ -71,16 +71,16 @@ describe('Logger Instance', function () { describe('Transports', function() { describe('add', function () { it('should throw error when adding an invalid transport', function () { - var logger = winston.createLogger(); + let logger = winston.createLogger(); assume(function () { logger.add(5); }).throws(/invalid transport/i); }); it('should add the expected transport', function (done) { - var logger = winston.createLogger(); - var expected = {message: 'foo', level: 'info'}; - var transport = new TransportStream({ + let logger = winston.createLogger(); + let expected = {message: 'foo', level: 'info'}; + let transport = new TransportStream({ log: function (info) { assume(info.message).equals('foo'); assume(info.level).equals('info'); @@ -119,12 +119,12 @@ describe('Logger Instance', function () { describe('remove', function () { it('should do nothing if transport was not added', function () { - var transports = [ + let transports = [ new winston.transports.Console(), new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) ]; - var logger = winston.createLogger({transports: transports}) + let logger = winston.createLogger({transports: transports}) .remove(new winston.transports.Console()); assume(logger.transports.length).equals(2); @@ -135,12 +135,12 @@ describe('Logger Instance', function () { }); it('should remove transport when matching one is found', function () { - var transports = [ + let transports = [ new winston.transports.Console(), new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) ]; - var logger = winston.createLogger({transports: transports}); + let logger = winston.createLogger({transports: transports}); assume(logger.transports.length).equals(2); logger.remove(transports[0]); @@ -173,14 +173,14 @@ describe('Logger Instance', function () { describe('clear', function () { it('should do nothing when no transports exist', function () { - var logger = winston.createLogger(); + let logger = winston.createLogger(); assume(logger.transports.length).equals(0); logger.clear(); assume(logger.transports.length).equals(0); }); it('should remove all transports', function () { - var logger = winston.createLogger({ + let logger = winston.createLogger({ transports: [new winston.transports.Console()] }); @@ -192,8 +192,8 @@ describe('Logger Instance', function () { describe('stream', function () { it('should return a log stream for all transports', function () { - var logger = winston.createLogger(); - var outStream = logger.stream(); + let logger = winston.createLogger(); + let outStream = logger.stream(); assume(isStream(outStream)).true(); }); @@ -203,20 +203,20 @@ describe('Logger Instance', function () { describe('Log Levels', function () { it('report unknown levels', function (done) { stdMocks.use(); - var logger = helpers.createLogger(function (info) { + let logger = helpers.createLogger(function (info) { }); - var expected = {message: 'foo', level: 'bar'}; + let expected = {message: 'foo', level: 'bar'}; logger.log(expected); stdMocks.restore(); - var output = stdMocks.flush(); + let output = stdMocks.flush(); assume(output.stderr).deep.equals(['[winston] Unknown logger level: bar\n']); done(); }); it('.()', function (done) { - var logger = helpers.createLogger(function (info) { + let logger = helpers.createLogger(function (info) { assume(info).is.an('object'); assume(info.level).equals('info'); assume(info.message).is.a('string'); @@ -235,8 +235,8 @@ describe('Logger Instance', function () { }); it('default levels', function (done) { - var logger = winston.createLogger(); - var expected = {message: 'foo', level: 'debug'}; + let logger = winston.createLogger(); + let expected = {message: 'foo', level: 'debug'}; function logLevelTransport(level) { return new TransportStream({ @@ -264,7 +264,7 @@ describe('Logger Instance', function () { }); it('custom levels', function (done) { - var logger = winston.createLogger({ + let logger = winston.createLogger({ levels: { bad: 0, test: 1, @@ -272,7 +272,7 @@ describe('Logger Instance', function () { } }); - var expected = {message: 'foo', level: 'test'}; + let expected = {message: 'foo', level: 'test'}; function filterLevelTransport(level) { return new TransportStream({ @@ -340,7 +340,7 @@ describe('Logger Instance', function () { describe('Log Levels Enabled', function () { it('default levels', function () { - var logger = winston.createLogger({ + let logger = winston.createLogger({ level: 'verbose', levels: winston.config.npm.levels, transports: [new winston.transports.Console()] @@ -371,10 +371,10 @@ describe('Logger Instance', function () { }); it('default levels, transport override', function () { - var transport = new winston.transports.Console(); + let transport = new winston.transports.Console(); transport.level = 'debug'; - var logger = winston.createLogger({ + let logger = winston.createLogger({ level: 'info', levels: winston.config.npm.levels, transports: [transport] @@ -405,7 +405,7 @@ describe('Logger Instance', function () { }); it('default levels, no transports', function () { - var logger = winston.createLogger({ + let logger = winston.createLogger({ level: 'verbose', levels: winston.config.npm.levels, transports: [] @@ -436,7 +436,7 @@ describe('Logger Instance', function () { }); it('custom levels', function () { - var logger = winston.createLogger({ + let logger = winston.createLogger({ level: 'test', levels: { bad: 0, @@ -462,7 +462,7 @@ describe('Logger Instance', function () { }); it('custom levels, no transports', function () { - var logger = winston.createLogger({ + let logger = winston.createLogger({ level: 'test', levels: { bad: 0, @@ -488,10 +488,10 @@ describe('Logger Instance', function () { }); it('custom levels, transport override', function () { - var transport = new winston.transports.Console(); + let transport = new winston.transports.Console(); transport.level = 'ok'; - var logger = winston.createLogger({ + let logger = winston.createLogger({ level: 'bad', levels: { bad: 0, @@ -626,11 +626,10 @@ describe('Logger Instance', function () { }) describe('Profiling', function () { - // todo(maverick1872): refine tests - it('profile(id, info)', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); + it('ending profiler with object argument should be included in output', function (done) { + let logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.something).equals('ok'); assume(info.level).equals('info'); assume(info.durationMs).is.a('number'); assume(info.message).equals('testing1'); @@ -647,10 +646,11 @@ describe('Logger Instance', function () { }, 100); }); - it('profile(id, callback) ignores callback', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); + // TODO: Revisit if this is a valid test + it('calling profile with a callback function should not make a difference', function (done) { + let logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.something).equals('ok'); assume(info.level).equals('info'); assume(info.durationMs).is.a('number'); assume(info.message).equals('testing2'); @@ -669,14 +669,11 @@ describe('Logger Instance', function () { }) }, 100); }); - }); - describe('Start Timer', function () { - // todo(maverick1872): refine tests - it('startTimer()', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'), - assume(info.something).equals('ok'); + it('should stop a timer when `done` is called on it', function (done) { + let logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.something).equals('ok'); assume(info.level).equals('info'); assume(info.durationMs).is.a('number'); assume(info.message).equals('testing1'); @@ -684,7 +681,7 @@ describe('Logger Instance', function () { done(); }); - var timer = logger.startTimer(); + let timer = logger.startTimer(); setTimeout(function () { timer.done({ message: 'testing1', @@ -695,6 +692,7 @@ describe('Logger Instance', function () { }); }); + // TODO: Revisit to improve these describe('Logging non-primitive data types', function () { describe('.log', function () { it(`.log(new Error()) uses Error instance as info`, function (done) { @@ -781,10 +779,10 @@ describe('Logger Instance', function () { logger.info(err); }); + // TODO: This test needs finished or removed it.skip(`.info('any string', new Error())`, function (done) { const err = new Error('test'); const logger = helpers.createLogger(function (info) { - // TODO (indexzero): assert this works. done(); }); @@ -793,7 +791,7 @@ describe('Logger Instance', function () { }); }); - describe('Child Loggers', function () { + describe('Metadata Precedence', function () { describe('Should support child loggers & defaultMeta', () => { it('sets child meta for text messages correctly', (done) => { const assertFn = ((msg) => { @@ -925,97 +923,99 @@ describe('Logger Instance', function () { }); }); - describe('Winston V2 usage API', function () { - it('.log(level, message)', function (done) { - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('Some super awesome log message'); - assume(info[MESSAGE]).is.a('string'); - done(); + describe('Backwards Compatability', function () { + describe('Winston V2 Log', function () { + it('.log(level, message)', function (done) { + let logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('Some super awesome log message'); + assume(info[MESSAGE]).is.a('string'); + done(); + }); + + logger.log('info', 'Some super awesome log message') }); - logger.log('info', 'Some super awesome log message') - }); + it(`.log(level, undefined) creates info with { message: undefined }`, function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(undefined); + done(); + }); - it(`.log(level, undefined) creates info with { message: undefined }`, function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(undefined); - done(); + logger.log('info', undefined); }); - logger.log('info', undefined); - }); + it(`.log(level, null) creates info with { message: null }`, function (done) { + const logger = helpers.createLogger(function (info) { + assume(info.message).equals(null); + done(); + }); - it(`.log(level, null) creates info with { message: null }`, function (done) { - const logger = helpers.createLogger(function (info) { - assume(info.message).equals(null); - done(); + logger.log('info', null); }); - logger.log('info', null); - }); + it(`.log(level, new Error()) uses Error instance as info`, function (done) { + const err = new Error('test'); + const logger = helpers.createLogger(function (info) { + assume(info).instanceOf(Error); + assume(info).equals(err); + done(); + }); - it(`.log(level, new Error()) uses Error instance as info`, function (done) { - const err = new Error('test'); - const logger = helpers.createLogger(function (info) { - assume(info).instanceOf(Error); - assume(info).equals(err); - done(); + logger.log('info', err); }); - logger.log('info', err); - }); + it('.log(level, message, meta)', function (done) { + let meta = {one: 2}; + let logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('Some super awesome log message'); + assume(info.one).equals(2); + assume(info[MESSAGE]).is.a('string'); + done(); + }); - it('.log(level, message, meta)', function (done) { - var meta = {one: 2}; - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('Some super awesome log message'); - assume(info.one).equals(2); - assume(info[MESSAGE]).is.a('string'); - done(); + logger.log('info', 'Some super awesome log message', meta); }); - logger.log('info', 'Some super awesome log message', meta); - }); - - it('.log(level, formatStr, ...splat)', function (done) { - const format = winston.format.combine( - winston.format.splat(), - winston.format.printf(info => `${info.level}: ${info.message}`) - ); + it('.log(level, formatStr, ...splat)', function (done) { + const format = winston.format.combine( + winston.format.splat(), + winston.format.printf(info => `${info.level}: ${info.message}`) + ); - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('100% such wow {"much":"javascript"}'); - assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); - assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"}'); - done(); - }, format); + let logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('100% such wow {"much":"javascript"}'); + assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); + assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"}'); + done(); + }, format); - logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}); - }); + logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}); + }); - it('.log(level, formatStr, ...splat, meta)', function (done) { - const format = winston.format.combine( - winston.format.splat(), - winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({thisIsMeta: info.thisIsMeta})}`) - ); + it('.log(level, formatStr, ...splat, meta)', function (done) { + const format = winston.format.combine( + winston.format.splat(), + winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({thisIsMeta: info.thisIsMeta})}`) + ); - var logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.level).equals('info'); - assume(info.message).equals('100% such wow {"much":"javascript"}'); - assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); - assume(info.thisIsMeta).true(); - assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"} {"thisIsMeta":true}'); - done(); - }, format); + let logger = helpers.createLogger(function (info) { + assume(info).is.an('object'); + assume(info.level).equals('info'); + assume(info.message).equals('100% such wow {"much":"javascript"}'); + assume(info[SPLAT]).deep.equals([100, 'wow', {much: 'javascript'}]); + assume(info.thisIsMeta).true(); + assume(info[MESSAGE]).equals('info: 100% such wow {"much":"javascript"} {"thisIsMeta":true}'); + done(); + }, format); - logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}, {thisIsMeta: true}); + logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}, {thisIsMeta: true}); + }); }); }); }); diff --git a/tests/unit/winston/profiler.test.js b/tests/unit/winston/profiler.test.js index 6ca38db0c..b0f86e95b 100644 --- a/tests/unit/winston/profiler.test.js +++ b/tests/unit/winston/profiler.test.js @@ -19,7 +19,7 @@ describe('Profiler', function () { it('.done({ info })', function (done) { var profiler = new Profiler({ write: function (info) { - assume(info).is.an('object'), + assume(info).is.an('object'); assume(info.something).equals('ok'); assume(info.level).equals('info'); assume(info.durationMs).is.a('number'); From 4b0624ba817282b519c386617a8f084f63b470de Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 09:48:25 -0700 Subject: [PATCH 05/39] fix: fix ci step to account for npm script rename --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f76579b93..7099eeca4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,8 +28,8 @@ jobs: run: npm clean-install - name: Lint run: npm run lint - - name: Test - run: npm test + - name: Test Coverage + run: npm test:coverage - name: Coveralls if: matrix.node == '16' uses: coverallsapp/github-action@master From c942452ecdd87011535b0f5727eb3ee65bc29f64 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 09:59:54 -0700 Subject: [PATCH 06/39] chore: rename tests dir back to test --- package.json | 2 +- {tests => test}/fixtures/.gitkeep | 0 {tests => test}/fixtures/keys/agent2-cert.pem | 0 {tests => test}/fixtures/keys/agent2-key.pem | 0 {tests => test}/fixtures/logs/.gitkeep | 0 {tests => test}/helpers/index.js | 0 {tests => test}/helpers/mocks/legacy-mixed-transport.js | 0 {tests => test}/helpers/mocks/legacy-transport.js | 0 {tests => test}/helpers/mocks/mock-transport.js | 0 {tests => test}/helpers/scripts/colorize.js | 0 {tests => test}/helpers/scripts/default-exceptions.js | 0 {tests => test}/helpers/scripts/default-rejections.js | 0 {tests => test}/helpers/scripts/exit-on-error.js | 0 {tests => test}/helpers/scripts/log-exceptions.js | 0 {tests => test}/helpers/scripts/log-rejections.js | 0 {tests => test}/helpers/scripts/log-string-exception.js | 0 {tests => test}/helpers/scripts/unhandle-exceptions.js | 0 {tests => test}/helpers/scripts/unhandle-rejections.js | 0 {tests => test}/integration/formats.test.js | 0 {tests => test}/tsconfig.json | 0 {tests => test}/typescript-definitions.ts | 0 {tests => test}/unit/formats/errors.test.js | 0 {tests => test}/unit/winston/config/config.test.js | 0 {tests => test}/unit/winston/container.test.js | 0 {tests => test}/unit/winston/create-logger.test.js | 0 {tests => test}/unit/winston/exception-handler.test.js | 0 {tests => test}/unit/winston/exception-stream.test.js | 0 {tests => test}/unit/winston/log-exception.test.js | 0 {tests => test}/unit/winston/logger-legacy.test.js | 0 {tests => test}/unit/winston/logger.test.js | 0 {tests => test}/unit/winston/profiler.test.js | 0 {tests => test}/unit/winston/rejection-handler.test.js | 0 {tests => test}/unit/winston/tail-file.test.js | 0 {tests => test}/unit/winston/transports/00-file-stress.test.js | 0 {tests => test}/unit/winston/transports/01-file-maxsize.test.js | 0 {tests => test}/unit/winston/transports/console.test.js | 0 {tests => test}/unit/winston/transports/error.test.js | 0 {tests => test}/unit/winston/transports/file-archive.test.js | 0 {tests => test}/unit/winston/transports/file-create-dir-test.js | 0 {tests => test}/unit/winston/transports/file-maxfiles-test.js | 0 .../unit/winston/transports/file-tailrolling.test.js | 0 {tests => test}/unit/winston/transports/file.test.js | 0 {tests => test}/unit/winston/transports/http.test.js | 0 {tests => test}/unit/winston/transports/stream.test.js | 0 {tests => test}/winston.test.js | 0 45 files changed, 1 insertion(+), 1 deletion(-) rename {tests => test}/fixtures/.gitkeep (100%) rename {tests => test}/fixtures/keys/agent2-cert.pem (100%) rename {tests => test}/fixtures/keys/agent2-key.pem (100%) rename {tests => test}/fixtures/logs/.gitkeep (100%) rename {tests => test}/helpers/index.js (100%) rename {tests => test}/helpers/mocks/legacy-mixed-transport.js (100%) rename {tests => test}/helpers/mocks/legacy-transport.js (100%) rename {tests => test}/helpers/mocks/mock-transport.js (100%) rename {tests => test}/helpers/scripts/colorize.js (100%) rename {tests => test}/helpers/scripts/default-exceptions.js (100%) rename {tests => test}/helpers/scripts/default-rejections.js (100%) rename {tests => test}/helpers/scripts/exit-on-error.js (100%) rename {tests => test}/helpers/scripts/log-exceptions.js (100%) rename {tests => test}/helpers/scripts/log-rejections.js (100%) rename {tests => test}/helpers/scripts/log-string-exception.js (100%) rename {tests => test}/helpers/scripts/unhandle-exceptions.js (100%) rename {tests => test}/helpers/scripts/unhandle-rejections.js (100%) rename {tests => test}/integration/formats.test.js (100%) rename {tests => test}/tsconfig.json (100%) rename {tests => test}/typescript-definitions.ts (100%) rename {tests => test}/unit/formats/errors.test.js (100%) rename {tests => test}/unit/winston/config/config.test.js (100%) rename {tests => test}/unit/winston/container.test.js (100%) rename {tests => test}/unit/winston/create-logger.test.js (100%) rename {tests => test}/unit/winston/exception-handler.test.js (100%) rename {tests => test}/unit/winston/exception-stream.test.js (100%) rename {tests => test}/unit/winston/log-exception.test.js (100%) rename {tests => test}/unit/winston/logger-legacy.test.js (100%) rename {tests => test}/unit/winston/logger.test.js (100%) rename {tests => test}/unit/winston/profiler.test.js (100%) rename {tests => test}/unit/winston/rejection-handler.test.js (100%) rename {tests => test}/unit/winston/tail-file.test.js (100%) rename {tests => test}/unit/winston/transports/00-file-stress.test.js (100%) rename {tests => test}/unit/winston/transports/01-file-maxsize.test.js (100%) rename {tests => test}/unit/winston/transports/console.test.js (100%) rename {tests => test}/unit/winston/transports/error.test.js (100%) rename {tests => test}/unit/winston/transports/file-archive.test.js (100%) rename {tests => test}/unit/winston/transports/file-create-dir-test.js (100%) rename {tests => test}/unit/winston/transports/file-maxfiles-test.js (100%) rename {tests => test}/unit/winston/transports/file-tailrolling.test.js (100%) rename {tests => test}/unit/winston/transports/file.test.js (100%) rename {tests => test}/unit/winston/transports/http.test.js (100%) rename {tests => test}/unit/winston/transports/stream.test.js (100%) rename {tests => test}/winston.test.js (100%) diff --git a/package.json b/package.json index c17f765ef..bd517c7e4 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "lint": "populist lib/*.js lib/winston/*.js lib/winston/**/*.js", "pretest": "npm run lint", "test:coverage": "nyc --reporter=text --reporter lcov npm run test", - "test": "mocha tests/*.test.js tests/**/*.test.js --exit", + "test": "mocha test/*.test.js test/**/*.test.js --exit", "build": "rimraf dist && babel lib -d dist", "prepublishOnly": "npm run build" }, diff --git a/tests/fixtures/.gitkeep b/test/fixtures/.gitkeep similarity index 100% rename from tests/fixtures/.gitkeep rename to test/fixtures/.gitkeep diff --git a/tests/fixtures/keys/agent2-cert.pem b/test/fixtures/keys/agent2-cert.pem similarity index 100% rename from tests/fixtures/keys/agent2-cert.pem rename to test/fixtures/keys/agent2-cert.pem diff --git a/tests/fixtures/keys/agent2-key.pem b/test/fixtures/keys/agent2-key.pem similarity index 100% rename from tests/fixtures/keys/agent2-key.pem rename to test/fixtures/keys/agent2-key.pem diff --git a/tests/fixtures/logs/.gitkeep b/test/fixtures/logs/.gitkeep similarity index 100% rename from tests/fixtures/logs/.gitkeep rename to test/fixtures/logs/.gitkeep diff --git a/tests/helpers/index.js b/test/helpers/index.js similarity index 100% rename from tests/helpers/index.js rename to test/helpers/index.js diff --git a/tests/helpers/mocks/legacy-mixed-transport.js b/test/helpers/mocks/legacy-mixed-transport.js similarity index 100% rename from tests/helpers/mocks/legacy-mixed-transport.js rename to test/helpers/mocks/legacy-mixed-transport.js diff --git a/tests/helpers/mocks/legacy-transport.js b/test/helpers/mocks/legacy-transport.js similarity index 100% rename from tests/helpers/mocks/legacy-transport.js rename to test/helpers/mocks/legacy-transport.js diff --git a/tests/helpers/mocks/mock-transport.js b/test/helpers/mocks/mock-transport.js similarity index 100% rename from tests/helpers/mocks/mock-transport.js rename to test/helpers/mocks/mock-transport.js diff --git a/tests/helpers/scripts/colorize.js b/test/helpers/scripts/colorize.js similarity index 100% rename from tests/helpers/scripts/colorize.js rename to test/helpers/scripts/colorize.js diff --git a/tests/helpers/scripts/default-exceptions.js b/test/helpers/scripts/default-exceptions.js similarity index 100% rename from tests/helpers/scripts/default-exceptions.js rename to test/helpers/scripts/default-exceptions.js diff --git a/tests/helpers/scripts/default-rejections.js b/test/helpers/scripts/default-rejections.js similarity index 100% rename from tests/helpers/scripts/default-rejections.js rename to test/helpers/scripts/default-rejections.js diff --git a/tests/helpers/scripts/exit-on-error.js b/test/helpers/scripts/exit-on-error.js similarity index 100% rename from tests/helpers/scripts/exit-on-error.js rename to test/helpers/scripts/exit-on-error.js diff --git a/tests/helpers/scripts/log-exceptions.js b/test/helpers/scripts/log-exceptions.js similarity index 100% rename from tests/helpers/scripts/log-exceptions.js rename to test/helpers/scripts/log-exceptions.js diff --git a/tests/helpers/scripts/log-rejections.js b/test/helpers/scripts/log-rejections.js similarity index 100% rename from tests/helpers/scripts/log-rejections.js rename to test/helpers/scripts/log-rejections.js diff --git a/tests/helpers/scripts/log-string-exception.js b/test/helpers/scripts/log-string-exception.js similarity index 100% rename from tests/helpers/scripts/log-string-exception.js rename to test/helpers/scripts/log-string-exception.js diff --git a/tests/helpers/scripts/unhandle-exceptions.js b/test/helpers/scripts/unhandle-exceptions.js similarity index 100% rename from tests/helpers/scripts/unhandle-exceptions.js rename to test/helpers/scripts/unhandle-exceptions.js diff --git a/tests/helpers/scripts/unhandle-rejections.js b/test/helpers/scripts/unhandle-rejections.js similarity index 100% rename from tests/helpers/scripts/unhandle-rejections.js rename to test/helpers/scripts/unhandle-rejections.js diff --git a/tests/integration/formats.test.js b/test/integration/formats.test.js similarity index 100% rename from tests/integration/formats.test.js rename to test/integration/formats.test.js diff --git a/tests/tsconfig.json b/test/tsconfig.json similarity index 100% rename from tests/tsconfig.json rename to test/tsconfig.json diff --git a/tests/typescript-definitions.ts b/test/typescript-definitions.ts similarity index 100% rename from tests/typescript-definitions.ts rename to test/typescript-definitions.ts diff --git a/tests/unit/formats/errors.test.js b/test/unit/formats/errors.test.js similarity index 100% rename from tests/unit/formats/errors.test.js rename to test/unit/formats/errors.test.js diff --git a/tests/unit/winston/config/config.test.js b/test/unit/winston/config/config.test.js similarity index 100% rename from tests/unit/winston/config/config.test.js rename to test/unit/winston/config/config.test.js diff --git a/tests/unit/winston/container.test.js b/test/unit/winston/container.test.js similarity index 100% rename from tests/unit/winston/container.test.js rename to test/unit/winston/container.test.js diff --git a/tests/unit/winston/create-logger.test.js b/test/unit/winston/create-logger.test.js similarity index 100% rename from tests/unit/winston/create-logger.test.js rename to test/unit/winston/create-logger.test.js diff --git a/tests/unit/winston/exception-handler.test.js b/test/unit/winston/exception-handler.test.js similarity index 100% rename from tests/unit/winston/exception-handler.test.js rename to test/unit/winston/exception-handler.test.js diff --git a/tests/unit/winston/exception-stream.test.js b/test/unit/winston/exception-stream.test.js similarity index 100% rename from tests/unit/winston/exception-stream.test.js rename to test/unit/winston/exception-stream.test.js diff --git a/tests/unit/winston/log-exception.test.js b/test/unit/winston/log-exception.test.js similarity index 100% rename from tests/unit/winston/log-exception.test.js rename to test/unit/winston/log-exception.test.js diff --git a/tests/unit/winston/logger-legacy.test.js b/test/unit/winston/logger-legacy.test.js similarity index 100% rename from tests/unit/winston/logger-legacy.test.js rename to test/unit/winston/logger-legacy.test.js diff --git a/tests/unit/winston/logger.test.js b/test/unit/winston/logger.test.js similarity index 100% rename from tests/unit/winston/logger.test.js rename to test/unit/winston/logger.test.js diff --git a/tests/unit/winston/profiler.test.js b/test/unit/winston/profiler.test.js similarity index 100% rename from tests/unit/winston/profiler.test.js rename to test/unit/winston/profiler.test.js diff --git a/tests/unit/winston/rejection-handler.test.js b/test/unit/winston/rejection-handler.test.js similarity index 100% rename from tests/unit/winston/rejection-handler.test.js rename to test/unit/winston/rejection-handler.test.js diff --git a/tests/unit/winston/tail-file.test.js b/test/unit/winston/tail-file.test.js similarity index 100% rename from tests/unit/winston/tail-file.test.js rename to test/unit/winston/tail-file.test.js diff --git a/tests/unit/winston/transports/00-file-stress.test.js b/test/unit/winston/transports/00-file-stress.test.js similarity index 100% rename from tests/unit/winston/transports/00-file-stress.test.js rename to test/unit/winston/transports/00-file-stress.test.js diff --git a/tests/unit/winston/transports/01-file-maxsize.test.js b/test/unit/winston/transports/01-file-maxsize.test.js similarity index 100% rename from tests/unit/winston/transports/01-file-maxsize.test.js rename to test/unit/winston/transports/01-file-maxsize.test.js diff --git a/tests/unit/winston/transports/console.test.js b/test/unit/winston/transports/console.test.js similarity index 100% rename from tests/unit/winston/transports/console.test.js rename to test/unit/winston/transports/console.test.js diff --git a/tests/unit/winston/transports/error.test.js b/test/unit/winston/transports/error.test.js similarity index 100% rename from tests/unit/winston/transports/error.test.js rename to test/unit/winston/transports/error.test.js diff --git a/tests/unit/winston/transports/file-archive.test.js b/test/unit/winston/transports/file-archive.test.js similarity index 100% rename from tests/unit/winston/transports/file-archive.test.js rename to test/unit/winston/transports/file-archive.test.js diff --git a/tests/unit/winston/transports/file-create-dir-test.js b/test/unit/winston/transports/file-create-dir-test.js similarity index 100% rename from tests/unit/winston/transports/file-create-dir-test.js rename to test/unit/winston/transports/file-create-dir-test.js diff --git a/tests/unit/winston/transports/file-maxfiles-test.js b/test/unit/winston/transports/file-maxfiles-test.js similarity index 100% rename from tests/unit/winston/transports/file-maxfiles-test.js rename to test/unit/winston/transports/file-maxfiles-test.js diff --git a/tests/unit/winston/transports/file-tailrolling.test.js b/test/unit/winston/transports/file-tailrolling.test.js similarity index 100% rename from tests/unit/winston/transports/file-tailrolling.test.js rename to test/unit/winston/transports/file-tailrolling.test.js diff --git a/tests/unit/winston/transports/file.test.js b/test/unit/winston/transports/file.test.js similarity index 100% rename from tests/unit/winston/transports/file.test.js rename to test/unit/winston/transports/file.test.js diff --git a/tests/unit/winston/transports/http.test.js b/test/unit/winston/transports/http.test.js similarity index 100% rename from tests/unit/winston/transports/http.test.js rename to test/unit/winston/transports/http.test.js diff --git a/tests/unit/winston/transports/stream.test.js b/test/unit/winston/transports/stream.test.js similarity index 100% rename from tests/unit/winston/transports/stream.test.js rename to test/unit/winston/transports/stream.test.js diff --git a/tests/winston.test.js b/test/winston.test.js similarity index 100% rename from tests/winston.test.js rename to test/winston.test.js From e72d96b6662ea199d6ed9be7757c1f78af39e8c7 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 10:52:57 -0700 Subject: [PATCH 07/39] fix: correct relative file paths --- package.json | 6 +++-- test/helpers/scripts/default-exceptions.js | 3 ++- test/helpers/scripts/default-rejections.js | 10 ++------ test/helpers/scripts/exit-on-error.js | 3 ++- test/helpers/scripts/log-exceptions.js | 3 ++- test/helpers/scripts/log-rejections.js | 10 ++------ test/helpers/scripts/log-string-exception.js | 3 ++- test/helpers/scripts/unhandle-exceptions.js | 3 ++- test/helpers/scripts/unhandle-rejections.js | 3 ++- test/{ => integration}/winston.test.js | 4 ++-- test/unit/winston/exception-stream.test.js | 3 ++- test/unit/winston/log-exception.test.js | 23 ++++++++++--------- test/unit/winston/logger.test.js | 14 +++++------ test/unit/winston/tail-file.test.js | 3 ++- .../winston/transports/00-file-stress.test.js | 8 +++---- .../transports/01-file-maxsize.test.js | 5 ++-- .../winston/transports/file-archive.test.js | 7 +++--- ...te-dir-test.js => file-create-dir.test.js} | 2 +- ...maxfiles-test.js => file-maxfiles.test.js} | 12 +++++----- .../transports/file-tailrolling.test.js | 9 ++++---- test/unit/winston/transports/file.test.js | 7 +++--- 21 files changed, 72 insertions(+), 69 deletions(-) rename test/{ => integration}/winston.test.js (94%) rename test/unit/winston/transports/{file-create-dir-test.js => file-create-dir.test.js} (93%) rename test/unit/winston/transports/{file-maxfiles-test.js => file-maxfiles.test.js} (84%) diff --git a/package.json b/package.json index bd517c7e4..5af09efe2 100644 --- a/package.json +++ b/package.json @@ -60,8 +60,10 @@ "scripts": { "lint": "populist lib/*.js lib/winston/*.js lib/winston/**/*.js", "pretest": "npm run lint", - "test:coverage": "nyc --reporter=text --reporter lcov npm run test", - "test": "mocha test/*.test.js test/**/*.test.js --exit", + "test": "mocha test/unit/**/*.test.js test/integration/**/*.test.js --exit", + "test:coverage": "nyc --reporter=text --reporter lcov npm run test:unit", + "test:unit": "mocha test/unit/**/*.test.js --exit", + "test:integration": "mocha test/integration/**/*.test.js --exit", "build": "rimraf dist && babel lib -d dist", "prepublishOnly": "npm run build" }, diff --git a/test/helpers/scripts/default-exceptions.js b/test/helpers/scripts/default-exceptions.js index a7350374c..49646f829 100644 --- a/test/helpers/scripts/default-exceptions.js +++ b/test/helpers/scripts/default-exceptions.js @@ -8,10 +8,11 @@ var path = require('path'), winston = require('../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); winston.exceptions.handle([ new winston.transports.File({ - filename: path.join(__dirname, '..', '..', 'fixtures', 'logs', 'default-exception.log'), + filename: path.join(testLogFixturesPath, 'default-exception.log'), handleExceptions: true }) ]); diff --git a/test/helpers/scripts/default-rejections.js b/test/helpers/scripts/default-rejections.js index 90ae53281..b095db375 100644 --- a/test/helpers/scripts/default-rejections.js +++ b/test/helpers/scripts/default-rejections.js @@ -8,17 +8,11 @@ var path = require("path"), winston = require("../../../lib/winston"); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); winston.rejections.handle([ new winston.transports.File({ - filename: path.join( - __dirname, - "..", - "..", - "fixtures", - "logs", - "default-rejection.log" - ), + filename: path.join(testLogFixturesPath, "default-rejection.log"), handleRejections: true }) ]); diff --git a/test/helpers/scripts/exit-on-error.js b/test/helpers/scripts/exit-on-error.js index ccbb01140..9231938ba 100644 --- a/test/helpers/scripts/exit-on-error.js +++ b/test/helpers/scripts/exit-on-error.js @@ -8,6 +8,7 @@ var path = require('path'), winston = require('../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); winston.exitOnError = function (err) { process.stdout.write(err.message); @@ -16,7 +17,7 @@ winston.exitOnError = function (err) { winston.handleExceptions([ new winston.transports.File({ - filename: path.join(__dirname, '..', 'logs', 'exit-on-error.log'), + filename: path.join(testLogFixturesPath, 'exit-on-error.log'), handleExceptions: true }) ]); diff --git a/test/helpers/scripts/log-exceptions.js b/test/helpers/scripts/log-exceptions.js index 9315b6f4f..f545c01bd 100644 --- a/test/helpers/scripts/log-exceptions.js +++ b/test/helpers/scripts/log-exceptions.js @@ -8,11 +8,12 @@ var path = require('path'), winston = require('../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); var logger = winston.createLogger({ transports: [ new winston.transports.File({ - filename: path.join(__dirname, '..', '..', 'fixtures', 'logs', 'exception.log'), + filename: path.join(testLogFixturesPath, 'exception.log'), handleExceptions: true }) ] diff --git a/test/helpers/scripts/log-rejections.js b/test/helpers/scripts/log-rejections.js index b8025a178..ea3592375 100644 --- a/test/helpers/scripts/log-rejections.js +++ b/test/helpers/scripts/log-rejections.js @@ -8,18 +8,12 @@ var path = require("path"), winston = require("../../../lib/winston"); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); var logger = winston.createLogger({ transports: [ new winston.transports.File({ - filename: path.join( - __dirname, - "..", - "..", - "fixtures", - "logs", - "rejections.log" - ), + filename: path.join(testLogFixturesPath, "rejections.log"), handleRejections: true }) ] diff --git a/test/helpers/scripts/log-string-exception.js b/test/helpers/scripts/log-string-exception.js index c186e5c3e..b223cf059 100644 --- a/test/helpers/scripts/log-string-exception.js +++ b/test/helpers/scripts/log-string-exception.js @@ -8,11 +8,12 @@ var path = require('path'), winston = require('../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); var logger = winston.createLogger({ transports: [ new winston.transports.File({ - filename: path.join(__dirname, '..', '..', 'fixtures', 'logs', 'string-exception.log'), + filename: path.join(testLogFixturesPath, 'string-exception.log'), handleExceptions: true }) ] diff --git a/test/helpers/scripts/unhandle-exceptions.js b/test/helpers/scripts/unhandle-exceptions.js index b3c0b52e4..3c84a5270 100644 --- a/test/helpers/scripts/unhandle-exceptions.js +++ b/test/helpers/scripts/unhandle-exceptions.js @@ -8,11 +8,12 @@ var path = require('path'), winston = require('../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); var logger = winston.createLogger({ transports: [ new winston.transports.File({ - filename: path.join(__dirname, '..', 'logs', 'unhandle-exception.log') + filename: path.join(testLogFixturesPath, 'unhandle-exception.log') }) ] }); diff --git a/test/helpers/scripts/unhandle-rejections.js b/test/helpers/scripts/unhandle-rejections.js index 98c64dabf..4e5574ffc 100644 --- a/test/helpers/scripts/unhandle-rejections.js +++ b/test/helpers/scripts/unhandle-rejections.js @@ -8,11 +8,12 @@ var path = require('path'), winston = require('../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); var logger = winston.createLogger({ transports: [ new winston.transports.File({ - filename: path.join(__dirname, '..', 'logs', 'unhandle-rejections.log') + filename: path.join(testLogFixturesPath, 'unhandle-rejections.log') }) ] }); diff --git a/test/winston.test.js b/test/integration/winston.test.js similarity index 94% rename from test/winston.test.js rename to test/integration/winston.test.js index a24c39113..8d084fed0 100644 --- a/test/winston.test.js +++ b/test/integration/winston.test.js @@ -8,7 +8,7 @@ const { format } = require('util'); const assume = require('assume'); -const winston = require('../lib/winston'); +const winston = require('../../lib/winston'); describe('winston', function () { @@ -35,7 +35,7 @@ describe('winston', function () { }); it('exposes version', function () { - assume(winston.version).equals(require('../package').version); + assume(winston.version).equals(require('../../package.json').version); }); it('abstract-winston-logger'); diff --git a/test/unit/winston/exception-stream.test.js b/test/unit/winston/exception-stream.test.js index 8883f03a9..201c733fa 100644 --- a/test/unit/winston/exception-stream.test.js +++ b/test/unit/winston/exception-stream.test.js @@ -11,10 +11,11 @@ const { Writable } = require('readable-stream'); const path = require('path'); const winston = require('../../../lib/winston'); const ExceptionStream = require('../../../lib/winston/exception-stream'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); describe('ExceptionStream', function () { it('has expected methods', function () { - var filename = path.join(__dirname, 'fixtures', 'logs', 'exception-stream.log'); + var filename = path.join(testLogFixturesPath, 'exception-stream.log'); var transport = new winston.transports.File({ filename }); var instance = new ExceptionStream(transport); diff --git a/test/unit/winston/log-exception.test.js b/test/unit/winston/log-exception.test.js index b0ed146e0..65e1d0cfb 100644 --- a/test/unit/winston/log-exception.test.js +++ b/test/unit/winston/log-exception.test.js @@ -12,17 +12,19 @@ const path = require('path'); const { spawn } = require('child_process'); const winston = require('../../../lib/winston'); const helpers = require('../../helpers'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); +const testHelperScriptsPath = path.join(__dirname, '..', '..', 'helpers', 'scripts'); describe('Logger, ExceptionHandler', function () { this.timeout(5000); describe('.exceptions.unhandle()', function () { it('does not log to any transports', function (done) { - var logFile = path.join(__dirname, 'fixtures', 'logs', 'unhandle-exception.log'); + var logFile = path.join(testLogFixturesPath, 'unhandle-exception.log'); helpers.tryUnlink(logFile); - spawn('node', [path.join(__dirname, 'helpers', 'scripts', 'unhandle-exceptions.js')]) + spawn('node', [path.join(testHelperScriptsPath, 'unhandle-exceptions.js')]) .on('exit', function () { fs.exists(logFile, function (exists) { assume(exists).false(); @@ -40,7 +42,7 @@ describe('Logger, ExceptionHandler', function () { var logger = winston.createLogger({ exceptionHandlers: [ new winston.transports.Console(), - new winston.transports.File({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log') }) + new winston.transports.File({ filename: path.join(testLogFixturesPath, 'filelog.log') }) ] }); @@ -53,8 +55,7 @@ describe('Logger, ExceptionHandler', function () { }); it('Custom exitOnError function does not exit', function (done) { - const scriptDir = path.join(__dirname, 'helpers', 'scripts'); - const child = spawn('node', [path.join(scriptDir, 'exit-on-error.js')]); + const child = spawn('node', [path.join(testHelperScriptsPath, 'exit-on-error.js')]); const stdout = []; child.stdout.setEncoding('utf8'); @@ -73,19 +74,19 @@ describe('Logger, ExceptionHandler', function () { describe('.exceptions.handle()', function () { describe('should save the error information to the specified file', function () { it('when strings are thrown as errors', helpers.assertHandleExceptions({ - script: path.join(__dirname, 'helpers', 'scripts', 'log-string-exception.js'), - logfile: path.join(__dirname, 'fixtures', 'logs', 'string-exception.log'), + script: path.join(testHelperScriptsPath, 'log-string-exception.js'), + logfile: path.join(testLogFixturesPath, 'string-exception.log'), message: 'OMG NEVER DO THIS STRING EXCEPTIONS ARE AWFUL' })); it('with a custom winston.Logger instance', helpers.assertHandleExceptions({ - script: path.join(__dirname, 'helpers', 'scripts', 'log-exceptions.js'), - logfile: path.join(__dirname, 'fixtures', 'logs', 'exception.log') + script: path.join(testHelperScriptsPath, 'log-exceptions.js'), + logfile: path.join(testLogFixturesPath, 'exception.log') })); it('with the default winston logger', helpers.assertHandleExceptions({ - script: path.join(__dirname, 'helpers', 'scripts', 'default-exceptions.js'), - logfile: path.join(__dirname, 'fixtures', 'logs', 'default-exception.log') + script: path.join(testHelperScriptsPath, 'default-exceptions.js'), + logfile: path.join(testLogFixturesPath, 'default-exception.log') })); }); }); diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 8041cc333..83504f594 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -21,7 +21,7 @@ const TransportStream = require('winston-transport'); const format = require('../../../lib/winston').format; const helpers = require('../../helpers'); const mockTransport = require('../../helpers/mocks/mock-transport'); - +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); describe('Logger Instance', function () { describe('Configuration', function () { @@ -97,12 +97,12 @@ describe('Logger Instance', function () { let transports = [ new winston.transports.File({ name: 'filelog-info.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'), + filename: path.join(testLogFixturesPath, 'filelog-info.log'), level: 'info' }), new winston.transports.File({ name: 'filelog-error.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'), + filename: path.join(testLogFixturesPath, 'filelog-error.log'), level: 'error' }) ]; @@ -121,7 +121,7 @@ describe('Logger Instance', function () { it('should do nothing if transport was not added', function () { let transports = [ new winston.transports.Console(), - new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) + new winston.transports.File({filename: path.join(testLogFixturesPath, 'filelog.log')}) ]; let logger = winston.createLogger({transports: transports}) @@ -137,7 +137,7 @@ describe('Logger Instance', function () { it('should remove transport when matching one is found', function () { let transports = [ new winston.transports.Console(), - new winston.transports.File({filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log')}) + new winston.transports.File({filename: path.join(testLogFixturesPath, 'filelog.log')}) ]; let logger = winston.createLogger({transports: transports}); @@ -152,12 +152,12 @@ describe('Logger Instance', function () { let transports = [ new winston.transports.File({ name: 'filelog-info.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'), + filename: path.join(testLogFixturesPath, 'filelog-info.log'), level: 'info' }), new winston.transports.File({ name: 'filelog-error.log', - filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'), + filename: path.join(testLogFixturesPath, 'filelog-error.log'), level: 'error' }) ]; diff --git a/test/unit/winston/tail-file.test.js b/test/unit/winston/tail-file.test.js index cf8d9923e..030b0f85d 100644 --- a/test/unit/winston/tail-file.test.js +++ b/test/unit/winston/tail-file.test.js @@ -12,6 +12,7 @@ const path = require('path'); const winston = require('../../../lib/winston'); const tailFile = require('../../../lib/winston/tail-file'); const { Stream } = require('readable-stream'); +const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); // // Test helper that performs writes to a specific log file @@ -60,7 +61,7 @@ describe('tailFile', function () { }); it('returns a stream that emits "line" for every line', function (done) { - var tailable = path.join(__dirname, 'fixtures', 'logs', 'common-tail-file.log'); + var tailable = path.join(testLogFixturesPath, 'common-tail-file.log'); var expected = 0; // // Performs the actual tail and asserts it. diff --git a/test/unit/winston/transports/00-file-stress.test.js b/test/unit/winston/transports/00-file-stress.test.js index e1552833f..ec1af5e16 100644 --- a/test/unit/winston/transports/00-file-stress.test.js +++ b/test/unit/winston/transports/00-file-stress.test.js @@ -19,7 +19,7 @@ const winston = require('../../../../lib/winston'); describe('File (stress)', function () { this.timeout(30 * 1000); - const logPath = path.resolve(__dirname, '../fixtures/logs/file-stress-test.log'); + const fileStressLogFile = path.resolve(__dirname, '../../../fixtures/logs/file-stress-test.log'); beforeEach(function () { try { fs.unlinkSync(logPath); @@ -31,7 +31,7 @@ describe('File (stress)', function () { it('should handle a high volume of writes', function (done) { const logger = winston.createLogger({ transports: [new winston.transports.File({ - filename: logPath + filename: fileStressLogFile })] }); @@ -70,7 +70,7 @@ describe('File (stress)', function () { it('should handle a high volume of large writes', function (done) { const logger = winston.createLogger({ transports: [new winston.transports.File({ - filename: logPath + filename: fileStressLogFile })] }); @@ -114,7 +114,7 @@ describe('File (stress)', function () { it('should handle a high volume of large writes synchronous', function (done) { const logger = winston.createLogger({ transports: [new winston.transports.File({ - filename: logPath + filename: fileStressLogFile })] }); diff --git a/test/unit/winston/transports/01-file-maxsize.test.js b/test/unit/winston/transports/01-file-maxsize.test.js index 1f0bf7f3c..2edfa17bb 100644 --- a/test/unit/winston/transports/01-file-maxsize.test.js +++ b/test/unit/winston/transports/01-file-maxsize.test.js @@ -10,6 +10,7 @@ const fs = require('fs'); const path = require('path'); const assume = require('assume'); const winston = require('../../../../index'); +const testLogFixturesPath = path.join(__dirname, '..', '..', '..', 'fixtures', 'logs'); const MESSAGE = Symbol.for('message'); @@ -17,7 +18,7 @@ const MESSAGE = Symbol.for('message'); // Remove all log fixtures // function removeFixtures(done) { - rimraf(path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize*'), done); + rimraf(path.join(testLogFixturesPath, 'testmaxsize*'), done); } describe('File (maxsize)', function () { @@ -35,7 +36,7 @@ describe('File (maxsize)', function () { const maxsizeTransport = new winston.transports.File({ level: 'info', format: winston.format.printf(info => info.message), - filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize.log'), + filename: path.join(testLogFixturesPath, 'testmaxsize.log'), maxsize: 4096 }) diff --git a/test/unit/winston/transports/file-archive.test.js b/test/unit/winston/transports/file-archive.test.js index 2c5266d91..fc7cafcfd 100644 --- a/test/unit/winston/transports/file-archive.test.js +++ b/test/unit/winston/transports/file-archive.test.js @@ -12,6 +12,7 @@ const rimraf = require('rimraf'); const fs = require('fs'); const path = require('path'); const winston = require('../../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', '..', 'fixtures', 'logs'); const { MESSAGE } = require('triple-beam'); @@ -19,7 +20,7 @@ const { MESSAGE } = require('triple-beam'); // Remove all log fixtures // function removeFixtures(done) { - rimraf(path.join(__dirname, '..', 'fixtures', 'logs', 'testarchive*'), done); + rimraf(path.join(testLogFixturesPath, 'testarchive*'), done); } @@ -37,7 +38,7 @@ describe('winston/transports/file/zippedArchive', function () { zippedArchive: true, tailable: true, filename: 'testarchive.log', - dirname: path.join(__dirname, '..', 'fixtures', 'logs'), + dirname: testLogFixturesPath, maxsize: 4096, maxFiles: 3 }); @@ -76,7 +77,7 @@ describe('winston/transports/file/zippedArchive', function () { it('should be only 3 files called testarchive.log, testarchive1.log.gz and testarchive2.log.gz', function () { for (var num = 0; num < 4; num++) { const file = !num ? 'testarchive.log' : 'testarchive' + num + '.log.gz'; - const fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + const fullpath = path.join(testLogFixturesPath, file); if (num === 3) { return assert.throws(function () { diff --git a/test/unit/winston/transports/file-create-dir-test.js b/test/unit/winston/transports/file-create-dir.test.js similarity index 93% rename from test/unit/winston/transports/file-create-dir-test.js rename to test/unit/winston/transports/file-create-dir.test.js index eecde1eb7..2d271517a 100644 --- a/test/unit/winston/transports/file-create-dir-test.js +++ b/test/unit/winston/transports/file-create-dir.test.js @@ -8,7 +8,7 @@ const winston = require('../../../../lib/winston'); /* eslint-disable no-sync */ describe('winston/transports/file/createLogDir', function () { - const logDir = path.resolve(__dirname, '../fixtures/temp_logs'); + const logDir = path.resolve(__dirname, '../../../fixtures/temp_logs'); beforeEach(function () { fs.rmdirSync(logDir); diff --git a/test/unit/winston/transports/file-maxfiles-test.js b/test/unit/winston/transports/file-maxfiles.test.js similarity index 84% rename from test/unit/winston/transports/file-maxfiles-test.js rename to test/unit/winston/transports/file-maxfiles.test.js index 7d37ecdd5..943549e80 100644 --- a/test/unit/winston/transports/file-maxfiles-test.js +++ b/test/unit/winston/transports/file-maxfiles.test.js @@ -1,5 +1,5 @@ /* - * file-maxfiles-test.js: Tests for instances of the File transport setting the max file size, + * file-maxfiles.test.js: Tests for instances of the File transport setting the max file size, * and setting a number for max files created. * maxSize * maxFiles = total storage used by winston. * @@ -15,11 +15,12 @@ var assert = require('assert'), vows = require('vows'), winston = require('../../../../lib/winston'), helpers = require('../../../helpers'); +const testLogFixturesPath = path.join(__dirname, '..', '..', '..', 'fixtures', 'logs'); var maxfilesTransport = new winston.transports.File({ timestamp: false, json: false, - filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles.log'), + filename: path.join(testLogFixturesPath, 'testmaxfiles.log'), maxsize: 4096, maxFiles: 3 }); @@ -34,7 +35,7 @@ vows.describe('winston/transports/file/maxfiles').addBatch({ }, "when delete old test files": { topic: function () { - exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles*'), this.callback); + exec('rm -rf ' + path.join(testLogFixturesPath, 'testmaxfiles*'), this.callback); }, "and when passed more files than the maxFiles": { topic: function () { @@ -69,7 +70,7 @@ vows.describe('winston/transports/file/maxfiles').addBatch({ "should be only 3 files called 5.log, 4.log and 3.log": function () { for (var num = 0; num < 6; num++) { var file = !num ? 'testmaxfiles.log' : 'testmaxfiles' + num + '.log', - fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + fullpath = path.join(testLogFixturesPath, file); // There should be no files with that name if (num >= 0 && num < 3) { @@ -87,8 +88,7 @@ vows.describe('winston/transports/file/maxfiles').addBatch({ "should have the correct content": function () { ['D', 'E', 'F'].forEach(function (name, inx) { var counter = inx + 3, - logsDir = path.join(__dirname, '..', 'fixtures', 'logs'), - content = fs.readFileSync(path.join(logsDir, 'testmaxfiles' + counter + '.log'), 'utf-8'); + content = fs.readFileSync(path.join(testLogFixturesPath, 'testmaxfiles' + counter + '.log'), 'utf-8'); // The content minus the 7 characters added by winston assert.lengthOf(content.match(new RegExp(name, 'g')), 4068); }); diff --git a/test/unit/winston/transports/file-tailrolling.test.js b/test/unit/winston/transports/file-tailrolling.test.js index 25e88a814..503a8efb6 100644 --- a/test/unit/winston/transports/file-tailrolling.test.js +++ b/test/unit/winston/transports/file-tailrolling.test.js @@ -4,6 +4,7 @@ const rimraf = require('rimraf'); const fs = require('fs'); const path = require('path'); const winston = require('../../../../lib/winston'); +const testLogFixturesPath = path.join(__dirname, '..', '..', '..', 'fixtures', 'logs'); const { MESSAGE } = require('triple-beam'); @@ -11,7 +12,7 @@ const { MESSAGE } = require('triple-beam'); // Remove all log fixtures // function removeFixtures(done) { - rimraf(path.join(__dirname, '..', 'fixtures', 'logs', 'testtailrollingfiles*'), done); + rimraf(path.join(testLogFixturesPath, 'testtailrollingfiles*'), done); } @@ -27,7 +28,7 @@ describe('winston/transports/file/tailrolling', function () { tailrollTransport = new winston.transports.File({ timestamp: false, json: false, - filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testtailrollingfiles.log'), + filename: path.join(testLogFixturesPath, 'testtailrollingfiles.log'), maxsize: 4096, maxFiles: 3, tailable: true @@ -68,7 +69,7 @@ describe('winston/transports/file/tailrolling', function () { it('should be 3 log files, base to maxFiles - 1', function () { for (var num = 0; num < 4; num++) { const file = !num ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + num + '.log'; - const fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + const fullpath = path.join(testLogFixturesPath, file); if (num === 3) { return assert.ok(!fs.existsSync(fullpath)); @@ -83,7 +84,7 @@ describe('winston/transports/file/tailrolling', function () { it('should have files in correct order', function () { ['D', 'C', 'B'].forEach(function (letter, i) { const file = !i ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + i + '.log'; - let content = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'logs', file), 'ascii'); + let content = fs.readFileSync(path.join(testLogFixturesPath, file), 'ascii'); content = content.replace(/\s+/g, ''); assert(content.match(new RegExp(letter, 'g'))[0].length, content.length); diff --git a/test/unit/winston/transports/file.test.js b/test/unit/winston/transports/file.test.js index 18838bc64..94e5a0d03 100644 --- a/test/unit/winston/transports/file.test.js +++ b/test/unit/winston/transports/file.test.js @@ -7,6 +7,7 @@ const fs = require('fs'); const { MESSAGE } = require('triple-beam'); const split = require('split2'); const assume = require('assume'); +const testFileFixturesPath = path.join(__dirname, '..', '..', '..', 'fixtures', 'file'); function noop() {}; @@ -14,7 +15,7 @@ describe('File({ filename })', function () { this.timeout(10 * 1000); it('should write to the file when logged to with expected object', function (done) { - var filename = path.join(__dirname, '..', 'fixtures', 'file', 'simple.log'); + var filename = path.join(testFileFixturesPath, 'simple.log'); var transport = new winston.transports.File({ filename: filename }); @@ -96,7 +97,7 @@ describe('File({ filename })', function () { describe('File({ stream })', function () { it('should display the deprecation notice'); it('should write to the stream when logged to with expected object', function (done) { - var streamfile = path.join(__dirname, '..', 'fixtures', 'file', 'simple-stream.log'); + var streamfile = path.join(testFileFixturesPath, 'simple-stream.log'); var stream = fs.createWriteStream(streamfile); var streamTransport = new winston.transports.File({ stream: stream @@ -113,7 +114,7 @@ require('abstract-winston-transport')({ name: 'File', Transport: winston.transports.File, construct: { - filename: path.join(__dirname, '..', 'fixtures', 'file', 'abstract.log') + filename: path.join(testFileFixturesPath, 'abstract.log') }, after(opts, done) { const abstractFile = opts.construct.filename; From 4495caa198a1f2d9939194eeb8a5cb0c61091c4b Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 12:16:01 -0700 Subject: [PATCH 08/39] make sure all tests actually run --- .github/workflows/ci.yml | 2 ++ package.json | 6 +++--- test/unit/winston/transports/00-file-stress.test.js | 8 ++++---- test/unit/winston/transports/01-file-maxsize.test.js | 2 +- test/unit/winston/transports/console.test.js | 1 + test/unit/winston/transports/file-create-dir.test.js | 2 +- test/unit/winston/transports/file-maxfiles.test.js | 3 +++ test/unit/winston/transports/file.test.js | 2 +- test/unit/winston/transports/stream.test.js | 2 +- 9 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7099eeca4..a1d5ff177 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,8 @@ jobs: run: npm run lint - name: Test Coverage run: npm test:coverage + - name: Integration Tests + run: npm test:integration - name: Coveralls if: matrix.node == '16' uses: coverallsapp/github-action@master diff --git a/package.json b/package.json index 5af09efe2..a420ee286 100644 --- a/package.json +++ b/package.json @@ -60,10 +60,10 @@ "scripts": { "lint": "populist lib/*.js lib/winston/*.js lib/winston/**/*.js", "pretest": "npm run lint", - "test": "mocha test/unit/**/*.test.js test/integration/**/*.test.js --exit", + "test": "mocha './test/**/*.test.js' --recursive --exit", "test:coverage": "nyc --reporter=text --reporter lcov npm run test:unit", - "test:unit": "mocha test/unit/**/*.test.js --exit", - "test:integration": "mocha test/integration/**/*.test.js --exit", + "test:unit": "mocha './test/unit/**/*.test.js' --recursive --exit", + "test:integration": "mocha './test/integration/**/*.test.js' --recursive --exit", "build": "rimraf dist && babel lib -d dist", "prepublishOnly": "npm run build" }, diff --git a/test/unit/winston/transports/00-file-stress.test.js b/test/unit/winston/transports/00-file-stress.test.js index ec1af5e16..55cae623d 100644 --- a/test/unit/winston/transports/00-file-stress.test.js +++ b/test/unit/winston/transports/00-file-stress.test.js @@ -22,7 +22,7 @@ describe('File (stress)', function () { const fileStressLogFile = path.resolve(__dirname, '../../../fixtures/logs/file-stress-test.log'); beforeEach(function () { try { - fs.unlinkSync(logPath); + fs.unlinkSync(fileStressLogFile); } catch (ex) { if (ex && ex.code !== 'ENOENT') { return done(ex); } } @@ -47,7 +47,7 @@ describe('File (stress)', function () { setTimeout(function () { clearInterval(interval); - helpers.tryRead(logPath) + helpers.tryRead(fileStressLogFile) .on('error', function (err) { assume(err).false(); logger.close(); @@ -90,7 +90,7 @@ describe('File (stress)', function () { setTimeout(function () { clearInterval(interval); - helpers.tryRead(logPath) + helpers.tryRead(fileStressLogFile) .on('error', function (err) { assume(err).false(); logger.close(); @@ -130,7 +130,7 @@ describe('File (stress)', function () { msgs.forEach(msg => logger.info(msg)); setTimeout(function () { - helpers.tryRead(logPath) + helpers.tryRead(fileStressLogFile) .on('error', function (err) { assume(err).false(); logger.close(); diff --git a/test/unit/winston/transports/01-file-maxsize.test.js b/test/unit/winston/transports/01-file-maxsize.test.js index 2edfa17bb..01ca88076 100644 --- a/test/unit/winston/transports/01-file-maxsize.test.js +++ b/test/unit/winston/transports/01-file-maxsize.test.js @@ -9,7 +9,7 @@ const rimraf = require('rimraf'); const fs = require('fs'); const path = require('path'); const assume = require('assume'); -const winston = require('../../../../index'); +const winston = require('../../../../lib/winston'); const testLogFixturesPath = path.join(__dirname, '..', '..', '..', 'fixtures', 'logs'); const MESSAGE = Symbol.for('message'); diff --git a/test/unit/winston/transports/console.test.js b/test/unit/winston/transports/console.test.js index c25bae9af..b6f4aeed5 100644 --- a/test/unit/winston/transports/console.test.js +++ b/test/unit/winston/transports/console.test.js @@ -139,6 +139,7 @@ require('abstract-winston-transport')({ Transport: winston.transports.Console }); +// TODO(invalid-test): test is no longer valid as we don't have the vows dependency anymore // vows.describe('winston/transports/console').addBatch({ // "An instance of the Console Transport": { // "with syslog levels": { diff --git a/test/unit/winston/transports/file-create-dir.test.js b/test/unit/winston/transports/file-create-dir.test.js index 2d271517a..3abfa2f9f 100644 --- a/test/unit/winston/transports/file-create-dir.test.js +++ b/test/unit/winston/transports/file-create-dir.test.js @@ -11,7 +11,7 @@ describe('winston/transports/file/createLogDir', function () { const logDir = path.resolve(__dirname, '../../../fixtures/temp_logs'); beforeEach(function () { - fs.rmdirSync(logDir); + fs.rmSync(logDir, {recursive: true, force: true}) }); it('should create directory if it does not exist', function () { diff --git a/test/unit/winston/transports/file-maxfiles.test.js b/test/unit/winston/transports/file-maxfiles.test.js index 943549e80..45583b400 100644 --- a/test/unit/winston/transports/file-maxfiles.test.js +++ b/test/unit/winston/transports/file-maxfiles.test.js @@ -8,6 +8,8 @@ * */ +/* + TODO(invalid-test): test is no longer valid as we don't have the vows dependency anymore var assert = require('assert'), exec = require('child_process').exec, fs = require('fs'), @@ -97,3 +99,4 @@ vows.describe('winston/transports/file/maxfiles').addBatch({ } } }).export(module); +*/ \ No newline at end of file diff --git a/test/unit/winston/transports/file.test.js b/test/unit/winston/transports/file.test.js index 94e5a0d03..7d892f33e 100644 --- a/test/unit/winston/transports/file.test.js +++ b/test/unit/winston/transports/file.test.js @@ -1,7 +1,7 @@ 'use strict'; const path = require('path'); -const winston = require('../../../../index'); +const winston = require('../../../../lib/winston'); const helpers = require('../../../helpers'); const fs = require('fs'); const { MESSAGE } = require('triple-beam'); diff --git a/test/unit/winston/transports/stream.test.js b/test/unit/winston/transports/stream.test.js index b21de661d..6f75d5cdd 100644 --- a/test/unit/winston/transports/stream.test.js +++ b/test/unit/winston/transports/stream.test.js @@ -4,7 +4,7 @@ const path = require('path'); const writeable = require('../../../helpers').writeable; const { MESSAGE } = require('triple-beam'); const os = require('os'); -const winston = require('../../../../index'); +const winston = require('../../../../lib/winston'); const split = require('split2'); const assume = require('assume'); From f951b9a460353335cd48fcfe9d22138498a59151 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 13:00:22 -0700 Subject: [PATCH 09/39] feat: add nyc configuration file --- .nycrc | 7 +++++++ test/unit/winston/create-logger.test.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .nycrc diff --git a/.nycrc b/.nycrc new file mode 100644 index 000000000..60501d066 --- /dev/null +++ b/.nycrc @@ -0,0 +1,7 @@ +{ + "check-coverage": true, + "branches": 61.51, + "lines": 70.85, + "functions": 73.21, + "statements": 70.54 +} \ No newline at end of file diff --git a/test/unit/winston/create-logger.test.js b/test/unit/winston/create-logger.test.js index b4e0c44b7..080e131ff 100644 --- a/test/unit/winston/create-logger.test.js +++ b/test/unit/winston/create-logger.test.js @@ -104,4 +104,4 @@ describe('Create Logger', function () { extendedLogger.info('test3'); extendedLogger.warn('a warning', {with: 'meta', test: 4}); }); -}); \ No newline at end of file +}); From 6ba9967108383d8215507a43e623a4d92222a3c9 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 13:12:12 -0700 Subject: [PATCH 10/39] chore: fix missing end of file newlines --- .nycrc | 2 +- test/unit/winston/transports/file-maxfiles.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.nycrc b/.nycrc index 60501d066..a59b639ff 100644 --- a/.nycrc +++ b/.nycrc @@ -4,4 +4,4 @@ "lines": 70.85, "functions": 73.21, "statements": 70.54 -} \ No newline at end of file +} diff --git a/test/unit/winston/transports/file-maxfiles.test.js b/test/unit/winston/transports/file-maxfiles.test.js index 45583b400..4422aad91 100644 --- a/test/unit/winston/transports/file-maxfiles.test.js +++ b/test/unit/winston/transports/file-maxfiles.test.js @@ -99,4 +99,4 @@ vows.describe('winston/transports/file/maxfiles').addBatch({ } } }).export(module); -*/ \ No newline at end of file +*/ From fd14dfe1044aea51d5928da4c366d76cf472f2ca Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 13:23:56 -0700 Subject: [PATCH 11/39] fix: ci steps --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1d5ff177..1f84bbe2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,9 +29,9 @@ jobs: - name: Lint run: npm run lint - name: Test Coverage - run: npm test:coverage + run: npm run test:coverage - name: Integration Tests - run: npm test:integration + run: npm run test:integration - name: Coveralls if: matrix.node == '16' uses: coverallsapp/github-action@master From 70fa7547233df121797e9a63ed931fb8ae7901fa Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 14:44:24 -0700 Subject: [PATCH 12/39] fix: ci steps try 2 --- .github/workflows/ci.yml | 6 +++--- package.json | 3 +-- test/unit/winston/transports/file-create-dir.test.js | 8 +++++++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f84bbe2a..74aeb68d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,11 +28,11 @@ jobs: run: npm clean-install - name: Lint run: npm run lint - - name: Test Coverage - run: npm run test:coverage - name: Integration Tests run: npm run test:integration - - name: Coveralls + - name: Test Coverage + run: npm run test:coverage + - name: Report test coverage to Coveralls.io if: matrix.node == '16' uses: coverallsapp/github-action@master with: diff --git a/package.json b/package.json index a420ee286..b500879c5 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "types": "./index.d.ts", "scripts": { "lint": "populist lib/*.js lib/winston/*.js lib/winston/**/*.js", - "pretest": "npm run lint", "test": "mocha './test/**/*.test.js' --recursive --exit", "test:coverage": "nyc --reporter=text --reporter lcov npm run test:unit", "test:unit": "mocha './test/unit/**/*.test.js' --recursive --exit", @@ -68,7 +67,7 @@ "prepublishOnly": "npm run build" }, "engines": { - "node": ">= 6.4.0" + "node": ">= 12.0.0" }, "license": "MIT" } diff --git a/test/unit/winston/transports/file-create-dir.test.js b/test/unit/winston/transports/file-create-dir.test.js index 3abfa2f9f..b13efc1ec 100644 --- a/test/unit/winston/transports/file-create-dir.test.js +++ b/test/unit/winston/transports/file-create-dir.test.js @@ -4,6 +4,7 @@ const fs = require('fs'); const assert = require('assert'); const path = require('path'); const winston = require('../../../../lib/winston'); +const rimraf = require("rimraf"); /* eslint-disable no-sync */ @@ -11,7 +12,12 @@ describe('winston/transports/file/createLogDir', function () { const logDir = path.resolve(__dirname, '../../../fixtures/temp_logs'); beforeEach(function () { - fs.rmSync(logDir, {recursive: true, force: true}) + rimraf(logDir, (err) => { + if (err){ + console.log('Error encountered when removing `temp_logs` dir') + console.log(err); + } + }) }); it('should create directory if it does not exist', function () { From e18e1bb09cd48841c7a2ef787a01afa255e3d901 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 14:46:05 -0700 Subject: [PATCH 13/39] chore: rename ci jobs --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74aeb68d5..5e844568e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: CI +name: CI Checks on: pull_request: @@ -11,7 +11,7 @@ on: - master jobs: - unit-tests: + Tests: runs-on: ubuntu-latest strategy: matrix: From 692de0dd399027caf4f4793bb1f89217f67432fc Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 19:36:54 -0700 Subject: [PATCH 14/39] chore: leverage yaml file for nyc configuration --- .nycrc | 7 ------- .nycrc.yml | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) delete mode 100644 .nycrc create mode 100644 .nycrc.yml diff --git a/.nycrc b/.nycrc deleted file mode 100644 index a59b639ff..000000000 --- a/.nycrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "check-coverage": true, - "branches": 61.51, - "lines": 70.85, - "functions": 73.21, - "statements": 70.54 -} diff --git a/.nycrc.yml b/.nycrc.yml new file mode 100644 index 000000000..e733219c7 --- /dev/null +++ b/.nycrc.yml @@ -0,0 +1,5 @@ +check-coverage: true +branches: 61.51 +lines: 70.85 +functions: 73.21 +statements: 70.54 From dc005b7deb9595be84ae3085f710c4c1cd2641fb Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 19:52:47 -0700 Subject: [PATCH 15/39] chore: move nyc configuration from npm script to associated configuration file --- .nycrc.yml | 5 ++++- package.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.nycrc.yml b/.nycrc.yml index e733219c7..ce121842b 100644 --- a/.nycrc.yml +++ b/.nycrc.yml @@ -1,5 +1,8 @@ +reporter: + - text + - lcov check-coverage: true branches: 61.51 lines: 70.85 functions: 73.21 -statements: 70.54 +statements: 70.54 \ No newline at end of file diff --git a/package.json b/package.json index b500879c5..8fa389097 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "scripts": { "lint": "populist lib/*.js lib/winston/*.js lib/winston/**/*.js", "test": "mocha './test/**/*.test.js' --recursive --exit", - "test:coverage": "nyc --reporter=text --reporter lcov npm run test:unit", + "test:coverage": "nyc npm run test:unit", "test:unit": "mocha './test/unit/**/*.test.js' --recursive --exit", "test:integration": "mocha './test/integration/**/*.test.js' --recursive --exit", "build": "rimraf dist && babel lib -d dist", From f2ee50a6d0545f2e0fe5c9c3102367a7369d4878 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 20:00:11 -0700 Subject: [PATCH 16/39] chore: move common mocha configurations from npm script to dedicated configuration --- .mocharc.yml | 2 ++ package.json | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 .mocharc.yml diff --git a/.mocharc.yml b/.mocharc.yml new file mode 100644 index 000000000..080d59c6f --- /dev/null +++ b/.mocharc.yml @@ -0,0 +1,2 @@ +recursive: true +exit: true \ No newline at end of file diff --git a/package.json b/package.json index 8fa389097..344c48c16 100644 --- a/package.json +++ b/package.json @@ -59,10 +59,10 @@ "types": "./index.d.ts", "scripts": { "lint": "populist lib/*.js lib/winston/*.js lib/winston/**/*.js", - "test": "mocha './test/**/*.test.js' --recursive --exit", + "test": "mocha './test/**/*.test.js'", "test:coverage": "nyc npm run test:unit", - "test:unit": "mocha './test/unit/**/*.test.js' --recursive --exit", - "test:integration": "mocha './test/integration/**/*.test.js' --recursive --exit", + "test:unit": "mocha './test/unit/**/*.test.js'", + "test:integration": "mocha './test/integration/**/*.test.js'", "build": "rimraf dist && babel lib -d dist", "prepublishOnly": "npm run build" }, From 85ea8a610a9b4428c525663ea6e29d9e5fb431fd Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 20:03:15 -0700 Subject: [PATCH 17/39] feat: introduce a in-memory mock transport generator --- test/helpers/mocks/mock-transport.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/test/helpers/mocks/mock-transport.js b/test/helpers/mocks/mock-transport.js index 5522143a9..5e67f7207 100644 --- a/test/helpers/mocks/mock-transport.js +++ b/test/helpers/mocks/mock-transport.js @@ -1,9 +1,11 @@ const stream = require('stream') const winston = require('../../../lib/winston'); +const {Writable} = require("stream"); +const {output} = require("./legacy-transport"); /** * Returns a new Winston transport instance which will invoke - * the `write` method on each call to `.log` + * the `write` method on each call to `.log` * * @param {function} write Write function for the specified stream * @returns {StreamTransportInstance} A transport instance @@ -17,6 +19,23 @@ function createMockTransport(write) { return new winston.transports.Stream({ stream: writeable }) } +/** + * Returns a valid Winston transport that writes to the passed array object + * @param array Array to be used to store the "written" chunks + * @returns {winston.transports.Stream} + */ +function inMemory(array) { + const memoryStream = new Writable({ + objectMode: true, + write: (chunk, encoding, next) => { + array.push(chunk); + next() + } + }); + return new winston.transports.Stream({stream: memoryStream}) +} + module.exports = { - createMockTransport + createMockTransport, + inMemory }; From b233a8b62c6c68fad4c4478df2ca3c6ca5b6d7d3 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 20:09:48 -0700 Subject: [PATCH 18/39] chore: make test callback functions consistent --- test/unit/winston/logger.test.js | 140 +++++++++++++++---------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 83504f594..460cd64bf 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -23,9 +23,9 @@ const helpers = require('../../helpers'); const mockTransport = require('../../helpers/mocks/mock-transport'); const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); -describe('Logger Instance', function () { - describe('Configuration', function () { - it('.configure()', function () { +describe('Logger Instance', () => { + describe('Configuration', () => { + it('.configure()', () => { let logger = winston.createLogger({ transports: [new winston.transports.Console()] }); @@ -38,7 +38,7 @@ describe('Logger Instance', function () { assume(logger.transports.length).equals(0); }); - it('.configure({ transports })', function () { + it('.configure({ transports })', () => { let logger = winston.createLogger(); assume(logger.transports.length).equals(0); @@ -51,7 +51,7 @@ describe('Logger Instance', function () { assume(logger.transports[0].name).equals('console'); }); - it('.configure({ transports, format })', function () { + it('.configure({ transports, format })', () => { let logger = winston.createLogger(), format = logger.format; @@ -68,16 +68,16 @@ describe('Logger Instance', function () { }); }); - describe('Transports', function() { - describe('add', function () { - it('should throw error when adding an invalid transport', function () { + describe('Transports', () => { + describe('add', () => { + it('should throw error when adding an invalid transport', () => { let logger = winston.createLogger(); - assume(function () { + assume(() => { logger.add(5); }).throws(/invalid transport/i); }); - it('should add the expected transport', function (done) { + it('should add the expected transport', (done) => { let logger = winston.createLogger(); let expected = {message: 'foo', level: 'info'}; let transport = new TransportStream({ @@ -93,7 +93,7 @@ describe('Logger Instance', function () { logger.log(expected); }); - it('should allow adding multiple transports', function () { + it('should allow adding multiple transports', () => { let transports = [ new winston.transports.File({ name: 'filelog-info.log', @@ -117,8 +117,8 @@ describe('Logger Instance', function () { }); }); - describe('remove', function () { - it('should do nothing if transport was not added', function () { + describe('remove', () => { + it('should do nothing if transport was not added', () => { let transports = [ new winston.transports.Console(), new winston.transports.File({filename: path.join(testLogFixturesPath, 'filelog.log')}) @@ -134,7 +134,7 @@ describe('Logger Instance', function () { })).deep.equals(transports); }); - it('should remove transport when matching one is found', function () { + it('should remove transport when matching one is found', () => { let transports = [ new winston.transports.Console(), new winston.transports.File({filename: path.join(testLogFixturesPath, 'filelog.log')}) @@ -148,7 +148,7 @@ describe('Logger Instance', function () { assume(logger.transports[0]).equals(transports[1]); }); - it('should remove specified logger even when duplicate exists', function () { + it('should remove specified logger even when duplicate exists', () => { let transports = [ new winston.transports.File({ name: 'filelog-info.log', @@ -171,15 +171,15 @@ describe('Logger Instance', function () { }); }); - describe('clear', function () { - it('should do nothing when no transports exist', function () { + describe('clear', () => { + it('should do nothing when no transports exist', () => { let logger = winston.createLogger(); assume(logger.transports.length).equals(0); logger.clear(); assume(logger.transports.length).equals(0); }); - it('should remove all transports', function () { + it('should remove all transports', () => { let logger = winston.createLogger({ transports: [new winston.transports.Console()] }); @@ -190,8 +190,8 @@ describe('Logger Instance', function () { }); }); - describe('stream', function () { - it('should return a log stream for all transports', function () { + describe('stream', () => { + it('should return a log stream for all transports', () => { let logger = winston.createLogger(); let outStream = logger.stream(); @@ -200,8 +200,8 @@ describe('Logger Instance', function () { }); }); - describe('Log Levels', function () { - it('report unknown levels', function (done) { + describe('Log Levels', () => { + it('report unknown levels', (done) => { stdMocks.use(); let logger = helpers.createLogger(function (info) { }); @@ -215,7 +215,7 @@ describe('Logger Instance', function () { done(); }); - it('.()', function (done) { + it('.()', (done) => { let logger = helpers.createLogger(function (info) { assume(info).is.an('object'); assume(info.level).equals('info'); @@ -234,7 +234,7 @@ describe('Logger Instance', function () { logger.info(''); }); - it('default levels', function (done) { + it('default levels', (done) => { let logger = winston.createLogger(); let expected = {message: 'foo', level: 'debug'}; @@ -263,7 +263,7 @@ describe('Logger Instance', function () { .log(expected); }); - it('custom levels', function (done) { + it('custom levels', (done) => { let logger = winston.createLogger({ levels: { bad: 0, @@ -300,7 +300,7 @@ describe('Logger Instance', function () { .log(expected); }); - it('sets transports levels', done => { + it('sets transports levels', (done) => { let logger; const transport = new TransportStream({ log(obj) { @@ -338,8 +338,8 @@ describe('Logger Instance', function () { }); }); - describe('Log Levels Enabled', function () { - it('default levels', function () { + describe('Log Levels Enabled', () => { + it('default levels', () => { let logger = winston.createLogger({ level: 'verbose', levels: winston.config.npm.levels, @@ -370,7 +370,7 @@ describe('Logger Instance', function () { assume(logger.isSillyEnabled()).false(); }); - it('default levels, transport override', function () { + it('default levels, transport override', () => { let transport = new winston.transports.Console(); transport.level = 'debug'; @@ -404,7 +404,7 @@ describe('Logger Instance', function () { assume(logger.isSillyEnabled()).false(); }); - it('default levels, no transports', function () { + it('default levels, no transports', () => { let logger = winston.createLogger({ level: 'verbose', levels: winston.config.npm.levels, @@ -435,7 +435,7 @@ describe('Logger Instance', function () { assume(logger.isSillyEnabled()).false(); }); - it('custom levels', function () { + it('custom levels', () => { let logger = winston.createLogger({ level: 'test', levels: { @@ -461,7 +461,7 @@ describe('Logger Instance', function () { assume(logger.isOkEnabled()).false(); }); - it('custom levels, no transports', function () { + it('custom levels, no transports', () => { let logger = winston.createLogger({ level: 'test', levels: { @@ -487,7 +487,7 @@ describe('Logger Instance', function () { assume(logger.isOkEnabled()).false(); }); - it('custom levels, transport override', function () { + it('custom levels, transport override', () => { let transport = new winston.transports.Console(); transport.level = 'ok'; @@ -518,19 +518,19 @@ describe('Logger Instance', function () { }) }); - describe('Transport Events', function () { - it(`'finish' event awaits transports to emit 'finish'`, function (done) { + describe('Transport Events', () => { + it(`'finish' event awaits transports to emit 'finish'`, (done) => { const transports = [ new TransportStream({ - log: function () { + log: () => { } }), new TransportStream({ - log: function () { + log: () => { } }), new TransportStream({ - log: function () { + log: () => { } }) ]; @@ -549,7 +549,7 @@ describe('Logger Instance', function () { // Assert that all transport 'finish' events have been // emitted when the logger emits 'finish'. - logger.on('finish', function () { + logger.on('finish', () => { assume(finished[0]).true(); assume(finished[1]).true(); assume(finished[2]).true(); @@ -588,8 +588,8 @@ describe('Logger Instance', function () { }); }) - describe('Formats', function () { - it(`rethrows errors from user-defined formats`, function () { + describe('Formats', () => { + it(`rethrows errors from user-defined formats`, () => { stdMocks.use(); const logger = winston.createLogger({ transports: [new winston.transports.Console()], @@ -625,8 +625,8 @@ describe('Logger Instance', function () { }); }) - describe('Profiling', function () { - it('ending profiler with object argument should be included in output', function (done) { + describe('Profiling', () => { + it('ending profiler with object argument should be included in output', (done) => { let logger = helpers.createLogger(function (info) { assume(info).is.an('object'); assume(info.something).equals('ok'); @@ -638,7 +638,7 @@ describe('Logger Instance', function () { }); logger.profile('testing1'); - setTimeout(function () { + setTimeout(() => { logger.profile('testing1', { something: 'ok', level: 'info' @@ -647,7 +647,7 @@ describe('Logger Instance', function () { }); // TODO: Revisit if this is a valid test - it('calling profile with a callback function should not make a difference', function (done) { + it('calling profile with a callback function should not make a difference', (done) => { let logger = helpers.createLogger(function (info) { assume(info).is.an('object'); assume(info.something).equals('ok'); @@ -658,11 +658,11 @@ describe('Logger Instance', function () { done(); }); - logger.profile('testing2', function () { + logger.profile('testing2', () => { done(new Error('Unexpected callback invoked')); }); - setTimeout(function () { + setTimeout(() => { logger.profile('testing2', { something: 'ok', level: 'info' @@ -670,7 +670,7 @@ describe('Logger Instance', function () { }, 100); }); - it('should stop a timer when `done` is called on it', function (done) { + it('should stop a timer when `done` is called on it', (done) => { let logger = helpers.createLogger(function (info) { assume(info).is.an('object'); assume(info.something).equals('ok'); @@ -682,7 +682,7 @@ describe('Logger Instance', function () { }); let timer = logger.startTimer(); - setTimeout(function () { + setTimeout(() => { timer.done({ message: 'testing1', something: 'ok', @@ -693,9 +693,9 @@ describe('Logger Instance', function () { }); // TODO: Revisit to improve these - describe('Logging non-primitive data types', function () { - describe('.log', function () { - it(`.log(new Error()) uses Error instance as info`, function (done) { + describe('Logging non-primitive data types', () => { + describe('.log', () => { + it(`.log(new Error()) uses Error instance as info`, (done) => { const err = new Error('test'); err.level = 'info'; @@ -708,7 +708,7 @@ describe('Logger Instance', function () { logger.log(err); }); - it(`.info('Hello') preserve meta without splat format`, function (done) { + it(`.info('Hello') preserve meta without splat format`, (done) => { const logged = []; const logger = helpers.createLogger(function (info, enc, next) { logged.push(info); @@ -721,7 +721,7 @@ describe('Logger Instance', function () { logger.info('Hello', {label: 'world'}); }); - it(`.info('Hello %d') does not mutate unnecessarily with string interpolation tokens`, function (done) { + it(`.info('Hello %d') does not mutate unnecessarily with string interpolation tokens`, (done) => { const logged = []; const logger = helpers.createLogger(function (info, enc, next) { logged.push(info); @@ -734,7 +734,7 @@ describe('Logger Instance', function () { logger.info('Hello %j', {label: 'world'}, {extra: true}); }); - it(`.info('Hello') and .info('Hello %d') preserve meta with splat format`, function (done) { + it(`.info('Hello') and .info('Hello %d') preserve meta with splat format`, (done) => { const logged = []; const logger = helpers.createLogger(function (info, enc, next) { logged.push(info); @@ -749,8 +749,8 @@ describe('Logger Instance', function () { }); }); - describe('.info', function () { - it('.info(undefined) creates info with { message: undefined }', function (done) { + describe('.info', () => { + it('.info(undefined) creates info with { message: undefined }', (done) => { const logger = helpers.createLogger(function (info) { assume(info.message).equals(undefined); done(); @@ -759,7 +759,7 @@ describe('Logger Instance', function () { logger.info(undefined); }); - it('.info(null) creates info with { message: null }', function (done) { + it('.info(null) creates info with { message: null }', (done) => { const logger = helpers.createLogger(function (info) { assume(info.message).equals(null); done(); @@ -768,7 +768,7 @@ describe('Logger Instance', function () { logger.info(null); }); - it('.info(new Error()) uses Error instance as info', function (done) { + it('.info(new Error()) uses Error instance as info', (done) => { const err = new Error('test'); const logger = helpers.createLogger(function (info) { assume(info).instanceOf(Error); @@ -780,7 +780,7 @@ describe('Logger Instance', function () { }); // TODO: This test needs finished or removed - it.skip(`.info('any string', new Error())`, function (done) { + it.skip(`.info('any string', new Error())`, (done) => { const err = new Error('test'); const logger = helpers.createLogger(function (info) { done(); @@ -791,7 +791,7 @@ describe('Logger Instance', function () { }); }); - describe('Metadata Precedence', function () { + describe('Metadata Precedence', () => { describe('Should support child loggers & defaultMeta', () => { it('sets child meta for text messages correctly', (done) => { const assertFn = ((msg) => { @@ -923,9 +923,9 @@ describe('Logger Instance', function () { }); }); - describe('Backwards Compatability', function () { - describe('Winston V2 Log', function () { - it('.log(level, message)', function (done) { + describe('Backwards Compatability', () => { + describe('Winston V2 Log', () => { + it('.log(level, message)', (done) => { let logger = helpers.createLogger(function (info) { assume(info).is.an('object'); assume(info.level).equals('info'); @@ -937,7 +937,7 @@ describe('Logger Instance', function () { logger.log('info', 'Some super awesome log message') }); - it(`.log(level, undefined) creates info with { message: undefined }`, function (done) { + it(`.log(level, undefined) creates info with { message: undefined }`, (done) => { const logger = helpers.createLogger(function (info) { assume(info.message).equals(undefined); done(); @@ -946,7 +946,7 @@ describe('Logger Instance', function () { logger.log('info', undefined); }); - it(`.log(level, null) creates info with { message: null }`, function (done) { + it(`.log(level, null) creates info with { message: null }`, (done) => { const logger = helpers.createLogger(function (info) { assume(info.message).equals(null); done(); @@ -955,7 +955,7 @@ describe('Logger Instance', function () { logger.log('info', null); }); - it(`.log(level, new Error()) uses Error instance as info`, function (done) { + it(`.log(level, new Error()) uses Error instance as info`, (done) => { const err = new Error('test'); const logger = helpers.createLogger(function (info) { assume(info).instanceOf(Error); @@ -966,7 +966,7 @@ describe('Logger Instance', function () { logger.log('info', err); }); - it('.log(level, message, meta)', function (done) { + it('.log(level, message, meta)', (done) => { let meta = {one: 2}; let logger = helpers.createLogger(function (info) { assume(info).is.an('object'); @@ -980,7 +980,7 @@ describe('Logger Instance', function () { logger.log('info', 'Some super awesome log message', meta); }); - it('.log(level, formatStr, ...splat)', function (done) { + it('.log(level, formatStr, ...splat)', (done) => { const format = winston.format.combine( winston.format.splat(), winston.format.printf(info => `${info.level}: ${info.message}`) @@ -998,7 +998,7 @@ describe('Logger Instance', function () { logger.log('info', '%d%% such %s %j', 100, 'wow', {much: 'javascript'}); }); - it('.log(level, formatStr, ...splat, meta)', function (done) { + it('.log(level, formatStr, ...splat, meta)', (done) => { const format = winston.format.combine( winston.format.splat(), winston.format.printf(info => `${info.level}: ${info.message} ${JSON.stringify({thisIsMeta: info.thisIsMeta})}`) From ce2f607da44d22e3884da3019328e5ce0b3dfb39 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 20:38:35 -0700 Subject: [PATCH 19/39] feat: introduce tests proving issues with metadata precedence --- test/unit/winston/logger.test.js | 424 ++++++++++++++++++++++++------- 1 file changed, 337 insertions(+), 87 deletions(-) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 460cd64bf..e62aae2c5 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -20,7 +20,7 @@ const winston = require('../../../lib/winston'); const TransportStream = require('winston-transport'); const format = require('../../../lib/winston').format; const helpers = require('../../helpers'); -const mockTransport = require('../../helpers/mocks/mock-transport'); +const mockTransports = require('../../helpers/mocks/mock-transport'); const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); describe('Logger Instance', () => { @@ -791,136 +791,386 @@ describe('Logger Instance', () => { }); }); + describe('Children', () => { + it('handles error stack traces in child loggers correctly', (done) => { + const assertFn = ((msg) => { + assume(msg.level).equals('error'); + assume(msg.message).equals('dummy error'); + assume(msg.stack).includes('logger.test.js'); + assume(msg.service).equals('user-service'); + done(); + }); + + const logger = winston.createLogger({ + transports: [ + mockTransports.createMockTransport(assertFn) + ] + }); + + const childLogger = logger.child({service: 'user-service'}); + childLogger.error(Error('dummy error')); + }); + + it('defaultMeta should autobind correctly', (done) => { + const logger = helpers.createLogger(info => { + assume(info.message).equals('test'); + done(); + }); + + const log = logger.info; + log('test'); + }); + }) + describe('Metadata Precedence', () => { - describe('Should support child loggers & defaultMeta', () => { - it('sets child meta for text messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.requestId).equals('451'); - done(); + let actualOutput = []; + + beforeEach(() => { + actualOutput = []; + }); + + describe('Single logger instance', () => { + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] }); + logger.info("some message"); + logger.warn("I'm a test"); + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include default metadata defined on the logger instance', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true}, + ]; + const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} }); - const childLogger = logger.child({requestId: '451'}); - childLogger.info('dummy message'); - }); + logger.info("some message"); - it('sets child meta for json messages correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message.text).equals('dummy'); - assume(msg.requestId).equals('451'); - done(); + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMeta: true}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], }); + logger.info("some message", {logMeta: true}); + + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true, logMeta: true}, + ]; + const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} }); - const childLogger = logger.child({requestId: '451'}); - childLogger.info({text: 'dummy'}); - }); + logger.info("some message", {logMeta: true}); - it('merges child and provided meta correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('user-service'); - assume(msg.requestId).equals('451'); - done(); + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include override default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: false}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} + }); + + logger.info("some message", {defaultMeta: false}); + + assume(actualOutput).eqls(expectedOutput); + }) + }); + + describe('Multiple logger instances', () => { + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + + logger.info("some message"); + logger2.warn("I'm a test"); + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include default metadata defined on all logger instances', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1"}, + {message: "some message", level: "info", loggerName: "logger2"}, + ]; const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} }); - const childLogger = logger.child({service: 'user-service'}); - childLogger.info('dummy message', {requestId: '451'}); - }); + logger.info("some message"); + logger2.info("some message"); - it('provided meta take precedence over defaultMeta', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('audit-service'); - assume(msg.requestId).equals('451'); - done(); + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMetadata: true}, + {message: "some message", level: "info", logMetadata: false}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] }); + logger.info("some message", {logMetadata: true}); + logger2.info("some message", {logMetadata: false}); + + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1", logMetadata: true}, + {message: "some message", level: "info", loggerName: "logger2", logMetadata: false}, + ]; + const logger = winston.createLogger({ - defaultMeta: {service: 'user-service'}, - transports: [ - mockTransport.createMockTransport(assertFn) - ] + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.info("some message", {logMetadata: true}); + logger2.info("some message", {logMetadata: false}); - logger.info('dummy message', { - requestId: '451', - service: 'audit-service' + assume(actualOutput).eqls(expectedOutput); + }) + + it('should include overridden default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1-override"}, + {message: "some message", level: "info", loggerName: "logger2-override"}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.info("some message", {loggerName: "logger1-override"}); + logger2.info("some message", {loggerName: "logger2-override"}); + + assume(actualOutput).eqls(expectedOutput); + }) + }); + + describe('Single child logger instance', () => { + it("should inherit the parent's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child(); + + rootLogger.info("some message"); + childLogger.info("some message") + + assume(actualOutput).eqls(expectedOutput); }); - it('provided meta take precedence over child meta', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('info'); - assume(msg.message).equals('dummy message'); - assume(msg.service).equals('audit-service'); - assume(msg.requestId).equals('451'); - done(); + it("should include both the parent's & child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: true}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger = rootLogger.child({isChild: true}); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + rootLogger.info("some message"); + childLogger.info("some message") + + assume(actualOutput).eqls(expectedOutput); + }); + + it("should override the parent's default metadata with the child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger = rootLogger.child({loggerName: "child"}); + + rootLogger.info("some message"); + childLogger.info("some message") + + assume(actualOutput).eqls(expectedOutput); + }); + + it("should override the parent's default metadata without affecting the parent", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "child"}, // child logger + {message: "some message", level: "info", loggerName: "child-override"}, // child logger overridden + {message: "some message", level: "info", loggerName: "root"}, // root logger + ]; - const childLogger = logger.child({service: 'user-service'}); - childLogger.info('dummy message', { - requestId: '451', - service: 'audit-service' + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger = rootLogger.child({loggerName: "child"}); + + childLogger.info("some message") + childLogger.info("some message", {loggerName: "child-override"}) + rootLogger.info("some message"); + + assume(actualOutput).eqls(expectedOutput); }); - it('handles error stack traces in child loggers correctly', (done) => { - const assertFn = ((msg) => { - assume(msg.level).equals('error'); - assume(msg.message).equals('dummy error'); - assume(msg.stack).includes('logger.test.js'); - assume(msg.service).equals('user-service'); - done(); + it("should override the parent's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger = rootLogger.child(); - const logger = winston.createLogger({ - transports: [ - mockTransport.createMockTransport(assertFn) - ] + rootLogger.info("some message"); + childLogger.info("some message", {loggerName: "child"}) + + assume(actualOutput).eqls(expectedOutput); + }); + + it("should override the child's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: null}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger = rootLogger.child({isChild: true}); - const childLogger = logger.child({service: 'user-service'}); - childLogger.error(Error('dummy error')); + rootLogger.info("some message"); + childLogger.info("some message", {isChild: null}) + + assume(actualOutput).eqls(expectedOutput); }); - it('defaultMeta() autobinds correctly', (done) => { - const logger = helpers.createLogger(info => { - assume(info.message).equals('test'); - done(); + it("should override both the parent's & child's default metadata with the log specific metadata", + () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child", isChild: null}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger = rootLogger.child({isChild: true}); + + rootLogger.info("some message"); + childLogger.info("some message", {loggerName: "child", isChild: null}) - const log = logger.info; - log('test'); + assume(actualOutput).eqls(expectedOutput); }); }); + + describe('Multiple child logger instances', () => { + it("should have independent default metadata that overrides the parent's", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger + {message: "some message", level: "info", loggerInfo: {name: "child1", isChild: true}}, // child1 logger + {message: "some message", level: "info", loggerInfo: {name: "child1-override", isChild: false}}, // child1 logger override + {message: "some message", level: "info", loggerInfo: {name: "child2", isChild: true}}, // child2 logger + {message: "some message", level: "info", loggerInfo: {name: "child2-override", isChild: false}}, // child2 logger override + {message: "some message", level: "info", loggerInfo: {name: "child3", isChild: true}}, // child3 logger + {message: "some message", level: "info", loggerInfo: {name: "child3-override", isChild: false}}, // child3 logger override + {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerInfo: {name: "root", isChild: false}} + }); + const childLogger1 = rootLogger.child({loggerInfo: {name: "child1", isChild: true}}); + const childLogger2 = rootLogger.child({loggerInfo: {name: "child2", isChild: true}}); + const childLogger3 = rootLogger.child({loggerInfo: {name: "child3", isChild: true}}); + + rootLogger.info("some message"); + childLogger1.info("some message") + childLogger1.info("some message", {loggerInfo: {name: "child1-override", isChild: false}}) + childLogger2.info("some message") + childLogger2.info("some message", {loggerInfo: {name: "child2-override", isChild: false}}) + childLogger3.info("some message") + childLogger3.info("some message", {loggerInfo: {name: "child3-override", isChild: false}}) + rootLogger.info("some message") + + assume(actualOutput).eqls(expectedOutput); + }) + }) }); describe('Backwards Compatability', () => { From 96dfeda6a39dba260f9b1fbf290a9bb87bf80bbd Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 20:48:50 -0700 Subject: [PATCH 20/39] fix: introduce fix for application of default metadata --- lib/winston/logger.js | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/lib/winston/logger.js b/lib/winston/logger.js index 30d7dc0f4..afd6f71a8 100644 --- a/lib/winston/logger.js +++ b/lib/winston/logger.js @@ -9,7 +9,7 @@ const { Stream, Transform } = require('readable-stream'); const asyncForEach = require('async/forEach'); -const { LEVEL, SPLAT } = require('triple-beam'); +const { LEVEL, SPLAT, MESSAGE } = require('triple-beam'); const isStream = require('is-stream'); const ExceptionHandler = require('./exception-handler'); const RejectionHandler = require('./rejection-handler'); @@ -42,30 +42,11 @@ class Logger extends Transform { this.configure(options); } - child(defaultRequestMetadata) { + child(childMetadata) { const logger = this; return Object.create(logger, { - write: { - value: function (info) { - const infoClone = Object.assign( - {}, - defaultRequestMetadata, - info - ); - - // Object.assign doesn't copy inherited Error - // properties so we have to do that explicitly - // - // Remark (indexzero): we should remove this - // since the errors format will handle this case. - // - if (info instanceof Error) { - infoClone.stack = info.stack; - infoClone.message = info.message; - } - - logger.write(infoClone); - } + defaultMeta: { + value: Object.assign({}, this.defaultMeta, childMetadata) } }); } @@ -288,6 +269,10 @@ class Logger extends Transform { info[LEVEL] = info.level; } + if (!info[MESSAGE]) { + info[MESSAGE] = info.message; + } + // Remark: really not sure what to do here, but this has been reported as // very confusing by pre winston@2.0.0 users as quite confusing when using // custom levels. @@ -648,7 +633,9 @@ class Logger extends Transform { _addDefaultMeta(msg) { if (this.defaultMeta) { - Object.assign(msg, this.defaultMeta); + // The msg must be cloned as it is being mutated, but any metadata provided with the msg takes precedence over default + const msgClone = JSON.parse(JSON.stringify(msg)); + Object.assign(msg, this.defaultMeta, msgClone); } } } From b44d4b1d5cafc5de295bd0b74759ddff0542d8aa Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 21:09:26 -0700 Subject: [PATCH 21/39] feat: add equivalent tests for .log() method --- test/unit/winston/logger.test.js | 841 ++++++++++++++++++++++--------- 1 file changed, 596 insertions(+), 245 deletions(-) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index e62aae2c5..39b226332 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -830,347 +830,698 @@ describe('Logger Instance', () => { }); describe('Single logger instance', () => { - it('should log to passed array correctly when using the `inMemory` transport', () => { - const expectedOutput = [ - {message: "some message", level: "info"}, - {message: "I'm a test", level: "warn"} - ]; + describe('When logging with [LEVEL]() methods', () => { + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + + logger.info("some message"); + logger.warn("I'm a test"); + assume(actualOutput).eqls(expectedOutput); + }); + + it('should include default metadata defined on the logger instance', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true}, + ]; - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} + }); + + logger.info("some message"); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message"); - logger.warn("I'm a test"); - assume(actualOutput).eqls(expectedOutput); - }) + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMeta: true}, + ]; - it('should include default metadata defined on the logger instance', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true}, - ]; + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + }); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} + logger.info("some message", {logMeta: true}); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message"); + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true, logMeta: true}, + ]; - assume(actualOutput).eqls(expectedOutput); - }) + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} + }); - it('should include metadata log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", logMeta: true}, - ]; + logger.info("some message", {logMeta: true}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message", {logMeta: true}); + it('should include override default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: false}, + ]; - assume(actualOutput).eqls(expectedOutput); - }) + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} + }); - it('should include both default metadata & log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true, logMeta: true}, - ]; + logger.info("some message", {defaultMeta: false}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} + assume(actualOutput).eqls(expectedOutput); }); + }); - logger.info("some message", {logMeta: true}); + describe('When logging with log() method', () => { + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; - assume(actualOutput).eqls(expectedOutput); - }) + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); - it('should include override default metadata with log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: false}, - ]; + logger.log({level: 'info', message: "some message"}); + logger.log({level: 'warn', message: "I'm a test"}); + assume(actualOutput).eqls(expectedOutput); + }); + + it('should include default metadata defined on the logger instance', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} + }); + + logger.log({level: 'info', message: "some message"}); + + assume(actualOutput).eqls(expectedOutput); + }); + + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMeta: true}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + }); + + logger.log({level: 'info', message: "some message", logMeta: true}); + + assume(actualOutput).eqls(expectedOutput); + }); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true, logMeta: true}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} + }); + + logger.log({level: 'info', message: "some message", logMeta: true}); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message", {defaultMeta: false}); + it('should include override default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: false}, + ]; - assume(actualOutput).eqls(expectedOutput); - }) + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {defaultMeta: true} + }); + + logger.log({level: 'info', message: "some message", defaultMeta: false}); + + assume(actualOutput).eqls(expectedOutput); + }); + }); }); describe('Multiple logger instances', () => { - it('should log to passed array correctly when using the `inMemory` transport', () => { - const expectedOutput = [ - {message: "some message", level: "info"}, - {message: "I'm a test", level: "warn"} - ]; + describe('When logging with [LEVEL]() methods', () => { + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + + logger.info("some message"); + logger2.warn("I'm a test"); + assume(actualOutput).eqls(expectedOutput); + }); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] + it('should include default metadata defined on all logger instances', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1"}, + {message: "some message", level: "info", loggerName: "logger2"}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.info("some message"); + logger2.info("some message"); + + assume(actualOutput).eqls(expectedOutput); }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] + + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMetadata: true}, + {message: "some message", level: "info", logMetadata: false}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + + logger.info("some message", {logMetadata: true}); + logger2.info("some message", {logMetadata: false}); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message"); - logger2.warn("I'm a test"); - assume(actualOutput).eqls(expectedOutput); - }) + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1", logMetadata: true}, + {message: "some message", level: "info", loggerName: "logger2", logMetadata: false}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.info("some message", {logMetadata: true}); + logger2.info("some message", {logMetadata: false}); + + assume(actualOutput).eqls(expectedOutput); + }); - it('should include default metadata defined on all logger instances', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1"}, - {message: "some message", level: "info", loggerName: "logger2"}, - ]; + it('should include overridden default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1-override"}, + {message: "some message", level: "info", loggerName: "logger2-override"}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.info("some message", {loggerName: "logger1-override"}); + logger2.info("some message", {loggerName: "logger2-override"}); + + assume(actualOutput).eqls(expectedOutput); + }); + }); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} + describe('When logging with log() method', () => { + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + + logger.log({level: 'info', message: "some message"}); + logger2.log({level: 'warn', message: "I'm a test"}); + assume(actualOutput).eqls(expectedOutput); }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} + + it('should include default metadata defined on all logger instances', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1"}, + {message: "some message", level: "info", loggerName: "logger2"}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.log({level: 'info', message: "some message"}); + logger2.log({level: 'info', message: "some message"}); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message"); - logger2.info("some message"); + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMetadata: true}, + {message: "some message", level: "info", logMetadata: false}, + ]; - assume(actualOutput).eqls(expectedOutput); - }) + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)] + }); - it('should include metadata log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", logMetadata: true}, - {message: "some message", level: "info", logMetadata: false}, - ]; + logger.log({level: 'info', message: "some message", logMetadata: true}); + logger2.log({level: 'info', message: "some message", logMetadata: false}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] + assume(actualOutput).eqls(expectedOutput); }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] + + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1", logMetadata: true}, + {message: "some message", level: "info", loggerName: "logger2", logMetadata: false}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.log({level: 'info', message: "some message", logMetadata: true}); + logger2.log({level: 'info', message: "some message", logMetadata: false}); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message", {logMetadata: true}); - logger2.info("some message", {logMetadata: false}); + it('should include overridden default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1-override"}, + {message: "some message", level: "info", loggerName: "logger2-override"}, + ]; + + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "logger2"} + }); + + logger.log({level: 'info', message: "some message", loggerName: "logger1-override"}); + logger2.log({level: 'info', message: "some message", loggerName: "logger2-override"}); + + assume(actualOutput).eqls(expectedOutput); + }); + }); + }); + + describe('Single child logger instance', () => { + describe('When logging with [LEVEL]() methods', () => { + it("should inherit the parent's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child(); + + rootLogger.info("some message"); + childLogger.info("some message"); + + assume(actualOutput).eqls(expectedOutput); + }); - assume(actualOutput).eqls(expectedOutput); - }) + it("should include both the parent's & child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: true}, // child logger + ]; - it('should include both default metadata & log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1", logMetadata: true}, - {message: "some message", level: "info", loggerName: "logger2", logMetadata: false}, - ]; + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({isChild: true}); + + rootLogger.info("some message"); + childLogger.info("some message"); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} + assume(actualOutput).eqls(expectedOutput); }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} + + it("should override the parent's default metadata with the child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({loggerName: "child"}); + + rootLogger.info("some message"); + childLogger.info("some message"); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message", {logMetadata: true}); - logger2.info("some message", {logMetadata: false}); + it("should override the parent's default metadata without affecting the parent", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "child"}, // child logger + {message: "some message", level: "info", loggerName: "child-override"}, // child logger overridden + {message: "some message", level: "info", loggerName: "root"}, // root logger + ]; - assume(actualOutput).eqls(expectedOutput); - }) + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({loggerName: "child"}); - it('should include overridden default metadata with log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1-override"}, - {message: "some message", level: "info", loggerName: "logger2-override"}, - ]; + childLogger.info("some message"); + childLogger.info("some message", {loggerName: "child-override"}); + rootLogger.info("some message"); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} + assume(actualOutput).eqls(expectedOutput); }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} + + it("should override the parent's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child(); + + rootLogger.info("some message"); + childLogger.info("some message", {loggerName: "child"}); + + assume(actualOutput).eqls(expectedOutput); }); - logger.info("some message", {loggerName: "logger1-override"}); - logger2.info("some message", {loggerName: "logger2-override"}); + it("should override the child's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: null}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); - }) - }); + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({isChild: true}); - describe('Single child logger instance', () => { - it("should inherit the parent's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root"}, // child logger - ]; + rootLogger.info("some message"); + childLogger.info("some message", {isChild: null}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} + assume(actualOutput).eqls(expectedOutput); }); - const childLogger = rootLogger.child(); - rootLogger.info("some message"); - childLogger.info("some message") + it("should override both the parent's & child's default metadata with the log specific metadata", + () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child", isChild: null}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({isChild: true}); + + rootLogger.info("some message"); + childLogger.info("some message", {loggerName: "child", isChild: null}); - assume(actualOutput).eqls(expectedOutput); + assume(actualOutput).eqls(expectedOutput); + }); }); - it("should include both the parent's & child's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root", isChild: true}, // child logger - ]; + describe('When logging with log() method', () => { + it("should inherit the parent's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root"}, // child logger + ]; - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child(); + + rootLogger.log({level: 'info', message: "some message"}); + childLogger.log({level: 'info', message: "some message"}); + + assume(actualOutput).eqls(expectedOutput); }); - const childLogger = rootLogger.child({isChild: true}); - rootLogger.info("some message"); - childLogger.info("some message") + it("should include both the parent's & child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: true}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); - }); + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({isChild: true}); - it("should override the parent's default metadata with the child's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child"}, // child logger - ]; + rootLogger.log({level: 'info', message: "some message"}); + childLogger.log({level: 'info', message: "some message"}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} + assume(actualOutput).eqls(expectedOutput); }); - const childLogger = rootLogger.child({loggerName: "child"}); - rootLogger.info("some message"); - childLogger.info("some message") + it("should override the parent's default metadata with the child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); - }); + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({loggerName: "child"}); - it("should override the parent's default metadata without affecting the parent", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "child"}, // child logger - {message: "some message", level: "info", loggerName: "child-override"}, // child logger overridden - {message: "some message", level: "info", loggerName: "root"}, // root logger - ]; + rootLogger.log({level: 'info', message: "some message"}); + childLogger.log({level: 'info', message: "some message"}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} + assume(actualOutput).eqls(expectedOutput); }); - const childLogger = rootLogger.child({loggerName: "child"}); - childLogger.info("some message") - childLogger.info("some message", {loggerName: "child-override"}) - rootLogger.info("some message"); + it("should override the parent's default metadata without affecting the parent", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "child"}, // child logger + {message: "some message", level: "info", loggerName: "child-override"}, // child logger overridden + {message: "some message", level: "info", loggerName: "root"}, // root logger + ]; - assume(actualOutput).eqls(expectedOutput); - }); + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({loggerName: "child"}); - it("should override the parent's default metadata with the log specific metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child"}, // child logger - ]; + childLogger.log({level: 'info', message: "some message"}); + childLogger.log({level: 'info', message: "some message", loggerName: "child-override"}); + rootLogger.log({level: 'info', message: "some message"}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} + assume(actualOutput).eqls(expectedOutput); }); - const childLogger = rootLogger.child(); - rootLogger.info("some message"); - childLogger.info("some message", {loggerName: "child"}) + it("should override the parent's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); - }); + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child(); - it("should override the child's default metadata with the log specific metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root", isChild: null}, // child logger - ]; + rootLogger.log({level: 'info', message: "some message"}); + childLogger.log({level: 'info', message: "some message", loggerName: "child"}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} + assume(actualOutput).eqls(expectedOutput); }); - const childLogger = rootLogger.child({isChild: true}); - rootLogger.info("some message"); - childLogger.info("some message", {isChild: null}) + it("should override the child's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: null}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); - }); + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({isChild: true}); - it("should override both the parent's & child's default metadata with the log specific metadata", - () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child", isChild: null}, // child logger - ]; + rootLogger.log({level: 'info', message: "some message"}); + childLogger.log({level: 'info', message: "some message", isChild: null}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} + assume(actualOutput).eqls(expectedOutput); }); - const childLogger = rootLogger.child({isChild: true}); - rootLogger.info("some message"); - childLogger.info("some message", {loggerName: "child", isChild: null}) + it("should override both the parent's & child's default metadata with the log specific metadata", + () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child", isChild: null}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger = rootLogger.child({isChild: true}); + + rootLogger.log({level: 'info', message: "some message"}); + childLogger.log({level: 'info', message: "some message", loggerName: "child", isChild: null}); - assume(actualOutput).eqls(expectedOutput); + assume(actualOutput).eqls(expectedOutput); + }); }); }); describe('Multiple child logger instances', () => { - it("should have independent default metadata that overrides the parent's", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger - {message: "some message", level: "info", loggerInfo: {name: "child1", isChild: true}}, // child1 logger - {message: "some message", level: "info", loggerInfo: {name: "child1-override", isChild: false}}, // child1 logger override - {message: "some message", level: "info", loggerInfo: {name: "child2", isChild: true}}, // child2 logger - {message: "some message", level: "info", loggerInfo: {name: "child2-override", isChild: false}}, // child2 logger override - {message: "some message", level: "info", loggerInfo: {name: "child3", isChild: true}}, // child3 logger - {message: "some message", level: "info", loggerInfo: {name: "child3-override", isChild: false}}, // child3 logger override - {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger - ]; + describe('When logging with [LEVEL]() methods', () => { + it("should have independent default metadata that overrides the parent's", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger + {message: "some message", level: "info", loggerInfo: {name: "child1", isChild: true}}, // child1 logger + {message: "some message", level: "info", loggerInfo: {name: "child1-override", isChild: false}}, // child1 logger override + {message: "some message", level: "info", loggerInfo: {name: "child2", isChild: true}}, // child2 logger + {message: "some message", level: "info", loggerInfo: {name: "child2-override", isChild: false}}, // child2 logger override + {message: "some message", level: "info", loggerInfo: {name: "child3", isChild: true}}, // child3 logger + {message: "some message", level: "info", loggerInfo: {name: "child3-override", isChild: false}}, // child3 logger override + {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerInfo: {name: "root", isChild: false}} + }); + const childLogger1 = rootLogger.child({loggerInfo: {name: "child1", isChild: true}}); + const childLogger2 = rootLogger.child({loggerInfo: {name: "child2", isChild: true}}); + const childLogger3 = rootLogger.child({loggerInfo: {name: "child3", isChild: true}}); + + rootLogger.info("some message"); + childLogger1.info("some message") + childLogger1.info("some message", {loggerInfo: {name: "child1-override", isChild: false}}) + childLogger2.info("some message") + childLogger2.info("some message", {loggerInfo: {name: "child2-override", isChild: false}}) + childLogger3.info("some message") + childLogger3.info("some message", {loggerInfo: {name: "child3-override", isChild: false}}) + rootLogger.info("some message") + + assume(actualOutput).eqls(expectedOutput); + }); + }); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerInfo: {name: "root", isChild: false}} + describe('When logging with log() method', () => { + it("should have independent default metadata that overrides the parent's", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger + {message: "some message", level: "info", loggerInfo: {name: "child1", isChild: true}}, // child1 logger + {message: "some message", level: "info", loggerInfo: {name: "child1-override", isChild: false}}, // child1 logger override + {message: "some message", level: "info", loggerInfo: {name: "child2", isChild: true}}, // child2 logger + {message: "some message", level: "info", loggerInfo: {name: "child2-override", isChild: false}}, // child2 logger override + {message: "some message", level: "info", loggerInfo: {name: "child3", isChild: true}}, // child3 logger + {message: "some message", level: "info", loggerInfo: {name: "child3-override", isChild: false}}, // child3 logger override + {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {loggerInfo: {name: "root", isChild: false}} + }); + const childLogger1 = rootLogger.child({loggerInfo: {name: "child1", isChild: true}}); + const childLogger2 = rootLogger.child({loggerInfo: {name: "child2", isChild: true}}); + const childLogger3 = rootLogger.child({loggerInfo: {name: "child3", isChild: true}}); + + rootLogger.log({level: 'info', message: "some message"}); + childLogger1.log({level: 'info', message: "some message"}); + childLogger1.log({level: 'info', message: "some message", loggerInfo: {name: "child1-override", isChild: false}}); + childLogger2.log({level: 'info', message: "some message"}); + childLogger2.log({level: 'info', message: "some message", loggerInfo: {name: "child2-override", isChild: false}}); + childLogger3.log({level: 'info', message: "some message"}); + childLogger3.log({level: 'info', message: "some message", loggerInfo: {name: "child3-override", isChild: false}}); + rootLogger.log({level: 'info', message: "some message"}); + + assume(actualOutput).eqls(expectedOutput); }); - const childLogger1 = rootLogger.child({loggerInfo: {name: "child1", isChild: true}}); - const childLogger2 = rootLogger.child({loggerInfo: {name: "child2", isChild: true}}); - const childLogger3 = rootLogger.child({loggerInfo: {name: "child3", isChild: true}}); - - rootLogger.info("some message"); - childLogger1.info("some message") - childLogger1.info("some message", {loggerInfo: {name: "child1-override", isChild: false}}) - childLogger2.info("some message") - childLogger2.info("some message", {loggerInfo: {name: "child2-override", isChild: false}}) - childLogger3.info("some message") - childLogger3.info("some message", {loggerInfo: {name: "child3-override", isChild: false}}) - rootLogger.info("some message") - - assume(actualOutput).eqls(expectedOutput); - }) - }) + }); + }); }); describe('Backwards Compatability', () => { From f7486366740cfe1694e6e4068eb98615d1da2d64 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 30 Jan 2022 21:48:04 -0700 Subject: [PATCH 22/39] chore: update nyc coverage --- .nycrc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nycrc.yml b/.nycrc.yml index ce121842b..37ef1b757 100644 --- a/.nycrc.yml +++ b/.nycrc.yml @@ -4,5 +4,5 @@ reporter: check-coverage: true branches: 61.51 lines: 70.85 -functions: 73.21 +functions: 73.08 statements: 70.54 \ No newline at end of file From f89285a092daa2e994a97122c0f3aacb1c5de032 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Mon, 7 Feb 2022 21:04:26 -0700 Subject: [PATCH 23/39] chore: undo accidental indent --- test/unit/winston/logger.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index d10db61d9..67141c8f5 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -25,7 +25,7 @@ const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs') describe('Logger Instance', function () { describe('Configuration', function () { - it('.configure()', function () { + it('.configure()', function () { let logger = winston.createLogger({ transports: [new winston.transports.Console()] }); From b2efe8ff612f73078c12551d6df2f171933db82d Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Tue, 8 Feb 2022 16:58:38 -0700 Subject: [PATCH 24/39] chore: add new test to ensure a parents metadata updates don't propogate to the child --- test/unit/winston/logger.test.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 67141c8f5..eb17bae46 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -1209,6 +1209,27 @@ describe('Logger Instance', function () { assume(actualOutput).eqls(expectedOutput); }); + it("should not reflect changes to the parent's metadata if it changes after the child is created", () => { + const expectedOutput = [ + {message: "some message", level: "info", label: "parent"}, // child logger + {message: "some message", level: "info", label: "parent"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {label: "parent"} + }); + const childLogger = rootLogger.child(); + + childLogger.info("some message"); + rootLogger.defaultMeta = { + defaultMeta: {label: "updatedLabel"} + }; + childLogger.info("some message"); + + assume(actualOutput).eqls(expectedOutput); + }); + it("should include both the parent's & child's default metadata", () => { const expectedOutput = [ {message: "some message", level: "info", loggerName: "root"}, // root logger From 010e955928848ef216d1b206c34e2d53636ee0e1 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Tue, 8 Feb 2022 16:59:29 -0700 Subject: [PATCH 25/39] chore: fix nyc coverage requirements --- .nycrc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nycrc.yml b/.nycrc.yml index ce121842b..37ef1b757 100644 --- a/.nycrc.yml +++ b/.nycrc.yml @@ -4,5 +4,5 @@ reporter: check-coverage: true branches: 61.51 lines: 70.85 -functions: 73.21 +functions: 73.08 statements: 70.54 \ No newline at end of file From f393a50d319665a016771a7eabc81c04a361fedf Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Tue, 8 Feb 2022 23:13:40 -0700 Subject: [PATCH 26/39] feat: introduce test proving issue with Profilers instance not including metadata --- test/unit/winston/logger.test.js | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index eb17bae46..64d08743e 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -24,6 +24,12 @@ const mockTransports = require('../../helpers/mocks/mock-transport'); const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); describe('Logger Instance', function () { + let actualOutput = []; + + beforeEach(() => { + actualOutput = []; + }); + describe('Configuration', function () { it('.configure()', function () { let logger = winston.createLogger({ @@ -670,15 +676,10 @@ describe('Logger Instance', function () { }, 100); }); - it('should stop a timer when `done` is called on it', function (done) { - let logger = helpers.createLogger(function (info) { - assume(info).is.an('object'); - assume(info.something).equals('ok'); - assume(info.level).equals('info'); - assume(info.durationMs).is.a('number'); - assume(info.message).equals('testing1'); - assume(info[MESSAGE]).is.a('string'); - done(); + it('should stop a profiler instance generated via `startTimer()` when `done()` is called on it', function (done) { + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {rootLogger: true} }); let timer = logger.startTimer(); @@ -688,6 +689,14 @@ describe('Logger Instance', function () { something: 'ok', level: 'info' }); + assume(actualOutput).is.length(1); + assume(actualOutput[0]).contains('durationMs'); + assume(actualOutput[0].durationMs).is.a('number'); + assume(actualOutput[0].message).equals('testing1'); + assume(actualOutput[0].level).equals('info'); + assume(actualOutput[0].something).equals('ok'); + assume(actualOutput[0].rootLogger).is.true(); + done() }, 100); }); }); @@ -823,12 +832,6 @@ describe('Logger Instance', function () { }); describe('Metadata Precedence', () => { - let actualOutput = []; - - beforeEach(() => { - actualOutput = []; - }); - describe('Single logger instance', () => { describe('When logging with [LEVEL]() methods', () => { it('should log to passed array correctly when using the `inMemory` transport', () => { From 3577d1df50d8440ae4958a448fb5befbd37472d9 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Tue, 8 Feb 2022 23:14:41 -0700 Subject: [PATCH 27/39] feat: ensure Profiler triggers the logger's add default metadata functionality --- lib/winston/profiler.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/winston/profiler.js b/lib/winston/profiler.js index edcc5a65a..a418a4fa1 100644 --- a/lib/winston/profiler.js +++ b/lib/winston/profiler.js @@ -32,7 +32,8 @@ module.exports = class Profiler { /** * Ends the current timer (i.e. Profiler) instance and logs the `msg` along * with the duration since creation. - * @returns {mixed} - TODO: add return description. + * @returns boolean - `false` if the logger stream wishes for the calling code to wait for the 'drain' event to be + * emitted before continuing to write additional data; otherwise `true` * @private */ done(...args) { @@ -45,7 +46,7 @@ module.exports = class Profiler { const info = typeof args[args.length - 1] === 'object' ? args.pop() : {}; info.level = info.level || 'info'; info.durationMs = (Date.now()) - this.start; - + this.logger._addDefaultMeta(info) return this.logger.write(info); } }; From fc39513a71089f9aef87be9a1eafcbf1a02bb662 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Tue, 8 Feb 2022 23:19:27 -0700 Subject: [PATCH 28/39] fix: add a safety net to calling 'addDefaultMeta' on the logger instance --- .nycrc.yml | 2 +- lib/winston/profiler.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.nycrc.yml b/.nycrc.yml index 37ef1b757..421964226 100644 --- a/.nycrc.yml +++ b/.nycrc.yml @@ -4,5 +4,5 @@ reporter: check-coverage: true branches: 61.51 lines: 70.85 -functions: 73.08 +functions: 73.56 statements: 70.54 \ No newline at end of file diff --git a/lib/winston/profiler.js b/lib/winston/profiler.js index a418a4fa1..3e22bda92 100644 --- a/lib/winston/profiler.js +++ b/lib/winston/profiler.js @@ -21,6 +21,8 @@ module.exports = class Profiler { * @private */ constructor(logger) { + // TODO there is no restriction on what the Profiler considers a Logger. As such there is no guarantees it adheres + // to the proper interface. This needs to hardened. if (!logger) { throw new Error('Logger is required for profiling.'); } @@ -46,7 +48,7 @@ module.exports = class Profiler { const info = typeof args[args.length - 1] === 'object' ? args.pop() : {}; info.level = info.level || 'info'; info.durationMs = (Date.now()) - this.start; - this.logger._addDefaultMeta(info) + if (this.logger._addDefaultMeta) this.logger._addDefaultMeta(info) return this.logger.write(info); } }; From d9f105c1cd48e7d45ab0e5fe52367c4ece46952f Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Tue, 8 Feb 2022 23:51:24 -0700 Subject: [PATCH 29/39] chore: fix failing build issues --- .nycrc.yml | 2 +- lib/winston/profiler.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.nycrc.yml b/.nycrc.yml index 421964226..37ef1b757 100644 --- a/.nycrc.yml +++ b/.nycrc.yml @@ -4,5 +4,5 @@ reporter: check-coverage: true branches: 61.51 lines: 70.85 -functions: 73.56 +functions: 73.08 statements: 70.54 \ No newline at end of file diff --git a/lib/winston/profiler.js b/lib/winston/profiler.js index 3e22bda92..a8dda1351 100644 --- a/lib/winston/profiler.js +++ b/lib/winston/profiler.js @@ -34,7 +34,7 @@ module.exports = class Profiler { /** * Ends the current timer (i.e. Profiler) instance and logs the `msg` along * with the duration since creation. - * @returns boolean - `false` if the logger stream wishes for the calling code to wait for the 'drain' event to be + * @returns {boolean} - `false` if the logger stream wishes for the calling code to wait for the 'drain' event to be * emitted before continuing to write additional data; otherwise `true` * @private */ @@ -48,7 +48,7 @@ module.exports = class Profiler { const info = typeof args[args.length - 1] === 'object' ? args.pop() : {}; info.level = info.level || 'info'; info.durationMs = (Date.now()) - this.start; - if (this.logger._addDefaultMeta) this.logger._addDefaultMeta(info) + if (this.logger._addDefaultMeta) this.logger._addDefaultMeta(info); return this.logger.write(info); } }; From 8eab107a5f10a26b7e62df01910a9ad0cd7573ac Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 12 Feb 2022 10:37:06 -0700 Subject: [PATCH 30/39] feat: add test to ensure changes to parents metadata are not propogated to a child --- test/unit/winston/logger.test.js | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 64d08743e..d8a5b97d5 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -1364,6 +1364,27 @@ describe('Logger Instance', function () { assume(actualOutput).eqls(expectedOutput); }); + it("should not reflect changes to the parent's metadata if it changes after the child is created", () => { + const expectedOutput = [ + {message: "some message", level: "info", label: "parent"}, // child logger + {message: "some message", level: "info", label: "parent"}, // child logger + ]; + + const rootLogger = winston.createLogger({ + transports: [mockTransports.inMemory(actualOutput)], + defaultMeta: {label: "parent"} + }); + const childLogger = rootLogger.child(); + + childLogger.log("info", "some message"); + rootLogger.defaultMeta = { + defaultMeta: {label: "updatedLabel"} + }; + childLogger.log("info", "some message"); + + assume(actualOutput).eqls(expectedOutput); + }); + it("should include both the parent's & child's default metadata", () => { const expectedOutput = [ {message: "some message", level: "info", loggerName: "root"}, // root logger @@ -1548,6 +1569,27 @@ describe('Logger Instance', function () { }); }); + describe('Metadata application with formats', () => { + describe('Printf Format', () => { + it('should result in equivalent messages when using log() and [LEVEL]()', () => { + const logger = winston.createLogger({ + level: "debug", + defaultMeta: { id: 'APP', service: 'Authentication' }, + format: winston.format.combine( + winston.format.printf( + info => `${info.service} - ${info.level}: [${info.id}] ${info.message}` + ) + ), + transports: [mockTransports.inMemory(actualOutput)] + }); + + logger.info("This is my info"); + logger.log("info", "This is my info"); + assume(actualOutput[0][MESSAGE]).eqls(actualOutput[1][MESSAGE]); + }); + }); + }) + describe('Backwards Compatability', function () { describe('Winston V2 Log', function () { it('.log(level, message)', function (done) { From 4e830d6883897411294c13d86aba0f319dee5242 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 12 Feb 2022 12:48:50 -0700 Subject: [PATCH 31/39] fix: remove linebreak configuration from editorconfig --- .editorconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index fab77dc55..fc3d197f1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,6 @@ root = true # default configuration [*] charset = utf-8 -end_of_line = crlf trim_trailing_whitespace = true insert_final_newline = true indent_style = space From 8724f4b6e526475755ee12557492c72003973f8f Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 12 Feb 2022 16:10:42 -0700 Subject: [PATCH 32/39] chore: combine level and log tests of same kind to ensure both output the same --- test/unit/winston/logger.test.js | 1082 +++++++++++++----------------- 1 file changed, 463 insertions(+), 619 deletions(-) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index d8a5b97d5..5d0f5b53f 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -24,10 +24,12 @@ const mockTransports = require('../../helpers/mocks/mock-transport'); const testLogFixturesPath = path.join(__dirname, '..', '..', 'fixtures', 'logs'); describe('Logger Instance', function () { - let actualOutput = []; + let levelOutput = []; + let logOutput = []; beforeEach(() => { - actualOutput = []; + levelOutput = []; + logOutput = []; }); describe('Configuration', function () { @@ -204,6 +206,35 @@ describe('Logger Instance', function () { assume(isStream(outStream)).true(); }); }); + + describe('Multiple Transports', function () { + it.skip('should log the same thing to every configured transport', function () { + winston.add(new Winston.transports.Console({ + format: Winston.format.combine( + Winston.format(info => { + info.message = info.message + "Console"; + return info; + })(), + Winston.format.splat(), Winston.format.simple(), Winston.format(info => { + // console.log(info); // meta is there! + return info; + })()), + handleExceptions: true + })); + Winston.add(new Winston.transports.File({ + filename: "test.log", + format: Winston.format.combine(Winston.format(info => { + // console.log(info); // meta is gone :(! and so is SPLAT only a array of length 1 + return info; + })(), Winston.format.splat(), Winston.format.simple()) + })); + + + for (let index = 0; index < 10; index++) { + Winston.error("test %s" + index, "blub", "metainfo"); + } + }); + }); }); describe('Log Levels', function () { @@ -678,7 +709,7 @@ describe('Logger Instance', function () { it('should stop a profiler instance generated via `startTimer()` when `done()` is called on it', function (done) { const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], + transports: [mockTransports.inMemory(levelOutput)], defaultMeta: {rootLogger: true} }); @@ -689,13 +720,13 @@ describe('Logger Instance', function () { something: 'ok', level: 'info' }); - assume(actualOutput).is.length(1); - assume(actualOutput[0]).contains('durationMs'); - assume(actualOutput[0].durationMs).is.a('number'); - assume(actualOutput[0].message).equals('testing1'); - assume(actualOutput[0].level).equals('info'); - assume(actualOutput[0].something).equals('ok'); - assume(actualOutput[0].rootLogger).is.true(); + assume(levelOutput).is.length(1); + assume(levelOutput[0]).contains('durationMs'); + assume(levelOutput[0].durationMs).is.a('number'); + assume(levelOutput[0].message).equals('testing1'); + assume(levelOutput[0].level).equals('info'); + assume(levelOutput[0].something).equals('ok'); + assume(levelOutput[0].rootLogger).is.true(); done() }, 100); }); @@ -833,674 +864,504 @@ describe('Logger Instance', function () { describe('Metadata Precedence', () => { describe('Single logger instance', () => { - describe('When logging with [LEVEL]() methods', () => { - it('should log to passed array correctly when using the `inMemory` transport', () => { - const expectedOutput = [ - {message: "some message", level: "info"}, - {message: "I'm a test", level: "warn"} - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; - logger.info("some message"); - logger.warn("I'm a test"); - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] }); - - it('should include default metadata defined on the logger instance', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} - }); - - logger.info("some message"); - - assume(actualOutput).eqls(expectedOutput); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)] }); - it('should include metadata log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", logMeta: true}, - ]; + logger1.info("some message"); + logger1.warn("I'm a test"); + logger2.log({level: 'info', message: "some message"}); + logger2.log({level: 'warn', message: "I'm a test"}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - logger.info("some message", {logMeta: true}); + it('should include default metadata defined on the logger instance', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true}, + ]; - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {defaultMeta: true} }); - - it('should include both default metadata & log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true, logMeta: true}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} - }); - - logger.info("some message", {logMeta: true}); - - assume(actualOutput).eqls(expectedOutput); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {defaultMeta: true} }); - it('should include override default metadata with log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: false}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} - }); - - logger.info("some message", {defaultMeta: false}); + logger1.info("some message"); + logger2.log({level: "info", message: "some message"}); - assume(actualOutput).eqls(expectedOutput); - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); }); - describe('When logging with log() method', () => { - it('should log to passed array correctly when using the `inMemory` transport', () => { - const expectedOutput = [ - {message: "some message", level: "info"}, - {message: "I'm a test", level: "warn"} - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMeta: true}, + ]; - logger.log({level: 'info', message: "some message"}); - logger.log({level: 'warn', message: "I'm a test"}); - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], }); - - it('should include default metadata defined on the logger instance', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} - }); - - logger.log({level: 'info', message: "some message"}); - - assume(actualOutput).eqls(expectedOutput); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], }); - it('should include metadata log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", logMeta: true}, - ]; + logger1.info("some message", {logMeta: true}); + logger2.log({level: "info", message: "some message", logMeta: true}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - logger.log({level: 'info', message: "some message", logMeta: true}); + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: true, logMeta: true}, + ]; - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {defaultMeta: true} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {defaultMeta: true} }); - it('should include both default metadata & log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true, logMeta: true}, - ]; + logger1.info("some message", {logMeta: true}); + logger2.log({level: "info", message: "some message", logMeta: true}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - logger.log({level: 'info', message: "some message", logMeta: true}); + it('should include override default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", defaultMeta: false}, + ]; - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {defaultMeta: true} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {defaultMeta: true} }); - it('should include override default metadata with log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: false}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {defaultMeta: true} - }); - - logger.log({level: 'info', message: "some message", defaultMeta: false}); + logger1.info("some message", {defaultMeta: false}); + logger2.log({level: "info", message: "some message", defaultMeta: false}); - assume(actualOutput).eqls(expectedOutput); - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); }); }); describe('Multiple logger instances', () => { - describe('When logging with [LEVEL]() methods', () => { - it('should log to passed array correctly when using the `inMemory` transport', () => { - const expectedOutput = [ - {message: "some message", level: "info"}, - {message: "I'm a test", level: "warn"} - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); + it('should log to passed array correctly when using the `inMemory` transport', () => { + const expectedOutput = [ + {message: "some message", level: "info"}, + {message: "I'm a test", level: "warn"} + ]; - logger.info("some message"); - logger2.warn("I'm a test"); - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] }); - - it('should include default metadata defined on all logger instances', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1"}, - {message: "some message", level: "info", loggerName: "logger2"}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} - }); - - logger.info("some message"); - logger2.info("some message"); - - assume(actualOutput).eqls(expectedOutput); + const logger1a = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] }); - - it('should include metadata log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", logMetadata: true}, - {message: "some message", level: "info", logMetadata: false}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); - - logger.info("some message", {logMetadata: true}); - logger2.info("some message", {logMetadata: false}); - - assume(actualOutput).eqls(expectedOutput); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)] }); - - it('should include both default metadata & log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1", logMetadata: true}, - {message: "some message", level: "info", loggerName: "logger2", logMetadata: false}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} - }); - - logger.info("some message", {logMetadata: true}); - logger2.info("some message", {logMetadata: false}); - - assume(actualOutput).eqls(expectedOutput); + const logger2a = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)] }); - it('should include overridden default metadata with log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1-override"}, - {message: "some message", level: "info", loggerName: "logger2-override"}, - ]; + logger1.info("some message"); + logger1a.warn("I'm a test"); + logger2.log({level: "info", message: "some message"}); + logger2a.log({level: "warn", message: "I'm a test"}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); }); - logger.info("some message", {loggerName: "logger1-override"}); - logger2.info("some message", {loggerName: "logger2-override"}); + it('should include default metadata defined on all logger instances', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1"}, + {message: "some message", level: "info", loggerName: "logger2"}, + ]; - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "logger1"} }); - }); - - describe('When logging with log() method', () => { - it('should log to passed array correctly when using the `inMemory` transport', () => { - const expectedOutput = [ - {message: "some message", level: "info"}, - {message: "I'm a test", level: "warn"} - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); - - logger.log({level: 'info', message: "some message"}); - logger2.log({level: 'warn', message: "I'm a test"}); - assume(actualOutput).eqls(expectedOutput); + const logger1a = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "logger2"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2a = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "logger2"} }); - it('should include default metadata defined on all logger instances', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1"}, - {message: "some message", level: "info", loggerName: "logger2"}, - ]; + logger1.info("some message"); + logger1a.info("some message"); + logger2.log({level: "info", message: "some message"}); + logger2a.log({level: "info", message: "some message"}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - logger.log({level: 'info', message: "some message"}); - logger2.log({level: 'info', message: "some message"}); + it('should include metadata log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", logMetadata: true}, + {message: "some message", level: "info", logMetadata: false}, + ]; - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] + }); + const logger1a = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)] + }); + const logger2a = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)] }); - it('should include metadata log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", logMetadata: true}, - {message: "some message", level: "info", logMetadata: false}, - ]; + logger1.info("some message", {logMetadata: true}); + logger1a.info("some message", {logMetadata: false}); + logger2.log({level: "info", message: "some message", logMetadata: true}); + logger2a.log({level: "info", message: "some message", logMetadata: false}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)] - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - logger.log({level: 'info', message: "some message", logMetadata: true}); - logger2.log({level: 'info', message: "some message", logMetadata: false}); + it('should include both default metadata & log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1", logMetadata: true}, + {message: "some message", level: "info", loggerName: "logger2", logMetadata: false}, + ]; - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger1a = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "logger2"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2a = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "logger2"} }); - it('should include both default metadata & log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1", logMetadata: true}, - {message: "some message", level: "info", loggerName: "logger2", logMetadata: false}, - ]; + logger1.info("some message", {logMetadata: true}); + logger1a.info("some message", {logMetadata: false}); + logger2.log({level: "info", message: "some message", logMetadata: true}); + logger2a.log({level: "info", message: "some message", logMetadata: false}); - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - logger.log({level: 'info', message: "some message", logMetadata: true}); - logger2.log({level: 'info', message: "some message", logMetadata: false}); + it('should include overridden default metadata with log specific metadata', () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "logger1-override"}, + {message: "some message", level: "info", loggerName: "logger2-override"}, + ]; - assume(actualOutput).eqls(expectedOutput); + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger1a = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "logger2"} + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "logger1"} + }); + const logger2a = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "logger2"} }); - it('should include overridden default metadata with log specific metadata', () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "logger1-override"}, - {message: "some message", level: "info", loggerName: "logger2-override"}, - ]; - - const logger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger1"} - }); - const logger2 = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "logger2"} - }); - - logger.log({level: 'info', message: "some message", loggerName: "logger1-override"}); - logger2.log({level: 'info', message: "some message", loggerName: "logger2-override"}); + logger1.info("some message", {loggerName: "logger1-override"}); + logger1a.info("some message", {loggerName: "logger2-override"}); + logger2.log({level: "info", message: "some message", loggerName: "logger1-override"}); + logger2a.log({level: "info", message: "some message", loggerName: "logger2-override"}); - assume(actualOutput).eqls(expectedOutput); - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); }); }); describe('Single child logger instance', () => { - describe('When logging with [LEVEL]() methods', () => { - it("should inherit the parent's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root"}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child(); - - rootLogger.info("some message"); - childLogger.info("some message"); + it("should inherit the parent's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root"}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "root"} }); - - it("should not reflect changes to the parent's metadata if it changes after the child is created", () => { - const expectedOutput = [ - {message: "some message", level: "info", label: "parent"}, // child logger - {message: "some message", level: "info", label: "parent"}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {label: "parent"} - }); - const childLogger = rootLogger.child(); - - childLogger.info("some message"); - rootLogger.defaultMeta = { - defaultMeta: {label: "updatedLabel"} - }; - childLogger.info("some message"); - - assume(actualOutput).eqls(expectedOutput); + const childLogger1 = rootLogger1.child(); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger2 = rootLogger2.child(); - it("should include both the parent's & child's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root", isChild: true}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({isChild: true}); + rootLogger1.info("some message"); + childLogger1.info("some message"); + rootLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message"}); - rootLogger.info("some message"); - childLogger.info("some message"); - - assume(actualOutput).eqls(expectedOutput); - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - it("should override the parent's default metadata with the child's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child"}, // child logger - ]; + it("should not reflect changes to the parent's metadata if it changes after the child is created", () => { + const expectedOutput = [ + {message: "some message", level: "info", label: "parent"}, // child logger + {message: "some message", level: "info", label: "parent"}, // child logger + ]; - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({loggerName: "child"}); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {label: "parent"} + }); + const childLogger1 = rootLogger1.child(); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {label: "parent"} + }); + const childLogger2 = rootLogger2.child(); + + childLogger1.info("some message"); + rootLogger1.defaultMeta = { + defaultMeta: {label: "updatedLabel"} + }; + childLogger1.info("some message"); + childLogger2.log({level: "info", message: "some message"}); + rootLogger2.defaultMeta = { + defaultMeta: {label: "updatedLabel"} + }; + childLogger2.log({level: "info", message: "some message"}); + + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - rootLogger.info("some message"); - childLogger.info("some message"); + it("should include both the parent's & child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: true}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "root"} }); - - it("should override the parent's default metadata without affecting the parent", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "child"}, // child logger - {message: "some message", level: "info", loggerName: "child-override"}, // child logger overridden - {message: "some message", level: "info", loggerName: "root"}, // root logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({loggerName: "child"}); - - childLogger.info("some message"); - childLogger.info("some message", {loggerName: "child-override"}); - rootLogger.info("some message"); - - assume(actualOutput).eqls(expectedOutput); + const childLogger1 = rootLogger1.child({isChild: true}); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger2 = rootLogger2.child({isChild: true}); - it("should override the parent's default metadata with the log specific metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child"}, // child logger - ]; + rootLogger1.info("some message"); + childLogger1.info("some message"); + rootLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message"}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child(); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - rootLogger.info("some message"); - childLogger.info("some message", {loggerName: "child"}); + it("should override the parent's default metadata with the child's default metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "root"} }); - - it("should override the child's default metadata with the log specific metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root", isChild: null}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({isChild: true}); - - rootLogger.info("some message"); - childLogger.info("some message", {isChild: null}); - - assume(actualOutput).eqls(expectedOutput); + const childLogger1 = rootLogger1.child({loggerName: "child"}); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger2 = rootLogger2.child({loggerName: "child"}); - it("should override both the parent's & child's default metadata with the log specific metadata", - () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child", isChild: null}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({isChild: true}); - - rootLogger.info("some message"); - childLogger.info("some message", {loggerName: "child", isChild: null}); + rootLogger1.info("some message"); + childLogger1.info("some message"); + rootLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message"}); - assume(actualOutput).eqls(expectedOutput); - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); }); - describe('When logging with log() method', () => { - it("should inherit the parent's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root"}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child(); - - rootLogger.log({level: 'info', message: "some message"}); - childLogger.log({level: 'info', message: "some message"}); + it("should override the parent's default metadata without affecting the parent", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "child"}, // child logger + {message: "some message", level: "info", loggerName: "child-override"}, // child logger overridden + {message: "some message", level: "info", loggerName: "root"}, // root logger + ]; - assume(actualOutput).eqls(expectedOutput); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "root"} }); - - it("should not reflect changes to the parent's metadata if it changes after the child is created", () => { - const expectedOutput = [ - {message: "some message", level: "info", label: "parent"}, // child logger - {message: "some message", level: "info", label: "parent"}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {label: "parent"} - }); - const childLogger = rootLogger.child(); - - childLogger.log("info", "some message"); - rootLogger.defaultMeta = { - defaultMeta: {label: "updatedLabel"} - }; - childLogger.log("info", "some message"); - - assume(actualOutput).eqls(expectedOutput); + const childLogger1 = rootLogger1.child({loggerName: "child"}); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger2 = rootLogger2.child({loggerName: "child"}); - it("should include both the parent's & child's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root", isChild: true}, // child logger - ]; + childLogger1.info("some message"); + childLogger1.info("some message", {loggerName: "child-override"}); + rootLogger1.info("some message"); + childLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message", loggerName: "child-override"}); + rootLogger2.log({level: "info", message: "some message"}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({isChild: true}); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - rootLogger.log({level: 'info', message: "some message"}); - childLogger.log({level: 'info', message: "some message"}); + it("should override the parent's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child"}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "root"} }); - - it("should override the parent's default metadata with the child's default metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child"}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({loggerName: "child"}); - - rootLogger.log({level: 'info', message: "some message"}); - childLogger.log({level: 'info', message: "some message"}); - - assume(actualOutput).eqls(expectedOutput); + const childLogger1 = rootLogger1.child(); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger2 = rootLogger2.child(); - it("should override the parent's default metadata without affecting the parent", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "child"}, // child logger - {message: "some message", level: "info", loggerName: "child-override"}, // child logger overridden - {message: "some message", level: "info", loggerName: "root"}, // root logger - ]; + rootLogger1.info("some message"); + childLogger1.info("some message", {loggerName: "child"}); + rootLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message", loggerName: "child"}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({loggerName: "child"}); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - childLogger.log({level: 'info', message: "some message"}); - childLogger.log({level: 'info', message: "some message", loggerName: "child-override"}); - rootLogger.log({level: 'info', message: "some message"}); + it("should override the child's default metadata with the log specific metadata", () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "root", isChild: null}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "root"} }); - - it("should override the parent's default metadata with the log specific metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child"}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child(); - - rootLogger.log({level: 'info', message: "some message"}); - childLogger.log({level: 'info', message: "some message", loggerName: "child"}); - - assume(actualOutput).eqls(expectedOutput); + const childLogger1 = rootLogger1.child({isChild: true}); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger2 = rootLogger2.child({isChild: true}); - it("should override the child's default metadata with the log specific metadata", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "root", isChild: null}, // child logger - ]; + rootLogger1.info("some message"); + childLogger1.info("some message", {isChild: null}); + rootLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message", isChild: null}); - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({isChild: true}); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); - rootLogger.log({level: 'info', message: "some message"}); - childLogger.log({level: 'info', message: "some message", isChild: null}); + it("should override both the parent's & child's default metadata with the log specific metadata", + () => { + const expectedOutput = [ + {message: "some message", level: "info", loggerName: "root"}, // root logger + {message: "some message", level: "info", loggerName: "child", isChild: null}, // child logger + ]; - assume(actualOutput).eqls(expectedOutput); + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], + defaultMeta: {loggerName: "root"} }); + const childLogger1 = rootLogger1.child({isChild: true}); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], + defaultMeta: {loggerName: "root"} + }); + const childLogger2 = rootLogger2.child({isChild: true}); - it("should override both the parent's & child's default metadata with the log specific metadata", - () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerName: "root"}, // root logger - {message: "some message", level: "info", loggerName: "child", isChild: null}, // child logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], - defaultMeta: {loggerName: "root"} - }); - const childLogger = rootLogger.child({isChild: true}); - - rootLogger.log({level: 'info', message: "some message"}); - childLogger.log({level: 'info', message: "some message", loggerName: "child", isChild: null}); + rootLogger1.info("some message"); + childLogger1.info("some message", {loggerName: "child", isChild: null}); + rootLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message", loggerName: "child", isChild: null}); - assume(actualOutput).eqls(expectedOutput); - }); + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); }); }); describe('Multiple child logger instances', () => { - describe('When logging with [LEVEL]() methods', () => { - it("should have independent default metadata that overrides the parent's", () => { + it("should have independent default metadata that overrides the parent's", () => { const expectedOutput = [ {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger {message: "some message", level: "info", loggerInfo: {name: "child1", isChild: true}}, // child1 logger @@ -1512,60 +1373,43 @@ describe('Logger Instance', function () { {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger ]; - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], + const rootLogger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)], defaultMeta: {loggerInfo: {name: "root", isChild: false}} }); - const childLogger1 = rootLogger.child({loggerInfo: {name: "child1", isChild: true}}); - const childLogger2 = rootLogger.child({loggerInfo: {name: "child2", isChild: true}}); - const childLogger3 = rootLogger.child({loggerInfo: {name: "child3", isChild: true}}); - - rootLogger.info("some message"); - childLogger1.info("some message") - childLogger1.info("some message", {loggerInfo: {name: "child1-override", isChild: false}}) - childLogger2.info("some message") - childLogger2.info("some message", {loggerInfo: {name: "child2-override", isChild: false}}) - childLogger3.info("some message") - childLogger3.info("some message", {loggerInfo: {name: "child3-override", isChild: false}}) - rootLogger.info("some message") - - assume(actualOutput).eqls(expectedOutput); - }); - }); - - describe('When logging with log() method', () => { - it("should have independent default metadata that overrides the parent's", () => { - const expectedOutput = [ - {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger - {message: "some message", level: "info", loggerInfo: {name: "child1", isChild: true}}, // child1 logger - {message: "some message", level: "info", loggerInfo: {name: "child1-override", isChild: false}}, // child1 logger override - {message: "some message", level: "info", loggerInfo: {name: "child2", isChild: true}}, // child2 logger - {message: "some message", level: "info", loggerInfo: {name: "child2-override", isChild: false}}, // child2 logger override - {message: "some message", level: "info", loggerInfo: {name: "child3", isChild: true}}, // child3 logger - {message: "some message", level: "info", loggerInfo: {name: "child3-override", isChild: false}}, // child3 logger override - {message: "some message", level: "info", loggerInfo: {name: "root", isChild: false}}, // root logger - ]; - - const rootLogger = winston.createLogger({ - transports: [mockTransports.inMemory(actualOutput)], + const childLogger1 = rootLogger1.child({loggerInfo: {name: "child1", isChild: true}}); + const childLogger1a = rootLogger1.child({loggerInfo: {name: "child2", isChild: true}}); + const childLogger1b = rootLogger1.child({loggerInfo: {name: "child3", isChild: true}}); + const rootLogger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)], defaultMeta: {loggerInfo: {name: "root", isChild: false}} }); - const childLogger1 = rootLogger.child({loggerInfo: {name: "child1", isChild: true}}); - const childLogger2 = rootLogger.child({loggerInfo: {name: "child2", isChild: true}}); - const childLogger3 = rootLogger.child({loggerInfo: {name: "child3", isChild: true}}); - - rootLogger.log({level: 'info', message: "some message"}); - childLogger1.log({level: 'info', message: "some message"}); - childLogger1.log({level: 'info', message: "some message", loggerInfo: {name: "child1-override", isChild: false}}); - childLogger2.log({level: 'info', message: "some message"}); - childLogger2.log({level: 'info', message: "some message", loggerInfo: {name: "child2-override", isChild: false}}); - childLogger3.log({level: 'info', message: "some message"}); - childLogger3.log({level: 'info', message: "some message", loggerInfo: {name: "child3-override", isChild: false}}); - rootLogger.log({level: 'info', message: "some message"}); - - assume(actualOutput).eqls(expectedOutput); + const childLogger2 = rootLogger2.child({loggerInfo: {name: "child1", isChild: true}}); + const childLogger2a = rootLogger2.child({loggerInfo: {name: "child2", isChild: true}}); + const childLogger2b = rootLogger2.child({loggerInfo: {name: "child3", isChild: true}}); + + rootLogger1.info("some message"); + childLogger1.info("some message"); + childLogger1.info("some message", {loggerInfo: {name: "child1-override", isChild: false}}); + childLogger1a.info("some message"); + childLogger1a.info("some message", {loggerInfo: {name: "child2-override", isChild: false}}); + childLogger1b.info("some message"); + childLogger1b.info("some message", {loggerInfo: {name: "child3-override", isChild: false}}); + rootLogger1.info("some message"); + + rootLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message"}); + childLogger2.log({level: "info", message: "some message", loggerInfo: {name: "child1-override", isChild: false}}); + childLogger2a.log({level: "info", message: "some message"}); + childLogger2a.log({level: "info", message: "some message", loggerInfo: {name: "child2-override", isChild: false}}); + childLogger2b.log({level: "info", message: "some message"}); + childLogger2b.log({level: "info", message: "some message", loggerInfo: {name: "child3-override", isChild: false}}); + rootLogger2.log({level: "info", message: "some message"}); + + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); }); - }); }); }); @@ -1580,12 +1424,12 @@ describe('Logger Instance', function () { info => `${info.service} - ${info.level}: [${info.id}] ${info.message}` ) ), - transports: [mockTransports.inMemory(actualOutput)] + transports: [mockTransports.inMemory(levelOutput)] }); logger.info("This is my info"); - logger.log("info", "This is my info"); - assume(actualOutput[0][MESSAGE]).eqls(actualOutput[1][MESSAGE]); + logger.log({level: "info", message: "This is my info"}); + assume(levelOutput[0][MESSAGE]).eqls(levelOutput[1][MESSAGE]); }); }); }) From a2ec0c218927f9374c06999f98a922e97e5ede2e Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 12 Feb 2022 16:49:11 -0700 Subject: [PATCH 33/39] feat: introduce tests proving issues reported --- test/helpers/mocks/mock-transport.js | 4 +-- test/unit/winston/logger.test.js | 53 ++++++++++++++-------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/test/helpers/mocks/mock-transport.js b/test/helpers/mocks/mock-transport.js index 5e67f7207..3c89abbc0 100644 --- a/test/helpers/mocks/mock-transport.js +++ b/test/helpers/mocks/mock-transport.js @@ -24,7 +24,7 @@ function createMockTransport(write) { * @param array Array to be used to store the "written" chunks * @returns {winston.transports.Stream} */ -function inMemory(array) { +function inMemory(array, options = {}) { const memoryStream = new Writable({ objectMode: true, write: (chunk, encoding, next) => { @@ -32,7 +32,7 @@ function inMemory(array) { next() } }); - return new winston.transports.Stream({stream: memoryStream}) + return new winston.transports.Stream({stream: memoryStream, ...options}) } module.exports = { diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 5d0f5b53f..9f52e4964 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -208,31 +208,26 @@ describe('Logger Instance', function () { }); describe('Multiple Transports', function () { - it.skip('should log the same thing to every configured transport', function () { - winston.add(new Winston.transports.Console({ - format: Winston.format.combine( - Winston.format(info => { - info.message = info.message + "Console"; - return info; - })(), - Winston.format.splat(), Winston.format.simple(), Winston.format(info => { - // console.log(info); // meta is there! - return info; - })()), - handleExceptions: true - })); - Winston.add(new Winston.transports.File({ - filename: "test.log", - format: Winston.format.combine(Winston.format(info => { - // console.log(info); // meta is gone :(! and so is SPLAT only a array of length 1 - return info; - })(), Winston.format.splat(), Winston.format.simple()) - })); + it('should log the same thing to every configured transport', function () { + console.log('Reproduction of Issue #1430'); + this.skip(); + const transport1Output = []; + const transport2Output = []; + const customFormat = winston.format.combine( + winston.format.splat(), + winston.format.printf((info) => JSON.stringify(info)) + ); + + const logger = winston.createLogger(); + logger.add(mockTransports.inMemory(transport1Output, {format: customFormat})); + logger.add(mockTransports.inMemory(transport2Output, {format: customFormat})); for (let index = 0; index < 10; index++) { - Winston.error("test %s" + index, "blub", "metainfo"); + logger.info("test %s" + index, "blub", "metainfo"); } + + assume(transport1Output).eqls(transport2Output); }); }); }); @@ -819,14 +814,20 @@ describe('Logger Instance', function () { logger.info(err); }); - // TODO: This test needs finished or removed - it.skip(`.info('any string', new Error())`, function (done) { + it(`.info('any string', new Error())`, function () { + console.log(`The current result of this log statement results in the error message being concatenated with \ +the log message provided.\nThis behavior needs to be verified if it's intentional IMO`) + this.skip(); const err = new Error('test'); - const logger = helpers.createLogger(function (info) { - done(); + const logger = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] }); - logger.info(err); + logger.info('test message!', err); + + assume(levelOutput[0].level).eqls("info"); + assume(levelOutput[0].message).eqls("test message! test"); + assume(levelOutput[0].stack).exists("stack trace must exist"); }); }); }); From c4dd5eac189491f18bf6700eec071fa75611c4e6 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 12 Feb 2022 17:15:02 -0700 Subject: [PATCH 34/39] feat: introduce tests for non-primitive data types in metadata --- test/unit/winston/logger.test.js | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 9f52e4964..724b25bc3 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -863,6 +863,54 @@ the log message provided.\nThis behavior needs to be verified if it's intentiona }); }); + describe('Metadata with non-primitive data types', function() { + it('should support a Map', function() { + const expectedOutput = [ + {level: "info", message: "test message", someMap: new Map([["val1","c"], ["val2", "b"]])} + ]; + + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)] + }); + const logMeta = { + someMap: new Map([["val1","a"], ["val2", "b"], ["val1","c"]]) + }; + + logger1.info("test message", logMeta); + logger2.info({level: "info", message: "test message", ...logMeta}); + + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); + + it('should support a Set', function() { + const expectedOutput = [ + {level: "info", message: "test message", someSet: new Set(["a", "b"])} + ] + + const logger1 = winston.createLogger({ + transports: [mockTransports.inMemory(levelOutput)] + }); + const logger2 = winston.createLogger({ + transports: [mockTransports.inMemory(logOutput)] + }); + const logMeta = { + someSet: new Set(["a","b", "a"]) + }; + + logger1.info("test message", logMeta); + logger2.info({level: "info", message: "test message", ...logMeta}); + + assume(levelOutput).eqls(logOutput); + assume(expectedOutput).eqls(levelOutput); + assume(expectedOutput).eqls(logOutput); + }); + }); + describe('Metadata Precedence', () => { describe('Single logger instance', () => { it('should log to passed array correctly when using the `inMemory` transport', () => { From b36158ff3407aef39cf56b0222976ff71a37bbb2 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 12 Feb 2022 17:37:33 -0700 Subject: [PATCH 35/39] chore: deep clone when instantiating child logger --- lib/winston/logger.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/winston/logger.js b/lib/winston/logger.js index cf7431c97..241607fa1 100644 --- a/lib/winston/logger.js +++ b/lib/winston/logger.js @@ -44,9 +44,10 @@ class Logger extends Transform { child(childMetadata) { const logger = this; + const clonedParentMetadata = JSON.parse(JSON.stringify(this.defaultMeta)) return Object.create(logger, { defaultMeta: { - value: Object.assign({}, this.defaultMeta, childMetadata) + value: Object.assign({}, clonedParentMetadata, childMetadata) } }); } From 830d15bb8f6e5b089120ab54a6e5b14ed9f94728 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sat, 12 Feb 2022 17:40:43 -0700 Subject: [PATCH 36/39] chore: remove unused imports --- test/helpers/mocks/mock-transport.js | 1 - test/unit/winston/logger.test.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/test/helpers/mocks/mock-transport.js b/test/helpers/mocks/mock-transport.js index 3c89abbc0..0355e4584 100644 --- a/test/helpers/mocks/mock-transport.js +++ b/test/helpers/mocks/mock-transport.js @@ -1,7 +1,6 @@ const stream = require('stream') const winston = require('../../../lib/winston'); const {Writable} = require("stream"); -const {output} = require("./legacy-transport"); /** * Returns a new Winston transport instance which will invoke diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 724b25bc3..58e6f219d 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -10,8 +10,6 @@ const assume = require('assume'); const path = require('path'); -const stream = require('readable-stream'); -const util = require('util'); const { EOL } = require('os'); const isStream = require('is-stream'); const stdMocks = require('std-mocks'); From 97a87b6919a0ed9eaae982c407e5261d7b54a8f2 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Sun, 20 Feb 2022 20:40:06 -0700 Subject: [PATCH 37/39] chore: address comments on logger test additions --- test/unit/winston/logger.test.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/unit/winston/logger.test.js b/test/unit/winston/logger.test.js index 58e6f219d..6910dded9 100755 --- a/test/unit/winston/logger.test.js +++ b/test/unit/winston/logger.test.js @@ -936,16 +936,16 @@ the log message provided.\nThis behavior needs to be verified if it's intentiona it('should include default metadata defined on the logger instance', () => { const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true}, + {message: "some message", level: "info", isRoot: true}, ]; const logger1 = winston.createLogger({ transports: [mockTransports.inMemory(levelOutput)], - defaultMeta: {defaultMeta: true} + defaultMeta: {isRoot: true} }); const logger2 = winston.createLogger({ transports: [mockTransports.inMemory(logOutput)], - defaultMeta: {defaultMeta: true} + defaultMeta: {isRoot: true} }); logger1.info("some message"); @@ -978,16 +978,16 @@ the log message provided.\nThis behavior needs to be verified if it's intentiona it('should include both default metadata & log specific metadata', () => { const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: true, logMeta: true}, + {message: "some message", level: "info", isRoot: true, logMeta: true}, ]; const logger1 = winston.createLogger({ transports: [mockTransports.inMemory(levelOutput)], - defaultMeta: {defaultMeta: true} + defaultMeta: {isRoot: true} }); const logger2 = winston.createLogger({ transports: [mockTransports.inMemory(logOutput)], - defaultMeta: {defaultMeta: true} + defaultMeta: {isRoot: true} }); logger1.info("some message", {logMeta: true}); @@ -998,22 +998,22 @@ the log message provided.\nThis behavior needs to be verified if it's intentiona assume(expectedOutput).eqls(logOutput); }); - it('should include override default metadata with log specific metadata', () => { + it('should override default metadata with log specific metadata', () => { const expectedOutput = [ - {message: "some message", level: "info", defaultMeta: false}, + {message: "some message", level: "info", isRoot: false}, ]; const logger1 = winston.createLogger({ transports: [mockTransports.inMemory(levelOutput)], - defaultMeta: {defaultMeta: true} + defaultMeta: {isRoot: true} }); const logger2 = winston.createLogger({ transports: [mockTransports.inMemory(logOutput)], - defaultMeta: {defaultMeta: true} + defaultMeta: {isRoot: true} }); - logger1.info("some message", {defaultMeta: false}); - logger2.log({level: "info", message: "some message", defaultMeta: false}); + logger1.info("some message", {isRoot: false}); + logger2.log({level: "info", message: "some message", isRoot: false}); assume(levelOutput).eqls(logOutput); assume(expectedOutput).eqls(levelOutput); @@ -1083,7 +1083,7 @@ the log message provided.\nThis behavior needs to be verified if it's intentiona assume(expectedOutput).eqls(logOutput); }); - it('should include metadata log specific metadata', () => { + it('should include log specific metadata', () => { const expectedOutput = [ {message: "some message", level: "info", logMetadata: true}, {message: "some message", level: "info", logMetadata: false}, From ddb4dd1aa50fa341bfbd9e450697254b2ce31f16 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Mon, 21 Feb 2022 09:31:39 -0700 Subject: [PATCH 38/39] Replace JSON.stringify with one that accounts for cyclical refs --- lib/winston/logger.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/winston/logger.js b/lib/winston/logger.js index 241607fa1..1abab9457 100644 --- a/lib/winston/logger.js +++ b/lib/winston/logger.js @@ -17,6 +17,7 @@ const LegacyTransportStream = require('winston-transport/legacy'); const Profiler = require('./profiler'); const { warn } = require('./common'); const config = require('./config'); +const jsonStringify = require('safe-stable-stringify'); /** * Captures the number of format (i.e. %s strings) in a given string. @@ -44,7 +45,7 @@ class Logger extends Transform { child(childMetadata) { const logger = this; - const clonedParentMetadata = JSON.parse(JSON.stringify(this.defaultMeta)) + const clonedParentMetadata = JSON.parse(jsonStringify(this.defaultMeta)) return Object.create(logger, { defaultMeta: { value: Object.assign({}, clonedParentMetadata, childMetadata) @@ -634,7 +635,7 @@ class Logger extends Transform { _addDefaultMeta(msg) { if (this.defaultMeta) { // The msg must be cloned as it is being mutated, but any metadata provided with the msg takes precedence over default - const msgClone = JSON.parse(JSON.stringify(msg)); + const msgClone = JSON.parse(jsonStringify(msg)); Object.assign(msg, this.defaultMeta, msgClone); } } From 01982844284ca02f25ad9825927dfc9adb083d29 Mon Sep 17 00:00:00 2001 From: Jonathon Terry <10217028+Maverick1872@users.noreply.github.com> Date: Mon, 21 Feb 2022 09:35:50 -0700 Subject: [PATCH 39/39] Add lint rule for semicolons. Add script to run linter fix operation. Fix missing semis --- .eslintrc | 1 + lib/winston/logger.js | 2 +- package.json | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index 54abcead2..ffae4d782 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,7 @@ "extends": "@dabh/eslint-config-populist", "rules": { "one-var": ["error", { "var": "never", "let": "never", "const": "never" }], + "semi": "error", "strict": 0 }, "parserOptions": { diff --git a/lib/winston/logger.js b/lib/winston/logger.js index 1abab9457..dbcbfb557 100644 --- a/lib/winston/logger.js +++ b/lib/winston/logger.js @@ -45,7 +45,7 @@ class Logger extends Transform { child(childMetadata) { const logger = this; - const clonedParentMetadata = JSON.parse(jsonStringify(this.defaultMeta)) + const clonedParentMetadata = JSON.parse(jsonStringify(this.defaultMeta)); return Object.create(logger, { defaultMeta: { value: Object.assign({}, clonedParentMetadata, childMetadata) diff --git a/package.json b/package.json index 07cdaa8bd..e1bdbbbf4 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "types": "./index.d.ts", "scripts": { "lint": "eslint lib/*.js lib/winston/*.js lib/winston/**/*.js --resolve-plugins-relative-to ./node_modules/@dabh/eslint-config-populist", + "lint:fix": "npm run lint -- --fix", "test": "mocha", "test:coverage": "nyc npm run test:unit", "test:unit": "mocha test/unit",