From 592965a2953b4ddf0f2a63639d5bf1eaa9588c04 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Thu, 31 Aug 2023 13:11:01 +0900 Subject: [PATCH] fix(watch): wait for the process to exit --- src/watch/index.ts | 7 ++++++- tests/specs/watch.ts | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/watch/index.ts b/src/watch/index.ts index b1379686..5b3c68d9 100644 --- a/src/watch/index.ts +++ b/src/watch/index.ts @@ -64,12 +64,17 @@ export const watchCommand = command({ let runProcess: ChildProcess | undefined; - const reRun = debounce(() => { + const reRun = debounce(async () => { if ( runProcess && (!runProcess.killed && runProcess.exitCode === null) ) { + const waitForExit = new Promise((resolve) => { + runProcess!.on('exit', resolve); + }); runProcess.kill(); + + await waitForExit; } // Not first run diff --git a/tests/specs/watch.ts b/tests/specs/watch.ts index e216aede..01c0c487 100644 --- a/tests/specs/watch.ts +++ b/tests/specs/watch.ts @@ -106,6 +106,50 @@ export default testSuite(async ({ describe }, fixturePath: string) => { await tsxProcess; }, 10_000); + test('wait for exit', async ({ onTestFinish }) => { + const fixture = await createFixture({ + 'index.js': ` + console.log('start'); + const sleepSync = (delay) => { + const waitTo = Date.now() + delay; + while (Date.now() < waitTo) {} + }; + process.on('exit', () => { + sleepSync(300); + console.log('end'); + }); + `, + }); + + onTestFinish(async () => await fixture.rm()); + + const tsxProcess = tsx({ + args: [ + 'watch', + path.join(fixture.path, 'index.js'), + ], + }); + + const stdout = await new Promise((resolve) => { + const buffers: Buffer[] = []; + async function onStdOut(data: Buffer) { + buffers.push(data); + const chunkString = data.toString(); + if (chunkString.match('start\n')) { + tsxProcess.stdin?.write('enter'); + } else if (chunkString.match('end\n')) { + tsxProcess.kill(); + resolve(Buffer.concat(buffers).toString()); + } + } + + tsxProcess.stdout!.on('data', onStdOut); + tsxProcess.stderr!.on('data', onStdOut); + }); + + expect(stdout).toBe('\u001Bcstart\nend\n'); + }, 10_000); + describe('help', ({ test }) => { test('shows help', async () => { const tsxProcess = await tsx({