| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -135,7 +135,6 @@ | |||
| 135 | 135 | ||
| 136 | 136 | # Test runner | |
| 137 | 137 | ||
| 138 | - /test/message/test_runner_* @nodejs/test_runner | ||
| 139 | 138 | /test/parallel/test-runner-* @nodejs/test_runner | |
| 140 | 139 | /doc/api/test.md @nodejs/test_runner | |
| 141 | 140 | /lib/test.js @nodejs/test_runner | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -642,6 +642,12 @@ environment variables. | |||
| 642 | 642 | If set, `NODE_COMMON_PORT`'s value overrides the `common.PORT` default value of | |
| 643 | 643 | 12346\. | |
| 644 | 644 | ||
| 645 | + ### `NODE_REGENERATE_SNAPSHOTS` | ||
| 646 | + | ||
| 647 | + If set, test snapshots for a the current test are regenerated. | ||
| 648 | + for example `NODE_REGENERATE_SNAPSHOTS=1 out/Release/node test/parallel/test-runner-output.mjs` | ||
| 649 | + will update all the test runner output snapshots. | ||
| 650 | + | ||
| 645 | 651 | ### `NODE_SKIP_FLAG_CHECK` | |
| 646 | 652 | ||
| 647 | 653 | If set, command line arguments passed to individual tests are not validated. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,53 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('.'); | ||
| 3 | + const path = require('node:path'); | ||
| 4 | + const fs = require('node:fs/promises'); | ||
| 5 | + const assert = require('node:assert/strict'); | ||
| 6 | + | ||
| 7 | + | ||
| 8 | + const stackFramesRegexp = /(\s+)((.+?)\s+\()?(?:\(?(.+?):(\d+)(?::(\d+))?)\)?(\s+\{)?(\n|$)/g; | ||
| 9 | + const windowNewlineRegexp = /\r/g; | ||
| 10 | + | ||
| 11 | + function replaceStackTrace(str) { | ||
| 12 | + return str.replace(stackFramesRegexp, '$1*$7\n'); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + function replaceWindowsLineEndings(str) { | ||
| 16 | + return str.replace(windowNewlineRegexp, ''); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + function transform(...args) { | ||
| 20 | + return (str) => args.reduce((acc, fn) => fn(acc), str); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + function getSnapshotPath(filename) { | ||
| 24 | + const { name, dir } = path.parse(filename); | ||
| 25 | + return path.resolve(dir, `${name}.snapshot`); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + async function assertSnapshot(actual, filename = process.argv[1]) { | ||
| 29 | + const snapshot = getSnapshotPath(filename); | ||
| 30 | + if (process.env.NODE_REGENERATE_SNAPSHOTS) { | ||
| 31 | + await fs.writeFile(snapshot, actual); | ||
| 32 | + } else { | ||
| 33 | + const expected = await fs.readFile(snapshot, 'utf8'); | ||
| 34 | + assert.strictEqual(actual, replaceWindowsLineEndings(expected)); | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + async function spawnAndAssert(filename, transform = (x) => x) { | ||
| 39 | + // TODO: Add an option to this function to alternatively or additionally compare stderr. | ||
| 40 | + // For now, tests that want to check stderr or both stdout and stderr can use spawnPromisified. | ||
| 41 | + const flags = common.parseTestFlags(filename); | ||
| 42 | + const { stdout } = await common.spawnPromisified(process.execPath, [...flags, filename]); | ||
| 43 | + await assertSnapshot(transform(stdout), filename); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + module.exports = { | ||
| 47 | + assertSnapshot, | ||
| 48 | + getSnapshotPath, | ||
| 49 | + replaceStackTrace, | ||
| 50 | + replaceWindowsLineEndings, | ||
| 51 | + spawnAndAssert, | ||
| 52 | + transform, | ||
| 53 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -61,6 +61,31 @@ const hasOpenSSL3 = hasCrypto && | |||
| 61 | 61 | ||
| 62 | 62 | const hasQuic = hasCrypto && !!process.config.variables.openssl_quic; | |
| 63 | 63 | ||
| 64 | + function parseTestFlags(filename = process.argv[1]) { | ||
| 65 | + // The copyright notice is relatively big and the flags could come afterwards. | ||
| 66 | + const bytesToRead = 1500; | ||
| 67 | + const buffer = Buffer.allocUnsafe(bytesToRead); | ||
| 68 | + const fd = fs.openSync(filename, 'r'); | ||
| 69 | + const bytesRead = fs.readSync(fd, buffer, 0, bytesToRead); | ||
| 70 | + fs.closeSync(fd); | ||
| 71 | + const source = buffer.toString('utf8', 0, bytesRead); | ||
| 72 | + | ||
| 73 | + const flagStart = source.indexOf('// Flags: --') + 10; | ||
| 74 | + | ||
| 75 | + if (flagStart === 9) { | ||
| 76 | + return []; | ||
| 77 | + } | ||
| 78 | + let flagEnd = source.indexOf('\n', flagStart); | ||
| 79 | + // Normalize different EOL. | ||
| 80 | + if (source[flagEnd - 1] === '\r') { | ||
| 81 | + flagEnd--; | ||
| 82 | + } | ||
| 83 | + return source | ||
| 84 | + .substring(flagStart, flagEnd) | ||
| 85 | + .replace(/_/g, '-') | ||
| 86 | + .split(' '); | ||
| 87 | + } | ||
| 88 | + | ||
| 64 | 89 | // Check for flags. Skip this for workers (both, the `cluster` module and | |
| 65 | 90 | // `worker_threads`) and child processes. | |
| 66 | 91 | // If the binary was built without-ssl then the crypto flags are | |
@@ -71,44 +96,25 @@ if (process.argv.length === 2 && | |||
| 71 | 96 | hasCrypto && | |
| 72 | 97 | require('cluster').isPrimary && | |
| 73 | 98 | fs.existsSync(process.argv[1])) { | |
| 74 | - // The copyright notice is relatively big and the flags could come afterwards. | ||
| 75 | - const bytesToRead = 1500; | ||
| 76 | - const buffer = Buffer.allocUnsafe(bytesToRead); | ||
| 77 | - const fd = fs.openSync(process.argv[1], 'r'); | ||
| 78 | - const bytesRead = fs.readSync(fd, buffer, 0, bytesToRead); | ||
| 79 | - fs.closeSync(fd); | ||
| 80 | - const source = buffer.toString('utf8', 0, bytesRead); | ||
| 81 | - | ||
| 82 | - const flagStart = source.indexOf('// Flags: --') + 10; | ||
| 83 | - if (flagStart !== 9) { | ||
| 84 | - let flagEnd = source.indexOf('\n', flagStart); | ||
| 85 | - // Normalize different EOL. | ||
| 86 | - if (source[flagEnd - 1] === '\r') { | ||
| 87 | - flagEnd--; | ||
| 88 | - } | ||
| 89 | - const flags = source | ||
| 90 | - .substring(flagStart, flagEnd) | ||
| 91 | - .replace(/_/g, '-') | ||
| 92 | - .split(' '); | ||
| 93 | - const args = process.execArgv.map((arg) => arg.replace(/_/g, '-')); | ||
| 94 | - for (const flag of flags) { | ||
| 95 | - if (!args.includes(flag) && | ||
| 96 | - // If the binary is build without `intl` the inspect option is | ||
| 97 | - // invalid. The test itself should handle this case. | ||
| 98 | - (process.features.inspector || !flag.startsWith('--inspect'))) { | ||
| 99 | - console.log( | ||
| 100 | - 'NOTE: The test started as a child_process using these flags:', | ||
| 101 | - inspect(flags), | ||
| 102 | - 'Use NODE_SKIP_FLAG_CHECK to run the test with the original flags.', | ||
| 103 | - ); | ||
| 104 | - const args = [...flags, ...process.execArgv, ...process.argv.slice(1)]; | ||
| 105 | - const options = { encoding: 'utf8', stdio: 'inherit' }; | ||
| 106 | - const result = spawnSync(process.execPath, args, options); | ||
| 107 | - if (result.signal) { | ||
| 108 | - process.kill(0, result.signal); | ||
| 109 | - } else { | ||
| 110 | - process.exit(result.status); | ||
| 111 | - } | ||
| 99 | + const flags = parseTestFlags(); | ||
| 100 | + const args = process.execArgv.map((arg) => arg.replace(/_/g, '-')); | ||
| 101 | + for (const flag of flags) { | ||
| 102 | + if (!args.includes(flag) && | ||
| 103 | + // If the binary is build without `intl` the inspect option is | ||
| 104 | + // invalid. The test itself should handle this case. | ||
| 105 | + (process.features.inspector || !flag.startsWith('--inspect'))) { | ||
| 106 | + console.log( | ||
| 107 | + 'NOTE: The test started as a child_process using these flags:', | ||
| 108 | + inspect(flags), | ||
| 109 | + 'Use NODE_SKIP_FLAG_CHECK to run the test with the original flags.', | ||
| 110 | + ); | ||
| 111 | + const args = [...flags, ...process.execArgv, ...process.argv.slice(1)]; | ||
| 112 | + const options = { encoding: 'utf8', stdio: 'inherit' }; | ||
| 113 | + const result = spawnSync(process.execPath, args, options); | ||
| 114 | + if (result.signal) { | ||
| 115 | + process.kill(0, result.signal); | ||
| 116 | + } else { | ||
| 117 | + process.exit(result.status); | ||
| 112 | 118 | } | |
| 113 | 119 | } | |
| 114 | 120 | } | |
@@ -929,6 +935,7 @@ const common = { | |||
| 929 | 935 | mustSucceed, | |
| 930 | 936 | nodeProcessAborted, | |
| 931 | 937 | PIPE, | |
| 938 | + parseTestFlags, | ||
| 932 | 939 | platformTimeout, | |
| 933 | 940 | printSkipMessage, | |
| 934 | 941 | pwdCommand, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -37,6 +37,7 @@ const { | |||
| 37 | 37 | getCallSite, | |
| 38 | 38 | mustNotCall, | |
| 39 | 39 | mustNotMutateObjectDeep, | |
| 40 | + parseTestFlags, | ||
| 40 | 41 | printSkipMessage, | |
| 41 | 42 | skip, | |
| 42 | 43 | nodeProcessAborted, | |
@@ -88,6 +89,7 @@ export { | |||
| 88 | 89 | getCallSite, | |
| 89 | 90 | mustNotCall, | |
| 90 | 91 | mustNotMutateObjectDeep, | |
| 92 | + parseTestFlags, | ||
| 91 | 93 | printSkipMessage, | |
| 92 | 94 | skip, | |
| 93 | 95 | nodeProcessAborted, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,6 @@ | |||
| 1 | 1 | // Flags: --no-warnings | |
| 2 | 2 | 'use strict'; | |
| 3 | - require('../common'); | ||
| 3 | + require('../../../common'); | ||
| 4 | 4 | const test = require('node:test'); | |
| 5 | 5 | ||
| 6 | 6 | test('promise timeout signal', { signal: AbortSignal.timeout(1) }, async (t) => { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -31,15 +31,15 @@ TAP version 13 | |||
| 31 | 31 | # Subtest: not ok 2 | |
| 32 | 32 | not ok 6 - not ok 2 | |
| 33 | 33 | --- | |
| 34 | - duration_ms: * | ||
| 34 | + duration_ms: ZERO | ||
| 35 | 35 | failureType: 'cancelledByParent' | |
| 36 | 36 | error: 'test did not finish before its parent and was cancelled' | |
| 37 | 37 | code: 'ERR_TEST_FAILURE' | |
| 38 | 38 | ... | |
| 39 | 39 | # Subtest: not ok 3 | |
| 40 | 40 | not ok 7 - not ok 3 | |
| 41 | 41 | --- | |
| 42 | - duration_ms: * | ||
| 42 | + duration_ms: ZERO | ||
| 43 | 43 | failureType: 'testAborted' | |
| 44 | 44 | error: 'This operation was aborted' | |
| 45 | 45 | code: 20 | |
@@ -59,7 +59,7 @@ TAP version 13 | |||
| 59 | 59 | # Subtest: not ok 4 | |
| 60 | 60 | not ok 8 - not ok 4 | |
| 61 | 61 | --- | |
| 62 | - duration_ms: * | ||
| 62 | + duration_ms: ZERO | ||
| 63 | 63 | failureType: 'testAborted' | |
| 64 | 64 | error: 'This operation was aborted' | |
| 65 | 65 | code: 20 | |
@@ -79,7 +79,7 @@ TAP version 13 | |||
| 79 | 79 | # Subtest: not ok 5 | |
| 80 | 80 | not ok 9 - not ok 5 | |
| 81 | 81 | --- | |
| 82 | - duration_ms: * | ||
| 82 | + duration_ms: ZERO | ||
| 83 | 83 | failureType: 'testAborted' | |
| 84 | 84 | error: 'This operation was aborted' | |
| 85 | 85 | code: 20 | |
@@ -161,15 +161,15 @@ not ok 2 - promise abort signal | |||
| 161 | 161 | # Subtest: not ok 2 | |
| 162 | 162 | not ok 6 - not ok 2 | |
| 163 | 163 | --- | |
| 164 | - duration_ms: * | ||
| 164 | + duration_ms: ZERO | ||
| 165 | 165 | failureType: 'cancelledByParent' | |
| 166 | 166 | error: 'test did not finish before its parent and was cancelled' | |
| 167 | 167 | code: 'ERR_TEST_FAILURE' | |
| 168 | 168 | ... | |
| 169 | 169 | # Subtest: not ok 3 | |
| 170 | 170 | not ok 7 - not ok 3 | |
| 171 | 171 | --- | |
| 172 | - duration_ms: * | ||
| 172 | + duration_ms: ZERO | ||
| 173 | 173 | failureType: 'testAborted' | |
| 174 | 174 | error: 'This operation was aborted' | |
| 175 | 175 | code: 20 | |
@@ -189,7 +189,7 @@ not ok 2 - promise abort signal | |||
| 189 | 189 | # Subtest: not ok 4 | |
| 190 | 190 | not ok 8 - not ok 4 | |
| 191 | 191 | --- | |
| 192 | - duration_ms: * | ||
| 192 | + duration_ms: ZERO | ||
| 193 | 193 | failureType: 'testAborted' | |
| 194 | 194 | error: 'This operation was aborted' | |
| 195 | 195 | code: 20 | |
@@ -209,7 +209,7 @@ not ok 2 - promise abort signal | |||
| 209 | 209 | # Subtest: not ok 5 | |
| 210 | 210 | not ok 9 - not ok 5 | |
| 211 | 211 | --- | |
| 212 | - duration_ms: * | ||
| 212 | + duration_ms: ZERO | ||
| 213 | 213 | failureType: 'testAborted' | |
| 214 | 214 | error: 'This operation was aborted' | |
| 215 | 215 | code: 20 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,6 @@ | |||
| 1 | 1 | // Flags: --no-warnings | |
| 2 | 2 | 'use strict'; | |
| 3 | - require('../common'); | ||
| 3 | + require('../../../common'); | ||
| 4 | 4 | const { describe, it } = require('node:test'); | |
| 5 | 5 | ||
| 6 | 6 | describe('describe timeout signal', { signal: AbortSignal.timeout(1) }, (t) => { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -31,31 +31,31 @@ TAP version 13 | |||
| 31 | 31 | # Subtest: not ok 2 | |
| 32 | 32 | not ok 6 - not ok 2 | |
| 33 | 33 | --- | |
| 34 | - duration_ms: * | ||
| 34 | + duration_ms: ZERO | ||
| 35 | 35 | failureType: 'cancelledByParent' | |
| 36 | 36 | error: 'test did not finish before its parent and was cancelled' | |
| 37 | 37 | code: 'ERR_TEST_FAILURE' | |
| 38 | 38 | ... | |
| 39 | 39 | # Subtest: not ok 3 | |
| 40 | 40 | not ok 7 - not ok 3 | |
| 41 | 41 | --- | |
| 42 | - duration_ms: * | ||
| 42 | + duration_ms: ZERO | ||
| 43 | 43 | failureType: 'cancelledByParent' | |
| 44 | 44 | error: 'test did not finish before its parent and was cancelled' | |
| 45 | 45 | code: 'ERR_TEST_FAILURE' | |
| 46 | 46 | ... | |
| 47 | 47 | # Subtest: not ok 4 | |
| 48 | 48 | not ok 8 - not ok 4 | |
| 49 | 49 | --- | |
| 50 | - duration_ms: * | ||
| 50 | + duration_ms: ZERO | ||
| 51 | 51 | failureType: 'cancelledByParent' | |
| 52 | 52 | error: 'test did not finish before its parent and was cancelled' | |
| 53 | 53 | code: 'ERR_TEST_FAILURE' | |
| 54 | 54 | ... | |
| 55 | 55 | # Subtest: not ok 5 | |
| 56 | 56 | not ok 9 - not ok 5 | |
| 57 | 57 | --- | |
| 58 | - duration_ms: * | ||
| 58 | + duration_ms: ZERO | ||
| 59 | 59 | failureType: 'cancelledByParent' | |
| 60 | 60 | error: 'test did not finish before its parent and was cancelled' | |
| 61 | 61 | code: 'ERR_TEST_FAILURE' | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,6 @@ | |||
| 1 | 1 | // Flags: --no-warnings | |
| 2 | 2 | 'use strict'; | |
| 3 | - require('../common'); | ||
| 3 | + require('../../../common'); | ||
| 4 | 4 | const assert = require('node:assert'); | |
| 5 | 5 | const { describe, it, test } = require('node:test'); | |
| 6 | 6 | const util = require('util'); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments