| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3df7938 commit 676bbd5
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -424,13 +424,18 @@ function watchFiles(testFiles, opts) { | |||
| 424 | 424 | const newFileName = ArrayPrototypeFind(updatedTestFiles, (x) => !ArrayPrototypeIncludes(testFiles, x)); | |
| 425 | 425 | const previousFileName = ArrayPrototypeFind(testFiles, (x) => !ArrayPrototypeIncludes(updatedTestFiles, x)); | |
| 426 | 426 | ||
| 427 | + testFiles = updatedTestFiles; | ||
| 428 | + | ||
| 427 | 429 | // When file renamed | |
| 428 | 430 | if (newFileName && previousFileName) { | |
| 429 | 431 | owners = new SafeSet().add(newFileName); | |
| 430 | 432 | watcher.filterFile(resolve(newFileName), owners); | |
| 431 | 433 | } | |
| 432 | 434 | ||
| 433 | - testFiles = updatedTestFiles; | ||
| 435 | + if (!newFileName && previousFileName) { | ||
| 436 | + return; // Avoid rerunning files when file deleted | ||
| 437 | + } | ||
| 438 | + | ||
| 434 | 439 | } | |
| 435 | 440 | ||
| 436 | 441 | watcher.unfilterFilesOwnedBy(owners); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,104 @@ | |||
| 1 | + // Flags: --expose-internals | ||
| 2 | + import * as common from '../common/index.mjs'; | ||
| 3 | + import { describe, it } from 'node:test'; | ||
| 4 | + import assert from 'node:assert'; | ||
| 5 | + import { spawn } from 'node:child_process'; | ||
| 6 | + import { writeFileSync, unlinkSync } from 'node:fs'; | ||
| 7 | + import util from 'internal/util'; | ||
| 8 | + import tmpdir from '../common/tmpdir.js'; | ||
| 9 | + | ||
| 10 | + if (common.isIBMi) | ||
| 11 | + common.skip('IBMi does not support `fs.watch()`'); | ||
| 12 | + | ||
| 13 | + if (common.isAIX) | ||
| 14 | + common.skip('folder watch capability is limited in AIX.'); | ||
| 15 | + | ||
| 16 | + tmpdir.refresh(); | ||
| 17 | + | ||
| 18 | + // This test updates these files repeatedly, | ||
| 19 | + // Reading them from disk is unreliable due to race conditions. | ||
| 20 | + const fixtureContent = { | ||
| 21 | + 'dependency.js': 'module.exports = {};', | ||
| 22 | + 'dependency.mjs': 'export const a = 1;', | ||
| 23 | + // Test 1 | ||
| 24 | + 'test.js': ` | ||
| 25 | + const test = require('node:test'); | ||
| 26 | + require('./dependency.js'); | ||
| 27 | + import('./dependency.mjs'); | ||
| 28 | + import('data:text/javascript,'); | ||
| 29 | + test('first test has ran');`, | ||
| 30 | + // Test 2 | ||
| 31 | + 'test-2.mjs': ` | ||
| 32 | + import test from 'node:test'; | ||
| 33 | + import './dependency.js'; | ||
| 34 | + import { a } from './dependency.mjs'; | ||
| 35 | + import 'data:text/javascript,'; | ||
| 36 | + test('second test has ran');`, | ||
| 37 | + // Test file to be deleted | ||
| 38 | + 'test-to-delete.mjs': ` | ||
| 39 | + import test from 'node:test'; | ||
| 40 | + import './dependency.js'; | ||
| 41 | + import { a } from './dependency.mjs'; | ||
| 42 | + import 'data:text/javascript,'; | ||
| 43 | + test('test to delete has ran');`, | ||
| 44 | + }; | ||
| 45 | + | ||
| 46 | + const fixturePaths = Object.fromEntries(Object.keys(fixtureContent) | ||
| 47 | + .map((file) => [file, tmpdir.resolve(file)])); | ||
| 48 | + | ||
| 49 | + Object.entries(fixtureContent) | ||
| 50 | + .forEach(([file, content]) => writeFileSync(fixturePaths[file], content)); | ||
| 51 | + | ||
| 52 | + describe('test runner watch mode with more complex setup', () => { | ||
| 53 | + it('should run tests when a dependency changed after a watched test file being deleted', async () => { | ||
| 54 | + const ran1 = util.createDeferredPromise(); | ||
| 55 | + const ran2 = util.createDeferredPromise(); | ||
| 56 | + const child = spawn(process.execPath, | ||
| 57 | + ['--watch', '--test'], | ||
| 58 | + { encoding: 'utf8', stdio: 'pipe', cwd: tmpdir.path }); | ||
| 59 | + let stdout = ''; | ||
| 60 | + let currentRun = ''; | ||
| 61 | + const runs = []; | ||
| 62 | + | ||
| 63 | + child.stdout.on('data', (data) => { | ||
| 64 | + stdout += data.toString(); | ||
| 65 | + currentRun += data.toString(); | ||
| 66 | + const testRuns = stdout.match(/# duration_ms\s\d+/g); | ||
| 67 | + | ||
| 68 | + if (testRuns?.length >= 2) { | ||
| 69 | + ran2.resolve(); | ||
| 70 | + return; | ||
| 71 | + } | ||
| 72 | + if (testRuns?.length >= 1) ran1.resolve(); | ||
| 73 | + }); | ||
| 74 | + | ||
| 75 | + await ran1.promise; | ||
| 76 | + runs.push(currentRun); | ||
| 77 | + currentRun = ''; | ||
| 78 | + const fileToDeletePathLocal = tmpdir.resolve('test-to-delete.mjs'); | ||
| 79 | + unlinkSync(fileToDeletePathLocal); | ||
| 80 | + | ||
| 81 | + const content = fixtureContent['dependency.mjs']; | ||
| 82 | + const path = fixturePaths['dependency.mjs']; | ||
| 83 | + const interval = setInterval(() => writeFileSync(path, content), common.platformTimeout(1000)); | ||
| 84 | + await ran2.promise; | ||
| 85 | + runs.push(currentRun); | ||
| 86 | + currentRun = ''; | ||
| 87 | + clearInterval(interval); | ||
| 88 | + child.kill(); | ||
| 89 | + | ||
| 90 | + assert.strictEqual(runs.length, 2); | ||
| 91 | + | ||
| 92 | + const [firstRun, secondRun] = runs; | ||
| 93 | + | ||
| 94 | + assert.match(firstRun, /# tests 3/); | ||
| 95 | + assert.match(firstRun, /# pass 3/); | ||
| 96 | + assert.match(firstRun, /# fail 0/); | ||
| 97 | + assert.match(firstRun, /# cancelled 0/); | ||
| 98 | + | ||
| 99 | + assert.match(secondRun, /# tests 2/); | ||
| 100 | + assert.match(secondRun, /# pass 2/); | ||
| 101 | + assert.match(secondRun, /# fail 0/); | ||
| 102 | + assert.match(secondRun, /# cancelled 0/); | ||
| 103 | + }); | ||
| 104 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments