From eed38d798270e230363abefd6934df8302c5f036 Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Sun, 22 Sep 2019 08:38:30 +0200 Subject: [PATCH] Mocha constructor: some fixes and cleanup (#4004) --- docs/index.md | 2 +- lib/mocha.js | 79 +++++++------------ lib/runner.js | 2 +- test/unit/mocha.spec.js | 166 +++++++++++++++++++++------------------ test/unit/runner.spec.js | 1 + 5 files changed, 120 insertions(+), 130 deletions(-) diff --git a/docs/index.md b/docs/index.md index 98c665b4f7..5dac9ff173 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1569,7 +1569,7 @@ mocha.setup({ // Use "tdd" interface, ignore leaks, and force all tests to be asynchronous mocha.setup({ ui: 'tdd', - ignoreLeaks: true, + checkLeaks: false, // default asyncOnly: true }); ``` diff --git a/lib/mocha.js b/lib/mocha.js index 5582324b8a..6c8bf2561b 100644 --- a/lib/mocha.js +++ b/lib/mocha.js @@ -69,18 +69,18 @@ exports.Test = require('./test'); * @param {boolean} [options.allowUncaught] - Propagate uncaught errors? * @param {boolean} [options.asyncOnly] - Force `done` callback or promise? * @param {boolean} [options.bail] - Bail after first test failure? - * @param {boolean} [options.checkLeaks] - If true, check leaks. + * @param {boolean} [options.checkLeaks] - Check for global variable leaks? + * @param {boolean} [options.color] - Color TTY output from reporter? * @param {boolean} [options.delay] - Delay root suite execution? - * @param {boolean} [options.enableTimeouts] - Enable timeouts? + * @param {boolean} [options.diff] - Show diff on failure? * @param {string} [options.fgrep] - Test filter given string. * @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite? * @param {boolean} [options.forbidPending] - Pending tests fail the suite? - * @param {boolean} [options.fullStackTrace] - Full stacktrace upon failure? + * @param {boolean} [options.fullTrace] - Full stacktrace upon failure? * @param {string[]} [options.global] - Variables expected in global scope. * @param {RegExp|string} [options.grep] - Test filter given regular expression. * @param {boolean} [options.growl] - Enable desktop notifications? - * @param {boolean} [options.hideDiff] - Suppress diffs from failures? - * @param {boolean} [options.ignoreLeaks] - Ignore global leaks? + * @param {boolean} [options.inlineDiffs] - Display inline diffs? * @param {boolean} [options.invert] - Invert test filter matches? * @param {boolean} [options.noHighlighting] - Disable syntax highlighting? * @param {string} [options.reporter] - Reporter name. @@ -89,8 +89,6 @@ exports.Test = require('./test'); * @param {number} [options.slow] - Slow threshold value. * @param {number|string} [options.timeout] - Timeout threshold value. * @param {string} [options.ui] - Interface name. - * @param {boolean} [options.color] - Color TTY output from reporter? - * @param {boolean} [options.useInlineDiffs] - Use inline diffs? */ function Mocha(options) { options = utils.assign({}, mocharc, options || {}); @@ -99,35 +97,14 @@ function Mocha(options) { // root suite this.suite = new exports.Suite('', new exports.Context(), true); - if ('useColors' in options) { - utils.deprecate( - 'useColors is DEPRECATED and will be removed from a future version of Mocha. Instead, use the "color" option' - ); - options.color = 'color' in options ? options.color : options.useColors; - } - - // Globals are passed in as options.global, with options.globals for backward compatibility. - options.globals = options.global || options.globals || []; - delete options.global; - this.grep(options.grep) .fgrep(options.fgrep) .ui(options.ui) .bail(options.bail) - .reporter(options.reporter, options.reporterOptions) - .useColors(options.color) + .reporter(options.reporter, options.reporterOption) .slow(options.slow) .useInlineDiffs(options.inlineDiffs) - .globals(options.globals); - - if ('enableTimeouts' in options) { - utils.deprecate( - 'enableTimeouts is DEPRECATED and will be removed from a future version of Mocha. Instead, use "timeout: false" to disable timeouts.' - ); - if (options.enableTimeouts === false) { - this.timeout(0); - } - } + .globals(options.global); // this guard exists because Suite#timeout does not consider `undefined` to be valid input if (typeof options.timeout !== 'undefined') { @@ -138,10 +115,6 @@ function Mocha(options) { this.retries(options.retries); } - if ('diff' in options) { - this.hideDiff(!options.diff); - } - [ 'allowUncaught', 'asyncOnly', @@ -257,6 +230,8 @@ Mocha.prototype.reporter = function(reporter, reporterOptions) { } this._reporter = _reporter; } + this.options.reporterOption = reporterOptions; + // alias option name is used in public reporters xunit/tap/progress this.options.reporterOptions = reporterOptions; return this; }; @@ -457,7 +432,7 @@ Mocha.prototype.invert = function() { * * @public * @see {@link Mocha#checkLeaks} - * @param {boolean} ignoreLeaks - Whether to ignore global leaks. + * @param {boolean} [ignoreLeaks=false] - Whether to ignore global leaks. * @return {Mocha} this * @chainable * @example @@ -466,7 +441,7 @@ Mocha.prototype.invert = function() { * mocha.ignoreLeaks(true); */ Mocha.prototype.ignoreLeaks = function(ignoreLeaks) { - this.options.ignoreLeaks = Boolean(ignoreLeaks); + this.options.checkLeaks = !ignoreLeaks; return this; }; @@ -480,7 +455,7 @@ Mocha.prototype.ignoreLeaks = function(ignoreLeaks) { * @chainable */ Mocha.prototype.checkLeaks = function() { - this.options.ignoreLeaks = false; + this.options.checkLeaks = true; return this; }; @@ -492,7 +467,7 @@ Mocha.prototype.checkLeaks = function() { * @chainable */ Mocha.prototype.fullTrace = function() { - this.options.fullStackTrace = true; + this.options.fullTrace = true; return this; }; @@ -555,7 +530,7 @@ Mocha.prototype._growl = growl.notify; * mocha.globals(['jQuery', 'MyLib']); */ Mocha.prototype.globals = function(globals) { - this.options.globals = this.options.globals + this.options.global = (this.options.global || []) .concat(globals) .filter(Boolean) .filter(function(elt, idx, arr) { @@ -574,7 +549,7 @@ Mocha.prototype.globals = function(globals) { */ Mocha.prototype.useColors = function(colors) { if (colors !== undefined) { - this.options.useColors = colors; + this.options.color = colors; } return this; }; @@ -584,12 +559,12 @@ Mocha.prototype.useColors = function(colors) { * in test failure output. * * @public - * @param {boolean} inlineDiffs - Whether to use inline diffs. + * @param {boolean} [inlineDiffs=false] - Whether to use inline diffs. * @return {Mocha} this * @chainable */ Mocha.prototype.useInlineDiffs = function(inlineDiffs) { - this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs; + this.options.inlineDiffs = inlineDiffs !== undefined && inlineDiffs; return this; }; @@ -597,12 +572,12 @@ Mocha.prototype.useInlineDiffs = function(inlineDiffs) { * Determines if reporter should include diffs in test failure output. * * @public - * @param {boolean} hideDiff - Whether to hide diffs. + * @param {boolean} [hideDiff=false] - Whether to hide diffs. * @return {Mocha} this * @chainable */ Mocha.prototype.hideDiff = function(hideDiff) { - this.options.hideDiff = hideDiff !== undefined && hideDiff; + this.options.diff = !(hideDiff === true); return this; }; @@ -814,8 +789,8 @@ Mocha.prototype.run = function(fn) { var runner = new exports.Runner(suite, options.delay); createStatsCollector(runner); var reporter = new this._reporter(runner, options); - runner.ignoreLeaks = options.ignoreLeaks !== false; - runner.fullStackTrace = options.fullStackTrace; + runner.checkLeaks = options.checkLeaks === true; + runner.fullStackTrace = options.fullTrace; runner.asyncOnly = options.asyncOnly; runner.allowUncaught = options.allowUncaught; runner.forbidOnly = options.forbidOnly; @@ -823,17 +798,17 @@ Mocha.prototype.run = function(fn) { if (options.grep) { runner.grep(options.grep, options.invert); } - if (options.globals) { - runner.globals(options.globals); + if (options.global) { + runner.globals(options.global); } if (options.growl) { this._growl(runner); } - if (options.useColors !== undefined) { - exports.reporters.Base.useColors = options.useColors; + if (options.color !== undefined) { + exports.reporters.Base.useColors = options.color; } - exports.reporters.Base.inlineDiffs = options.useInlineDiffs; - exports.reporters.Base.hideDiff = options.hideDiff; + exports.reporters.Base.inlineDiffs = options.inlineDiffs; + exports.reporters.Base.hideDiff = !options.diff; function done(failures) { fn = fn || utils.noop; diff --git a/lib/runner.js b/lib/runner.js index 3ef0da1f4d..d8d8dd6fb8 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -244,7 +244,7 @@ Runner.prototype.globals = function(arr) { * @private */ Runner.prototype.checkGlobals = function(test) { - if (this.ignoreLeaks) { + if (!this.checkLeaks) { return; } var ok = this._globals; diff --git a/test/unit/mocha.spec.js b/test/unit/mocha.spec.js index ed99a3e257..648853feab 100644 --- a/test/unit/mocha.spec.js +++ b/test/unit/mocha.spec.js @@ -18,37 +18,12 @@ describe('Mocha', function() { describe('constructor', function() { beforeEach(function() { - sandbox.stub(Mocha.prototype, 'useColors').returnsThis(); - sandbox.stub(utils, 'deprecate'); sandbox.stub(Mocha.prototype, 'timeout').returnsThis(); sandbox.stub(Mocha.prototype, 'globals').returnsThis(); + sandbox.stub(Mocha.prototype, 'useInlineDiffs').returnsThis(); }); - describe('when "useColors" option is defined', function() { - it('should prefer "color" over "useColors"', function() { - // eslint-disable-next-line no-new - new Mocha({useColors: true, color: false}); - expect(Mocha.prototype.useColors, 'to have a call satisfying', [ - false - ]).and('was called once'); - }); - - it('should assign "useColors" to "color"', function() { - // eslint-disable-next-line no-new - new Mocha({useColors: true}); - expect(Mocha.prototype.useColors, 'to have a call satisfying', [ - true - ]).and('was called once'); - }); - - it('should call utils.deprecate()', function() { - // eslint-disable-next-line no-new - new Mocha({useColors: true}); - expect(utils.deprecate, 'was called once'); - }); - }); - - describe('when "timeout" option is `undefined`', function() { + describe('when "options.timeout" is `undefined`', function() { it('should not attempt to set timeout', function() { // eslint-disable-next-line no-new new Mocha({timeout: undefined}); @@ -56,7 +31,7 @@ describe('Mocha', function() { }); }); - describe('when "timeout" option is `false`', function() { + describe('when "options.timeout" is `false`', function() { it('should set a timeout of 0', function() { // eslint-disable-next-line no-new new Mocha({timeout: false}); @@ -74,34 +49,16 @@ describe('Mocha', function() { ['singular'] ]).and('was called once'); }); - it('should delete mocha.options.global', function() { - var mocha = new Mocha({global: ['singular']}); - expect(mocha.options.global, 'to be', undefined); - }); }); - describe('when "options.globals" is provided', function() { - it('should pass "options.globals" to #globals()', function() { + describe('when "options.inlineDiffs" is `undefined`', function() { + it('should set inlineDiffs to `true`', function() { // eslint-disable-next-line no-new - new Mocha({globals: ['plural']}); - expect(Mocha.prototype.globals, 'to have a call satisfying', [ - ['plural'] - ]).and('was called once'); - }); - }); - - describe('when "options.global" AND "options.globals" are provided', function() { - it('should pass "options.global" to #globals(), ignoring "options.globals"', function() { - // eslint-disable-next-line no-new - new Mocha({global: ['singular'], globals: ['plural']}); - expect(Mocha.prototype.globals, 'to have a call satisfying', [ - ['singular'] + new Mocha({inlineDiffs: true}); + expect(Mocha.prototype.useInlineDiffs, 'to have a call satisfying', [ + true ]).and('was called once'); }); - it('should delete mocha.options.global', function() { - var mocha = new Mocha({global: ['singular'], globals: ['plural']}); - expect(mocha.options.global, 'to be', undefined); - }); }); }); @@ -132,10 +89,10 @@ describe('Mocha', function() { }); describe('#checkLeaks()', function() { - it('should set the ignoreLeaks option to false', function() { + it('should set the checkLeaks option to true', function() { var mocha = new Mocha(opts); mocha.checkLeaks(); - expect(mocha.options, 'to have property', 'ignoreLeaks', false); + expect(mocha.options, 'to have property', 'checkLeaks', true); }); it('should be chainable', function() { @@ -157,11 +114,24 @@ describe('Mocha', function() { }); }); + describe('#enableTimeouts()', function() { + it('should set the suite._enableTimeouts to true if no argument', function() { + var mocha = new Mocha(opts); + mocha.enableTimeouts(); + expect(mocha.suite._enableTimeouts, 'to be', true); + }); + + it('should be chainable', function() { + var mocha = new Mocha(opts); + expect(mocha.enableTimeouts(), 'to be', mocha); + }); + }); + describe('#fullTrace()', function() { - it('should set the fullStackTrace option to true', function() { + it('should set the fullTrace option to true', function() { var mocha = new Mocha(opts); mocha.fullTrace(); - expect(mocha.options, 'to have property', 'fullStackTrace', true); + expect(mocha.options, 'to have property', 'fullTrace', true); }); it('should be chainable', function() { @@ -173,7 +143,7 @@ describe('Mocha', function() { describe('#globals()', function() { it('should be an empty array initially', function() { var mocha = new Mocha(); - expect(mocha.options.globals, 'to be empty'); + expect(mocha.options.global, 'to be empty'); }); it('should be chainable', function() { @@ -185,13 +155,13 @@ describe('Mocha', function() { it('should not modify the whitelist when given empty string', function() { var mocha = new Mocha(opts); mocha.globals(''); - expect(mocha.options.globals, 'to be empty'); + expect(mocha.options.global, 'to be empty'); }); it('should not modify the whitelist when given empty array', function() { var mocha = new Mocha(opts); mocha.globals([]); - expect(mocha.options.globals, 'to be empty'); + expect(mocha.options.global, 'to be empty'); }); }); @@ -203,24 +173,24 @@ describe('Mocha', function() { it('should add string to the whitelist', function() { var mocha = new Mocha(opts); mocha.globals(elem); - expect(mocha.options.globals, 'to contain', elem); - expect(mocha.options.globals, 'to have length', 1); + expect(mocha.options.global, 'to contain', elem); + expect(mocha.options.global, 'to have length', 1); }); it('should add contents of string array to the whitelist', function() { var mocha = new Mocha(opts); var elems = [elem, elem2]; mocha.globals(elems); - expect(mocha.options.globals, 'to contain', elem, elem2); - expect(mocha.options.globals, 'to have length', elems.length); + expect(mocha.options.global, 'to contain', elem, elem2); + expect(mocha.options.global, 'to have length', elems.length); }); it('should not have duplicates', function() { var mocha = new Mocha({globals: [elem, elem2]}); var elems = [elem, elem2, elem3]; mocha.globals(elems); - expect(mocha.options.globals, 'to contain', elem, elem2, elem3); - expect(mocha.options.globals, 'to have length', elems.length); + expect(mocha.options.global, 'to contain', elem, elem2, elem3); + expect(mocha.options.global, 'to have length', elems.length); }); }); }); @@ -254,23 +224,48 @@ describe('Mocha', function() { }); }); + describe('#hideDiff()', function() { + it('should set the diff option to false when param equals true', function() { + var mocha = new Mocha(opts); + mocha.hideDiff(true); + expect(mocha.options, 'to have property', 'diff', false); + }); + + it('should set the diff option to true when param equals false', function() { + var mocha = new Mocha(opts); + mocha.hideDiff(false); + expect(mocha.options, 'to have property', 'diff', true); + }); + + it('should set the diff option to true when the param is undefined', function() { + var mocha = new Mocha(opts); + mocha.hideDiff(); + expect(mocha.options, 'to have property', 'diff', true); + }); + + it('should be chainable', function() { + var mocha = new Mocha(opts); + expect(mocha.hideDiff(), 'to be', mocha); + }); + }); + describe('#ignoreLeaks()', function() { - it('should set the ignoreLeaks option to true when param equals true', function() { + it('should set the checkLeaks option to false when param equals true', function() { var mocha = new Mocha(opts); mocha.ignoreLeaks(true); - expect(mocha.options, 'to have property', 'ignoreLeaks', true); + expect(mocha.options, 'to have property', 'checkLeaks', false); }); - it('should set the ignoreLeaks option to false when param equals false', function() { + it('should set the checkLeaks option to true when param equals false', function() { var mocha = new Mocha(opts); mocha.ignoreLeaks(false); - expect(mocha.options, 'to have property', 'ignoreLeaks', false); + expect(mocha.options, 'to have property', 'checkLeaks', true); }); - it('should set the ignoreLeaks option to false when the param is undefined', function() { + it('should set the checkLeaks option to true when the param is undefined', function() { var mocha = new Mocha(opts); mocha.ignoreLeaks(); - expect(mocha.options, 'to have property', 'ignoreLeaks', false); + expect(mocha.options, 'to have property', 'checkLeaks', true); }); it('should be chainable', function() { @@ -357,23 +352,42 @@ describe('Mocha', function() { }); }); + describe('#useColors()', function() { + it('should set the color option to true', function() { + var mocha = new Mocha(opts); + mocha.useColors(true); + expect(mocha.options, 'to have property', 'color', true); + }); + + it('should not create the color property', function() { + var mocha = new Mocha(opts); + mocha.useColors(); + expect(mocha.options, 'not to have property', 'color'); + }); + + it('should be chainable', function() { + var mocha = new Mocha(opts); + expect(mocha.useColors(), 'to be', mocha); + }); + }); + describe('#useInlineDiffs()', function() { - it('should set the useInlineDiffs option to true when param equals true', function() { + it('should set the inlineDiffs option to true when param equals true', function() { var mocha = new Mocha(opts); mocha.useInlineDiffs(true); - expect(mocha.options, 'to have property', 'useInlineDiffs', true); + expect(mocha.options, 'to have property', 'inlineDiffs', true); }); - it('should set the useInlineDiffs option to false when param equals false', function() { + it('should set the inlineDiffs option to false when param equals false', function() { var mocha = new Mocha(opts); mocha.useInlineDiffs(false); - expect(mocha.options, 'to have property', 'useInlineDiffs', false); + expect(mocha.options, 'to have property', 'inlineDiffs', false); }); - it('should set the useInlineDiffs option to false when the param is undefined', function() { + it('should set the inlineDiffs option to false when the param is undefined', function() { var mocha = new Mocha(opts); mocha.useInlineDiffs(); - expect(mocha.options, 'to have property', 'useInlineDiffs', false); + expect(mocha.options, 'to have property', 'inlineDiffs', false); }); it('should be chainable', function() { diff --git a/test/unit/runner.spec.js b/test/unit/runner.spec.js index ec2b8a0f34..31ac938b1f 100644 --- a/test/unit/runner.spec.js +++ b/test/unit/runner.spec.js @@ -23,6 +23,7 @@ describe('Runner', function() { beforeEach(function() { suite = new Suite('Suite', 'root'); runner = new Runner(suite); + runner.checkLeaks = true; sandbox = sinon.createSandbox(); });