Skip to content

Commit

Permalink
Merge 2e56fbc into f23c17d
Browse files Browse the repository at this point in the history
  • Loading branch information
novemberborn committed Apr 1, 2017
2 parents f23c17d + 2e56fbc commit b6d69e8
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 26 deletions.
24 changes: 13 additions & 11 deletions lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class Test {
this.endCallbackFinisher = null;
this.finishDueToAttributedError = null;
this.finishDueToInactivity = null;
this.finishing = false;
this.finished = false;
this.pendingAssertions = [];
this.pendingThrowsAssertion = null;
this.planCount = null;
Expand Down Expand Up @@ -152,15 +152,15 @@ class Test {
}

countPassedAssertion() {
if (this.finishing) {
if (this.finished) {
this.saveFirstError(new Error('Assertion passed, but test has already ended'));
}

this.assertCount++;
}

addPendingAssertion(promise) {
if (this.finishing) {
if (this.finished) {
this.saveFirstError(new Error('Assertion passed, but test has already ended'));
}

Expand All @@ -169,7 +169,7 @@ class Test {
}

addFailedAssertion(error) {
if (this.finishing) {
if (this.finished) {
this.saveFirstError(new Error('Assertion failed, but test has already ended'));
}

Expand Down Expand Up @@ -365,21 +365,19 @@ class Test {
}

finish() {
this.finishing = true;

if (!this.assertError && this.pendingThrowsAssertion) {
return this.waitForPendingThrowsAssertion();
}

this.verifyPlan();
this.verifyAssertions();

if (this.assertError || this.pendingAssertions.length === 0) {
return this.completeFinish();
}

// Finish after potential errors from pending assertions have been consumed.
return Promise.all(this.pendingAssertions).then(() => this.completeFinish());
// Retry finishing after potential errors from pending assertions have been consumed.
const consumedErrors = Promise.all(this.pendingAssertions);
// Note that more assertions may be added in the meantime.
this.pendingAssertions = [];
return consumedErrors.then(() => this.finish());
}

finishPromised() {
Expand All @@ -389,6 +387,10 @@ class Test {
}

completeFinish() {
this.verifyPlan();
this.verifyAssertions();

this.finished = true;
this.duration = globals.now() - this.startedAt;

let reason = this.assertError;
Expand Down
51 changes: 36 additions & 15 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,8 @@ test('number of assertions matches t.plan when the test exits, but before all pe
result = r;
}).run().then(passed => {
t.is(passed, false);
t.match(result.reason.message, /Assertion passed, but test has already ended/);
t.is(result.reason.name, 'Error');
t.is(result.reason.assertion, 'plan');
t.is(result.reason.operator, '===');
t.end();
});
});
Expand All @@ -604,35 +604,30 @@ test('number of assertions matches t.plan when the test exits, but before all pe
a.throws(delay.reject(10, new Error('foo')), 'foo');
a.notThrows(delay(10), 'foo');
setTimeout(() => {
a.fail();
a.pass();
}, 5);
}, null, r => {
result = r;
}).run().then(passed => {
t.is(passed, false);
t.match(result.reason.message, /Assertion failed, but test has already ended/);
t.is(result.reason.name, 'Error');
t.is(result.reason.assertion, 'plan');
t.is(result.reason.operator, '===');
t.end();
});
});

test('number of assertions doesn\'t match plan when the test exits, but before all promises resolve another is added', t => {
let result;
const passed = ava(a => {
ava(a => {
a.plan(3);
a.throws(delay.reject(10, new Error('foo')), 'foo');
a.notThrows(delay(10), 'foo');
setTimeout(() => {
a.throws(Promise.reject(new Error('foo')), 'foo');
}, 5);
}, null, r => {
result = r;
}).run();

t.is(passed, false);
t.is(result.reason.assertion, 'plan');
t.is(result.reason.operator, '===');
t.end();
}).run().then(passed => {
t.is(passed, true);
t.end();
});
});

test('assertions return promises', t => {
Expand All @@ -646,6 +641,32 @@ test('assertions return promises', t => {
});
});

// https://github.com/avajs/ava/issues/1330
test('no crash when adding assertions after the test has ended', t => {
t.plan(3);

ava(a => {
a.pass();
setTimeout(() => {
t.doesNotThrow(() => a.pass());
}, 5);
}).run();

ava(a => {
a.pass();
setTimeout(() => {
t.doesNotThrow(() => a.fail());
}, 5);
}).run();

ava(a => {
a.pass();
setTimeout(() => {
t.doesNotThrow(() => a.notThrows(Promise.resolve()));
}, 5);
}).run();
});

test('contextRef', t => {
new Test({
contextRef: {context: {foo: 'bar'}},
Expand Down

0 comments on commit b6d69e8

Please sign in to comment.