From 4a19a96da89a1533025295a7cd78b74c12528f04 Mon Sep 17 00:00:00 2001 From: tim Date: Sat, 10 Jun 2017 12:13:37 +0200 Subject: [PATCH] show output for .throws() when promise is resolved --- lib/assert.js | 16 +++++++++++----- test/assert.js | 47 +++++++++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index 28b8ae09c9..f3bde67c75 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -41,7 +41,6 @@ function wrapAssertions(callbacks) { const fail = callbacks.fail; const noop = () => {}; - const makeNoop = () => noop; const makeRethrow = reason => () => { throw reason; }; @@ -119,6 +118,7 @@ function wrapAssertions(callbacks) { }, throws(fn, err, message) { + const assertion = 'throws'; let promise; if (isPromise(fn)) { promise = fn; @@ -126,7 +126,7 @@ function wrapAssertions(callbacks) { promise = observableToPromise(fn); } else if (typeof fn !== 'function') { fail(this, new AssertionError({ - assertion: 'throws', + assertion, improperUsage: true, message: '`t.throws()` must be called with a function, Promise, or Observable', values: [formatAssertError.formatWithLabel('Called with:', fn)] @@ -174,10 +174,16 @@ function wrapAssertions(callbacks) { if (promise) { // Record stack before it gets lost in the promise chain. const stack = getStack(); - const intermediate = promise.then(makeNoop, makeRethrow).then(fn => test(fn, stack)); + const intermediate = promise.then(value => { + throw new AssertionError({ + assertion, + message: 'Expected promise to be rejected, but it was resolved instead', + values: [formatAssertError.formatWithLabel('Resolved with:', value)] + }); + }, reason => test(makeRethrow(reason), stack)); + pending(this, intermediate); - // Don't reject the returned promise, even if the assertion fails. - return intermediate.catch(noop); + return intermediate; } try { diff --git a/test/assert.js b/test/assert.js index 64bb9bee9e..99073031dd 100644 --- a/test/assert.js +++ b/test/assert.js @@ -27,27 +27,31 @@ function failsWith(t, fn, subset) { return; } - t.is(lastFailure.assertion, subset.assertion); - t.is(lastFailure.message, subset.message); - t.is(lastFailure.name, 'AssertionError'); - t.is(lastFailure.operator, subset.operator); - if (subset.statements) { - t.is(lastFailure.statements.length, subset.statements.length); - lastFailure.statements.forEach((s, i) => { - t.is(s[0], subset.statements[i][0]); - t.match(s[1], subset.statements[i][1]); + testFailResults(t, lastFailure, subset); +} + +function testFailResults(t, actual, expected) { + t.is(actual.assertion, expected.assertion); + t.is(actual.message, expected.message); + t.is(actual.name, 'AssertionError'); + t.is(actual.operator, expected.operator); + if (expected.statements) { + t.is(actual.statements.length, expected.statements.length); + actual.statements.forEach((s, i) => { + t.is(s[0], expected.statements[i][0]); + t.match(s[1], expected.statements[i][1]); }); } else { - t.same(lastFailure.statements, []); + t.same(actual.statements, []); } - if (subset.values) { - t.is(lastFailure.values.length, subset.values.length); - lastFailure.values.forEach((s, i) => { - t.is(s.label, subset.values[i].label); - t.match(s.formatted, subset.values[i].formatted); + if (expected.values) { + t.is(actual.values.length, expected.values.length); + actual.values.forEach((s, i) => { + t.is(s.label, expected.values[i].label); + t.match(s.formatted, expected.values[i].formatted); }); } else { - t.same(lastFailure.values, []); + t.same(actual.values, []); } } @@ -648,6 +652,17 @@ test('.throws() fails if passed a bad value', t => { t.end(); }); +test('promise .throws() fails when promise is resolved', t => { + return assertions.throws(Promise.resolve('foo')) + .catch(err => { + testFailResults(t, err, { + assertion: 'throws', + message: 'Expected promise to be rejected, but it was resolved instead', + values: [{label: 'Resolved with:', formatted: formatValue('foo')}] + }); + }); +}); + test('.notThrows()', t => { passes(t, () => { assertions.notThrows(() => {});