From 81d55bf2d6e43f34e5ed281248caa721878e6e56 Mon Sep 17 00:00:00 2001 From: Moshe Atlow Date: Wed, 28 Jan 2026 19:29:10 +0200 Subject: [PATCH] test_runner: fix passing `expectFailure` --- lib/internal/test_runner/test.js | 9 +++++++++ .../test-runner-expect-error-but-pass.js | 18 ++++++++++++++++++ test/parallel/test-runner-expect-error.js | 15 +++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 test/parallel/test-runner-expect-error-but-pass.js create mode 100644 test/parallel/test-runner-expect-error.js diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index e426438faba75f..beeb49c1763473 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -82,6 +82,7 @@ const kParentAlreadyFinished = 'parentAlreadyFinished'; const kSubtestsFailed = 'subtestsFailed'; const kTestCodeFailure = 'testCodeFailure'; const kTestTimeoutFailure = 'testTimeoutFailure'; +const kExpectedFailure = 'expectedFailure'; const kHookFailure = 'hookFailed'; const kDefaultTimeout = null; const noop = FunctionPrototype; @@ -957,6 +958,14 @@ class Test extends AsyncResource { } pass() { + if (this.error == null && this.expectFailure === true && !this.skipped) { + this.passed = false; + this.error = new ERR_TEST_FAILURE( + 'test was expected to fail but passed', + kExpectedFailure, + ); + return; + } if (this.error !== null) { return; } diff --git a/test/parallel/test-runner-expect-error-but-pass.js b/test/parallel/test-runner-expect-error-but-pass.js new file mode 100644 index 00000000000000..b6900724fa8dbe --- /dev/null +++ b/test/parallel/test-runner-expect-error-but-pass.js @@ -0,0 +1,18 @@ +'use strict'; +const common = require('../common'); +const assert = require('node:assert'); +const { run, test } = require('node:test'); + +if (!process.env.NODE_TEST_CONTEXT) { + const stream = run({ files: [__filename] }); + + stream.on('test:pass', common.mustNotCall()); + stream.on('test:fail', common.mustCall((event) => { + assert.strictEqual(event.expectFailure, true); + assert.strictEqual(event.details.error.code, 'ERR_TEST_FAILURE'); + assert.strictEqual(event.details.error.failureType, 'expectedFailure'); + assert.strictEqual(event.details.error.cause, 'test was expected to fail but passed'); + }, 1)); +} else { + test('passing test', { expectFailure: true }, () => {}); +} diff --git a/test/parallel/test-runner-expect-error.js b/test/parallel/test-runner-expect-error.js new file mode 100644 index 00000000000000..6185c91df43c26 --- /dev/null +++ b/test/parallel/test-runner-expect-error.js @@ -0,0 +1,15 @@ +'use strict'; +const common = require('../common'); +const assert = require('node:assert'); +const { run, test } = require('node:test'); + +if (!process.env.NODE_TEST_CONTEXT) { + const stream = run({ files: [__filename] }); + + stream.on('test:fail', common.mustNotCall()); + stream.on('test:pass', common.mustCall((event) => { + assert.strictEqual(event.expectFailure, true); + }, 1)); +} else { + test('failing test', { expectFailure: true }, () => assert.fail('should not pass')); +}