GeezerVison is showing github.com — test_runner: emit event when file changes in watch mode · nodejs/node@4d64727
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: doc/api/test.md +16Lines changed: 16 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1121,6 +1121,9 @@ const customReporter = new Transform({ | 1121 | 1121 | case 'test:watch:drained': | 1122 | 1122 | callback(null, 'test watch queue drained'); | 1123 | 1123 | break; | | 1124 | + case 'test:watch:restarted': | | 1125 | + callback(null, 'test watch restarted due to file change'); | | 1126 | + break; | 1124 | 1127 | case 'test:start': | 1125 | 1128 | callback(null, `test ${event.data.name} started`); | 1126 | 1129 | break; | @@ -1166,6 +1169,9 @@ const customReporter = new Transform({ | 1166 | 1169 | case 'test:watch:drained': | 1167 | 1170 | callback(null, 'test watch queue drained'); | 1168 | 1171 | break; | | 1172 | + case 'test:watch:restarted': | | 1173 | + callback(null, 'test watch restarted due to file change'); | | 1174 | + break; | 1169 | 1175 | case 'test:start': | 1170 | 1176 | callback(null, `test ${event.data.name} started`); | 1171 | 1177 | break; | @@ -1210,6 +1216,9 @@ export default async function * customReporter(source) { | 1210 | 1216 | case 'test:watch:drained': | 1211 | 1217 | yield 'test watch queue drained\n'; | 1212 | 1218 | break; | | 1219 | + case 'test:watch:restarted': | | 1220 | + yield 'test watch restarted due to file change\n'; | | 1221 | + break; | 1213 | 1222 | case 'test:start': | 1214 | 1223 | yield `test ${event.data.name} started\n`; | 1215 | 1224 | break; | @@ -1250,6 +1259,9 @@ module.exports = async function * customReporter(source) { | 1250 | 1259 | case 'test:watch:drained': | 1251 | 1260 | yield 'test watch queue drained\n'; | 1252 | 1261 | break; | | 1262 | + case 'test:watch:restarted': | | 1263 | + yield 'test watch restarted due to file change\n'; | | 1264 | + break; | 1253 | 1265 | case 'test:start': | 1254 | 1266 | yield `test ${event.data.name} started\n`; | 1255 | 1267 | break; | @@ -3175,6 +3187,10 @@ generated for each test file in addition to a final cumulative summary. | 3175 | 3187 |
| 3176 | 3188 | Emitted when no more tests are queued for execution in watch mode. | 3177 | 3189 |
| | 3190 | +### Event: `'test:watch:restarted'` | | 3191 | + | | 3192 | +Emitted when one or more tests are restarted due to a file change in watch mode. | | 3193 | + | 3178 | 3194 | ## Class: `TestContext` | 3179 | 3195 |
| 3180 | 3196 | <!-- YAML | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/test_runner/runner.js +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -481,6 +481,7 @@ function watchFiles(testFiles, opts) { | 481 | 481 | // Reset the topLevel counter | 482 | 482 | opts.root.harness.counters.topLevel = 0; | 483 | 483 | } | | 484 | + | 484 | 485 | await runningSubtests.get(file); | 485 | 486 | runningSubtests.set(file, runTestFile(file, filesWatcher, opts)); | 486 | 487 | } | @@ -508,6 +509,8 @@ function watchFiles(testFiles, opts) { | 508 | 509 | // Reset the root start time to recalculate the duration | 509 | 510 | // of the run | 510 | 511 | opts.root.clearExecutionTime(); | | 512 | + opts.root.reporter[kEmitMessage]('test:watch:restarted'); | | 513 | + | 511 | 514 | // Restart test files | 512 | 515 | if (opts.isolation === 'none') { | 513 | 516 | PromisePrototypeThen(restartTestFile(kIsolatedProcessName), undefined, (error) => { | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-runner-run-watch.mjs +50Lines changed: 50 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -257,6 +257,56 @@ describe('test runner watch mode', () => { | 257 | 257 | assert.notDeepStrictEqual(durations[0][1], durations[1][1]); | 258 | 258 | }); | 259 | 259 |
| | 260 | + it('should emit test:watch:restarted when file is updated', async () => { | | 261 | + let alreadyDrained = false; | | 262 | + const events = []; | | 263 | + const testWatchRestarted = common.mustCall(1); | | 264 | + | | 265 | + const controller = new AbortController(); | | 266 | + const stream = run({ | | 267 | + cwd: tmpdir.path, | | 268 | + watch: true, | | 269 | + signal: controller.signal, | | 270 | + }).on('data', function({ type }) { | | 271 | + events.push(type); | | 272 | + if (type === 'test:watch:restarted') { | | 273 | + testWatchRestarted(); | | 274 | + } | | 275 | + if (type === 'test:watch:drained') { | | 276 | + if (alreadyDrained) { | | 277 | + controller.abort(); | | 278 | + } | | 279 | + alreadyDrained = true; | | 280 | + } | | 281 | + }); | | 282 | + | | 283 | + await once(stream, 'test:watch:drained'); | | 284 | + | | 285 | + writeFileSync(join(tmpdir.path, 'test.js'), fixtureContent['test.js']); | | 286 | + | | 287 | + // eslint-disable-next-line no-unused-vars | | 288 | + for await (const _ of stream); | | 289 | + | | 290 | + assert.partialDeepStrictEqual(events, [ | | 291 | + 'test:watch:drained', | | 292 | + 'test:watch:restarted', | | 293 | + 'test:watch:drained', | | 294 | + ]); | | 295 | + }); | | 296 | + | | 297 | + it('should not emit test:watch:restarted since watch mode is disabled', async () => { | | 298 | + const stream = run({ | | 299 | + cwd: tmpdir.path, | | 300 | + watch: false, | | 301 | + }); | | 302 | + | | 303 | + stream.on('test:watch:restarted', common.mustNotCall()); | | 304 | + writeFileSync(join(tmpdir.path, 'test.js'), fixtureContent['test.js']); | | 305 | + | | 306 | + // eslint-disable-next-line no-unused-vars | | 307 | + for await (const _ of stream); | | 308 | + }); | | 309 | + | 260 | 310 | describe('test runner watch mode with different cwd', () => { | 261 | 311 | it( | 262 | 312 | 'should execute run using a different cwd for the runner than the process cwd', | |
|