mirror of https://github.com/nodejs/node.git
test_runner: add cwd option to run
PR-URL: https://github.com/nodejs/node/pull/54705 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>pull/55255/head
parent
fe45be207b
commit
1c7795e52e
|
@ -1256,6 +1256,9 @@ added:
|
|||
- v18.9.0
|
||||
- v16.19.0
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/54705
|
||||
description: Added the `cwd` option.
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/53937
|
||||
description: Added coverage options.
|
||||
|
@ -1286,6 +1289,9 @@ changes:
|
|||
parallel.
|
||||
If `false`, it would only run one test file at a time.
|
||||
**Default:** `false`.
|
||||
* `cwd`: {string} Specifies the current working directory to be used by the test runner.
|
||||
Serves as the base path for resolving files according to the [test runner execution model][].
|
||||
**Default:** `process.cwd()`.
|
||||
* `files`: {Array} An array containing the list of files to run.
|
||||
**Default:** matching files from [test runner execution model][].
|
||||
* `forceExit`: {boolean} Configures the test runner to exit the process once
|
||||
|
|
|
@ -487,7 +487,6 @@ function sortCoverageFiles(a, b) {
|
|||
|
||||
function setupCoverage(options) {
|
||||
let originalCoverageDirectory = process.env.NODE_V8_COVERAGE;
|
||||
const cwd = process.cwd();
|
||||
|
||||
if (originalCoverageDirectory) {
|
||||
// NODE_V8_COVERAGE was already specified. Convert it to an absolute path
|
||||
|
@ -495,7 +494,7 @@ function setupCoverage(options) {
|
|||
// so that no preexisting coverage files interfere with the results of the
|
||||
// coverage report. Then, once the coverage is computed, move the coverage
|
||||
// files back to the original NODE_V8_COVERAGE directory.
|
||||
originalCoverageDirectory = resolve(cwd, originalCoverageDirectory);
|
||||
originalCoverageDirectory = resolve(options.cwd, originalCoverageDirectory);
|
||||
}
|
||||
|
||||
const coverageDirectory = mkdtempSync(join(tmpdir(), 'node-coverage-'));
|
||||
|
@ -512,7 +511,7 @@ function setupCoverage(options) {
|
|||
return new TestCoverage(
|
||||
coverageDirectory,
|
||||
originalCoverageDirectory,
|
||||
cwd,
|
||||
options.cwd,
|
||||
options.coverageExcludeGlobs,
|
||||
options.coverageIncludeGlobs,
|
||||
{
|
||||
|
|
|
@ -116,7 +116,7 @@ function createProcessEventHandler(eventName, rootTest) {
|
|||
const name = test.hookType ? `Test hook "${test.hookType}"` : `Test "${test.name}"`;
|
||||
let locInfo = '';
|
||||
if (test.loc) {
|
||||
const relPath = relative(process.cwd(), test.loc.file);
|
||||
const relPath = relative(rootTest.config.cwd, test.loc.file);
|
||||
locInfo = ` at ${relPath}:${test.loc.line}:${test.loc.column}`;
|
||||
}
|
||||
|
||||
|
@ -260,6 +260,7 @@ function lazyBootstrapRoot() {
|
|||
loc: entryFile ? [1, 1, entryFile] : undefined,
|
||||
};
|
||||
const globalOptions = parseCommandLine();
|
||||
globalOptions.cwd = process.cwd();
|
||||
createTestTree(rootTestOptions, globalOptions);
|
||||
globalRoot.reporter.on('test:summary', (data) => {
|
||||
if (!data.success) {
|
||||
|
|
|
@ -33,7 +33,7 @@ const {
|
|||
|
||||
const { spawn } = require('child_process');
|
||||
const { finished } = require('internal/streams/end-of-stream');
|
||||
const { resolve } = require('path');
|
||||
const { resolve, sep, isAbsolute } = require('path');
|
||||
const { DefaultDeserializer, DefaultSerializer } = require('v8');
|
||||
const { getOptionValue } = require('internal/options');
|
||||
const { Interface } = require('internal/readline/interface');
|
||||
|
@ -56,6 +56,7 @@ const {
|
|||
validateObject,
|
||||
validateOneOf,
|
||||
validateInteger,
|
||||
validateString,
|
||||
validateStringArray,
|
||||
} = require('internal/validators');
|
||||
const { getInspectPort, isUsingInspector, isInspectorMessage } = require('internal/util/inspector');
|
||||
|
@ -63,7 +64,6 @@ const { isRegExp } = require('internal/util/types');
|
|||
const { pathToFileURL } = require('internal/url');
|
||||
const {
|
||||
createDeferredPromise,
|
||||
getCWDURL,
|
||||
kEmptyObject,
|
||||
} = require('internal/util');
|
||||
const { kEmitMessage } = require('internal/test_runner/tests_stream');
|
||||
|
@ -137,7 +137,8 @@ function getRunArgs(path, { forceExit,
|
|||
testSkipPatterns,
|
||||
only,
|
||||
argv: suppliedArgs,
|
||||
execArgv }) {
|
||||
execArgv,
|
||||
cwd }) {
|
||||
const argv = ArrayPrototypeFilter(process.execArgv, filterExecArgv);
|
||||
if (forceExit === true) {
|
||||
ArrayPrototypePush(argv, '--test-force-exit');
|
||||
|
@ -494,7 +495,8 @@ function watchFiles(testFiles, opts) {
|
|||
// When file renamed (created / deleted) we need to update the watcher
|
||||
if (newFileName) {
|
||||
owners = new SafeSet().add(newFileName);
|
||||
watcher.filterFile(resolve(newFileName), owners);
|
||||
const resolveFileName = isAbsolute(newFileName) ? newFileName : resolve(opts.cwd, newFileName);
|
||||
watcher.filterFile(resolveFileName, owners);
|
||||
}
|
||||
|
||||
if (!newFileName && previousFileName) {
|
||||
|
@ -562,6 +564,7 @@ function run(options = kEmptyObject) {
|
|||
functionCoverage = 0,
|
||||
execArgv = [],
|
||||
argv = [],
|
||||
cwd = process.cwd(),
|
||||
} = options;
|
||||
|
||||
if (files != null) {
|
||||
|
@ -586,6 +589,8 @@ function run(options = kEmptyObject) {
|
|||
validateArray(globPatterns, 'options.globPatterns');
|
||||
}
|
||||
|
||||
validateString(cwd, 'options.cwd');
|
||||
|
||||
if (globPatterns?.length > 0 && files?.length > 0) {
|
||||
throw new ERR_INVALID_ARG_VALUE(
|
||||
'options.globPatterns', globPatterns, 'is not supported when specifying \'options.files\'',
|
||||
|
@ -673,12 +678,9 @@ function run(options = kEmptyObject) {
|
|||
lineCoverage: lineCoverage,
|
||||
branchCoverage: branchCoverage,
|
||||
functionCoverage: functionCoverage,
|
||||
cwd,
|
||||
};
|
||||
const root = createTestTree(rootTestOptions, globalOptions);
|
||||
|
||||
// This const should be replaced by a run option in the future.
|
||||
const cwd = process.cwd();
|
||||
|
||||
let testFiles = files ?? createTestFileList(globPatterns, cwd);
|
||||
|
||||
if (shard) {
|
||||
|
@ -731,7 +733,8 @@ function run(options = kEmptyObject) {
|
|||
};
|
||||
} else if (isolation === 'none') {
|
||||
if (watch) {
|
||||
filesWatcher = watchFiles(testFiles, opts);
|
||||
const absoluteTestFiles = ArrayPrototypeMap(testFiles, (file) => (isAbsolute(file) ? file : resolve(cwd, file)));
|
||||
filesWatcher = watchFiles(absoluteTestFiles, opts);
|
||||
runFiles = async () => {
|
||||
root.harness.bootstrapPromise = null;
|
||||
root.harness.buildPromise = null;
|
||||
|
@ -744,7 +747,7 @@ function run(options = kEmptyObject) {
|
|||
const { promise, resolve: finishBootstrap } = createDeferredPromise();
|
||||
|
||||
await root.runInAsyncScope(async () => {
|
||||
const parentURL = getCWDURL().href;
|
||||
const parentURL = pathToFileURL(cwd + sep).href;
|
||||
const cascadedLoader = esmLoader.getOrInitializeCascadedLoader();
|
||||
let topLevelTestCount = 0;
|
||||
|
||||
|
@ -757,7 +760,7 @@ function run(options = kEmptyObject) {
|
|||
|
||||
for (let i = 0; i < testFiles.length; ++i) {
|
||||
const testFile = testFiles[i];
|
||||
const fileURL = pathToFileURL(testFile);
|
||||
const fileURL = pathToFileURL(resolve(cwd, testFile));
|
||||
const parent = i === 0 ? undefined : parentURL;
|
||||
let threw = false;
|
||||
let importError;
|
||||
|
|
|
@ -6,6 +6,12 @@ const options = {
|
|||
file: {
|
||||
type: 'string',
|
||||
},
|
||||
cwd: {
|
||||
type: 'string',
|
||||
},
|
||||
isolation: {
|
||||
type: 'string',
|
||||
},
|
||||
};
|
||||
const {
|
||||
values,
|
||||
|
@ -13,12 +19,24 @@ const {
|
|||
} = parseArgs({ args: process.argv.slice(2), options });
|
||||
|
||||
let files;
|
||||
let cwd;
|
||||
let isolation;
|
||||
|
||||
if (values.file) {
|
||||
files = [values.file];
|
||||
}
|
||||
|
||||
if (values.cwd) {
|
||||
cwd = values.cwd;
|
||||
}
|
||||
|
||||
if (values.isolation) {
|
||||
isolation = values.isolation;
|
||||
}
|
||||
|
||||
run({
|
||||
files,
|
||||
watch: true
|
||||
watch: true,
|
||||
cwd,
|
||||
isolation,
|
||||
}).compose(tap).pipe(process.stdout);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { allowGlobals, mustCall } from '../common/index.mjs';
|
||||
import * as fixtures from '../common/fixtures.mjs';
|
||||
import { deepStrictEqual } from 'node:assert';
|
||||
import { run } from 'node:test';
|
||||
|
||||
const stream = run({
|
||||
cwd: fixtures.path('test-runner', 'no-isolation'),
|
||||
isolation: 'none',
|
||||
});
|
||||
|
||||
|
||||
stream.on('test:pass', mustCall(4));
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
allowGlobals(globalThis.GLOBAL_ORDER);
|
||||
deepStrictEqual(globalThis.GLOBAL_ORDER, [
|
||||
'before one: <root>',
|
||||
'suite one',
|
||||
'before two: <root>',
|
||||
'suite two',
|
||||
'beforeEach one: suite one - test',
|
||||
'beforeEach two: suite one - test',
|
||||
'suite one - test',
|
||||
'afterEach one: suite one - test',
|
||||
'afterEach two: suite one - test',
|
||||
'before suite two: suite two',
|
||||
'beforeEach one: suite two - test',
|
||||
'beforeEach two: suite two - test',
|
||||
'suite two - test',
|
||||
'afterEach one: suite two - test',
|
||||
'afterEach two: suite two - test',
|
||||
'after one: <root>',
|
||||
'after two: <root>',
|
||||
]);
|
|
@ -1,6 +1,6 @@
|
|||
// Flags: --expose-internals
|
||||
import * as common from '../common/index.mjs';
|
||||
import { describe, it, beforeEach } from 'node:test';
|
||||
import { describe, it, beforeEach, run } from 'node:test';
|
||||
import assert from 'node:assert';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { once } from 'node:events';
|
||||
|
@ -41,11 +41,23 @@ function refresh() {
|
|||
|
||||
const runner = join(import.meta.dirname, '..', 'fixtures', 'test-runner-watch.mjs');
|
||||
|
||||
async function testWatch({ fileToUpdate, file, action = 'update', cwd = tmpdir.path, fileToCreate }) {
|
||||
async function testWatch(
|
||||
{
|
||||
fileToUpdate,
|
||||
file,
|
||||
action = 'update',
|
||||
cwd = tmpdir.path,
|
||||
fileToCreate,
|
||||
runnerCwd,
|
||||
isolation
|
||||
}
|
||||
) {
|
||||
const ran1 = util.createDeferredPromise();
|
||||
const ran2 = util.createDeferredPromise();
|
||||
const args = [runner];
|
||||
if (file) args.push('--file', file);
|
||||
if (runnerCwd) args.push('--cwd', runnerCwd);
|
||||
if (isolation) args.push('--isolation', isolation);
|
||||
const child = spawn(process.execPath,
|
||||
args,
|
||||
{ encoding: 'utf8', stdio: 'pipe', cwd });
|
||||
|
@ -91,10 +103,12 @@ async function testWatch({ fileToUpdate, file, action = 'update', cwd = tmpdir.p
|
|||
currentRun = '';
|
||||
const fileToRenamePath = tmpdir.resolve(fileToUpdate);
|
||||
const newFileNamePath = tmpdir.resolve(`test-renamed-${fileToUpdate}`);
|
||||
const interval = setInterval(() => renameSync(fileToRenamePath, newFileNamePath), common.platformTimeout(1000));
|
||||
const interval = setInterval(() => {
|
||||
renameSync(fileToRenamePath, newFileNamePath);
|
||||
clearInterval(interval);
|
||||
}, common.platformTimeout(1000));
|
||||
await ran2.promise;
|
||||
runs.push(currentRun);
|
||||
clearInterval(interval);
|
||||
child.kill();
|
||||
await once(child, 'exit');
|
||||
|
||||
|
@ -129,11 +143,11 @@ async function testWatch({ fileToUpdate, file, action = 'update', cwd = tmpdir.p
|
|||
unlinkSync(fileToDeletePath);
|
||||
} else {
|
||||
ran2.resolve();
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, common.platformTimeout(1000));
|
||||
await ran2.promise;
|
||||
runs.push(currentRun);
|
||||
clearInterval(interval);
|
||||
child.kill();
|
||||
await once(child, 'exit');
|
||||
|
||||
|
@ -150,15 +164,17 @@ async function testWatch({ fileToUpdate, file, action = 'update', cwd = tmpdir.p
|
|||
currentRun = '';
|
||||
const newFilePath = tmpdir.resolve(fileToCreate);
|
||||
const interval = setInterval(
|
||||
() => writeFileSync(
|
||||
newFilePath,
|
||||
'module.exports = {};'
|
||||
),
|
||||
() => {
|
||||
writeFileSync(
|
||||
newFilePath,
|
||||
'module.exports = {};'
|
||||
);
|
||||
clearInterval(interval);
|
||||
},
|
||||
common.platformTimeout(1000)
|
||||
);
|
||||
await ran2.promise;
|
||||
runs.push(currentRun);
|
||||
clearInterval(interval);
|
||||
child.kill();
|
||||
await once(child, 'exit');
|
||||
|
||||
|
@ -221,7 +237,100 @@ describe('test runner watch mode', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should run new tests when a new file is created in the watched directory', async () => {
|
||||
await testWatch({ action: 'create', fileToCreate: 'new-test-file.test.js' });
|
||||
it(
|
||||
'should run new tests when a new file is created in the watched directory',
|
||||
async () => {
|
||||
await testWatch({ action: 'create', fileToCreate: 'new-test-file.test.js' });
|
||||
});
|
||||
|
||||
describe('test runner watch mode with different cwd', () => {
|
||||
it(
|
||||
'should execute run using a different cwd for the runner than the process cwd',
|
||||
async () => {
|
||||
await testWatch(
|
||||
{
|
||||
fileToUpdate: 'test.js',
|
||||
action: 'rename',
|
||||
cwd: import.meta.dirname,
|
||||
runnerCwd: tmpdir.path
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
'should execute run using a different cwd for the runner than the process cwd with isolation process',
|
||||
async () => {
|
||||
await testWatch(
|
||||
{
|
||||
fileToUpdate: 'test.js',
|
||||
action: 'rename',
|
||||
cwd: import.meta.dirname,
|
||||
runnerCwd: tmpdir.path,
|
||||
isolation: 'process'
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should run with different cwd while in watch mode', async () => {
|
||||
const controller = new AbortController();
|
||||
const stream = run({
|
||||
cwd: tmpdir.path,
|
||||
watch: true,
|
||||
signal: controller.signal,
|
||||
}).on('data', function({ type }) {
|
||||
if (type === 'test:watch:drained') {
|
||||
stream.removeAllListeners('test:fail');
|
||||
stream.removeAllListeners('test:pass');
|
||||
controller.abort();
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustCall(1));
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
});
|
||||
|
||||
it('should run with different cwd while in watch mode and isolation "none"', async () => {
|
||||
const controller = new AbortController();
|
||||
const stream = run({
|
||||
cwd: tmpdir.path,
|
||||
watch: true,
|
||||
signal: controller.signal,
|
||||
isolation: 'none',
|
||||
}).on('data', function({ type }) {
|
||||
if (type === 'test:watch:drained') {
|
||||
stream.removeAllListeners('test:fail');
|
||||
stream.removeAllListeners('test:pass');
|
||||
controller.abort();
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustCall(1));
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
});
|
||||
|
||||
it('should run with different cwd while in watch mode and isolation "process"', async () => {
|
||||
const controller = new AbortController();
|
||||
const stream = run({
|
||||
cwd: tmpdir.path,
|
||||
watch: true,
|
||||
signal: controller.signal,
|
||||
isolation: 'process',
|
||||
}).on('data', function({ type }) {
|
||||
if (type === 'test:watch:drained') {
|
||||
stream.removeAllListeners('test:fail');
|
||||
stream.removeAllListeners('test:pass');
|
||||
controller.abort();
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustCall(1));
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -496,6 +496,13 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should only allow a string in options.cwd', async () => {
|
||||
[Symbol(), {}, [], () => {}, 0, 1, 0n, 1n, true, false]
|
||||
.forEach((cwd) => assert.throws(() => run({ cwd }), {
|
||||
code: 'ERR_INVALID_ARG_TYPE'
|
||||
}));
|
||||
});
|
||||
|
||||
it('should only allow object as options', () => {
|
||||
[Symbol(), [], () => {}, 0, 1, 0n, 1n, '', '1', true, false]
|
||||
.forEach((options) => assert.throws(() => run(options), {
|
||||
|
@ -528,6 +535,73 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
|
|||
for await (const _ of stream);
|
||||
assert.match(stderr, /Warning: node:test run\(\) is being called recursively/);
|
||||
});
|
||||
|
||||
it('should run with different cwd', async () => {
|
||||
const stream = run({
|
||||
cwd: fixtures.path('test-runner', 'cwd')
|
||||
});
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustCall(1));
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
});
|
||||
|
||||
it('should handle a non-existent directory being provided as cwd', async () => {
|
||||
const diagnostics = [];
|
||||
const stream = run({
|
||||
cwd: fixtures.path('test-runner', 'cwd', 'non-existing')
|
||||
});
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustNotCall());
|
||||
stream.on('test:stderr', common.mustNotCall());
|
||||
stream.on('test:diagnostic', ({ message }) => {
|
||||
diagnostics.push(message);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
for (const entry of [
|
||||
'tests 0',
|
||||
'suites 0',
|
||||
'pass 0',
|
||||
'fail 0',
|
||||
'cancelled 0',
|
||||
'skipped 0',
|
||||
'todo 0',
|
||||
]
|
||||
) {
|
||||
assert.strictEqual(diagnostics.includes(entry), true);
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle a non-existent file being provided as cwd', async () => {
|
||||
const diagnostics = [];
|
||||
const stream = run({
|
||||
cwd: fixtures.path('test-runner', 'default-behavior', 'test', 'random.cjs')
|
||||
});
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustNotCall());
|
||||
stream.on('test:stderr', common.mustNotCall());
|
||||
stream.on('test:diagnostic', ({ message }) => {
|
||||
diagnostics.push(message);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
for (const entry of [
|
||||
'tests 0',
|
||||
'suites 0',
|
||||
'pass 0',
|
||||
'fail 0',
|
||||
'cancelled 0',
|
||||
'skipped 0',
|
||||
'todo 0',
|
||||
]
|
||||
) {
|
||||
assert.strictEqual(diagnostics.includes(entry), true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('forceExit', () => {
|
||||
|
|
|
@ -4,7 +4,8 @@ import { describe, it, beforeEach } from 'node:test';
|
|||
import { once } from 'node:events';
|
||||
import assert from 'node:assert';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { writeFileSync, renameSync, unlinkSync, existsSync } from 'node:fs';
|
||||
import { writeFileSync, renameSync, unlinkSync } from 'node:fs';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import util from 'internal/util';
|
||||
import tmpdir from '../common/tmpdir.js';
|
||||
|
||||
|
@ -69,10 +70,10 @@ async function testWatch({
|
|||
currentRun = '';
|
||||
const content = fixtureContent[fileToUpdate];
|
||||
const path = fixturePaths[fileToUpdate];
|
||||
const interval = setInterval(() => writeFileSync(path, content), common.platformTimeout(1000));
|
||||
writeFileSync(path, content);
|
||||
await setTimeout(common.platformTimeout(1000));
|
||||
await ran2.promise;
|
||||
runs.push(currentRun);
|
||||
clearInterval(interval);
|
||||
child.kill();
|
||||
await once(child, 'exit');
|
||||
|
||||
|
@ -92,10 +93,10 @@ async function testWatch({
|
|||
currentRun = '';
|
||||
const fileToRenamePath = tmpdir.resolve(fileToUpdate);
|
||||
const newFileNamePath = tmpdir.resolve(`test-renamed-${fileToUpdate}`);
|
||||
const interval = setInterval(() => renameSync(fileToRenamePath, newFileNamePath), common.platformTimeout(1000));
|
||||
renameSync(fileToRenamePath, newFileNamePath);
|
||||
await setTimeout(common.platformTimeout(1000));
|
||||
await ran2.promise;
|
||||
runs.push(currentRun);
|
||||
clearInterval(interval);
|
||||
child.kill();
|
||||
await once(child, 'exit');
|
||||
|
||||
|
@ -114,16 +115,10 @@ async function testWatch({
|
|||
runs.push(currentRun);
|
||||
currentRun = '';
|
||||
const fileToDeletePath = tmpdir.resolve(fileToUpdate);
|
||||
const interval = setInterval(() => {
|
||||
if (existsSync(fileToDeletePath)) {
|
||||
unlinkSync(fileToDeletePath);
|
||||
} else {
|
||||
ran2.resolve();
|
||||
}
|
||||
}, common.platformTimeout(1000));
|
||||
await ran2.promise;
|
||||
unlinkSync(fileToDeletePath);
|
||||
await setTimeout(common.platformTimeout(2000));
|
||||
ran2.resolve();
|
||||
runs.push(currentRun);
|
||||
clearInterval(interval);
|
||||
child.kill();
|
||||
await once(child, 'exit');
|
||||
|
||||
|
@ -139,16 +134,10 @@ async function testWatch({
|
|||
runs.push(currentRun);
|
||||
currentRun = '';
|
||||
const newFilePath = tmpdir.resolve(fileToCreate);
|
||||
const interval = setInterval(
|
||||
() => writeFileSync(
|
||||
newFilePath,
|
||||
'module.exports = {};'
|
||||
),
|
||||
common.platformTimeout(1000)
|
||||
);
|
||||
writeFileSync(newFilePath, 'module.exports = {};');
|
||||
await setTimeout(common.platformTimeout(1000));
|
||||
await ran2.promise;
|
||||
runs.push(currentRun);
|
||||
clearInterval(interval);
|
||||
child.kill();
|
||||
await once(child, 'exit');
|
||||
|
||||
|
|
Loading…
Reference in New Issue