diff --git a/lib/interfaces/common.js b/lib/interfaces/common.js index 7991e113f7..e7e84b2511 100644 --- a/lib/interfaces/common.js +++ b/lib/interfaces/common.js @@ -3,6 +3,7 @@ var Suite = require('../suite'); var errors = require('../errors'); var createMissingArgumentError = errors.createMissingArgumentError; +var createUnsupportedError = errors.createUnsupportedError; /** * Functions common to more than one interface. @@ -126,14 +127,14 @@ module.exports = function(suites, context, mocha) { suites.unshift(suite); if (opts.isOnly) { if (mocha.options.forbidOnly && shouldBeTested(suite)) { - throw new Error('`.only` forbidden'); + throw createUnsupportedError('`.only` forbidden'); } suite.parent.appendOnlySuite(suite); } if (suite.pending) { if (mocha.options.forbidPending && shouldBeTested(suite)) { - throw new Error('Pending test forbidden'); + throw createUnsupportedError('Pending test forbidden'); } } if (typeof opts.fn === 'function') { @@ -165,6 +166,8 @@ module.exports = function(suites, context, mocha) { * @returns {*} */ only: function(mocha, test) { + if (mocha.options.forbidOnly) + throw createUnsupportedError('`.only` forbidden'); test.markOnly(); return test; }, diff --git a/lib/runner.js b/lib/runner.js index aabffda96a..c2bdf28bc8 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -522,11 +522,6 @@ Runner.prototype.runTest = function(fn) { return; } - var suite = this.parents().reverse()[0] || this.suite; - if (this.forbidOnly && suite.hasOnly()) { - fn(new Error('`.only` forbidden')); - return; - } if (this.asyncOnly) { test.asyncOnly = true; } diff --git a/test/integration/fixtures/options/forbid-only/only-before-each.fixture.js b/test/integration/fixtures/options/forbid-only/only-before-each.fixture.js new file mode 100644 index 0000000000..19bfb86409 --- /dev/null +++ b/test/integration/fixtures/options/forbid-only/only-before-each.fixture.js @@ -0,0 +1,8 @@ +'use strict'; + +describe('test marked with only and beforeEach has skip', function() { + beforeEach(function() { + this.skip(); + }); + it.only('only test', function() {}); +}); diff --git a/test/integration/fixtures/options/forbid-only/only-before.fixture.js b/test/integration/fixtures/options/forbid-only/only-before.fixture.js new file mode 100644 index 0000000000..3924ac4082 --- /dev/null +++ b/test/integration/fixtures/options/forbid-only/only-before.fixture.js @@ -0,0 +1,8 @@ +'use strict'; + +describe('test marked with only and before has skip', function() { + before(function() { + this.skip(); + }); + it.only('only test', function() {}); +}); diff --git a/test/integration/options/forbidOnly.spec.js b/test/integration/options/forbidOnly.spec.js index 592f0f25df..1886becb7d 100644 --- a/test/integration/options/forbidOnly.spec.js +++ b/test/integration/options/forbidOnly.spec.js @@ -26,13 +26,19 @@ describe('--forbid-only', function() { it('should fail if there are tests marked only', function(done) { var fixture = path.join('options', 'forbid-only', 'only'); - runMochaJSON(fixture, args, function(err, res) { - if (err) { - return done(err); - } - expect(res, 'to have failed with error', onlyErrorMessage); - done(); - }); + var spawnOpts = {stdio: 'pipe'}; + runMocha( + fixture, + args, + function(err, res) { + if (err) { + return done(err); + } + expect(res, 'to have failed with output', new RegExp(onlyErrorMessage)); + done(); + }, + spawnOpts + ); }); it('should fail if there are tests in suites marked only', function(done) { @@ -45,11 +51,7 @@ describe('--forbid-only', function() { if (err) { return done(err); } - - expect(res, 'to satisfy', { - code: 1, - output: new RegExp(onlyErrorMessage) - }); + expect(res, 'to have failed with output', new RegExp(onlyErrorMessage)); done(); }, spawnOpts @@ -66,10 +68,7 @@ describe('--forbid-only', function() { if (err) { return done(err); } - expect(res, 'to satisfy', { - code: 1, - output: new RegExp(onlyErrorMessage) - }); + expect(res, 'to have failed with output', new RegExp(onlyErrorMessage)); done(); }, spawnOpts @@ -86,10 +85,7 @@ describe('--forbid-only', function() { if (err) { return done(err); } - expect(res, 'to satisfy', { - code: 1, - output: new RegExp(onlyErrorMessage) - }); + expect(res, 'to have failed with output', new RegExp(onlyErrorMessage)); done(); }, spawnOpts @@ -124,4 +120,38 @@ describe('--forbid-only', function() { } ); }); + + it('should fail even if before has "skip"', function(done) { + var fixture = path.join('options', 'forbid-only', 'only-before'); + var spawnOpts = {stdio: 'pipe'}; + runMocha( + fixture, + args, + function(err, res) { + if (err) { + return done(err); + } + expect(res, 'to have failed with output', new RegExp(onlyErrorMessage)); + done(); + }, + spawnOpts + ); + }); + + it('should fail even if beforeEach has "skip"', function(done) { + var fixture = path.join('options', 'forbid-only', 'only-before-each'); + var spawnOpts = {stdio: 'pipe'}; + runMocha( + fixture, + args, + function(err, res) { + if (err) { + return done(err); + } + expect(res, 'to have failed with output', new RegExp(onlyErrorMessage)); + done(); + }, + spawnOpts + ); + }); });