diff --git a/test/integration/fixtures/uncaught/after-runner.fixture.js b/test/integration/fixtures/uncaught/after-runner.fixture.js new file mode 100644 index 0000000000..dbb6403b82 --- /dev/null +++ b/test/integration/fixtures/uncaught/after-runner.fixture.js @@ -0,0 +1,9 @@ +'use strict'; + +describe("Uncaught exception after runner's end", () => { + it('test', () => { + setTimeout(() => { + throw new Error('Unexpected crash'); + }, 100); + }); +}); diff --git a/test/integration/fixtures/uncaught.fixture.js b/test/integration/fixtures/uncaught/double.fixture.js similarity index 100% rename from test/integration/fixtures/uncaught.fixture.js rename to test/integration/fixtures/uncaught/double.fixture.js diff --git a/test/integration/fixtures/uncaught-fatal.fixture.js b/test/integration/fixtures/uncaught/fatal.fixture.js similarity index 100% rename from test/integration/fixtures/uncaught-fatal.fixture.js rename to test/integration/fixtures/uncaught/fatal.fixture.js diff --git a/test/integration/fixtures/uncaught-hook.fixture.js b/test/integration/fixtures/uncaught/hook.fixture.js similarity index 100% rename from test/integration/fixtures/uncaught-hook.fixture.js rename to test/integration/fixtures/uncaught/hook.fixture.js diff --git a/test/integration/fixtures/regression/issue-1327.fixture.js b/test/integration/fixtures/uncaught/issue-1327.fixture.js similarity index 100% rename from test/integration/fixtures/regression/issue-1327.fixture.js rename to test/integration/fixtures/uncaught/issue-1327.fixture.js diff --git a/test/integration/fixtures/regression/issue-1417.fixture.js b/test/integration/fixtures/uncaught/issue-1417.fixture.js similarity index 100% rename from test/integration/fixtures/regression/issue-1417.fixture.js rename to test/integration/fixtures/uncaught/issue-1417.fixture.js diff --git a/test/integration/fixtures/uncaught-pending.fixture.js b/test/integration/fixtures/uncaught/pending.fixture.js similarity index 100% rename from test/integration/fixtures/uncaught-pending.fixture.js rename to test/integration/fixtures/uncaught/pending.fixture.js diff --git a/test/integration/regression.spec.js b/test/integration/regression.spec.js index 0682cdc353..0cf644e6b3 100644 --- a/test/integration/regression.spec.js +++ b/test/integration/regression.spec.js @@ -4,21 +4,6 @@ var run = require('./helpers').runMocha; var runJSON = require('./helpers').runMochaJSON; describe('regressions', function() { - it('issue-1327: should run the first test and then bail', function(done) { - var args = []; - runJSON('regression/issue-1327.fixture.js', args, function(err, res) { - if (err) { - return done(err); - } - expect(res, 'to have failed') - .and('to have passed test count', 1) - .and('to have failed test count', 1) - .and('to have passed test', 'test 1') - .and('to have failed test', 'test 1'); - done(); - }); - }); - it('issue-1991: Declarations do not get cleaned up unless you set them to `null` - Memory Leak', function(done) { // on a modern MBP takes ±5 seconds on node 4.0, but on older laptops with node 0.12 ±40 seconds. // Could easily take longer on even weaker machines (Travis-CI containers for example). @@ -90,22 +75,4 @@ describe('regressions', function() { done(); }); }); - - it('issue-1417 uncaught exceptions from async specs', function(done) { - runJSON('regression/issue-1417.fixture.js', [], function(err, res) { - if (err) { - done(err); - return; - } - expect(res, 'to have failed with errors', 'sync error a', 'sync error b') - .and('to have exit code', 2) - .and('not to have passed tests') - .and('not to have pending tests') - .and('to have failed test order', [ - 'fails exactly once when a global error is thrown synchronously and done errors', - 'fails exactly once when a global error is thrown synchronously and done completes' - ]); - done(); - }); - }); }); diff --git a/test/integration/uncaught.spec.js b/test/integration/uncaught.spec.js index 5b193280bc..c517bb0577 100644 --- a/test/integration/uncaught.spec.js +++ b/test/integration/uncaught.spec.js @@ -1,60 +1,56 @@ 'use strict'; -var assert = require('assert'); -var run = require('./helpers').runMochaJSON; +var helpers = require('./helpers'); +var run = helpers.runMochaJSON; +var runMocha = helpers.runMocha; +var invokeNode = helpers.invokeNode; var args = []; describe('uncaught exceptions', function() { it('handles uncaught exceptions from hooks', function(done) { - run('uncaught-hook.fixture.js', args, function(err, res) { + run('uncaught/hook.fixture.js', args, function(err, res) { if (err) { - done(err); - return; + return done(err); } - assert.strictEqual(res.stats.pending, 0); - assert.strictEqual(res.stats.passes, 0); - assert.strictEqual(res.stats.failures, 1); - - assert.strictEqual( - res.failures[0].fullTitle, - 'uncaught "before each" hook for "test"' - ); - assert.strictEqual(res.code, 1); + + expect(res, 'to have failed with error', 'oh noes') + .and('to have passed test count', 0) + .and('to have pending test count', 0) + .and('to have failed test count', 1) + .and('to have failed test', '"before each" hook for "test"'); + done(); }); }); it('handles uncaught exceptions from async specs', function(done) { - run('uncaught.fixture.js', args, function(err, res) { + run('uncaught/double.fixture.js', args, function(err, res) { if (err) { - done(err); - return; + return done(err); } - assert.strictEqual(res.stats.pending, 0); - assert.strictEqual(res.stats.passes, 0); - assert.strictEqual(res.stats.failures, 2); - - assert.strictEqual( - res.failures[0].title, - 'fails exactly once when a global error is thrown first' - ); - assert.strictEqual( - res.failures[1].title, - 'fails exactly once when a global error is thrown second' - ); - assert.strictEqual(res.code, 2); + + expect(res, 'to have failed with error', 'global error', 'test error') + .and('to have passed test count', 0) + .and('to have pending test count', 0) + .and('to have failed test count', 2) + .and( + 'to have failed test', + 'fails exactly once when a global error is thrown first', + 'fails exactly once when a global error is thrown second' + ); + done(); }); }); it('handles uncaught exceptions from which Mocha cannot recover', function(done) { - run('uncaught-fatal.fixture.js', args, function(err, res) { + run('uncaught/fatal.fixture.js', args, function(err, res) { if (err) { return done(err); } var testName = 'should bail if a successful test asynchronously fails'; - expect(res, 'to have failed') + expect(res, 'to have failed with error', 'global error') .and('to have passed test count', 1) .and('to have failed test count', 1) .and('to have passed test', testName) @@ -65,12 +61,12 @@ describe('uncaught exceptions', function() { }); it('handles uncaught exceptions within pending tests', function(done) { - run('uncaught-pending.fixture.js', args, function(err, res) { + run('uncaught/pending.fixture.js', args, function(err, res) { if (err) { return done(err); } - expect(res, 'to have failed') + expect(res, 'to have failed with error', 'I am uncaught!') .and('to have passed test count', 3) .and('to have pending test count', 1) .and('to have failed test count', 1) @@ -115,13 +111,66 @@ describe('uncaught exceptions', function() { }); it('removes uncaught exceptions handlers correctly', function(done) { - run('uncaught/listeners.fixture.js', args, function(err, res) { + var path = require.resolve('./fixtures/uncaught/listeners.fixture.js'); + invokeNode([path], function(err, res) { if (err) { return done(err); } - expect(res, 'to have passed').and('to have passed test count', 0); + expect(res, 'to have passed'); + done(); + }); + }); + it("handles uncaught exceptions after runner's end", function(done) { + runMocha( + 'uncaught/after-runner.fixture.js', + args, + function(err, res) { + if (err) { + return done(err); + } + + expect(res, 'to have failed').and('to satisfy', { + failing: 0, + passing: 1, + pending: 0, + output: expect.it('to contain', 'Error: Unexpected crash') + }); + + done(); + }, + 'pipe' + ); + }); + + it('issue-1327: should run the first test and then bail', function(done) { + run('uncaught/issue-1327.fixture.js', args, function(err, res) { + if (err) { + return done(err); + } + expect(res, 'to have failed with error', 'Too bad') + .and('to have passed test count', 1) + .and('to have failed test count', 1) + .and('to have passed test', 'test 1') + .and('to have failed test', 'test 1'); + done(); + }); + }); + + it('issue-1417: uncaught exceptions from async specs', function(done) { + run('uncaught/issue-1417.fixture.js', args, function(err, res) { + if (err) { + return done(err); + } + expect(res, 'to have failed with errors', 'sync error a', 'sync error b') + .and('to have exit code', 2) + .and('not to have passed tests') + .and('not to have pending tests') + .and('to have failed test order', [ + 'fails exactly once when a global error is thrown synchronously and done errors', + 'fails exactly once when a global error is thrown synchronously and done completes' + ]); done(); }); });