diff --git a/src/stream.ts b/src/stream.ts index 6750b09..d519c4c 100644 --- a/src/stream.ts +++ b/src/stream.ts @@ -14,6 +14,9 @@ export const waitForEvent = ( export const combineStreams = (streams: Readable[]): Readable => { let streamCount = streams.length; const combined = new PassThrough(); + if (streamCount === 0) { + combined.end(); + } const maybeEmitEnd = () => { if (--streamCount === 0) { combined.end(); diff --git a/src/test/main_test.ts b/src/test/main_test.ts index ecc757c..1e4f553 100644 --- a/src/test/main_test.ts +++ b/src/test/main_test.ts @@ -101,6 +101,32 @@ describe.for(variants)('exec ($name)', ({x, isAsync}) => { }); describe('exec (async)', () => { + test.each(['ignore', 'inherit'] as const)( + 'async iteration completes with stdio=%s', + async (stdio) => { + const proc = x(process.execPath, ['-e', ''], { + nodeOptions: {stdio} + }); + const lines = []; + for await (const line of proc) lines.push(line); + expect(lines).toEqual([]); + expect(proc.exitCode).toBe(0); + }, + 2000 + ); + + test('async iteration reports a nonzero exit without output streams', async () => { + const proc = x(process.execPath, ['-e', 'process.exit(1)'], { + nodeOptions: {stdio: 'ignore'}, + throwOnError: true + }); + await expect(async () => { + for await (const _line of proc) { + // no output streams + } + }).rejects.toThrow(NonZeroExitError); + }, 2000); + test('non-zero exitCode throws when throwOnError=true', async () => { const proc = x('node', ['-e', 'process.exit(1);'], {throwOnError: true}); try { diff --git a/src/test/stream_test.ts b/src/test/stream_test.ts index 79f9c7d..ec9fbcf 100644 --- a/src/test/stream_test.ts +++ b/src/test/stream_test.ts @@ -13,6 +13,14 @@ describe('waitForEvent', async () => { }); describe('combineStreams', async () => { + test('ends without input streams', async () => { + const chunks = []; + for await (const chunk of combineStreams([])) { + chunks.push(chunk); + } + expect(chunks).toEqual([]); + }, 1000); + test('works with a single stream', async () => { const stream = Readable.from(['foo', 'bar']); const combined = combineStreams([stream]);