Skip to content

Commit

Permalink
Correct issue with timeout 0 closing prematurely, without causing any…
Browse files Browse the repository at this point in the history
… new issues allowing --no-exit to close; [ci-skip] because we already tested this and are just keeping the branch in case we need to compare to the superior solution
  • Loading branch information
ScottFreeCode committed Aug 12, 2017
1 parent 075bd51 commit ead3576
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/runnable.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ Runnable.prototype.run = function (fn) {
var ctx = this.ctx;
var finished;
var emitted;
var keepalive = setInterval(function () {}, 30 * 1000);

// Sometimes the ctx exists, but it is not runnable
if (ctx && ctx.runnable) {
Expand All @@ -277,6 +278,7 @@ Runnable.prototype.run = function (fn) {

// finished
function done (err) {
clearInterval(keepalive);
var ms = self.timeout();
if (self.timedOut) {
return;
Expand Down
6 changes: 6 additions & 0 deletions test/integration/fixtures/timeout-0-done.fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

it('never finishes', function (done) {
process.send('process started');
this.timeout(0);
});
16 changes: 16 additions & 0 deletions test/integration/fixtures/timeout-0-noexit.fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

it('finishes', function () {
process.send('process started');
this.timeout(0);
});

it('finishes asynchronously', function (done) {
this.timeout(0);
setTimeout(done, 0);
});

it('finishes with a promise', function () {
this.timeout(0);
return Promise.resolve();
});
7 changes: 7 additions & 0 deletions test/integration/fixtures/timeout-0-promise.fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

it('never finishes', function () {
process.send('process started');
this.timeout(0);
return new Promise(function () {});
});
33 changes: 33 additions & 0 deletions test/integration/options.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

var assert = require('assert');
var run = require('./helpers').runMochaJSON;
var fork = require('child_process').fork;
var path = require('path');
var args = [];

describe('options', function () {
Expand Down Expand Up @@ -280,4 +282,35 @@ describe('options', function () {
});
});
});

describe('--no-exit', function () {
before(function () {
args = ['--no-exit'];
});

it('still allows process to finish', function (done) {
this.timeout(10 * 1000);
var child = fork(path.join(__dirname, '..', '..', 'bin', '_mocha'), args.concat([path.join(__dirname, 'fixtures', 'timeout-0-noexit.fixture.js')]), { silent: true });
child.on('error', function (error) {
if (timeout) { clearTimeout(timeout); }
if (done) { done(error); }
done = null;
});
var timeout;
child.on('message', function () {
timeout = setTimeout(function () {
child.kill('SIGINT');
if (done) { done(new Error('Test did not end right away like it should have')); }
done = null;
}, 5000);
});
child.on('exit', pass);
child.on('close', pass);
function pass () {
clearTimeout(timeout);
if (done) { done(); }
done = null;
}
});
});
});
54 changes: 54 additions & 0 deletions test/integration/timeout.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

var assert = require('assert');
var run = require('./helpers').runMochaJSON;
var fork = require('child_process').fork;
var path = require('path');
var args = [];

describe('this.timeout()', function () {
Expand All @@ -18,4 +20,56 @@ describe('this.timeout()', function () {
done();
});
});

describe('0 (no timeout)', function () {
this.timeout(10 * 1000);

it('does not spuriously end async tests that miss calling `done`', function (done) {
var child = fork(path.join(__dirname, '..', '..', 'bin', '_mocha'), [path.join(__dirname, 'fixtures', 'timeout-0-done.fixture.js')], { silent: true });
child.on('error', function (error) {
if (timeout) { clearTimeout(timeout); }
if (done) { done(error); }
done = null;
});
var timeout;
child.on('message', function () {
timeout = setTimeout(function () {
child.kill('SIGINT');
if (done) { done(); }
done = null;
}, 5000);
});
child.on('exit', fail);
child.on('close', fail);
function fail () {
clearTimeout(timeout);
if (done) { done(new Error('Test ended despite disabled timeout!')); }
done = null;
}
});

it('does not spuriously end promise tests that never resolve', function (done) {
var child = fork(path.join(__dirname, '..', '..', 'bin', '_mocha'), [path.join(__dirname, 'fixtures', 'timeout-0-promise.fixture.js')], { silent: true });
child.on('error', function (error) {
if (timeout) { clearTimeout(timeout); }
if (done) { done(error); }
done = null;
});
var timeout;
child.on('message', function () {
timeout = setTimeout(function () {
child.kill('SIGINT');
if (done) { done(); }
done = null;
}, 5000);
});
child.on('exit', fail);
child.on('close', fail);
function fail () {
clearTimeout(timeout);
if (done) { done(new Error('Test ended despite disabled timeout!')); }
done = null;
}
});
});
});

0 comments on commit ead3576

Please sign in to comment.