Skip to content

Commit

Permalink
Use parameters which by default is false
Browse files Browse the repository at this point in the history
  • Loading branch information
ilgonmic committed Jul 15, 2024
1 parent 964df70 commit 964fa2c
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 92 deletions.
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,10 @@ To ensure your tests aren't leaving messes around, here are some ideas to get st
- Try something like [wtfnode][npm-wtfnode]
- Use [`.only`](#exclusive-tests) until you find the test that causes Mocha to hang

### `--pass-on-failing-test-suite`

If set on true, Mocha returns zero code even if there are failed tests during run.

### `--fail-zero`

> _New in v9.1.0_ Fail test run if no tests are encountered with `exit-code: 1`.
Expand Down
93 changes: 44 additions & 49 deletions lib/cli/run-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,62 +21,49 @@ const {UnmatchedFile} = require('./collect-files');

/**
* Exits Mocha when tests + code under test has finished execution (default)
* @param {number} failOnFailingTestSuite - Exit code; typically # of failures
* @param {number} code - Exit code; typically # of failures
* @ignore
* @private
*/
const exitMochaLater = failOnFailingTestSuite => {
return code => {
process.on('exit', () => {
if (failOnFailingTestSuite) {
process.exitCode = Math.min(code, 255);
} else {
process.exitCode = 0;
}
});
};
const exitMochaLater = code => {
process.on('exit', () => {
process.exitCode = Math.min(code, 255);
});
};

/**
* Exits Mocha when Mocha itself has finished execution, regardless of
* what the tests or code under test is doing.
* @param {number} failOnFailingTestSuite - Exit code; typically # of failures
* @param {number} code - Exit code; typically # of failures
* @ignore
* @private
*/
const exitMocha = failOnFailingTestSuite => {
return code => {
let clampedCode;
if (failOnFailingTestSuite) {
clampedCode = Math.min(code, 255);
} else {
clampedCode = 0;
const exitMocha = code => {
const clampedCode = Math.min(code, 255);
let draining = 0;

// Eagerly set the process's exit code in case stream.write doesn't
// execute its callback before the process terminates.
process.exitCode = clampedCode;

// flush output for Node.js Windows pipe bug
// https://github.com/joyent/node/issues/6247 is just one bug example
// https://github.com/visionmedia/mocha/issues/333 has a good discussion
const done = () => {
if (!draining--) {
process.exit(clampedCode);
}
let draining = 0;

// Eagerly set the process's exit code in case stream.write doesn't
// execute its callback before the process terminates.
process.exitCode = clampedCode;

// flush output for Node.js Windows pipe bug
// https://github.com/joyent/node/issues/6247 is just one bug example
// https://github.com/visionmedia/mocha/issues/333 has a good discussion
const done = () => {
if (!draining--) {
process.exit(clampedCode);
}
};
};

const streams = [process.stdout, process.stderr];
const streams = [process.stdout, process.stderr];

streams.forEach(stream => {
// submit empty write request and wait for completion
draining += 1;
stream.write('', done);
});
streams.forEach(stream => {
// submit empty write request and wait for completion
draining += 1;
stream.write('', done);
});

done();
};
done();
};

/**
Expand Down Expand Up @@ -152,15 +139,15 @@ const handleUnmatchedFiles = (mocha, unmatchedFiles) => {
* @param {Mocha} mocha - Mocha instance
* @param {Options} [opts] - Command line options
* @param {boolean} [opts.exit] - Whether or not to force-exit after tests are complete
* @param {boolean} [opts.failOnFailingTestSuite] - Whether or not to fail test run if tests were failed
* @param {boolean} [opts.passOnFailingTestSuite] - Whether or not to fail test run if tests were failed
* @param {Object} fileCollectParams - Parameters that control test
* file collection. See `lib/cli/collect-files.js`.
* @returns {Promise<Runner>}
* @private
*/
const singleRun = async (
mocha,
{exit, failOnFailingTestSuite},
{exit, passOnFailingTestSuite},
fileCollectParams
) => {
const fileCollectionObj = collectFiles(fileCollectParams);
Expand All @@ -175,9 +162,7 @@ const singleRun = async (
// handles ESM modules
await mocha.loadFilesAsync();
return mocha.run(
exit
? exitMocha(failOnFailingTestSuite)
: exitMochaLater(failOnFailingTestSuite)
createExitHandler({exit, passOnFailingTestSuite})
);
};

Expand Down Expand Up @@ -209,9 +194,7 @@ const parallelRun = async (mocha, options, fileCollectParams) => {

// note that we DO NOT load any files here; this is handled by the worker
return mocha.run(
options.exit
? exitMocha(options.failOnFailingTestSuite)
: exitMochaLater(options.failOnFailingTestSuite)
createExitHandler(options)
);
};

Expand Down Expand Up @@ -308,3 +291,15 @@ exports.validateLegacyPlugin = (opts, pluginType, map = {}) => {
}
}
};

const createExitHandler = ({ exit, passOnFailingTestSuite }) => {
return code => {
const clampedCode = passOnFailingTestSuite
? 0
: Math.min(code, 255);

return exit
? exitMocha(clampedCode)
: exitMochaLater(clampedCode);
};
};
2 changes: 1 addition & 1 deletion lib/cli/run-option-metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const TYPES = (exports.types = {
'diff',
'dry-run',
'exit',
'fail-on-failing-test-suite',
'pass-on-failing-test-suite',
'fail-zero',
'forbid-only',
'forbid-pending',
Expand Down
6 changes: 3 additions & 3 deletions lib/cli/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ exports.builder = yargs =>
requiresArg: true,
coerce: list
},
'fail-on-failing-test-suite': {
default: true,
description: 'Fail test run if tests were failed',
'pass-on-failing-test-suite': {
default: false,
description: 'Not fail test run if tests were failed',
group: GROUPS.RULES
},
'fail-zero': {
Expand Down
12 changes: 6 additions & 6 deletions lib/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ exports.run = function (...args) {
* @param {boolean} [options.delay] - Delay root suite execution?
* @param {boolean} [options.diff] - Show diff on failure?
* @param {boolean} [options.dryRun] - Report tests without running them?
* @param {boolean} [options.failOnFailingTestSuite] - Fail test run if tests were failed?
* @param {boolean} [options.passOnFailingTestSuite] - Fail test run if tests were failed?
* @param {boolean} [options.failZero] - Fail test run if zero tests?
* @param {string} [options.fgrep] - Test filter given string.
* @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
Expand Down Expand Up @@ -217,7 +217,7 @@ function Mocha(options = {}) {
'delay',
'diff',
'dryRun',
'failOnFailingTestSuite',
'passOnFailingTestSuite',
'failZero',
'forbidOnly',
'forbidPending',
Expand Down Expand Up @@ -876,13 +876,13 @@ Mocha.prototype.failZero = function (failZero) {
* Fail test run if tests were failed.
*
* @public
* @see [CLI option](../#-fail-on-failing-test-suite)
* @param {boolean} [failOnFailingTestSuite=true] - Whether to fail test run.
* @see [CLI option](../#-pass-on-failing-test-suite)
* @param {boolean} [passOnFailingTestSuite=false] - Whether to fail test run.
* @return {Mocha} this
* @chainable
*/
Mocha.prototype.failOnFailingTestSuite = function(failOnFailingTestSuite) {
this.options.failOnFailingTestSuite = failOnFailingTestSuite !== false;
Mocha.prototype.passOnFailingTestSuite = function(passOnFailingTestSuite) {
this.options.passOnFailingTestSuite = passOnFailingTestSuite === true;
return this;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// this generic fixture does nothing special and will be used if no fixture is supplied

'use strict';

var assert = require('assert');
Expand Down
22 changes: 0 additions & 22 deletions test/integration/options/failOnFailingTestSuite.spec.js

This file was deleted.

40 changes: 40 additions & 0 deletions test/integration/options/passOnFailingTestSuite.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

var helpers = require('../helpers');
var runMochaJSON = helpers.runMochaJSON;

describe('Enabled --pass-on-failing-test-suite', function() {
var args = ['--pass-on-failing-test-suite=true'];

it('Test should finish with zero code with disabled option', function(done) {
var fixture = 'failing-sync.fixture.js';
runMochaJSON(fixture, args, function(err, res) {
if (err) {
return done(err);
}

expect(res, 'to have passed test count', 0)
.and('to have test count', 1)
.and('to have exit code', 0);
done();
});
});
});

describe('Disabled --pass-on-failing-test-suite', function() {
var args = ['--pass-on-failing-test-suite=false'];

it('Test should return non-zero code with enabled option', function(done) {
var fixture = 'failing-sync.fixture.js';
runMochaJSON(fixture, args, function(err, res) {
if (err) {
return done(err);
}

expect(res, 'to have passed test count', 0)
.and('to have test count', 1)
.and('to have exit code', 1);
done();
});
});
});
18 changes: 9 additions & 9 deletions test/unit/mocha.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,24 +376,24 @@ describe('Mocha', function () {
});
});

describe('failOnFailingTestSuite()', function() {
it('should set the failOnFailingTestSuite option to true', function() {
mocha.failOnFailingTestSuite();
describe('passOnFailingTestSuite()', function() {
it('should set the passOnFailingTestSuite option to false', function() {
mocha.passOnFailingTestSuite();
expect(
mocha.options,
'to have property',
'failOnFailingTestSuite',
true
'passOnFailingTestSuite',
false
);
});

it('should set the failOnFailingTestSuite option to false', function() {
mocha.failOnFailingTestSuite(false);
it('should set the passOnFailingTestSuite option to true', function() {
mocha.passOnFailingTestSuite(true);
expect(
mocha.options,
'to have property',
'failOnFailingTestSuite',
false
'passOnFailingTestSuite',
true
);
});
});
Expand Down

0 comments on commit 964fa2c

Please sign in to comment.