GeezerVison is showing github.com — test_runner: consolidate option parsing · nodejs/node@97da7ca
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/main/test_runner.js +14-44Lines changed: 14 additions & 44 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 |
| 3 | | -const { | 4 | | - NumberParseInt, | 5 | | - RegExpPrototypeExec, | 6 | | - StringPrototypeSplit, | 7 | | -} = primordials; | 8 | | - | 9 | 3 | const { | 10 | 4 | prepareMainThreadExecution, | 11 | 5 | markBootstrapComplete, | 12 | 6 | } = require('internal/process/pre_execution'); | 13 | | -const { getOptionValue } = require('internal/options'); | 14 | 7 | const { isUsingInspector } = require('internal/util/inspector'); | 15 | 8 | const { run } = require('internal/test_runner/runner'); | 16 | | -const { setupTestReporters } = require('internal/test_runner/utils'); | 17 | | -const { exitCodes: { kGenericUserError } } = internalBinding('errors'); | 18 | 9 | const { | 19 | | - codes: { | 20 | | - ERR_INVALID_ARG_VALUE, | 21 | | - }, | 22 | | -} = require('internal/errors'); | 23 | | - | | 10 | + parseCommandLine, | | 11 | + setupTestReporters, | | 12 | +} = require('internal/test_runner/utils'); | | 13 | +const { exitCodes: { kGenericUserError } } = internalBinding('errors'); | 24 | 14 | let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => { | 25 | 15 | debug = fn; | 26 | 16 | }); | 27 | 17 |
| 28 | 18 | prepareMainThreadExecution(false); | 29 | 19 | markBootstrapComplete(); | 30 | 20 |
| 31 | | -let concurrency = getOptionValue('--test-concurrency') || true; | | 21 | +const { | | 22 | + perFileTimeout, | | 23 | + runnerConcurrency, | | 24 | + shard, | | 25 | + watchMode, | | 26 | +} = parseCommandLine(); | | 27 | + | | 28 | +let concurrency = runnerConcurrency; | 32 | 29 | let inspectPort; | 33 | 30 |
| 34 | 31 | if (isUsingInspector()) { | @@ -38,39 +35,12 @@ if (isUsingInspector()) { | 38 | 35 | inspectPort = process.debugPort; | 39 | 36 | } | 40 | 37 |
| 41 | | -let shard; | 42 | | -const shardOption = getOptionValue('--test-shard'); | 43 | | -if (shardOption) { | 44 | | - if (!RegExpPrototypeExec(/^\d+\/\d+$/, shardOption)) { | 45 | | - process.exitCode = kGenericUserError; | 46 | | - | 47 | | - throw new ERR_INVALID_ARG_VALUE( | 48 | | - '--test-shard', | 49 | | - shardOption, | 50 | | - 'must be in the form of <index>/<total>', | 51 | | - ); | 52 | | - } | 53 | | - | 54 | | - const { 0: indexStr, 1: totalStr } = StringPrototypeSplit(shardOption, '/'); | 55 | | - | 56 | | - const index = NumberParseInt(indexStr, 10); | 57 | | - const total = NumberParseInt(totalStr, 10); | 58 | | - | 59 | | - shard = { | 60 | | - __proto__: null, | 61 | | - index, | 62 | | - total, | 63 | | - }; | 64 | | -} | 65 | | - | 66 | | -const timeout = getOptionValue('--test-timeout') || Infinity; | 67 | | - | 68 | 38 | const options = { | 69 | 39 | concurrency, | 70 | 40 | inspectPort, | 71 | | - watch: getOptionValue('--watch'), | | 41 | + watch: watchMode, | 72 | 42 | setup: setupTestReporters, | 73 | | - timeout, | | 43 | + timeout: perFileTimeout, | 74 | 44 | shard, | 75 | 45 | }; | 76 | 46 | debug('test runner configuration:', options); | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/test_runner/coverage.js +13-11Lines changed: 13 additions & 11 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -25,18 +25,20 @@ const { | 25 | 25 | readFileSync, | 26 | 26 | } = require('fs'); | 27 | 27 | const { setupCoverageHooks } = require('internal/util'); | 28 | | -const { getOptionValue } = require('internal/options'); | 29 | 28 | const { tmpdir } = require('os'); | 30 | 29 | const { join, resolve, relative, matchesGlob } = require('path'); | 31 | 30 | const { fileURLToPath } = require('internal/url'); | 32 | 31 | const { kMappings, SourceMap } = require('internal/source_map/source_map'); | | 32 | +const { parseCommandLine } = require('internal/test_runner/utils'); | 33 | 33 | const kCoverageFileRegex = /^coverage-(\d+)-(\d{13})-(\d+)\.json$/; | 34 | 34 | const kIgnoreRegex = /\/\* node:coverage ignore next (?<count>\d+ )?\*\//; | 35 | 35 | const kLineEndingRegex = /\r?\n$/u; | 36 | 36 | const kLineSplitRegex = /(?<=\r?\n)/u; | 37 | 37 | const kStatusRegex = /\/\* node:coverage (?<status>enable|disable) \*\//; | 38 | | -const excludeFileGlobs = getOptionValue('--test-coverage-exclude'); | 39 | | -const includeFileGlobs = getOptionValue('--test-coverage-include'); | | 38 | +const { | | 39 | + coverageExcludeGlobs, | | 40 | + coverageIncludeGlobs, | | 41 | +} = parseCommandLine(); | 40 | 42 |
| 41 | 43 | class CoverageLine { | 42 | 44 | constructor(line, startOffset, src, length = src?.length) { | @@ -498,18 +500,18 @@ function shouldSkipFileCoverage(url, workingDirectory) { | 498 | 500 | const relativePath = relative(workingDirectory, absolutePath); | 499 | 501 |
| 500 | 502 | // This check filters out files that match the exclude globs. | 501 | | - if (excludeFileGlobs?.length > 0) { | 502 | | - for (let i = 0; i < excludeFileGlobs.length; ++i) { | 503 | | - if (matchesGlob(relativePath, excludeFileGlobs[i]) || | 504 | | - matchesGlob(absolutePath, excludeFileGlobs[i])) return true; | | 503 | + if (coverageExcludeGlobs?.length > 0) { | | 504 | + for (let i = 0; i < coverageExcludeGlobs.length; ++i) { | | 505 | + if (matchesGlob(relativePath, coverageExcludeGlobs[i]) || | | 506 | + matchesGlob(absolutePath, coverageExcludeGlobs[i])) return true; | 505 | 507 | } | 506 | 508 | } | 507 | 509 |
| 508 | 510 | // This check filters out files that do not match the include globs. | 509 | | - if (includeFileGlobs?.length > 0) { | 510 | | - for (let i = 0; i < includeFileGlobs.length; ++i) { | 511 | | - if (matchesGlob(relativePath, includeFileGlobs[i]) || | 512 | | - matchesGlob(absolutePath, includeFileGlobs[i])) return false; | | 511 | + if (coverageIncludeGlobs?.length > 0) { | | 512 | + for (let i = 0; i < coverageIncludeGlobs.length; ++i) { | | 513 | + if (matchesGlob(relativePath, coverageIncludeGlobs[i]) || | | 514 | + matchesGlob(absolutePath, coverageIncludeGlobs[i])) return false; | 513 | 515 | } | 514 | 516 | return true; | 515 | 517 | } | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/test_runner/utils.js +41Lines changed: 41 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 9 | 9 | MathFloor, | 10 | 10 | MathMax, | 11 | 11 | MathMin, | | 12 | + NumberParseInt, | 12 | 13 | NumberPrototypeToFixed, | 13 | 14 | ObjectGetOwnPropertyDescriptor, | 14 | 15 | RegExp, | @@ -19,6 +20,7 @@ const { | 19 | 20 | StringPrototypePadStart, | 20 | 21 | StringPrototypeRepeat, | 21 | 22 | StringPrototypeSlice, | | 23 | + StringPrototypeSplit, | 22 | 24 | } = primordials; | 23 | 25 |
| 24 | 26 | const { AsyncResource } = require('async_hooks'); | @@ -196,13 +198,19 @@ function parseCommandLine() { | 196 | 198 | const forceExit = getOptionValue('--test-force-exit'); | 197 | 199 | const sourceMaps = getOptionValue('--enable-source-maps'); | 198 | 200 | const updateSnapshots = getOptionValue('--test-update-snapshots'); | | 201 | + const watchMode = getOptionValue('--watch'); | 199 | 202 | const isChildProcess = process.env.NODE_TEST_CONTEXT === 'child'; | 200 | 203 | const isChildProcessV8 = process.env.NODE_TEST_CONTEXT === 'child-v8'; | | 204 | + let coverageExcludeGlobs; | | 205 | + let coverageIncludeGlobs; | 201 | 206 | let destinations; | | 207 | + let perFileTimeout; | 202 | 208 | let reporters; | | 209 | + let runnerConcurrency; | 203 | 210 | let testNamePatterns; | 204 | 211 | let testSkipPatterns; | 205 | 212 | let testOnlyFlag; | | 213 | + let shard; | 206 | 214 |
| 207 | 215 | if (isChildProcessV8) { | 208 | 216 | kBuiltinReporters.set('v8-serializer', 'internal/test_runner/reporter/v8-serializer'); | @@ -232,9 +240,31 @@ function parseCommandLine() { | 232 | 240 | } | 233 | 241 |
| 234 | 242 | if (isTestRunner) { | | 243 | + perFileTimeout = getOptionValue('--test-timeout') || Infinity; | | 244 | + runnerConcurrency = getOptionValue('--test-concurrency') || true; | 235 | 245 | testOnlyFlag = false; | 236 | 246 | testNamePatterns = null; | | 247 | + | | 248 | + const shardOption = getOptionValue('--test-shard'); | | 249 | + if (shardOption) { | | 250 | + if (!RegExpPrototypeExec(/^\d+\/\d+$/, shardOption)) { | | 251 | + throw new ERR_INVALID_ARG_VALUE( | | 252 | + '--test-shard', | | 253 | + shardOption, | | 254 | + 'must be in the form of <index>/<total>', | | 255 | + ); | | 256 | + } | | 257 | + | | 258 | + const indexAndTotal = StringPrototypeSplit(shardOption, '/'); | | 259 | + shard = { | | 260 | + __proto__: null, | | 261 | + index: NumberParseInt(indexAndTotal[0], 10), | | 262 | + total: NumberParseInt(indexAndTotal[1], 10), | | 263 | + }; | | 264 | + } | 237 | 265 | } else { | | 266 | + perFileTimeout = Infinity; | | 267 | + runnerConcurrency = 1; | 238 | 268 | const testNamePatternFlag = getOptionValue('--test-name-pattern'); | 239 | 269 | testOnlyFlag = getOptionValue('--test-only'); | 240 | 270 | testNamePatterns = testNamePatternFlag?.length > 0 ? | @@ -247,18 +277,29 @@ function parseCommandLine() { | 247 | 277 | ArrayPrototypeMap(testSkipPatternFlag, (re) => convertStringToRegExp(re, '--test-skip-pattern')) : null; | 248 | 278 | } | 249 | 279 |
| | 280 | + if (coverage) { | | 281 | + coverageExcludeGlobs = getOptionValue('--test-coverage-exclude'); | | 282 | + coverageIncludeGlobs = getOptionValue('--test-coverage-include'); | | 283 | + } | | 284 | + | 250 | 285 | globalTestOptions = { | 251 | 286 | __proto__: null, | 252 | 287 | isTestRunner, | 253 | 288 | coverage, | | 289 | + coverageExcludeGlobs, | | 290 | + coverageIncludeGlobs, | 254 | 291 | forceExit, | | 292 | + perFileTimeout, | | 293 | + runnerConcurrency, | | 294 | + shard, | 255 | 295 | sourceMaps, | 256 | 296 | testOnlyFlag, | 257 | 297 | testNamePatterns, | 258 | 298 | testSkipPatterns, | 259 | 299 | updateSnapshots, | 260 | 300 | reporters, | 261 | 301 | destinations, | | 302 | + watchMode, | 262 | 303 | }; | 263 | 304 |
| 264 | 305 | return globalTestOptions; | |
|