From be5000aac1f7d0e9c44b3beecfb43938dabbd64c Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 28 Feb 2024 15:51:55 -0500 Subject: [PATCH] Fix throws assertions rejecting falsy values when any: true Fixes #3312 --- lib/assert.js | 4 +++- test-tap/assert.js | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index 9e93d31fa..21d2bf2f1 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -417,6 +417,7 @@ export class Assertions { } let retval; + let threw = false; let actual = null; try { retval = fn(); @@ -429,10 +430,11 @@ export class Assertions { })); } } catch (error) { + threw = true; actual = error; } - if (!actual) { + if (!threw) { throw fail(new AssertionError(message, { assertion: 't.throws()', formattedDetails: [formatWithLabel('Function returned:', retval)], diff --git a/test-tap/assert.js b/test-tap/assert.js index bbf0bc711..ceb514b51 100644 --- a/test-tap/assert.js +++ b/test-tap/assert.js @@ -882,11 +882,16 @@ test('.throws()', gather(t => { throw new Error('foo'); }), {expectBoolean: false}); - // Passes when string is thrown, only when any is set to true. + // Passes when string is thrown and `expectation.any` is true. passes(t, () => assertions.throws(() => { throw 'foo'; // eslint-disable-line no-throw-literal }, {any: true}), {expectBoolean: false}); + // Passes when false is thrown and `expectation.any` is true. + passes(t, () => assertions.throws(() => { + throw false; // eslint-disable-line no-throw-literal + }, {any: true}), {expectBoolean: false}); + // Passes because the correct error is thrown. passes(t, () => { const error = new Error('foo'); @@ -1098,9 +1103,12 @@ test('.throwsAsync()', gather(t => { // Passes because the promise was rejected with an error. throwsAsyncPasses(t, () => assertions.throwsAsync(Promise.reject(new Error()))); - // Passes because the promise was rejected with an with an non-error exception, & set `any` to true in expectation. + // Passes because the promise was rejected with a non-error reason and `expectation.any` is true. throwsAsyncPasses(t, () => assertions.throwsAsync(Promise.reject('foo'), {any: true})); // eslint-disable-line prefer-promise-reject-errors + // Passes because the promise was rejected with a falsy non-error reason and `expectation.any` is true. + throwsAsyncPasses(t, () => assertions.throwsAsync(Promise.reject(), {any: true})); + // Passes because the function returned a promise rejected with an error. throwsAsyncPasses(t, () => assertions.throwsAsync(() => Promise.reject(new Error())));