123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- 'use strict';
- const assume = require('assume');
- const Writable = require('readable-stream/writable');
- const LegacyTransportStream = require('../legacy');
- const LegacyTransport = require('./fixtures/legacy-transport');
- const { testLevels, testOrder } = require('./fixtures');
- const { infosFor, logFor, levelAndMessage } = require('abstract-winston-transport/utils');
- const { LEVEL } = require('triple-beam');
- //
- // Silence the deprecation notice for sanity in test output.
- // TODO: Test coverage for the deprecation notice because why not?
- //
- const deprecated = {
- original: LegacyTransportStream.prototype._deprecated,
- silence() {
- LegacyTransportStream.prototype._deprecated = () => {};
- },
- restore() {
- LegacyTransportStream.prototype._deprecated = this.original;
- }
- };
- describe('LegacyTransportStream', () => {
- let legacy;
- let transport;
- before(deprecated.silence);
- beforeEach(() => {
- legacy = new LegacyTransport();
- transport = new LegacyTransportStream({
- transport: legacy
- });
- });
- it('should have the appropriate methods defined', () => {
- assume(transport).instanceof(Writable);
- assume(transport._write).is.a('function');
- // eslint-disable-next-line no-undefined
- assume(transport.log).equals(undefined);
- });
- it('should error with no transport', () => {
- assume(() => {
- transport = new LegacyTransportStream();
- assume(transport).instanceof(stream.Writable);
- }).throws(/Invalid transport, must be an object with a log method./);
- });
- it('should error with invalid transport', () => {
- assume(() => {
- transport = new LegacyTransportStream();
- assume(transport).instanceof(stream.Writable);
- }).throws(/Invalid transport, must be an object with a log method./);
- });
- it('should display a deprecation notice', done => {
- deprecated.restore();
- const error = console.error; // eslint-disable-line no-console
- console.error = msg => { // eslint-disable-line no-console
- assume(msg).to.include('is a legacy winston transport. Consider upgrading');
- setImmediate(done);
- };
- legacy = new LegacyTransport();
- transport = new LegacyTransportStream({
- transport: legacy
- });
- console.error = error; // eslint-disable-line no-console
- deprecated.silence();
- });
- it('sets __winstonError on the LegacyTransport instance', function () {
- assume(legacy.__winstonError).is.a('function');
- assume(legacy.listeners('error')).deep.equals([
- legacy.__winstonError
- ]);
- });
- it('emits an error on LegacyTransport error', done => {
- const err = new Error('Pass-through from stream');
- transport.on('error', actual => {
- assume(err).equals(actual);
- done();
- });
- legacy.emit('error', err);
- });
- describe('_write(info, enc, callback)', () => {
- it('should log to any level when { level: undefined }', done => {
- const expected = testOrder.map(levelAndMessage);
- legacy.on('logged', logFor(testOrder.length, (err, infos) => {
- if (err) {
- return done(err);
- }
- assume(infos.length).equals(expected.length);
- assume(infos).deep.equals(expected);
- done();
- }));
- expected.forEach(transport.write.bind(transport));
- });
- it('should only log messages BELOW the level priority', done => {
- const expected = testOrder.map(levelAndMessage);
- transport = new LegacyTransportStream({
- level: 'info',
- transport: legacy
- });
- legacy.on('logged', logFor(5, (err, infos) => {
- if (err) {
- return done(err);
- }
- assume(infos.length).equals(5);
- assume(infos).deep.equals(expected.slice(0, 5));
- done();
- }));
- transport.levels = testLevels;
- expected.forEach(transport.write.bind(transport));
- });
- it('{ level } should be ignored when { handleExceptions: true }', () => {
- const expected = testOrder.map(levelAndMessage).map(info => {
- info.exception = true;
- return info;
- });
- transport = new LegacyTransportStream({
- transport: legacy,
- level: 'info'
- });
- legacy.on('logged', logFor(testOrder.length, (err, infos) => {
- // eslint-disable-next-line no-undefined
- assume(err).equals(undefined);
- assume(infos.length).equals(expected.length);
- assume(infos).deep.equals(expected);
- }));
- transport.levels = testLevels;
- expected.forEach(transport.write.bind(transport));
- });
- describe('when { exception: true } in info', () => {
- it('should not invoke log when { handleExceptions: false }', done => {
- const expected = [{
- exception: true,
- [LEVEL]: 'error',
- level: 'error',
- message: 'Test exception handling'
- }, {
- [LEVEL]: 'test',
- level: 'test',
- message: 'Testing ... 1 2 3.'
- }];
- legacy.on('logged', info => {
- // eslint-disable-next-line no-undefined
- assume(info.exception).equals(undefined);
- done();
- });
- expected.forEach(transport.write.bind(transport));
- });
- it('should invoke log when { handleExceptions: true }', done => {
- const actual = [];
- const expected = [{
- exception: true,
- [LEVEL]: 'error',
- level: 'error',
- message: 'Test exception handling'
- }, {
- [LEVEL]: 'test',
- level: 'test',
- message: 'Testing ... 1 2 3.'
- }];
- transport = new LegacyTransportStream({
- handleExceptions: true,
- transport: legacy
- });
- legacy.on('logged', info => {
- actual.push(info);
- if (actual.length === expected.length) {
- assume(actual).deep.equals(expected);
- return done();
- }
- });
- expected.forEach(transport.write.bind(transport));
- });
- });
- });
- describe('_writev(chunks, callback)', () => {
- it('should be called when necessary in streams plumbing', done => {
- const expected = infosFor({
- count: 50,
- levels: testOrder
- });
- legacy.on('logged', logFor(50 * testOrder.length, (err, infos) => {
- if (err) {
- return done(err);
- }
- assume(infos.length).equals(expected.length);
- assume(infos).deep.equals(expected);
- done();
- }));
- //
- // Make the standard _write throw to ensure that _writev is called.
- //
- transport._write = () => {
- throw new Error('This should never be called');
- };
- transport.cork();
- expected.forEach(transport.write.bind(transport));
- transport.uncork();
- });
- });
- describe('close()', () => {
- it('removes __winstonError from the transport', () => {
- assume(legacy.__winstonError).is.a('function');
- assume(legacy.listenerCount('error')).equal(1);
- transport.close();
- assume(legacy.__winstonError).falsy();
- assume(legacy.listenerCount('error')).equal(0);
- });
- it('invokes .close() on the transport', done => {
- legacy.on('closed:custom', done);
- transport.close();
- });
- });
- describe('{ silent }', () => {
- it('{ silent: true } ._write() never calls `.log`', done => {
- const expected = {
- [LEVEL]: 'info',
- level: 'info',
- message: 'there will be json'
- };
- legacy.once('logged', () => (
- assume(true).false('"logged" event emitted unexpectedly')
- ));
- transport.silent = true;
- transport.write(expected);
- setImmediate(() => done());
- });
- it('{ silent: true } ._writev() never calls `.log`', done => {
- const expected = {
- [LEVEL]: 'info',
- level: 'info',
- message: 'there will be json'
- };
- legacy.once('logged', () => (
- assume(true).false('"logged" event emitted unexpectedly')
- ));
- transport.cork();
- for (let i = 0; i < 15; i++) {
- transport.write(expected);
- }
- transport.silent = true;
- transport.uncork();
- setImmediate(() => done());
- });
- it('{ silent: true } ensures ._accept(write) always returns false', () => {
- transport.silent = true;
- const accepted = transport._accept({
- chunk: {}
- });
- assume(accepted).false();
- });
- });
- //
- // Restore the deprecation notice after tests complete.
- //
- after(() => deprecated.restore());
- });
|