| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,8 +5,8 @@ const { | |||
| 5 | 5 | } = primordials; | |
| 6 | 6 | ||
| 7 | 7 | const { | |
| 8 | - prepareMainThreadExecution, | ||
| 9 | 8 | markBootstrapComplete, | |
| 9 | + prepareTestRunnerMainExecution, | ||
| 10 | 10 | } = require('internal/process/pre_execution'); | |
| 11 | 11 | const { isUsingInspector } = require('internal/util/inspector'); | |
| 12 | 12 | const { run } = require('internal/test_runner/runner'); | |
@@ -16,10 +16,12 @@ let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => { | |||
| 16 | 16 | debug = fn; | |
| 17 | 17 | }); | |
| 18 | 18 | ||
| 19 | - prepareMainThreadExecution(false); | ||
| 20 | - markBootstrapComplete(); | ||
| 21 | - | ||
| 22 | 19 | const options = parseCommandLine(); | |
| 20 | + const isTestIsolationDisabled = options.isolation === 'none'; | ||
| 21 | + // We set initializeModules to false as we want to load user modules in the test runner run function | ||
| 22 | + // if we are running with --test-isolation=none | ||
| 23 | + prepareTestRunnerMainExecution(!isTestIsolationDisabled); | ||
| 24 | + markBootstrapComplete(); | ||
| 23 | 25 | ||
| 24 | 26 | if (isUsingInspector() && options.isolation === 'process') { | |
| 25 | 27 | process.emitWarning('Using the inspector with --test forces running at a concurrency of 1. ' + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -50,6 +50,15 @@ function prepareMainThreadExecution(expandArgv1 = false, initializeModules = tru | |||
| 50 | 50 | }); | |
| 51 | 51 | } | |
| 52 | 52 | ||
| 53 | + function prepareTestRunnerMainExecution(loadUserModules = true) { | ||
| 54 | + return prepareExecution({ | ||
| 55 | + expandArgv1: false, | ||
| 56 | + initializeModules: true, | ||
| 57 | + isMainThread: true, | ||
| 58 | + forceDefaultLoader: !loadUserModules, | ||
| 59 | + }); | ||
| 60 | + } | ||
| 61 | + | ||
| 53 | 62 | function prepareWorkerThreadExecution() { | |
| 54 | 63 | prepareExecution({ | |
| 55 | 64 | expandArgv1: false, | |
@@ -87,7 +96,7 @@ function prepareShadowRealmExecution() { | |||
| 87 | 96 | } | |
| 88 | 97 | ||
| 89 | 98 | function prepareExecution(options) { | |
| 90 | - const { expandArgv1, initializeModules, isMainThread } = options; | ||
| 99 | + const { expandArgv1, initializeModules, isMainThread, forceDefaultLoader } = options; | ||
| 91 | 100 | ||
| 92 | 101 | refreshRuntimeOptions(); | |
| 93 | 102 | ||
@@ -147,7 +156,7 @@ function prepareExecution(options) { | |||
| 147 | 156 | } | |
| 148 | 157 | ||
| 149 | 158 | if (initializeModules) { | |
| 150 | - setupUserModules(); | ||
| 159 | + setupUserModules(forceDefaultLoader); | ||
| 151 | 160 | } | |
| 152 | 161 | ||
| 153 | 162 | return mainEntry; | |
@@ -712,6 +721,7 @@ module.exports = { | |||
| 712 | 721 | prepareMainThreadExecution, | |
| 713 | 722 | prepareWorkerThreadExecution, | |
| 714 | 723 | prepareShadowRealmExecution, | |
| 724 | + prepareTestRunnerMainExecution, | ||
| 715 | 725 | markBootstrapComplete, | |
| 716 | 726 | loadPreloadModules, | |
| 717 | 727 | initializeFrozenIntrinsics, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -88,6 +88,7 @@ const { | |||
| 88 | 88 | const { Glob } = require('internal/fs/glob'); | |
| 89 | 89 | const { once } = require('events'); | |
| 90 | 90 | const { validatePath } = require('internal/fs/utils'); | |
| 91 | + const { loadPreloadModules } = require('internal/process/pre_execution'); | ||
| 91 | 92 | const { | |
| 92 | 93 | triggerUncaughtException, | |
| 93 | 94 | exitCodes: { kGenericUserError }, | |
@@ -692,6 +693,7 @@ function run(options = kEmptyObject) { | |||
| 692 | 693 | }; | |
| 693 | 694 | const root = createTestTree(rootTestOptions, globalOptions); | |
| 694 | 695 | let testFiles = files ?? createTestFileList(globPatterns, cwd); | |
| 696 | + const { isTestRunner } = globalOptions; | ||
| 695 | 697 | ||
| 696 | 698 | if (shard) { | |
| 697 | 699 | testFiles = ArrayPrototypeFilter(testFiles, (_, index) => index % shard.total === shard.index - 1); | |
@@ -765,6 +767,16 @@ function run(options = kEmptyObject) { | |||
| 765 | 767 | SafePromiseAllReturnVoid([root.harness.bootstrapPromise, promise]) : | |
| 766 | 768 | promise; | |
| 767 | 769 | ||
| 770 | + // We need to setup the user modules in the test runner if we are running with | ||
| 771 | + // --test-isolation=none and --test in order to avoid loading the user modules | ||
| 772 | + // BEFORE the creation of the root test (that would cause them to get lost). | ||
| 773 | + if (isTestRunner) { | ||
| 774 | + // If we are not coming from the test runner entry point, the user-required and imported | ||
| 775 | + // modules have already been loaded. | ||
| 776 | + // Since it's possible to delete modules from require.cache, a CommonJS module | ||
| 777 | + // could otherwise be executed twice. | ||
| 778 | + loadPreloadModules(); | ||
| 779 | + } | ||
| 768 | 780 | const userImports = getOptionValue('--import'); | |
| 769 | 781 | for (let i = 0; i < userImports.length; i++) { | |
| 770 | 782 | await cascadedLoader.import(userImports[i], parentURL, kEmptyObject); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -388,11 +388,16 @@ async function runTest( | |||
| 388 | 388 | const cjsPath = join(testFixtures, 'global-setup-teardown', 'required-module.cjs'); | |
| 389 | 389 | const esmpFile = fixtures.fileURL('test-runner', 'global-setup-teardown', 'imported-module.mjs'); | |
| 390 | 390 | ||
| 391 | - it('should run required module before globalSetup', async () => { | ||
| 391 | + // The difference in behavior is due to how --require and --import are handled by | ||
| 392 | + // the main entry point versus the test runner entry point. | ||
| 393 | + // When isolation is 'none', both --require and --import are handled by the test runner. | ||
| 394 | + const shouldRequireAfterSetup = runnerEnabled && isolation === 'none'; | ||
| 395 | + const shouldImportAfterSetup = runnerEnabled; | ||
| 396 | + | ||
| 397 | + it(`should run required module ${shouldRequireAfterSetup ? 'after' : 'before'} globalSetup`, async () => { | ||
| 392 | 398 | const setupFlagPath = tmpdir.resolve('setup-for-required.tmp'); | |
| 393 | 399 | const teardownFlagPath = tmpdir.resolve('teardown-for-required.tmp'); | |
| 394 | 400 | ||
| 395 | - // Create a setup file for test-file.js to find | ||
| 396 | 401 | fs.writeFileSync(setupFlagPath, ''); | |
| 397 | 402 | ||
| 398 | 403 | const { stdout } = await runTest({ | |
@@ -415,108 +420,63 @@ async function runTest( | |||
| 415 | 420 | assert.match(stdout, /Global setup executed/); | |
| 416 | 421 | assert.match(stdout, /Global teardown executed/); | |
| 417 | 422 | ||
| 418 | - // Verify that the required module was executed before the global setup | ||
| 419 | 423 | const requiredExecutedPosition = stdout.indexOf('Required module executed'); | |
| 420 | 424 | const globalSetupExecutedPosition = stdout.indexOf('Global setup executed'); | |
| 421 | - assert.ok(requiredExecutedPosition < globalSetupExecutedPosition, | ||
| 422 | - 'Required module should have been executed before global setup'); | ||
| 423 | 425 | ||
| 424 | - // After all tests complete, the teardown should have run | ||
| 426 | + assert.ok( | ||
| 427 | + shouldRequireAfterSetup ? | ||
| 428 | + requiredExecutedPosition > globalSetupExecutedPosition : | ||
| 429 | + requiredExecutedPosition < globalSetupExecutedPosition, | ||
| 430 | + `Required module should have been executed ${shouldRequireAfterSetup ? 'after' : 'before'} global setup` | ||
| 431 | + ); | ||
| 432 | + | ||
| 425 | 433 | assert.ok(fs.existsSync(teardownFlagPath), 'Teardown flag file should exist'); | |
| 426 | 434 | const content = fs.readFileSync(teardownFlagPath, 'utf8'); | |
| 427 | 435 | assert.strictEqual(content, 'Teardown was executed'); | |
| 428 | - | ||
| 429 | - // Setup flag should have been removed by teardown | ||
| 430 | 436 | assert.ok(!fs.existsSync(setupFlagPath), 'Setup flag file should have been removed'); | |
| 431 | 437 | }); | |
| 432 | 438 | ||
| 433 | - // This difference in behavior is due to the way --import is being handled by | ||
| 434 | - // run_main entry point or test_runner entry point | ||
| 435 | - if (runnerEnabled) { | ||
| 436 | - it('should run imported module after globalSetup', async () => { | ||
| 437 | - const setupFlagPath = tmpdir.resolve('setup-for-imported.tmp'); | ||
| 438 | - const teardownFlagPath = tmpdir.resolve('teardown-for-imported.tmp'); | ||
| 439 | - | ||
| 440 | - // Create a setup file for test-file.js to find | ||
| 441 | - fs.writeFileSync(setupFlagPath, 'non-empty'); | ||
| 442 | - | ||
| 443 | - const { stdout } = await runTest({ | ||
| 444 | - isolation, | ||
| 445 | - globalSetupFile: 'basic-setup-teardown.mjs', | ||
| 446 | - importPath: './imported-module.js', | ||
| 447 | - env: { | ||
| 448 | - SETUP_FLAG_PATH: setupFlagPath, | ||
| 449 | - TEARDOWN_FLAG_PATH: teardownFlagPath | ||
| 450 | - }, | ||
| 451 | - additionalFlags: [ | ||
| 452 | - `--import=${esmpFile}`, | ||
| 453 | - ], | ||
| 454 | - runnerEnabled | ||
| 455 | - }); | ||
| 456 | - | ||
| 457 | - assert.match(stdout, /pass 2/); | ||
| 458 | - assert.match(stdout, /fail 0/); | ||
| 459 | - assert.match(stdout, /Imported module executed/); | ||
| 460 | - assert.match(stdout, /Global setup executed/); | ||
| 461 | - assert.match(stdout, /Global teardown executed/); | ||
| 462 | - | ||
| 463 | - // Verify that the imported module was executed after the global setup | ||
| 464 | - const globalSetupExecutedPosition = stdout.indexOf('Global setup executed'); | ||
| 465 | - const importedExecutedPosition = stdout.indexOf('Imported module executed'); | ||
| 466 | - assert.ok(globalSetupExecutedPosition < importedExecutedPosition, | ||
| 467 | - 'Imported module should be executed after global setup'); | ||
| 468 | - | ||
| 469 | - // After all tests complete, the teardown should have run | ||
| 470 | - assert.ok(fs.existsSync(teardownFlagPath), 'Teardown flag file should exist'); | ||
| 471 | - const content = fs.readFileSync(teardownFlagPath, 'utf8'); | ||
| 472 | - assert.strictEqual(content, 'Teardown was executed'); | ||
| 473 | - | ||
| 474 | - // Setup flag should have been removed by teardown | ||
| 475 | - assert.ok(!fs.existsSync(setupFlagPath), 'Setup flag file should have been removed'); | ||
| 476 | - }); | ||
| 477 | - } else { | ||
| 478 | - it('should run imported module before globalSetup', async () => { | ||
| 479 | - const setupFlagPath = tmpdir.resolve('setup-for-imported.tmp'); | ||
| 480 | - const teardownFlagPath = tmpdir.resolve('teardown-for-imported.tmp'); | ||
| 481 | - | ||
| 482 | - // Create a setup file for test-file.js to find | ||
| 483 | - fs.writeFileSync(setupFlagPath, 'non-empty'); | ||
| 484 | - | ||
| 485 | - const { stdout } = await runTest({ | ||
| 486 | - isolation, | ||
| 487 | - globalSetupFile: 'basic-setup-teardown.mjs', | ||
| 488 | - importPath: './imported-module.js', | ||
| 489 | - env: { | ||
| 490 | - SETUP_FLAG_PATH: setupFlagPath, | ||
| 491 | - TEARDOWN_FLAG_PATH: teardownFlagPath | ||
| 492 | - }, | ||
| 493 | - additionalFlags: [ | ||
| 494 | - `--import=${esmpFile}`, | ||
| 495 | - ], | ||
| 496 | - runnerEnabled | ||
| 497 | - }); | ||
| 498 | - | ||
| 499 | - assert.match(stdout, /pass 2/); | ||
| 500 | - assert.match(stdout, /fail 0/); | ||
| 501 | - assert.match(stdout, /Imported module executed/); | ||
| 502 | - assert.match(stdout, /Global setup executed/); | ||
| 503 | - assert.match(stdout, /Global teardown executed/); | ||
| 504 | - | ||
| 505 | - // Verify that the imported module was executed before the global setup | ||
| 506 | - const importedExecutedPosition = stdout.indexOf('Imported module executed'); | ||
| 507 | - const globalSetupExecutedPosition = stdout.indexOf('Global setup executed'); | ||
| 508 | - assert.ok(importedExecutedPosition < globalSetupExecutedPosition, | ||
| 509 | - 'Imported module should be executed before global setup'); | ||
| 510 | - | ||
| 511 | - // After all tests complete, the teardown should have run | ||
| 512 | - assert.ok(fs.existsSync(teardownFlagPath), 'Teardown flag file should exist'); | ||
| 513 | - const content = fs.readFileSync(teardownFlagPath, 'utf8'); | ||
| 514 | - assert.strictEqual(content, 'Teardown was executed'); | ||
| 515 | - | ||
| 516 | - // Setup flag should have been removed by teardown | ||
| 517 | - assert.ok(!fs.existsSync(setupFlagPath), 'Setup flag file should have been removed'); | ||
| 439 | + it(`should run imported module ${shouldImportAfterSetup ? 'after' : 'before'} globalSetup`, async () => { | ||
| 440 | + const setupFlagPath = tmpdir.resolve('setup-for-imported.tmp'); | ||
| 441 | + const teardownFlagPath = tmpdir.resolve('teardown-for-imported.tmp'); | ||
| 442 | + | ||
| 443 | + fs.writeFileSync(setupFlagPath, 'non-empty'); | ||
| 444 | + | ||
| 445 | + const { stdout } = await runTest({ | ||
| 446 | + isolation, | ||
| 447 | + globalSetupFile: 'basic-setup-teardown.mjs', | ||
| 448 | + importPath: './imported-module.js', | ||
| 449 | + env: { | ||
| 450 | + SETUP_FLAG_PATH: setupFlagPath, | ||
| 451 | + TEARDOWN_FLAG_PATH: teardownFlagPath | ||
| 452 | + }, | ||
| 453 | + additionalFlags: [ | ||
| 454 | + `--import=${esmpFile}`, | ||
| 455 | + ], | ||
| 456 | + runnerEnabled | ||
| 518 | 457 | }); | |
| 519 | - } | ||
| 458 | + | ||
| 459 | + assert.match(stdout, /pass 2/); | ||
| 460 | + assert.match(stdout, /fail 0/); | ||
| 461 | + assert.match(stdout, /Imported module executed/); | ||
| 462 | + assert.match(stdout, /Global setup executed/); | ||
| 463 | + assert.match(stdout, /Global teardown executed/); | ||
| 464 | + | ||
| 465 | + const importedExecutedPosition = stdout.indexOf('Imported module executed'); | ||
| 466 | + const globalSetupExecutedPosition = stdout.indexOf('Global setup executed'); | ||
| 467 | + | ||
| 468 | + assert.ok( | ||
| 469 | + shouldImportAfterSetup ? | ||
| 470 | + importedExecutedPosition > globalSetupExecutedPosition : | ||
| 471 | + importedExecutedPosition < globalSetupExecutedPosition, | ||
| 472 | + `Imported module should have been executed ${shouldImportAfterSetup ? 'after' : 'before'} global setup` | ||
| 473 | + ); | ||
| 474 | + | ||
| 475 | + assert.ok(fs.existsSync(teardownFlagPath), 'Teardown flag file should exist'); | ||
| 476 | + const content = fs.readFileSync(teardownFlagPath, 'utf8'); | ||
| 477 | + assert.strictEqual(content, 'Teardown was executed'); | ||
| 478 | + assert.ok(!fs.existsSync(setupFlagPath), 'Setup flag file should have been removed'); | ||
| 479 | + }); | ||
| 520 | 480 | ||
| 521 | 481 | it('should execute globalSetup and globalTeardown correctly with imported module containing tests', async () => { | |
| 522 | 482 | const setupFlagPath = tmpdir.resolve('setup-executed.tmp'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -68,3 +68,15 @@ test('use --import (ESM) to define global hooks', async (t) => { | |||
| 68 | 68 | ||
| 69 | 69 | t.assert.equal(testHookOutput, order); | |
| 70 | 70 | }); | |
| 71 | + | ||
| 72 | + test('use --require to define global hooks', async (t) => { | ||
| 73 | + const { stdout } = await common.spawnPromisified(process.execPath, [ | ||
| 74 | + ...testArguments, | ||
| 75 | + '--require', fixtures.path('test-runner', 'no-isolation', 'global-hooks.cjs'), | ||
| 76 | + ...testFiles, | ||
| 77 | + ]); | ||
| 78 | + | ||
| 79 | + const testHookOutput = stdout.split('\n▶')[0]; | ||
| 80 | + | ||
| 81 | + t.assert.equal(testHookOutput, order); | ||
| 82 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments