Skip to content

Commit

Permalink
[Fix] Fix premature end of tests (and running sibling tests) when tes…
Browse files Browse the repository at this point in the history
…t includes subtests

Fixes tape-testing#222.
  • Loading branch information
nhamer authored and ljharb committed Oct 15, 2017
1 parent 9d839ed commit e9036cb
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 32 deletions.
44 changes: 20 additions & 24 deletions lib/test.js
Expand Up @@ -104,19 +104,11 @@ Test.prototype.test = function (name, opts, cb) {
this.emit('test', t);
t.on('prerun', function () {
self.assertCount++;
})
});

if (!self._pendingAsserts()) {
nextTick(function () {
self._end();
});
if (!this._pendingAsserts()) {
this._runProgeny();
}

nextTick(function() {
if (!self._plan && self.pendingCount == self._progeny.length) {
self._end();
}
});
};

Test.prototype.comment = function (msg) {
Expand Down Expand Up @@ -144,7 +136,6 @@ Test.prototype.timeoutAfter = function(ms) {
}

Test.prototype.end = function (err) {
var self = this;
if (arguments.length >= 1 && !!err) {
this.ifError(err);
}
Expand All @@ -153,18 +144,10 @@ Test.prototype.end = function (err) {
this.fail('.end() called twice');
}
this.calledEnd = true;
this._end();
this._runProgeny();
};

Test.prototype._end = function (err) {
var self = this;
if (this._progeny.length) {
var t = this._progeny.shift();
t.on('end', function () { self._end() });
t.run();
return;
}

if (!this.ended) this.emit('end');
var pendingAsserts = this._pendingAsserts();
if (!this._planError && this._plan !== undefined && pendingAsserts) {
Expand All @@ -177,6 +160,21 @@ Test.prototype._end = function (err) {
this.ended = true;
};

Test.prototype._runProgeny = function () {
var self = this;
if (this._progeny.length) {
var t = this._progeny.shift();
t.on('end', function () { self._runProgeny() });
nextTick(function() {
t.run();
});
return;
}
if(this.calledEnd || this._plan) {
this._end();
}
};

Test.prototype._exit = function () {
if (this._plan !== undefined &&
!this._planError && this.assertCount !== this._plan) {
Expand Down Expand Up @@ -298,9 +296,7 @@ Test.prototype._assert = function assert (ok, opts) {
if (extra.exiting) {
self._end();
} else {
nextTick(function () {
self._end();
});
self._runProgeny();
}
}

Expand Down
1 change: 1 addition & 0 deletions test/add-subtest-async.js
Expand Up @@ -7,5 +7,6 @@ test('parent', function (t) {
st.pass('child');
st.end();
});
t.end();
}, 100);
})
21 changes: 21 additions & 0 deletions test/async_end.js
@@ -0,0 +1,21 @@
var test = require('../');

test('async end', function(t) {
setTimeout(function() {
t.assert(!t.ended, '!t.ended');
t.end();
}, 200);
});

test('async end with subtest', function(t) {
setTimeout(function() {
t.assert(!t.ended, '!t.ended');
t.end();
}, 200);

t.test('subtest', function(g) {
g.assert(!t.ended, 'subtest !t.ended');
g.end();
});
});

24 changes: 16 additions & 8 deletions test/nested-sync-noplan-noend.js
@@ -1,25 +1,32 @@
var tape = require('../');
var tap = require('tap');
var concat = require('concat-stream');
var stripFullStack = require('./common').stripFullStack;

tap.test('nested sync test without plan or end', function (tt) {
tt.plan(1);

var test = tape.createHarness();
var tc = function (rows) {
tt.same(rows.toString('utf8'), [
tt.same(stripFullStack(rows.toString('utf8')), [
'TAP version 13',
'# nested without plan or end',
'not ok 1 test timed out after 100ms',
' ---',
' operator: fail',
' stack: |-',
' Error: test timed out after 100ms',
' [... stack stripped ...]',
' ...',
'# first',
'ok 1 should be truthy',
'# second',
'ok 2 should be truthy',
'# second',
'ok 3 should be truthy',
'',
'1..2',
'# tests 2',
'1..3',
'# tests 3',
'# pass 2',
'',
'# ok'
'# fail 1',
].join('\n') + '\n');
};

Expand All @@ -38,6 +45,7 @@ tap.test('nested sync test without plan or end', function (tt) {
q.end()
}, 10);
});
});

t.timeoutAfter(100);
});
});
98 changes: 98 additions & 0 deletions test/nested_test_ordering.js
@@ -0,0 +1,98 @@

var tape = require('../');
var tap = require('tap');
var concat = require('concat-stream');

var stripFullStack = require('./common').stripFullStack;

tap.test('plan vs end: plan', function (tt) {
tt.plan(1);

var test = tape.createHarness();
test.createStream().pipe(concat(function (rows) {
tt.same(rows.toString('utf8'), [
'TAP version 13',
'# first',
'ok 1 first test',
'ok 2 t not ended',
'ok 3 t has progeny',
'# second',
'ok 4 second test',
'# third',
'ok 5 third test',
'',
'1..5',
'# tests 5',
'# pass 5',
'',
'# ok'
].join('\n') + '\n');
}));

test('first', function (t) {
t.plan(4);
setTimeout(function () {
t.ok(1, 'first test');
t.ok(!t.ended, 't not ended');
t.ok(t._progeny.length, 't has progeny');
}, 200);

t.test('second', function (t) {
t.plan(1);
t.ok(1, 'second test');
});
});

test('third', function (t) {
t.plan(1);
setTimeout(function () {
t.ok(1, 'third test');
}, 100);
});
});

tap.test('plan vs end: end', function (tt) {
tt.plan(1);

var test = tape.createHarness();
test.createStream().pipe(concat(function (rows) {
tt.same(rows.toString('utf8'), [
'TAP version 13',
'# first',
'ok 1 first test',
'ok 2 t not ended',
'ok 3 t has progeny',
'# second',
'ok 4 second test',
'# third',
'ok 5 third test',
'',
'1..5',
'# tests 5',
'# pass 5',
'',
'# ok'
].join('\n') + '\n');
}));

test('first', function (t) {
setTimeout(function () {
t.ok(1, 'first test');
t.ok(!t.ended, 't not ended');
t.ok(t._progeny.length, 't has progeny');
t.end();
}, 200);

t.test('second', function (t) {
t.ok(1, 'second test');
t.end();
});
});

test('third', function (t) {
setTimeout(function () {
t.ok(1, 'third test');
t.end();
}, 100);
});
});

0 comments on commit e9036cb

Please sign in to comment.