11cb0ef41Sopenharmony_ci// Flags: --expose-internals
21cb0ef41Sopenharmony_ciimport * as common from '../common/index.mjs';
31cb0ef41Sopenharmony_ciimport path from 'node:path';
41cb0ef41Sopenharmony_ciimport { describe, it } from 'node:test';
51cb0ef41Sopenharmony_ciimport { spawn } from 'node:child_process';
61cb0ef41Sopenharmony_ciimport { writeFileSync } from 'node:fs';
71cb0ef41Sopenharmony_ciimport util from 'internal/util';
81cb0ef41Sopenharmony_ciimport tmpdir from '../common/tmpdir.js';
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciif (common.isIBMi)
121cb0ef41Sopenharmony_ci  common.skip('IBMi does not support `fs.watch()`');
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_citmpdir.refresh();
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci// This test updates these files repeatedly,
171cb0ef41Sopenharmony_ci// Reading them from disk is unreliable due to race conditions.
181cb0ef41Sopenharmony_ciconst fixtureContent = {
191cb0ef41Sopenharmony_ci  'dependency.js': 'module.exports = {};',
201cb0ef41Sopenharmony_ci  'dependency.mjs': 'export const a = 1;',
211cb0ef41Sopenharmony_ci  'test.js': `
221cb0ef41Sopenharmony_ciconst test = require('node:test');
231cb0ef41Sopenharmony_cirequire('./dependency.js');
241cb0ef41Sopenharmony_ciimport('./dependency.mjs');
251cb0ef41Sopenharmony_ciimport('data:text/javascript,');
261cb0ef41Sopenharmony_citest('test has ran');`,
271cb0ef41Sopenharmony_ci};
281cb0ef41Sopenharmony_ciconst fixturePaths = Object.keys(fixtureContent)
291cb0ef41Sopenharmony_ci  .reduce((acc, file) => ({ ...acc, [file]: path.join(tmpdir.path, file) }), {});
301cb0ef41Sopenharmony_ciObject.entries(fixtureContent)
311cb0ef41Sopenharmony_ci  .forEach(([file, content]) => writeFileSync(fixturePaths[file], content));
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ciasync function testWatch({ fileToUpdate, file }) {
341cb0ef41Sopenharmony_ci  const ran1 = util.createDeferredPromise();
351cb0ef41Sopenharmony_ci  const ran2 = util.createDeferredPromise();
361cb0ef41Sopenharmony_ci  const child = spawn(process.execPath,
371cb0ef41Sopenharmony_ci                      ['--watch', '--test', file ? fixturePaths[file] : undefined].filter(Boolean),
381cb0ef41Sopenharmony_ci                      { encoding: 'utf8', stdio: 'pipe', cwd: tmpdir.path });
391cb0ef41Sopenharmony_ci  let stdout = '';
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  child.stdout.on('data', (data) => {
421cb0ef41Sopenharmony_ci    stdout += data.toString();
431cb0ef41Sopenharmony_ci    const testRuns = stdout.match(/ - test has ran/g);
441cb0ef41Sopenharmony_ci    if (testRuns?.length >= 1) ran1.resolve();
451cb0ef41Sopenharmony_ci    if (testRuns?.length >= 2) ran2.resolve();
461cb0ef41Sopenharmony_ci  });
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  await ran1.promise;
491cb0ef41Sopenharmony_ci  const content = fixtureContent[fileToUpdate];
501cb0ef41Sopenharmony_ci  const path = fixturePaths[fileToUpdate];
511cb0ef41Sopenharmony_ci  const interval = setInterval(() => writeFileSync(path, content), common.platformTimeout(1000));
521cb0ef41Sopenharmony_ci  await ran2.promise;
531cb0ef41Sopenharmony_ci  clearInterval(interval);
541cb0ef41Sopenharmony_ci  child.kill();
551cb0ef41Sopenharmony_ci}
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_cidescribe('test runner watch mode', () => {
581cb0ef41Sopenharmony_ci  it('should run tests repeatedly', async () => {
591cb0ef41Sopenharmony_ci    await testWatch({ file: 'test.js', fileToUpdate: 'test.js' });
601cb0ef41Sopenharmony_ci  });
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  it('should run tests with dependency repeatedly', async () => {
631cb0ef41Sopenharmony_ci    await testWatch({ file: 'test.js', fileToUpdate: 'dependency.js' });
641cb0ef41Sopenharmony_ci  });
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  it('should run tests with ESM dependency', async () => {
671cb0ef41Sopenharmony_ci    await testWatch({ file: 'test.js', fileToUpdate: 'dependency.mjs' });
681cb0ef41Sopenharmony_ci  });
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  it('should support running tests without a file', async () => {
711cb0ef41Sopenharmony_ci    await testWatch({ fileToUpdate: 'test.js' });
721cb0ef41Sopenharmony_ci  });
731cb0ef41Sopenharmony_ci});
74