diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f93f5dc6e1142..5cedb0c6734d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,8 @@ release. -25.8.2
+25.9.0
+25.8.2
25.8.1
25.8.0
25.7.0
diff --git a/SECURITY.md b/SECURITY.md index d44018e915ee80..8e62ba5618b8ee 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -152,28 +152,33 @@ does not trust is considered a vulnerability: the correct use of Node.js APIs. * The unavailability of the runtime, including the unbounded degradation of its performance. -* Memory leaks qualify as vulnerabilities when all of the following criteria are met: - * The API is being correctly used. - * The API doesn't have a warning against its usage in a production environment. - * The API is public and documented. - * The API is on stable (2.0) status. - * The memory leak is significant enough to cause a denial of service quickly - or in a context not controlled by the user (for example, HTTP parsing). - * The memory leak is directly exploitable by an untrusted source without requiring application mistakes. - * The leak cannot be reasonably mitigated through standard operational practices (like process recycling). - * The leak occurs deterministically under normal usage patterns rather than edge cases. - * The leak occurs at a rate that would cause practical resource exhaustion within a practical timeframe under - typical workloads. - * The attack demonstrates [asymmetric resource consumption](https://cwe.mitre.org/data/definitions/405.html), - where the attacker expends significantly fewer resources than what's required by the server to process the - attack. Attacks requiring comparable resources on the attacker's side (which can be mitigated through common - practices like rate limiting) may not qualify. If Node.js loads configuration files or runs code by default (without a specific request from the user), and this is not documented, it is considered a vulnerability. Vulnerabilities related to this case may be fixed by a documentation update. +#### Denial of Service (DoS) vulnerabilities + +For a behavior to be considered a DoS vulnerability, the PoC must meet the following criteria: + +* The API is being correctly used. +* The API doesn't have a warning against its usage in a production environment. +* The API is public and documented. If the API comes from JavaScript, the behavior must be + well-defined in the [ECMAScript specification](https://tc39.es/ecma262/). +* The API has stable (2.0) status. +* The behavior is significant enough to cause a denial of service quickly + or in a context not controlled by the Node.js application developer (for example, HTTP parsing). +* The behavior is directly exploitable by an untrusted source without requiring application mistakes. +* The behavior cannot be reasonably mitigated through standard operational practices (like process recycling). +* The behavior occurs deterministically under normal usage patterns rather than edge cases. +* The behavior occurs at a rate that would cause practical resource exhaustion within a practical timeframe under + typical workloads. +* The attack demonstrates [asymmetric resource consumption](https://cwe.mitre.org/data/definitions/405.html), + where the attacker expends significantly fewer resources than what's required by the server to process the + attack. Attacks requiring comparable resources on the attacker's side (which can be mitigated through common + practices like rate limiting) may not qualify. + **Node.js does NOT trust**: * Data received from the remote end of inbound network connections diff --git a/doc/api/async_context.md b/doc/api/async_context.md index df6a6466fda98e..b72934a25ea802 100644 --- a/doc/api/async_context.md +++ b/doc/api/async_context.md @@ -389,7 +389,7 @@ try { ### `asyncLocalStorage.withScope(store)` > Stability: 1 - Experimental @@ -527,7 +527,7 @@ probably responsible for the context loss. ## Class: `RunScope` > Stability: 1 - Experimental @@ -543,7 +543,7 @@ exits, whether through normal completion or by throwing an error. ### `scope.dispose()` Explicitly ends the scope and restores the previous store value. This method diff --git a/doc/api/cli.md b/doc/api/cli.md index 9ef967373c63dc..4938654132073a 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1280,7 +1280,7 @@ Enable experimental support for storage inspection ### `--experimental-stream-iter` > Stability: 1 - Experimental diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 0bfe9a3fa3a463..cf6cde094c1b53 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -4488,7 +4488,7 @@ changes: - version: REPLACEME pr-url: https://github.com/nodejs/node/pull/62453 description: Runtime deprecation. - - version: REPLACEME + - version: v25.9.0 pr-url: https://github.com/nodejs/node/pull/62321 description: Documentation-only deprecation. --> @@ -4513,7 +4513,7 @@ changes: - version: REPLACEME pr-url: https://github.com/nodejs/node/pull/62453 description: Runtime deprecation. - - version: REPLACEME + - version: v25.9.0 pr-url: https://github.com/nodejs/node/pull/62321 description: Documentation-only deprecation. --> @@ -4528,15 +4528,26 @@ deprecated and will throw an error in a future version. -Type: Documentation-only +Type: Runtime [`module.register()`][] is deprecated. Use [`module.registerHooks()`][] instead. +The `module.register()` API provides off-thread async hooks for customizing ES modules; +the `module.registerHooks()` API provides similar hooks that are synchronous, in-thread, and +work for all types of modules. +Supporting async hooks has proven to be complex, involving worker threads orchestration, and there are issues +that have proven unresolveable. See [caveats of asynchronous customization hooks][]. Please migrate to +`module.registerHooks()` as soon as possible as `module.register()` will be +removed in a future version of Node.js. + [DEP0142]: #dep0142-repl_builtinlibs [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 @@ -4696,6 +4707,7 @@ instead. [`zlib.bytesWritten`]: zlib.md#zlibbyteswritten [alloc]: buffer.md#static-method-bufferallocsize-fill-encoding [alloc_unsafe_size]: buffer.md#static-method-bufferallocunsafesize +[caveats of asynchronous customization hooks]: module.md#caveats-of-asynchronous-customization-hooks [from_arraybuffer]: buffer.md#static-method-bufferfromarraybuffer-byteoffset-length [from_string_encoding]: buffer.md#static-method-bufferfromstring-encoding [legacy URL API]: url.md#legacy-url-api diff --git a/doc/api/diagnostics_channel.md b/doc/api/diagnostics_channel.md index d0916abbe376f5..99f7af3dd3e95b 100644 --- a/doc/api/diagnostics_channel.md +++ b/doc/api/diagnostics_channel.md @@ -1858,7 +1858,7 @@ Emitted when [`process.execve()`][] is invoked. > Stability: 1 - Experimental These channels are emitted for each [`locks.request()`][] call. See diff --git a/doc/api/fs.md b/doc/api/fs.md index c793dc67830f7c..8c2e91fb2c8dbb 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -380,7 +380,7 @@ added: v10.0.0 #### `filehandle.pull([...transforms][, options])` > Stability: 1 - Experimental @@ -457,7 +457,7 @@ run().catch(console.error); #### `filehandle.pullSync([...transforms][, options])` > Stability: 1 - Experimental @@ -1010,7 +1010,7 @@ the end of the file. #### `filehandle.writer([options])` > Stability: 1 - Experimental diff --git a/doc/api/module.md b/doc/api/module.md index 465749f28731c0..ebede62eeca3a4 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -178,12 +178,11 @@ isBuiltin('wss'); // false added: - v20.6.0 - v18.19.0 -deprecated: REPLACEME +deprecated: v25.9.0 changes: - version: REPLACEME - pr-url: https://github.com/nodejs/node/pull/62395 - description: Documentation-only deprecation (DEP0205). Use - `module.registerHooks()` instead. + pr-url: https://github.com/nodejs/node/pull/62401 + description: Runtime deprecation (DEP0205). - version: - v23.6.1 - v22.13.1 diff --git a/doc/api/process.md b/doc/api/process.md index 0180d1adf209be..ed24f30ff5232e 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -739,7 +739,7 @@ This feature is not available in [`Worker`][] threads. ## `process.addUncaughtExceptionCaptureCallback(fn)` > Stability: 1 - Experimental @@ -4060,7 +4060,7 @@ This implies calling `module.setSourceMapsSupport()` with an option diff --git a/doc/api/repl.md b/doc/api/repl.md index c26b2a56dc8ad5..3c61adb450fd71 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -709,7 +709,7 @@ npx codemod@latest @nodejs/repl-builtin-modules + > Stability: 1 - Experimental @@ -521,7 +521,7 @@ Including the `node:` prefix on the module specifier is optional. ### `from(input)` * `input` {string|ArrayBuffer|ArrayBufferView|Iterable|AsyncIterable|Object} @@ -561,7 +561,7 @@ run().catch(console.error); ### `fromSync(input)` * `input` {string|ArrayBuffer|ArrayBufferView|Iterable|Object} @@ -591,7 +591,7 @@ console.log(textSync(fromSync('hello'))); // 'hello' ### `pipeTo(source[, ...transforms], writer[, options])` * `source` {AsyncIterable|Iterable} The data source. @@ -648,7 +648,7 @@ run().catch(console.error); ### `pipeToSync(source[, ...transforms], writer[, options])` * `source` {Iterable} The sync data source. @@ -668,7 +668,7 @@ The `writer` must have the `*Sync` methods (`writeSync`, `writevSync`, ### `pull(source[, ...transforms][, options])` * `source` {AsyncIterable|Iterable} The data source. @@ -739,7 +739,7 @@ ac.abort(); // Pipeline throws AbortError on next iteration ### `pullSync(source[, ...transforms])` * `source` {Iterable} The sync data source. @@ -753,7 +753,7 @@ Synchronous version of [`pull()`][]. All transforms must be synchronous. ### `push([...transforms][, options])` * `...transforms` {Function|Object} Optional transforms applied to the @@ -817,7 +817,7 @@ The writer returned by `push()` conforms to the \[Writer interface]\[]. ### `duplex([options])` * `options` {Object} @@ -895,7 +895,7 @@ run().catch(console.error); ### `array(source[, options])` * `source` {AsyncIterable\|Iterable\} @@ -910,7 +910,7 @@ Collect all chunks as an array of `Uint8Array` values (without concatenating). ### `arrayBuffer(source[, options])` * `source` {AsyncIterable\|Iterable\} @@ -925,7 +925,7 @@ Collect all bytes into an `ArrayBuffer`. ### `arrayBufferSync(source[, options])` * `source` {Iterable\} @@ -939,7 +939,7 @@ Synchronous version of [`arrayBuffer()`][]. ### `arraySync(source[, options])` * `source` {Iterable\} @@ -953,7 +953,7 @@ Synchronous version of [`array()`][]. ### `bytes(source[, options])` * `source` {AsyncIterable\|Iterable\} @@ -986,7 +986,7 @@ run().catch(console.error); ### `bytesSync(source[, options])` * `source` {Iterable\} @@ -1000,7 +1000,7 @@ Synchronous version of [`bytes()`][]. ### `text(source[, options])` * `source` {AsyncIterable\|Iterable\} @@ -1032,7 +1032,7 @@ run().catch(console.error); ### `textSync(source[, options])` * `source` {Iterable\} @@ -1049,7 +1049,7 @@ Synchronous version of [`text()`][]. ### `ondrain(drainable)` * `drainable` {Object} An object implementing the drainable protocol. @@ -1104,7 +1104,7 @@ run().catch(console.error); ### `merge(...sources[, options])` * `...sources` {AsyncIterable\|Iterable\} Two or more iterables. @@ -1137,7 +1137,7 @@ run().catch(console.error); ### `tap(callback)` * `callback` {Function} `(chunks) => void` Called with each batch. @@ -1176,7 +1176,7 @@ chunks by the tapping callback; but return values are ignored. ### `tapSync(callback)` * `callback` {Function} @@ -1189,7 +1189,7 @@ Synchronous version of [`tap()`][]. ### `broadcast([options])` * `options` {Object} @@ -1290,7 +1290,7 @@ Alias for `broadcast.cancel()`. ### `Broadcast.from(input[, options])` * `input` {AsyncIterable|Iterable|Broadcastable} @@ -1303,7 +1303,7 @@ automatically and pushed to all subscribers. ### `share(source[, options])` * `source` {AsyncIterable} The source to share. @@ -1384,7 +1384,7 @@ Alias for `share.cancel()`. ### `Share.from(input[, options])` * `input` {AsyncIterable|Shareable} @@ -1396,7 +1396,7 @@ Create a {Share} from an existing source. ### `shareSync(source[, options])` * `source` {Iterable} The sync source to share. @@ -1411,7 +1411,7 @@ Synchronous version of [`share()`][]. ### `SyncShare.fromSync(input[, options])` * `input` {Iterable|SyncShareable} diff --git a/doc/api/test.md b/doc/api/test.md index 257b17ae845f9c..48dee7d5610b93 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -3563,6 +3563,44 @@ Emitted when no more tests are queued for execution in watch mode. Emitted when one or more tests are restarted due to a file change in watch mode. +## `getTestContext()` + + + +* Returns: {TestContext|SuiteContext|undefined} + +Returns the [`TestContext`][] or [`SuiteContext`][] object associated with the +currently executing test or suite, or `undefined` if called outside of a test or +suite. This function can be used to access context information from within the +test or suite function or any async operations within them. + +```mjs +import { getTestContext } from 'node:test'; + +test('example test', async () => { + const ctx = getTestContext(); + console.log(`Running test: ${ctx.name}`); +}); + +describe('example suite', () => { + const ctx = getTestContext(); + console.log(`Running suite: ${ctx.name}`); +}); +``` + +When called from a test, returns a [`TestContext`][]. +When called from a suite, returns a [`SuiteContext`][]. + +If called from outside a test or suite (e.g., at the top level of a module or in +a setTimeout callback after execution has completed), this function returns +`undefined`. + +When called from within a hook (before, beforeEach, after, afterEach), this +function returns the context of the test or suite that the hook is associated +with. + ## Class: `TestContext` + +* Type: {boolean} + +Indicates whether the suite and all of its subtests have passed. + +### `context.attempt` + + + +* Type: {number} + +The attempt number of the suite. This value is zero-based, so the first attempt is `0`, +the second attempt is `1`, and so on. This property is useful in conjunction with the +`--test-rerun-failures` option to determine the attempt number of the current run. + +### `context.diagnostic(message)` + + + +* `message` {string} A diagnostic message to output. + +Output a diagnostic message. This is typically used for logging information +about the current suite or its tests. + +```js +test.describe('my suite', (suite) => { + suite.diagnostic('Suite diagnostic message'); +}); +``` + [TAP]: https://testanything.org/ [`--experimental-test-coverage`]: cli.md#--experimental-test-coverage [`--experimental-test-module-mocks`]: cli.md#--experimental-test-module-mocks diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 82eda8b796b2b1..ece03f4a1208a7 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -2,7 +2,7 @@ @@ -1910,7 +1910,7 @@ added: v24.7.0 #### `cShakeParams.outputLength` * Type: {number} represents the requested output length in bits. @@ -2339,13 +2339,13 @@ added: v15.0.0 ### Class: `KangarooTwelveParams` #### `kangarooTwelveParams.customization` * Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined} @@ -2355,7 +2355,7 @@ The optional customization string for KangarooTwelve. #### `kangarooTwelveParams.name` * Type: {string} Must be `'KT128'`[^modern-algos] or `'KT256'`[^modern-algos] @@ -2363,7 +2363,7 @@ added: REPLACEME #### `kangarooTwelveParams.outputLength` * Type: {number} represents the requested output length in bits. @@ -2448,7 +2448,7 @@ added: v24.8.0 @@ -2464,7 +2464,7 @@ added: v24.8.0 #### `kmacParams.outputLength` * Type: {number} @@ -2741,13 +2741,13 @@ The length (in bytes) of the random salt to use. ### Class: `TurboShakeParams` #### `turboShakeParams.domainSeparation` * Type: {number|undefined} @@ -2757,7 +2757,7 @@ The optional domain separation byte (0x01-0x7f). Defaults to `0x1f`. #### `turboShakeParams.name` * Type: {string} Must be `'TurboSHAKE128'`[^modern-algos] or `'TurboSHAKE256'`[^modern-algos] @@ -2765,7 +2765,7 @@ added: REPLACEME #### `turboShakeParams.outputLength` * Type: {number} represents the requested output length in bits. diff --git a/doc/api/zlib_iter.md b/doc/api/zlib_iter.md index 73bdf4f7561c24..99bcdba745203d 100644 --- a/doc/api/zlib_iter.md +++ b/doc/api/zlib_iter.md @@ -1,6 +1,6 @@ # Iterable Compression - + > Stability: 1 - Experimental @@ -74,7 +74,7 @@ console.log(original); // 'hello' ## `compressBrotliSync([options])` * `options` {Object} @@ -106,7 +106,7 @@ Create a Brotli compression transform. Output is compatible with ## `compressDeflateSync([options])` * `options` {Object} @@ -126,7 +126,7 @@ Create a deflate compression transform. Output is compatible with ## `compressGzipSync([options])` * `options` {Object} @@ -146,7 +146,7 @@ and `decompressGzip()`/`decompressGzipSync()`. ## `compressZstdSync([options])` * `options` {Object} @@ -173,7 +173,7 @@ Create a Zstandard compression transform. Output is compatible with ## `decompressBrotliSync([options])` * `options` {Object} @@ -196,7 +196,7 @@ Create a Brotli decompression transform. ## `decompressDeflateSync([options])` * `options` {Object} @@ -212,7 +212,7 @@ Create a deflate decompression transform. ## `decompressGzipSync([options])` * `options` {Object} @@ -228,7 +228,7 @@ Create a gzip decompression transform. ## `decompressZstdSync([options])` * `options` {Object} diff --git a/doc/changelogs/CHANGELOG_V25.md b/doc/changelogs/CHANGELOG_V25.md index fbd24d6c72f2f8..2c2b5bdbbe58d8 100644 --- a/doc/changelogs/CHANGELOG_V25.md +++ b/doc/changelogs/CHANGELOG_V25.md @@ -8,6 +8,7 @@ +25.9.0
25.8.2
25.8.1
25.8.0
@@ -52,6 +53,148 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2026-04-01, Version 25.9.0 (Current), @aduh95 + +### Notable Changes + +#### Test runner module mocking improvements + +`MockModuleOptions.defaultExport` and `MockModuleOptions.namedExports` have been +consolidated into a single option `MockModuleOptions.exports` to align with user +expectations and other test runners. + +A `default` property on `MockModuleOptions.exports` represents the default +export, and own enumerable properties are treated as named exports. + +An automated migration is available to update user code: + + +```bash +npx codemod @nodejs/mock-module-exports +``` + +Contributed by sangwook in [#61727](https://github.com/nodejs/node/pull/61727). + +#### Other notable changes + +* \[[`312476cb84`](https://github.com/nodejs/node/commit/312476cb84)] - **(SEMVER-MINOR)** **async\_hooks**: add using scopes to `AsyncLocalStorage` (Stephen Belanger) [#61674](https://github.com/nodejs/node/pull/61674) +* \[[`62d2cd473b`](https://github.com/nodejs/node/commit/62d2cd473b)] - **(SEMVER-MINOR)** **cli**: add `--max-heap-size` option (tannal) [#58708](https://github.com/nodejs/node/pull/58708) +* \[[`d0ebf0e44b`](https://github.com/nodejs/node/commit/d0ebf0e44b)] - **(SEMVER-MINOR)** **crypto**: add `TurboSHAKE` and `KangarooTwelve` Web Cryptography algorithms (Filip Skokan) [#62183](https://github.com/nodejs/node/pull/62183) +* \[[`f85b9d9fa8`](https://github.com/nodejs/node/commit/f85b9d9fa8)] - **(SEMVER-MINOR)** **repl**: add customizable error handling (Anna Henningsen) [#62188](https://github.com/nodejs/node/pull/62188) +* \[[`67b854d407`](https://github.com/nodejs/node/commit/67b854d407)] - **(SEMVER-MINOR)** **repl**: remove dependency on `node:domain` (Matteo Collina) [#61227](https://github.com/nodejs/node/pull/61227) +* \[[`966b700623`](https://github.com/nodejs/node/commit/966b700623)] - **(SEMVER-MINOR)** **sea**: support code cache for ESM entrypoint in SEA (Joyee Cheung) [#62158](https://github.com/nodejs/node/pull/62158) +* \[[`e1f0d2a014`](https://github.com/nodejs/node/commit/e1f0d2a014)] - **(SEMVER-MINOR)** **stream**: add stream/iter Implementation (James M Snell) [#62066](https://github.com/nodejs/node/pull/62066) + +### Commits + +* \[[`312476cb84`](https://github.com/nodejs/node/commit/312476cb84)] - **(SEMVER-MINOR)** **async\_hooks**: add using scopes to AsyncLocalStorage (Stephen Belanger) [#61674](https://github.com/nodejs/node/pull/61674) +* \[[`bfff8cb2ab`](https://github.com/nodejs/node/commit/bfff8cb2ab)] - **(SEMVER-MINOR)** **benchmark**: add benchmarks for experimental stream/iter (James M Snell) [#62066](https://github.com/nodejs/node/pull/62066) +* \[[`c721d68502`](https://github.com/nodejs/node/commit/c721d68502)] - **benchmark**: fix destructuring in dgram/single-buffer (Ali Hassan) [#62084](https://github.com/nodejs/node/pull/62084) +* \[[`e2f03c8e92`](https://github.com/nodejs/node/commit/e2f03c8e92)] - **buffer**: improve performance of multiple Buffer operations (Ali Hassan) [#61871](https://github.com/nodejs/node/pull/61871) +* \[[`2fcd07f1ba`](https://github.com/nodejs/node/commit/2fcd07f1ba)] - **build**: support empty libname flags in `configure.py` (Antoine du Hamel) [#62477](https://github.com/nodejs/node/pull/62477) +* \[[`b800c57fce`](https://github.com/nodejs/node/commit/b800c57fce)] - **build**: fix timezone-update path references (Chengzhong Wu) [#62280](https://github.com/nodejs/node/pull/62280) +* \[[`7dc5a1e9b4`](https://github.com/nodejs/node/commit/7dc5a1e9b4)] - **build**: skip dockit on IBMi (SRAVANI GUNDEPALLI) [#62189](https://github.com/nodejs/node/pull/62189) +* \[[`f0eea0f905`](https://github.com/nodejs/node/commit/f0eea0f905)] - **build**: fix --node-builtin-modules-path (Filip Skokan) [#62115](https://github.com/nodejs/node/pull/62115) +* \[[`62d2cd473b`](https://github.com/nodejs/node/commit/62d2cd473b)] - **(SEMVER-MINOR)** **cli**: add --max-heap-size option (tannal) [#58708](https://github.com/nodejs/node/pull/58708) +* \[[`ac4b485698`](https://github.com/nodejs/node/commit/ac4b485698)] - **crypto**: update root certificates to NSS 3.121 (Node.js GitHub Bot) [#62485](https://github.com/nodejs/node/pull/62485) +* \[[`d0ebf0e44b`](https://github.com/nodejs/node/commit/d0ebf0e44b)] - **(SEMVER-MINOR)** **crypto**: add TurboSHAKE and KangarooTwelve Web Cryptography algorithms (Filip Skokan) [#62183](https://github.com/nodejs/node/pull/62183) +* \[[`3009980d9d`](https://github.com/nodejs/node/commit/3009980d9d)] - **crypto**: add crypto::GetSSLCtx API for addon access to OpenSSL contexts (Tim Perry) [#62254](https://github.com/nodejs/node/pull/62254) +* \[[`f5725ca81d`](https://github.com/nodejs/node/commit/f5725ca81d)] - **crypto**: reject ML-KEM/ML-DSA PKCS#8 import without seed in SubtleCrypto (Filip Skokan) [#62218](https://github.com/nodejs/node/pull/62218) +* \[[`f69ed4bc3f`](https://github.com/nodejs/node/commit/f69ed4bc3f)] - **crypto**: rename CShakeParams and KmacParams length to outputLength (Filip Skokan) [#61875](https://github.com/nodejs/node/pull/61875) +* \[[`4d96e53570`](https://github.com/nodejs/node/commit/4d96e53570)] - **crypto**: refactor WebCrypto AEAD algorithms auth tag handling (Filip Skokan) [#62169](https://github.com/nodejs/node/pull/62169) +* \[[`93d77719e8`](https://github.com/nodejs/node/commit/93d77719e8)] - **crypto**: read algorithm name property only once in normalizeAlgorithm (Filip Skokan) [#62170](https://github.com/nodejs/node/pull/62170) +* \[[`3d2e23a981`](https://github.com/nodejs/node/commit/3d2e23a981)] - **deps**: update ada to 3.4.4 (Node.js GitHub Bot) [#62414](https://github.com/nodejs/node/pull/62414) +* \[[`176d6d2205`](https://github.com/nodejs/node/commit/176d6d2205)] - **deps**: update timezone to 2026a (Node.js GitHub Bot) [#62164](https://github.com/nodejs/node/pull/62164) +* \[[`95c7fc67ba`](https://github.com/nodejs/node/commit/95c7fc67ba)] - **deps**: update googletest to 2461743991f9aa53e9a3625eafcbacd81a3c74cd (Node.js GitHub Bot) [#62484](https://github.com/nodejs/node/pull/62484) +* \[[`e5e9f2044a`](https://github.com/nodejs/node/commit/e5e9f2044a)] - **deps**: update simdjson to 4.5.0 (Node.js GitHub Bot) [#62382](https://github.com/nodejs/node/pull/62382) +* \[[`905b94266a`](https://github.com/nodejs/node/commit/905b94266a)] - **deps**: update ngtcp2 to 1.21.0 (Node.js GitHub Bot) [#62051](https://github.com/nodejs/node/pull/62051) +* \[[`180c150122`](https://github.com/nodejs/node/commit/180c150122)] - **deps**: V8: cherry-pick cf1bce40a5ef (Richard Lau) [#62449](https://github.com/nodejs/node/pull/62449) +* \[[`bc265aa003`](https://github.com/nodejs/node/commit/bc265aa003)] - **deps**: upgrade npm to 11.12.1 (npm team) [#62448](https://github.com/nodejs/node/pull/62448) +* \[[`f1b28612c4`](https://github.com/nodejs/node/commit/f1b28612c4)] - **deps**: V8: cherry-pick b25cd62c7ba2 (Yagiz Nizipli) [#62354](https://github.com/nodejs/node/pull/62354) +* \[[`757719d2af`](https://github.com/nodejs/node/commit/757719d2af)] - **deps**: disable rust icu compiled\_data features (Chengzhong Wu) [#62284](https://github.com/nodejs/node/pull/62284) +* \[[`3bdc955b63`](https://github.com/nodejs/node/commit/3bdc955b63)] - **deps**: update sqlite to 3.51.3 (Node.js GitHub Bot) [#62256](https://github.com/nodejs/node/pull/62256) +* \[[`a9703d194a`](https://github.com/nodejs/node/commit/a9703d194a)] - **deps**: update googletest to 73a63ea05dc8ca29ec1d2c1d66481dd0de1950f1 (Node.js GitHub Bot) [#61927](https://github.com/nodejs/node/pull/61927) +* \[[`85138935cb`](https://github.com/nodejs/node/commit/85138935cb)] - **deps**: update merve to 1.2.2 (Node.js GitHub Bot) [#62213](https://github.com/nodejs/node/pull/62213) +* \[[`231521e75e`](https://github.com/nodejs/node/commit/231521e75e)] - **diagnostics\_channel**: add diagnostics channels for web locks (Ilyas Shabi) [#62123](https://github.com/nodejs/node/pull/62123) +* \[[`0093863664`](https://github.com/nodejs/node/commit/0093863664)] - **doc**: deprecate `module.register()` (DEP0205) (Geoffrey Booth) [#62395](https://github.com/nodejs/node/pull/62395) +* \[[`0b96ece6be`](https://github.com/nodejs/node/commit/0b96ece6be)] - **doc**: clarify that features cannot be both experimental and deprecated (Antoine du Hamel) [#62456](https://github.com/nodejs/node/pull/62456) +* \[[`8d3ea975f5`](https://github.com/nodejs/node/commit/8d3ea975f5)] - **doc**: fix 'transfered' typo in quic.md (lilianakatrina684-a11y) [#62492](https://github.com/nodejs/node/pull/62492) +* \[[`08ff16e0ba`](https://github.com/nodejs/node/commit/08ff16e0ba)] - **doc**: move sqlite type conversion section to correct level (René) [#62482](https://github.com/nodejs/node/pull/62482) +* \[[`61cc747dd8`](https://github.com/nodejs/node/commit/61cc747dd8)] - **doc**: add Rafael to last security release steward (Rafael Gonzaga) [#62423](https://github.com/nodejs/node/pull/62423) +* \[[`64cfa5a6fa`](https://github.com/nodejs/node/commit/64cfa5a6fa)] - **doc**: use npm-published version of doc-kit (Aviv Keller) [#62139](https://github.com/nodejs/node/pull/62139) +* \[[`1020321fb0`](https://github.com/nodejs/node/commit/1020321fb0)] - **doc**: fix overstated Date header requirement in response.sendDate (Kit Dallege) [#62206](https://github.com/nodejs/node/pull/62206) +* \[[`9caa7855b2`](https://github.com/nodejs/node/commit/9caa7855b2)] - **doc**: fix guaranteed typo (lilianakatrina684-a11y) [#62374](https://github.com/nodejs/node/pull/62374) +* \[[`e254f65306`](https://github.com/nodejs/node/commit/e254f65306)] - **doc**: enhance clarification about the main field (Mowafak Almahaini) [#62302](https://github.com/nodejs/node/pull/62302) +* \[[`9e724b53f8`](https://github.com/nodejs/node/commit/9e724b53f8)] - **doc**: remove spawn with shell example from bat/cmd section (Kit Dallege) [#62243](https://github.com/nodejs/node/pull/62243) +* \[[`7f37c17516`](https://github.com/nodejs/node/commit/7f37c17516)] - **doc**: minor typo fix (Jeff Matson) [#62358](https://github.com/nodejs/node/pull/62358) +* \[[`eb0ca98f01`](https://github.com/nodejs/node/commit/eb0ca98f01)] - **doc**: add path to vulnerabilities.json mention (Rafael Gonzaga) [#62355](https://github.com/nodejs/node/pull/62355) +* \[[`198b6e0932`](https://github.com/nodejs/node/commit/198b6e0932)] - **doc**: deprecate CryptoKey use in node:crypto (Filip Skokan) [#62321](https://github.com/nodejs/node/pull/62321) +* \[[`17e5aee6c5`](https://github.com/nodejs/node/commit/17e5aee6c5)] - **doc**: fix small environment\_variables typo (chris) [#62279](https://github.com/nodejs/node/pull/62279) +* \[[`193d629895`](https://github.com/nodejs/node/commit/193d629895)] - **doc**: test and test-only targets do not run linter (Xavier Stouder) [#62120](https://github.com/nodejs/node/pull/62120) +* \[[`4a1f20ec4a`](https://github.com/nodejs/node/commit/4a1f20ec4a)] - **doc**: clarify fs.ReadStream and fs.WriteStream are not constructable (Kit Dallege) [#62208](https://github.com/nodejs/node/pull/62208) +* \[[`f976c9214d`](https://github.com/nodejs/node/commit/f976c9214d)] - **doc**: clarify that any truthy value of `shell` is part of DEP0190 (Antoine du Hamel) [#62249](https://github.com/nodejs/node/pull/62249) +* \[[`4d83972681`](https://github.com/nodejs/node/commit/4d83972681)] - **doc**: remove outdated Chrome 66 and ndb references from debugger (Kit Dallege) [#62202](https://github.com/nodejs/node/pull/62202) +* \[[`71f2eada5b`](https://github.com/nodejs/node/commit/71f2eada5b)] - **doc**: add throwIfNoEntry version history to fs.stat (kovan) [#62204](https://github.com/nodejs/node/pull/62204) +* \[[`670c80893b`](https://github.com/nodejs/node/commit/670c80893b)] - **doc**: add note (and caveat) for `mock.module` about customization hooks (Jacob Smith) [#62075](https://github.com/nodejs/node/pull/62075) +* \[[`2ff5cb13f5`](https://github.com/nodejs/node/commit/2ff5cb13f5)] - **doc,test**: clarify --eval syntax for leading '-' scripts (kovan) [#62244](https://github.com/nodejs/node/pull/62244) +* \[[`6c6c9004c4`](https://github.com/nodejs/node/commit/6c6c9004c4)] - **esm**: fix typo in worker loader hook comment (jakecastelli) [#62475](https://github.com/nodejs/node/pull/62475) +* \[[`1cdd23c9f3`](https://github.com/nodejs/node/commit/1cdd23c9f3)] - **esm**: fix source phase identity bug in loadCache eviction (Guy Bedford) [#62415](https://github.com/nodejs/node/pull/62415) +* \[[`4f4ff15794`](https://github.com/nodejs/node/commit/4f4ff15794)] - **esm**: fix path normalization in `finalizeResolution` (Antoine du Hamel) [#62080](https://github.com/nodejs/node/pull/62080) +* \[[`088167d102`](https://github.com/nodejs/node/commit/088167d102)] - **events**: avoid cloning listeners array on every emit (Gürgün Dayıoğlu) [#62261](https://github.com/nodejs/node/pull/62261) +* \[[`0250b436ee`](https://github.com/nodejs/node/commit/0250b436ee)] - **fs**: fix cpSync to handle non-ASCII characters (Stefan Stojanovic) [#61950](https://github.com/nodejs/node/pull/61950) +* \[[`b67a8fb171`](https://github.com/nodejs/node/commit/b67a8fb171)] - **inspector**: add Target.getTargets and extract TargetManager (Kohei) [#62487](https://github.com/nodejs/node/pull/62487) +* \[[`ffcc5a5722`](https://github.com/nodejs/node/commit/ffcc5a5722)] - **lib**: make SubtleCrypto.supports enumerable (Filip Skokan) [#62307](https://github.com/nodejs/node/pull/62307) +* \[[`92ef2ad8fa`](https://github.com/nodejs/node/commit/92ef2ad8fa)] - **lib**: prefer primordials in SubtleCrypto (Filip Skokan) [#62226](https://github.com/nodejs/node/pull/62226) +* \[[`40a43ac4d0`](https://github.com/nodejs/node/commit/40a43ac4d0)] - **module**: fix coverage of mocked CJS modules imported from ESM (Marco) [#62133](https://github.com/nodejs/node/pull/62133) +* \[[`3ef0a5b90e`](https://github.com/nodejs/node/commit/3ef0a5b90e)] - **quic**: remove CryptoKey support from session keys option (Filip Skokan) [#62335](https://github.com/nodejs/node/pull/62335) +* \[[`3c8dd8eb8e`](https://github.com/nodejs/node/commit/3c8dd8eb8e)] - **repl**: use vm DONT\_CONTEXTIFY context (Chengzhong Wu) [#62371](https://github.com/nodejs/node/pull/62371) +* \[[`f85b9d9fa8`](https://github.com/nodejs/node/commit/f85b9d9fa8)] - **(SEMVER-MINOR)** **repl**: add customizable error handling (Anna Henningsen) [#62188](https://github.com/nodejs/node/pull/62188) +* \[[`e4c164e045`](https://github.com/nodejs/node/commit/e4c164e045)] - **repl**: handle exceptions from async context after close (Anna Henningsen) [#62165](https://github.com/nodejs/node/pull/62165) +* \[[`67b854d407`](https://github.com/nodejs/node/commit/67b854d407)] - **(SEMVER-MINOR)** **repl**: remove dependency on domain module (Matteo Collina) [#61227](https://github.com/nodejs/node/pull/61227) +* \[[`966b700623`](https://github.com/nodejs/node/commit/966b700623)] - **(SEMVER-MINOR)** **sea**: support code cache for ESM entrypoint in SEA (Joyee Cheung) [#62158](https://github.com/nodejs/node/pull/62158) +* \[[`fe82baf970`](https://github.com/nodejs/node/commit/fe82baf970)] - **src**: improve EC JWK import performance (Filip Skokan) [#62396](https://github.com/nodejs/node/pull/62396) +* \[[`d490b171e0`](https://github.com/nodejs/node/commit/d490b171e0)] - **src**: handle null backing store in ArrayBufferViewContents::Read (Mert Can Altin) [#62343](https://github.com/nodejs/node/pull/62343) +* \[[`0e4af848bc`](https://github.com/nodejs/node/commit/0e4af848bc)] - **src**: convert context\_frame field in AsyncWrap to internal field (Anna Henningsen) [#62103](https://github.com/nodejs/node/pull/62103) +* \[[`02980b8c8f`](https://github.com/nodejs/node/commit/02980b8c8f)] - **src**: enable compilation/linking with OpenSSL 4.0 (Filip Skokan) [#62410](https://github.com/nodejs/node/pull/62410) +* \[[`064f7c2fa6`](https://github.com/nodejs/node/commit/064f7c2fa6)] - **src**: use stack allocation in indexOf latin1 path (Mert Can Altin) [#62268](https://github.com/nodejs/node/pull/62268) +* \[[`ede52bc2dc`](https://github.com/nodejs/node/commit/ede52bc2dc)] - **src,sqlite**: fix filterFunc dangling reference (Edy Silva) [#62281](https://github.com/nodejs/node/pull/62281) +* \[[`e1f0d2a014`](https://github.com/nodejs/node/commit/e1f0d2a014)] - **(SEMVER-MINOR)** **stream**: add stream/iter Implementation (James M Snell) [#62066](https://github.com/nodejs/node/pull/62066) +* \[[`03839fb087`](https://github.com/nodejs/node/commit/03839fb087)] - **stream**: preserve error over AbortError in pipeline (Marco) [#62113](https://github.com/nodejs/node/pull/62113) +* \[[`0000d2f011`](https://github.com/nodejs/node/commit/0000d2f011)] - **stream**: replace bind with arrow function for onwrite callback (Ali Hassan) [#62087](https://github.com/nodejs/node/pull/62087) +* \[[`3796a73719`](https://github.com/nodejs/node/commit/3796a73719)] - **test**: update WPT for WebCryptoAPI to 2cb332d710 (Node.js GitHub Bot) [#62483](https://github.com/nodejs/node/pull/62483) +* \[[`ad8309415b`](https://github.com/nodejs/node/commit/ad8309415b)] - **test**: update WPT for url to fc3e651593 (Node.js GitHub Bot) [#62379](https://github.com/nodejs/node/pull/62379) +* \[[`bed89b037e`](https://github.com/nodejs/node/commit/bed89b037e)] - **test**: wait for reattach before initial break on restart (Yuya Inoue) [#62471](https://github.com/nodejs/node/pull/62471) +* \[[`c9ffffcc55`](https://github.com/nodejs/node/commit/c9ffffcc55)] - **test**: disable flaky WPT Blob test on AIX (James M Snell) [#62470](https://github.com/nodejs/node/pull/62470) +* \[[`fd41ef31f6`](https://github.com/nodejs/node/commit/fd41ef31f6)] - **(SEMVER-MINOR)** **test**: add tests for experimental stream/iter implementation (James M Snell) [#62066](https://github.com/nodejs/node/pull/62066) +* \[[`1b9d8d3eec`](https://github.com/nodejs/node/commit/1b9d8d3eec)] - **test**: avoid flaky run wait in debugger restart test (Yuya Inoue) [#62112](https://github.com/nodejs/node/pull/62112) +* \[[`cb08a29d51`](https://github.com/nodejs/node/commit/cb08a29d51)] - **test**: skip test-cluster-dgram-reuse on AIX 7.3 (Stewart X Addison) [#62238](https://github.com/nodejs/node/pull/62238) +* \[[`abea0af8a9`](https://github.com/nodejs/node/commit/abea0af8a9)] - **test**: add WebCrypto Promise.prototype.then pollution regression tests (Filip Skokan) [#62226](https://github.com/nodejs/node/pull/62226) +* \[[`47a2132269`](https://github.com/nodejs/node/commit/47a2132269)] - **test**: update WPT for WebCryptoAPI to 6a1c545d77 (Node.js GitHub Bot) [#62187](https://github.com/nodejs/node/pull/62187) +* \[[`2c63d3006c`](https://github.com/nodejs/node/commit/2c63d3006c)] - **test\_runner**: add exports option for module mocks (sangwook) [#61727](https://github.com/nodejs/node/pull/61727) +* \[[`44ac0e1302`](https://github.com/nodejs/node/commit/44ac0e1302)] - **test\_runner**: make it compatible with fake timers (Matteo Collina) [#59272](https://github.com/nodejs/node/pull/59272) +* \[[`1865691275`](https://github.com/nodejs/node/commit/1865691275)] - **test\_runner**: set non-zero exit code when suite errors occur (Edy Silva) [#62282](https://github.com/nodejs/node/pull/62282) +* \[[`0252b2bab8`](https://github.com/nodejs/node/commit/0252b2bab8)] - **tools**: bump picomatch from 4.0.3 to 4.0.4 in /tools/eslint (dependabot\[bot]) [#62439](https://github.com/nodejs/node/pull/62439) +* \[[`3368155267`](https://github.com/nodejs/node/commit/3368155267)] - **tools**: bump yaml from 2.8.2 to 2.8.3 in /tools/doc (dependabot\[bot]) [#62437](https://github.com/nodejs/node/pull/62437) +* \[[`5e47c359f5`](https://github.com/nodejs/node/commit/5e47c359f5)] - **tools**: adopt the `--check-for-duplicates` NCU flag (Antoine du Hamel) [#62478](https://github.com/nodejs/node/pull/62478) +* \[[`4a604e82d0`](https://github.com/nodejs/node/commit/4a604e82d0)] - **tools**: bump picomatch in /tools/doc (dependabot\[bot]) [#62438](https://github.com/nodejs/node/pull/62438) +* \[[`d1a98b4ddb`](https://github.com/nodejs/node/commit/d1a98b4ddb)] - **tools**: bump flatted from 3.4.1 to 3.4.2 in /tools/eslint (dependabot\[bot]) [#62375](https://github.com/nodejs/node/pull/62375) +* \[[`c32daa1ab4`](https://github.com/nodejs/node/commit/c32daa1ab4)] - **tools**: bump eslint deps (Huáng Jùnliàng) [#62356](https://github.com/nodejs/node/pull/62356) +* \[[`7a2fcc6d41`](https://github.com/nodejs/node/commit/7a2fcc6d41)] - **tools**: do not swallow error in `lint-nix` workflow (Antoine du Hamel) [#62292](https://github.com/nodejs/node/pull/62292) +* \[[`c41a2871b5`](https://github.com/nodejs/node/commit/c41a2871b5)] - **tools**: add eslint-plugin-regexp (Huáng Jùnliàng) [#62093](https://github.com/nodejs/node/pull/62093) +* \[[`56dfeb06df`](https://github.com/nodejs/node/commit/56dfeb06df)] - **tools**: fix timeout errors in `lint-nix` job (Antoine du Hamel) [#62265](https://github.com/nodejs/node/pull/62265) +* \[[`22fc8078e8`](https://github.com/nodejs/node/commit/22fc8078e8)] - **tools**: bump flatted from 3.3.3 to 3.4.1 in /tools/eslint (dependabot\[bot]) [#62255](https://github.com/nodejs/node/pull/62255) +* \[[`409b0663bd`](https://github.com/nodejs/node/commit/409b0663bd)] - **tools**: bump undici from 6.23.0 to 6.24.1 in /tools/doc (dependabot\[bot]) [#62250](https://github.com/nodejs/node/pull/62250) +* \[[`67c69750f4`](https://github.com/nodejs/node/commit/67c69750f4)] - **tools**: validate all commits that are pushed to `main` (Antoine du Hamel) [#62246](https://github.com/nodejs/node/pull/62246) +* \[[`7d9db8cd21`](https://github.com/nodejs/node/commit/7d9db8cd21)] - **tools**: keep GN files when updating Merve (Antoine du Hamel) [#62167](https://github.com/nodejs/node/pull/62167) +* \[[`6c8fa42ba2`](https://github.com/nodejs/node/commit/6c8fa42ba2)] - **typings**: rationalise TypedArray types (René) [#62174](https://github.com/nodejs/node/pull/62174) +* \[[`531c64d04e`](https://github.com/nodejs/node/commit/531c64d04e)] - **url**: enable simdutf for ada (Yagiz Nizipli) [#61477](https://github.com/nodejs/node/pull/61477) +* \[[`2000caccde`](https://github.com/nodejs/node/commit/2000caccde)] - **util**: allow color aliases in styleText (sangwook) [#62180](https://github.com/nodejs/node/pull/62180) +* \[[`0aed332ab4`](https://github.com/nodejs/node/commit/0aed332ab4)] - **wasm**: support js string constant esm import (Guy Bedford) [#62198](https://github.com/nodejs/node/pull/62198) +* \[[`d3fd4a978b`](https://github.com/nodejs/node/commit/d3fd4a978b)] - **worker**: heap profile optimizations (Ilyas Shabi) [#62201](https://github.com/nodejs/node/pull/62201) +* \[[`e992a34a18`](https://github.com/nodejs/node/commit/e992a34a18)] - **zlib**: fix use-after-free when reset() is called during write (Matteo Collina) [#62325](https://github.com/nodejs/node/pull/62325) + ## 2026-03-24, Version 25.8.2 (Current), @RafaelGSS diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 04c374c00cfc3e..8ae6761fba571a 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -31,7 +31,10 @@ const { } = require('internal/errors').codes; const { getOptionValue } = require('internal/options'); const { isURL, pathToFileURL } = require('internal/url'); -const { kEmptyObject } = require('internal/util'); +const { + getDeprecationWarningEmitter, + kEmptyObject, +} = require('internal/util'); const { compileSourceTextModule, SourceTextModuleTypes: { kUser }, @@ -955,7 +958,16 @@ function isCascadedLoaderInitialized() { * }); * ``` */ +const emitRegisterDeprecation = getDeprecationWarningEmitter( + 'DEP0205', + '`module.register()` is deprecated. Use `module.registerHooks()` instead.', + undefined, + false, +); + function register(specifier, parentURL = undefined, options) { + emitRegisterDeprecation(); + if (parentURL != null && typeof parentURL === 'object' && !isURL(parentURL)) { options = parentURL; parentURL = options.parentURL; diff --git a/lib/internal/test_runner/harness.js b/lib/internal/test_runner/harness.js index 5418a14a4410a4..fed3d3a49a241f 100644 --- a/lib/internal/test_runner/harness.js +++ b/lib/internal/test_runner/harness.js @@ -21,7 +21,7 @@ const { }, } = require('internal/errors'); const { exitCodes: { kGenericUserError } } = internalBinding('errors'); -const { kCancelledByParent, Test, Suite } = require('internal/test_runner/test'); +const { kCancelledByParent, Test, Suite, TestContext, SuiteContext } = require('internal/test_runner/test'); const { parseCommandLine, reporterScope, @@ -431,8 +431,27 @@ function hook(hook) { }; } +function getTestContext() { + const test = testResources.get(executionAsyncId()); + // Exclude the reporter sentinel + if (test === undefined || test === reporterScope) { + return undefined; + } + // For hooks (hookType is set), return the test/suite being hooked (the parent) + const actualTest = test.hookType !== undefined ? test.parent : test; + if (actualTest === undefined) { + return undefined; + } + // Return SuiteContext for suites, TestContext for tests + if (actualTest instanceof Suite) { + return new SuiteContext(actualTest); + } + return new TestContext(actualTest); +} + module.exports = { createTestTree, + getTestContext, test: runInParentContext(Test), suite: runInParentContext(Suite), before: hook('before'), diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index 97d53c097261d7..68e780673dd8f6 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -494,6 +494,18 @@ class SuiteContext { get fullName() { return getFullName(this.#suite); } + + get passed() { + return this.#suite.passed; + } + + get attempt() { + return this.#suite.attempt ?? 0; + } + + diagnostic(message) { + this.#suite.diagnostic(message); + } } function parseExpectFailure(expectFailure) { @@ -1656,4 +1668,6 @@ module.exports = { kUnwrapErrors, Suite, Test, + TestContext, + SuiteContext, }; diff --git a/lib/test.js b/lib/test.js index fb09d0625a08fc..50d276e9b0fb16 100644 --- a/lib/test.js +++ b/lib/test.js @@ -5,7 +5,7 @@ const { ObjectDefineProperty, } = primordials; -const { test, suite, before, after, beforeEach, afterEach } = require('internal/test_runner/harness'); +const { test, suite, before, after, beforeEach, afterEach, getTestContext } = require('internal/test_runner/harness'); const { run } = require('internal/test_runner/runner'); module.exports = test; @@ -15,6 +15,7 @@ ObjectAssign(module.exports, { before, beforeEach, describe: suite, + getTestContext, it: test, run, suite, diff --git a/test/es-module/test-esm-register-deprecation.mjs b/test/es-module/test-esm-register-deprecation.mjs new file mode 100644 index 00000000000000..171e5971a091fe --- /dev/null +++ b/test/es-module/test-esm-register-deprecation.mjs @@ -0,0 +1,60 @@ +import { spawnPromisified } from '../common/index.mjs'; +import * as fixtures from '../common/fixtures.mjs'; + +import assert from 'node:assert'; +import { execPath } from 'node:process'; +import { describe, it } from 'node:test'; + +const urlToRegister = fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'); +const urlToRegisterEscaped = JSON.stringify(urlToRegister.href); + + +describe('module.register() deprecation (DEP0205)', { concurrency: !process.env.TEST_PARALLEL }, () => { + it('emits DEP0205 when module.register() is called', async () => { + const { code, stderr } = await spawnPromisified(execPath, [ + '--input-type=module', + '--eval', + `import { register } from 'node:module'; register(${urlToRegisterEscaped});`, + ]); + + assert.match(stderr, /\[DEP0205\]/); + assert.strictEqual(code, 0); + }); + + it('only emits the warning once per process', async () => { + const { code, stderr } = await spawnPromisified(execPath, [ + '--input-type=module', + '--eval', + `import { register } from 'node:module'; + register(${urlToRegisterEscaped}); + register(${urlToRegisterEscaped});`, + ]); + + assert.strictEqual(stderr.split('[DEP0205]').length - 1, 1); + assert.strictEqual(code, 0); + }); + + it('does not emit when --no-deprecation is set', async () => { + const { code, stderr } = await spawnPromisified(execPath, [ + '--no-deprecation', + '--input-type=module', + '--eval', + `import { register } from 'node:module'; register(${urlToRegisterEscaped});`, + ]); + + assert.doesNotMatch(stderr, /DEP0205/); + assert.strictEqual(code, 0); + }); + + it('throws when --throw-deprecation is set', async () => { + const { code, stderr } = await spawnPromisified(execPath, [ + '--throw-deprecation', + '--input-type=module', + '--eval', + `import { register } from 'node:module'; register(${urlToRegisterEscaped});`, + ]); + + assert.match(stderr, /DEP0205/); + assert.notStrictEqual(code, 0); + }); +}); diff --git a/test/module-hooks/test-async-loader-hooks-use-hooks-require-esm.mjs b/test/module-hooks/test-async-loader-hooks-use-hooks-require-esm.mjs index a86b0607246fa9..1eee6a6014aa15 100644 --- a/test/module-hooks/test-async-loader-hooks-use-hooks-require-esm.mjs +++ b/test/module-hooks/test-async-loader-hooks-use-hooks-require-esm.mjs @@ -7,6 +7,7 @@ import { spawnSyncAndAssert } from '../common/child_process.js'; spawnSyncAndAssert( execPath, [ + '--no-deprecation', '--no-experimental-require-module', '--import', fixtures.fileURL('es-module-loaders/builtin-named-exports.mjs'), diff --git a/test/parallel/test-runner-get-test-context.js b/test/parallel/test-runner-get-test-context.js new file mode 100644 index 00000000000000..bc5be4f01cee4a --- /dev/null +++ b/test/parallel/test-runner-get-test-context.js @@ -0,0 +1,54 @@ +'use strict'; +require('../common'); +const assert = require('node:assert'); +const { test, getTestContext, describe, it } = require('node:test'); + +// Outside a test — must return undefined +assert.strictEqual(getTestContext(), undefined); + +test('getTestContext returns current context inside test', async () => { + const ctx = getTestContext(); + assert.ok(ctx !== undefined); + assert.strictEqual(ctx.name, 'getTestContext returns current context inside test'); + assert.strictEqual(typeof ctx.signal, 'object'); + assert.strictEqual(typeof ctx.fullName, 'string'); +}); + +test('getTestContext works in nested test', async (t) => { + await t.test('child', async () => { + const ctx = getTestContext(); + assert.ok(ctx !== undefined); + assert.strictEqual(ctx.name, 'child'); + }); +}); + +describe('getTestContext works in describe/it', () => { + it('has correct name', () => { + const ctx = getTestContext(); + assert.ok(ctx !== undefined); + assert.strictEqual(ctx.name, 'has correct name'); + }); +}); + +describe('getTestContext returns SuiteContext in suite', () => { + it('suite context is available', () => { + const ctx = getTestContext(); + assert.ok(ctx !== undefined); + // Suite name appears as parent in nested test context + assert.strictEqual(typeof ctx.signal, 'object'); + assert.strictEqual(typeof ctx.fullName, 'string'); + }); +}); + +test('getTestContext works in test body during async operations', async (t) => { + const ctx = getTestContext(); + assert.ok(ctx !== undefined); + assert.strictEqual(ctx.name, 'getTestContext works in test body during async operations'); + + // Also works in nested async context + const ctxInSetImmediate = await new Promise((resolve) => { + setImmediate(() => resolve(getTestContext())); + }); + assert.ok(ctxInSetImmediate !== undefined); + assert.strictEqual(ctxInSetImmediate.name, 'getTestContext works in test body during async operations'); +}); diff --git a/test/parallel/test-runner-test-fullname.js b/test/parallel/test-runner-test-fullname.js index 5e8ad47bddbd87..cab35a7a9355aa 100644 --- a/test/parallel/test-runner-test-fullname.js +++ b/test/parallel/test-runner-test-fullname.js @@ -9,6 +9,11 @@ before(common.mustCall((t) => { suite('suite', common.mustCall((t) => { assert.strictEqual(t.fullName, 'suite'); + // Test new SuiteContext properties + assert.strictEqual(typeof t.passed, 'boolean'); + assert.strictEqual(t.attempt, 0); + // diagnostic() can be called to add diagnostic output + t.diagnostic('Suite diagnostic message'); test('test', (t) => { assert.strictEqual(t.fullName, 'suite > test'); @@ -26,3 +31,18 @@ suite('suite', common.mustCall((t) => { test((t) => { assert.strictEqual(t.fullName, ''); }); + +// Test SuiteContext passed, attempt, and diagnostic properties +suite('suite with context checks', common.mustCall((ctx) => { + assert.strictEqual(ctx.fullName, 'suite with context checks'); + assert.strictEqual(typeof ctx.passed, 'boolean'); + assert.strictEqual(ctx.attempt, 0); + // Verify diagnostic method is callable + ctx.diagnostic('Test diagnostic message in suite'); + + test('child test', () => { + // Verify properties are accessible in nested test + assert.strictEqual(typeof ctx.passed, 'boolean'); + assert.strictEqual(ctx.attempt, 0); + }); +}));