Skip to content

Commit

Permalink
fail-fast when .only encountered in Suite w/ --forbid-only
Browse files Browse the repository at this point in the history
  • Loading branch information
boneskull authored and outsideris committed Dec 5, 2018
1 parent 00d5e90 commit d0c0cc0
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 26 deletions.
10 changes: 10 additions & 0 deletions lib/interfaces/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ module.exports = function(suites, context, mocha) {
suite.file = opts.file;
suites.unshift(suite);
if (opts.isOnly) {
if (
mocha.options.forbidOnly &&
(!mocha.options.grep ||
(mocha.options.grep &&
mocha.options.grep.test(suite.fullTitle()) &&
!mocha.options.invert))
) {
throw new Error('`.only` forbidden');
}

suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);
}
if (typeof opts.fn === 'function') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

describe.only('forbid only - suite marked with only', function() {});
2 changes: 1 addition & 1 deletion test/integration/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ module.exports = {
var result = JSON.parse(res.output);
result.code = res.code;
} catch (err) {
return fn(err);
return fn(new Error('output is not valid JSON:\n\n' + res.output));
}

fn(null, result);
Expand Down
134 changes: 109 additions & 25 deletions test/integration/options.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

var path = require('path');
var helpers = require('./helpers');
var run = helpers.runMochaJSON;
var runMochaJSON = helpers.runMochaJSON;
var runMocha = helpers.runMocha;
var runRaw = helpers.runMochaJSONRaw;
var directInvoke = helpers.invokeMocha;
var resolvePath = helpers.resolveFixturePath;
Expand All @@ -15,7 +16,10 @@ describe('options', function() {
});

it('should fail synchronous specs', function(done) {
run('options/async-only-sync.fixture.js', args, function(err, res) {
runMochaJSON('options/async-only-sync.fixture.js', args, function(
err,
res
) {
if (err) {
done(err);
return;
Expand All @@ -26,7 +30,10 @@ describe('options', function() {
});

it('should allow asynchronous specs', function(done) {
run('options/async-only-async.fixture.js', args, function(err, res) {
runMochaJSON('options/async-only-async.fixture.js', args, function(
err,
res
) {
if (err) {
done(err);
return;
Expand All @@ -43,7 +50,7 @@ describe('options', function() {
});

it('should stop after the first error', function(done) {
run('options/bail.fixture.js', args, function(err, res) {
runMochaJSON('options/bail.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -58,7 +65,10 @@ describe('options', function() {
});

it('should stop all tests after the first error in before hook', function(done) {
run('options/bail-with-before.fixture.js', args, function(err, res) {
runMochaJSON('options/bail-with-before.fixture.js', args, function(
err,
res
) {
if (err) {
done(err);
return;
Expand All @@ -71,7 +81,10 @@ describe('options', function() {
});

it('should stop all hooks after the first error', function(done) {
run('options/bail-with-after.fixture.js', args, function(err, res) {
runMochaJSON('options/bail-with-after.fixture.js', args, function(
err,
res
) {
if (err) {
done(err);
return;
Expand All @@ -90,7 +103,7 @@ describe('options', function() {
});

it('should sort tests in alphabetical order', function(done) {
run('options/sort*', args, function(err, res) {
runMochaJSON('options/sort*', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -108,7 +121,7 @@ describe('options', function() {
it('should run tests passed via file first', function(done) {
args = ['--file', resolvePath('options/file-alpha.fixture.js')];

run('options/file-beta.fixture.js', args, function(err, res) {
runMochaJSON('options/file-beta.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -128,7 +141,7 @@ describe('options', function() {
resolvePath('options/file-beta.fixture.js')
];

run('options/file-theta.fixture.js', args, function(err, res) {
runMochaJSON('options/file-theta.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -152,7 +165,7 @@ describe('options', function() {
});

it('should run the generated test suite', function(done) {
run('options/delay.fixture.js', args, function(err, res) {
runMochaJSON('options/delay.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -163,7 +176,7 @@ describe('options', function() {
});

it('should execute exclusive tests only', function(done) {
run('options/delay-only.fixture.js', args, function(err, res) {
runMochaJSON('options/delay-only.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -180,7 +193,7 @@ describe('options', function() {
});

it('should throw an error if the test suite failed to run', function(done) {
run('options/delay-fail.fixture.js', args, function(err, res) {
runMochaJSON('options/delay-fail.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -197,7 +210,7 @@ describe('options', function() {
describe('--grep', function() {
it('runs specs matching a string', function(done) {
args = ['--grep', 'match'];
run('options/grep.fixture.js', args, function(err, res) {
runMochaJSON('options/grep.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -212,7 +225,7 @@ describe('options', function() {
describe('runs specs matching a RegExp', function() {
it('with RegExp like strings(pattern follow by flag)', function(done) {
args = ['--grep', '/match/i'];
run('options/grep.fixture.js', args, function(err, res) {
runMochaJSON('options/grep.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -226,7 +239,7 @@ describe('options', function() {

it('string as pattern', function(done) {
args = ['--grep', '.*'];
run('options/grep.fixture.js', args, function(err, res) {
runMochaJSON('options/grep.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -243,7 +256,7 @@ describe('options', function() {
describe('with --invert', function() {
it('runs specs that do not match the pattern', function(done) {
args = ['--grep', 'fail', '--invert'];
run('options/grep.fixture.js', args, function(err, res) {
runMochaJSON('options/grep.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -260,7 +273,7 @@ describe('options', function() {
describe('--retries', function() {
it('retries after a certain threshold', function(done) {
args = ['--retries', '3'];
run('options/retries.fixture.js', args, function(err, res) {
runMochaJSON('options/retries.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -282,7 +295,7 @@ describe('options', function() {
});

it('succeeds if there are only passed tests', function(done) {
run('options/forbid-only/passed.js', args, function(err, res) {
runMochaJSON('options/forbid-only/passed.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -293,7 +306,7 @@ describe('options', function() {
});

it('fails if there are tests marked only', function(done) {
run('options/forbid-only/only.js', args, function(err, res) {
runMochaJSON('options/forbid-only/only.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand All @@ -304,15 +317,83 @@ describe('options', function() {
});

it('fails if there are tests in suites marked only', function(done) {
run('options/forbid-only/only-suite.js', args, function(err, res) {
runMocha('options/forbid-only/only-suite.js', args, function(err, res) {
if (err) {
done(err);
return;
}
expect(res, 'to have failed with error', onlyErrorMessage);
expect(res, 'to satisfy', {
code: 1,
output: new RegExp(onlyErrorMessage)
});
done();
});
});

it('fails if there is empty suite marked only', function(done) {
runMocha('options/forbid-only/only-empty-suite.js', args, function(
err,
res
) {
if (err) {
done(err);
return;
}
expect(res, 'to satisfy', {
code: 1,
output: new RegExp(onlyErrorMessage)
});
done();
});
});

it('fails if there is suite marked only which matches a grep', function(done) {
runMocha(
'options/forbid-only/only-suite.js',
args.concat('--fgrep', 'suite marked with only'),
function(err, res) {
if (err) {
done(err);
return;
}
expect(res, 'to satisfy', {
code: 1,
output: new RegExp(onlyErrorMessage)
});
done();
}
);
});

it('succeeds if suite marked only does not match grep', function(done) {
runMochaJSON(
'options/forbid-only/only-suite.js',
args.concat('--fgrep', 'bumble bees'),
function(err, res) {
if (err) {
done(err);
return;
}
expect(res, 'to have passed');
done();
}
);
});

it('succeeds if suite marked only does not match grep (using "invert")', function(done) {
runMochaJSON(
'options/forbid-only/only-suite.js',
args.concat('--fgrep', 'suite marked with only', '--invert'),
function(err, res) {
if (err) {
done(err);
return;
}
expect(res, 'to have passed');
done();
}
);
});
});

describe('--forbid-pending', function() {
Expand All @@ -323,7 +404,10 @@ describe('options', function() {
});

it('succeeds if there are only passed tests', function(done) {
run('options/forbid-pending/passed.js', args, function(err, res) {
runMochaJSON('options/forbid-pending/passed.js', args, function(
err,
res
) {
if (err) {
done(err);
return;
Expand All @@ -344,7 +428,7 @@ describe('options', function() {

Object.keys(forbidPendingFailureTests).forEach(function(title) {
it(title, function(done) {
run(
runMochaJSON(
path.join(
'options',
'forbid-pending',
Expand Down Expand Up @@ -386,7 +470,7 @@ describe('options', function() {
var t;
var args = behaviors[behavior] ? [behaviors[behavior]] : [];

var mocha = run('exit.fixture.js', args, function(err) {
var mocha = runMochaJSON('exit.fixture.js', args, function(err) {
clearTimeout(t);
if (err) {
done(err);
Expand Down Expand Up @@ -447,7 +531,7 @@ describe('options', function() {
* Calls handleResult with the result.
*/
function runMochaTest(fixture, args, handleResult, done) {
run(fixture, args, function(err, res) {
runMochaJSON(fixture, args, function(err, res) {
if (err) {
done(err);
return;
Expand Down

0 comments on commit d0c0cc0

Please sign in to comment.