Skip to content

Commit

Permalink
Unified Handler Tests (#2020)
Browse files Browse the repository at this point in the history
* cleaning up

* added some debug

* fixed typo

* refactored tests to show they are almost identical

* fixed rejection trigger

* removed debug code

* cleaning up

* replaced hack with Mocha setting

* removed unreferenced variable
  • Loading branch information
fearphage authored Sep 28, 2024
1 parent 51a4551 commit 22aab6d
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 226 deletions.
1 change: 1 addition & 0 deletions .mocharc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
allow-uncaught: true
exclude:
- test/helpers/scripts/*.js
exit: true
Expand Down
101 changes: 101 additions & 0 deletions test/helpers/handler-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
const assume = require('assume');

const helpers = require('.');
const winston = require('../../lib/winston');

module.exports = function ({ helper, listener, name, setup, toggleSetting, trigger }) {
describe('basics', function () {
var handler;

beforeEach(function () {
handler = helpers[helper]();
});

it('has expected methods', function () {
assume(handler.handle).is.a('function');
assume(handler.unhandle).is.a('function');
assume(handler.getAllInfo).is.a('function');
assume(handler.getProcessInfo).is.a('function');
assume(handler.getOsInfo).is.a('function');
assume(handler.getTrace).is.a('function');
});

it(`new ${name}()`, function () {
assume(function () {
// eslint-disable-next-line no-new
new winston[name]();
}).throws(/Logger is required/);
});

it(`new ${name}(logger)`, function () {
var logger = winston.createLogger();
var handler_ = new winston[name](logger);
assume(handler_.logger).equals(logger);
});

it('.getProcessInfo()', function () {
helpers.assertProcessInfo(handler.getProcessInfo());
});

it('.getOsInfo()', function () {
helpers.assertOsInfo(handler.getOsInfo());
});

it('.getTrace(new Error)', function () {
helpers.assertTrace(handler.getTrace(new Error()));
});

it('.getTrace()', function () {
helpers.assertTrace(handler.getTrace());
});

it('.getAllInfo(undefined)', function () {
// eslint-disable-next-line no-undefined
handler.getAllInfo(undefined);
});
});

describe('when error case is triggered', function () {
beforeEach(function () {
this.listeners = helpers[setup]();
});

afterEach(function () {
this.listeners.restore();
});

it('.handle()', function (done) {
var msg = new Date().toString();
var writeable = helpers.writeable(function (info) {
assume(info).is.an('object');
assume(info.error).is.an('error');
assume(info.error.message).equals(msg);
assume(info.message).includes(`${listener}: ${msg}`);
assume(info.stack).is.a('string');
assume(info.process).is.an('object');
assume(info.os).is.an('object');
assume(info.trace).is.an('array');

done();
});

var transport = new winston.transports.Stream({ stream: writeable });
var handler = helpers[helper]({
exitOnError: false,
transports: [transport]
});

assume(handler.catcher).is.a('undefined');

transport[toggleSetting] = true;
handler.handle();

assume(handler.catcher).is.a('function');
assume(process.listeners(listener)).deep.equals([
handler.catcher
]);

trigger(msg);
});
});
};
8 changes: 2 additions & 6 deletions test/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@

const assume = require('assume'),
fs = require('fs'),
path = require('path'),
through = require('through2'),
spawn = require('child_process').spawn,
stream = require('stream'),
util = require('util'),
winston = require('../../lib/winston'),
mockTransport = require('./mocks/mock-transport');

Expand Down Expand Up @@ -100,7 +98,7 @@ helpers.clearExceptions = function () {
*/
helpers.clearRejections = function () {
var listeners = process.listeners('unhandledRejection');
process.removeAllListeners('unhandledRejections');
process.removeAllListeners('unhandledRejection');

return {
restore: function () {
Expand All @@ -125,9 +123,7 @@ helpers.throw = function (msg) {
* @param {String} msg Error mesage to use
*/
helpers.reject = function (msg) {
return new Promise((resolve, reject) => {
reject(msg);
});
return Promise.reject(msg);
};

/**
Expand Down
119 changes: 10 additions & 109 deletions test/unit/winston/exception-handler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,117 +6,18 @@
*
*/

const stream = require('stream');
const assume = require('assume');
const mocha = require('mocha');
const winston = require('../../../lib/winston');
const baseHandlerTests = require('../../helpers/handler-tests');
const helpers = require('../../helpers');

//
// This is an awful and fragile hack that
// needs to be changed ASAP.
// https://github.com/mochajs/mocha/issues/1985
//
var _runTest = mocha.Runner.prototype.runTest;
mocha.Runner.prototype.runTest = function () {
this.allowUncaught = true;
_runTest.apply(this, arguments);
};

describe('ExceptionHandler', function () {
this.timeout(5000);

it('has expected methods', function () {
var handler = helpers.exceptionHandler();
assume(handler.handle).is.a('function');
assume(handler.unhandle).is.a('function');
assume(handler.getAllInfo).is.a('function');
assume(handler.getProcessInfo).is.a('function');
assume(handler.getOsInfo).is.a('function');
assume(handler.getTrace).is.a('function');
});

it('new ExceptionHandler()', function () {
assume(function () {
new winston.ExceptionHandler();
}).throws(/Logger is required/);
});

it('new ExceptionHandler(logger)', function () {
var logger = winston.createLogger();
var handler = new winston.ExceptionHandler(logger);
assume(handler.logger).equals(logger);
});

it('.getProcessInfo()', function () {
var handler = helpers.exceptionHandler();
helpers.assertProcessInfo(handler.getProcessInfo());
});

it('.getOsInfo()', function () {
var handler = helpers.exceptionHandler();
helpers.assertOsInfo(handler.getOsInfo());
});

it('.getTrace(new Error)', function () {
var handler = helpers.exceptionHandler();
helpers.assertTrace(handler.getTrace(new Error()));
});

it('.getTrace()', function () {
var handler = helpers.exceptionHandler();
helpers.assertTrace(handler.getTrace());
});

it('.handle()', function (done) {
var existing = helpers.clearExceptions();
var writeable = new stream.Writable({
objectMode: true,
write: function (info) {
assume(info).is.an('object');
assume(info.error).is.an('error');
assume(info.error.message).equals('wtf this error');
assume(info.message).includes('uncaughtException: wtf this error');
assume(info.stack).is.a('string');
assume(info.process).is.an('object');
assume(info.os).is.an('object');
assume(info.trace).is.an('array');

existing.restore();
done();
}
});

var transport = new winston.transports.Stream({ stream: writeable });
var handler = helpers.exceptionHandler({
exitOnError: false,
transports: [transport]
});

assume(handler.catcher).equals(undefined);

transport.handleExceptions = true;
handler.handle();

assume(handler.catcher).is.a('function');
assume(process.listeners('uncaughtException')).deep.equals([
handler.catcher
]);

helpers.throw('wtf this error');
});

it('.getAllInfo(undefined)', function () {
var handler = helpers.exceptionHandler();
// eslint-disable-next-line no-undefined
handler.getAllInfo(undefined);
});

after(function () {
//
// Restore normal `runTest` functionality
// so that we only affect the current suite.
//
mocha.Runner.prototype.runTest = _runTest;
this.timeout(100);

baseHandlerTests({
name: 'ExceptionHandler',
helper: 'exceptionHandler',
setup: 'clearExceptions',
listener: 'uncaughtException',
toggleSetting: 'handleExceptions',
trigger: msg => helpers.throw(msg)
});
});
121 changes: 10 additions & 111 deletions test/unit/winston/rejection-handler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,119 +6,18 @@
*
*/

const stream = require('stream');
const assume = require('assume');
const mocha = require('mocha');
const winston = require('../../../lib/winston');
const baseHandlerTests = require('../../helpers/handler-tests');
const helpers = require('../../helpers');

//
// This is an awful and fragile hack that
// needs to be changed ASAP.
// https://github.com/mochajs/mocha/issues/1985
//
var _runTest = mocha.Runner.prototype.runTest;
mocha.Runner.prototype.runTest = function () {
this.allowUncaught = true;
_runTest.apply(this, arguments);
};

describe('UnhandledRejectionHandler', function () {
this.timeout(5000);

it('has expected methods', function () {
var handler = helpers.rejectionHandler();
assume(handler.handle).is.a('function');
assume(handler.unhandle).is.a('function');
assume(handler.getAllInfo).is.a('function');
assume(handler.getProcessInfo).is.a('function');
assume(handler.getOsInfo).is.a('function');
assume(handler.getTrace).is.a('function');
});

it('new RejectionHandler()', function () {
assume(function () {
new winston.RejectionHandler();
}).throws(/Logger is required/);
});

it('new RejectionHandler(logger)', function () {
var logger = winston.createLogger();
var handler = new winston.RejectionHandler(logger);
assume(handler.logger).equals(logger);
});

it('.getProcessInfo()', function () {
var handler = helpers.rejectionHandler();
helpers.assertProcessInfo(handler.getProcessInfo());
});

it('.getOsInfo()', function () {
var handler = helpers.rejectionHandler();
helpers.assertOsInfo(handler.getOsInfo());
});

it('.getTrace(new Error)', function () {
var handler = helpers.rejectionHandler();
helpers.assertTrace(handler.getTrace(new Error()));
});

it('.getTrace()', function () {
var handler = helpers.rejectionHandler();
helpers.assertTrace(handler.getTrace());
});

it('.handle()', function (done) {
process.removeAllListeners('unhandledRejection');
var existing = helpers.clearRejections();
var writeable = new stream.Writable({
objectMode: true,
write: function (info) {
assume(info).is.an('object');
assume(info.error).is.an('error');
assume(info.rejection).is.true();
assume(info.error.message).equals('wtf this rejection');
assume(info.message).includes('unhandledRejection: wtf this rejection');
assume(info.stack).is.a('string');
assume(info.process).is.an('object');
assume(info.os).is.an('object');
assume(info.trace).is.an('array');

existing.restore();
done();
}
});

var transport = new winston.transports.Stream({ stream: writeable });
var handler = helpers.rejectionHandler({
exitOnError: false,
transports: [transport]
});

assume(handler.catcher).equals(undefined);

transport.handleRejections = true;
handler.handle();

assume(handler.catcher).is.a('function');
assume(process.listeners('unhandledRejection')).deep.equals([
handler.catcher
]);

helpers.reject(new Error('wtf this rejection'));
});

it('.getAllInfo(undefined)', function () {
var handler = helpers.rejectionHandler();
// eslint-disable-next-line no-undefined
handler.getAllInfo(undefined);
});

after(function () {
//
// Restore normal `runTest` functionality
// so that we only affect the current suite.
//
mocha.Runner.prototype.runTest = _runTest;
this.timeout(100);

baseHandlerTests({
name: 'RejectionHandler',
helper: 'rejectionHandler',
setup: 'clearRejections',
listener: 'unhandledRejection',
toggleSetting: 'handleRejections',
trigger: msg => helpers.reject(new Error(msg))
});
});

0 comments on commit 22aab6d

Please sign in to comment.