Skip to content

Commit ead3576

Browse files
committed
Correct issue with timeout 0 closing prematurely, without causing any 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
1 parent 075bd51 commit ead3576

File tree

6 files changed

+118
-0
lines changed

6 files changed

+118
-0
lines changed

lib/runnable.js

+2
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ Runnable.prototype.run = function (fn) {
260260
var ctx = this.ctx;
261261
var finished;
262262
var emitted;
263+
var keepalive = setInterval(function () {}, 30 * 1000);
263264

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

278279
// finished
279280
function done (err) {
281+
clearInterval(keepalive);
280282
var ms = self.timeout();
281283
if (self.timedOut) {
282284
return;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'use strict';
2+
3+
it('never finishes', function (done) {
4+
process.send('process started');
5+
this.timeout(0);
6+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
it('finishes', function () {
4+
process.send('process started');
5+
this.timeout(0);
6+
});
7+
8+
it('finishes asynchronously', function (done) {
9+
this.timeout(0);
10+
setTimeout(done, 0);
11+
});
12+
13+
it('finishes with a promise', function () {
14+
this.timeout(0);
15+
return Promise.resolve();
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
it('never finishes', function () {
4+
process.send('process started');
5+
this.timeout(0);
6+
return new Promise(function () {});
7+
});

test/integration/options.spec.js

+33
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
var assert = require('assert');
44
var run = require('./helpers').runMochaJSON;
5+
var fork = require('child_process').fork;
6+
var path = require('path');
57
var args = [];
68

79
describe('options', function () {
@@ -280,4 +282,35 @@ describe('options', function () {
280282
});
281283
});
282284
});
285+
286+
describe('--no-exit', function () {
287+
before(function () {
288+
args = ['--no-exit'];
289+
});
290+
291+
it('still allows process to finish', function (done) {
292+
this.timeout(10 * 1000);
293+
var child = fork(path.join(__dirname, '..', '..', 'bin', '_mocha'), args.concat([path.join(__dirname, 'fixtures', 'timeout-0-noexit.fixture.js')]), { silent: true });
294+
child.on('error', function (error) {
295+
if (timeout) { clearTimeout(timeout); }
296+
if (done) { done(error); }
297+
done = null;
298+
});
299+
var timeout;
300+
child.on('message', function () {
301+
timeout = setTimeout(function () {
302+
child.kill('SIGINT');
303+
if (done) { done(new Error('Test did not end right away like it should have')); }
304+
done = null;
305+
}, 5000);
306+
});
307+
child.on('exit', pass);
308+
child.on('close', pass);
309+
function pass () {
310+
clearTimeout(timeout);
311+
if (done) { done(); }
312+
done = null;
313+
}
314+
});
315+
});
283316
});

test/integration/timeout.spec.js

+54
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
var assert = require('assert');
44
var run = require('./helpers').runMochaJSON;
5+
var fork = require('child_process').fork;
6+
var path = require('path');
57
var args = [];
68

79
describe('this.timeout()', function () {
@@ -18,4 +20,56 @@ describe('this.timeout()', function () {
1820
done();
1921
});
2022
});
23+
24+
describe('0 (no timeout)', function () {
25+
this.timeout(10 * 1000);
26+
27+
it('does not spuriously end async tests that miss calling `done`', function (done) {
28+
var child = fork(path.join(__dirname, '..', '..', 'bin', '_mocha'), [path.join(__dirname, 'fixtures', 'timeout-0-done.fixture.js')], { silent: true });
29+
child.on('error', function (error) {
30+
if (timeout) { clearTimeout(timeout); }
31+
if (done) { done(error); }
32+
done = null;
33+
});
34+
var timeout;
35+
child.on('message', function () {
36+
timeout = setTimeout(function () {
37+
child.kill('SIGINT');
38+
if (done) { done(); }
39+
done = null;
40+
}, 5000);
41+
});
42+
child.on('exit', fail);
43+
child.on('close', fail);
44+
function fail () {
45+
clearTimeout(timeout);
46+
if (done) { done(new Error('Test ended despite disabled timeout!')); }
47+
done = null;
48+
}
49+
});
50+
51+
it('does not spuriously end promise tests that never resolve', function (done) {
52+
var child = fork(path.join(__dirname, '..', '..', 'bin', '_mocha'), [path.join(__dirname, 'fixtures', 'timeout-0-promise.fixture.js')], { silent: true });
53+
child.on('error', function (error) {
54+
if (timeout) { clearTimeout(timeout); }
55+
if (done) { done(error); }
56+
done = null;
57+
});
58+
var timeout;
59+
child.on('message', function () {
60+
timeout = setTimeout(function () {
61+
child.kill('SIGINT');
62+
if (done) { done(); }
63+
done = null;
64+
}, 5000);
65+
});
66+
child.on('exit', fail);
67+
child.on('close', fail);
68+
function fail () {
69+
clearTimeout(timeout);
70+
if (done) { done(new Error('Test ended despite disabled timeout!')); }
71+
done = null;
72+
}
73+
});
74+
});
2175
});

0 commit comments

Comments
 (0)