diff --git a/source/index.js b/source/index.js index 296790f..0654c8a 100644 --- a/source/index.js +++ b/source/index.js @@ -5,7 +5,7 @@ import {getResult} from './result.js'; import {handlePipe} from './pipe.js'; import {lineIterator, combineAsyncIterators} from './iterable.js'; -export default function nanoSpawn(file, second, third, previous) { +export default function spawn(file, second, third, previous) { const [commandArguments = [], options = {}] = Array.isArray(second) ? [second, third] : [[], second]; const context = getContext([file, ...commandArguments]); const spawnOptions = getOptions(options); @@ -21,6 +21,6 @@ export default function nanoSpawn(file, second, third, previous) { stdout, stderr, [Symbol.asyncIterator]: () => combineAsyncIterators(stdout, stderr), - pipe: (file, second, third) => nanoSpawn(file, second, third, subprocess), + pipe: (file, second, third) => spawn(file, second, third, subprocess), }); } diff --git a/source/index.test-d.ts b/source/index.test-d.ts index 676378a..8ec224c 100644 --- a/source/index.test-d.ts +++ b/source/index.test-d.ts @@ -5,7 +5,7 @@ import { expectNotAssignable, expectError, } from 'tsd'; -import nanoSpawn, { +import spawn, { type Options, type Result, type SubprocessError, @@ -13,7 +13,7 @@ import nanoSpawn, { } from './index.js'; try { - const result = await nanoSpawn('test'); + const result = await spawn('test'); expectType(result); expectType(result.stdout); expectType(result.stderr); @@ -48,101 +48,101 @@ expectAssignable({argv0: 'test'} as const); expectNotAssignable({other: 'test'} as const); expectNotAssignable('test'); -await nanoSpawn('test', {argv0: 'test'} as const); -expectError(await nanoSpawn('test', {argv0: true} as const)); -await nanoSpawn('test', {preferLocal: true} as const); -expectError(await nanoSpawn('test', {preferLocal: 'true'} as const)); -await nanoSpawn('test', {env: {}} as const); +await spawn('test', {argv0: 'test'} as const); +expectError(await spawn('test', {argv0: true} as const)); +await spawn('test', {preferLocal: true} as const); +expectError(await spawn('test', {preferLocal: 'true'} as const)); +await spawn('test', {env: {}} as const); // eslint-disable-next-line @typescript-eslint/naming-convention -await nanoSpawn('test', {env: {TEST: 'test'}} as const); -expectError(await nanoSpawn('test', {env: true} as const)); +await spawn('test', {env: {TEST: 'test'}} as const); +expectError(await spawn('test', {env: true} as const)); // eslint-disable-next-line @typescript-eslint/naming-convention -expectError(await nanoSpawn('test', {env: {TEST: true}} as const)); -await nanoSpawn('test', {stdin: 'pipe'} as const); -await nanoSpawn('test', {stdin: {string: 'test'} as const} as const); -expectError(await nanoSpawn('test', {stdin: {string: true} as const} as const)); -expectError(await nanoSpawn('test', {stdin: {other: 'test'} as const} as const)); -expectError(await nanoSpawn('test', {stdin: true} as const)); -await nanoSpawn('test', {stdout: 'pipe'} as const); -expectError(await nanoSpawn('test', {stdout: {string: 'test'} as const} as const)); -expectError(await nanoSpawn('test', {stdout: true} as const)); -await nanoSpawn('test', {stderr: 'pipe'} as const); -expectError(await nanoSpawn('test', {stderr: {string: 'test'} as const} as const)); -expectError(await nanoSpawn('test', {stderr: true} as const)); -await nanoSpawn('test', {stdio: ['pipe', 'pipe', 'pipe'] as const} as const); -await nanoSpawn('test', {stdio: [{string: 'test'} as const, 'pipe', 'pipe'] as const} as const); -expectError(await nanoSpawn('test', {stdio: ['pipe', {string: 'test'} as const, 'pipe'] as const} as const)); -expectError(await nanoSpawn('test', {stdio: ['pipe', 'pipe', {string: 'test'} as const] as const} as const)); -expectError(await nanoSpawn('test', {stdio: [{string: true} as const, 'pipe', 'pipe'] as const} as const)); -expectError(await nanoSpawn('test', {stdio: [{other: 'test'} as const, 'pipe', 'pipe'] as const} as const)); -expectError(await nanoSpawn('test', {stdio: [true, true, true] as const} as const)); -await nanoSpawn('test', {stdio: 'pipe'} as const); -expectError(await nanoSpawn('test', {stdio: true} as const)); -expectError(await nanoSpawn('test', {other: 'test'} as const)); +expectError(await spawn('test', {env: {TEST: true}} as const)); +await spawn('test', {stdin: 'pipe'} as const); +await spawn('test', {stdin: {string: 'test'} as const} as const); +expectError(await spawn('test', {stdin: {string: true} as const} as const)); +expectError(await spawn('test', {stdin: {other: 'test'} as const} as const)); +expectError(await spawn('test', {stdin: true} as const)); +await spawn('test', {stdout: 'pipe'} as const); +expectError(await spawn('test', {stdout: {string: 'test'} as const} as const)); +expectError(await spawn('test', {stdout: true} as const)); +await spawn('test', {stderr: 'pipe'} as const); +expectError(await spawn('test', {stderr: {string: 'test'} as const} as const)); +expectError(await spawn('test', {stderr: true} as const)); +await spawn('test', {stdio: ['pipe', 'pipe', 'pipe'] as const} as const); +await spawn('test', {stdio: [{string: 'test'} as const, 'pipe', 'pipe'] as const} as const); +expectError(await spawn('test', {stdio: ['pipe', {string: 'test'} as const, 'pipe'] as const} as const)); +expectError(await spawn('test', {stdio: ['pipe', 'pipe', {string: 'test'} as const] as const} as const)); +expectError(await spawn('test', {stdio: [{string: true} as const, 'pipe', 'pipe'] as const} as const)); +expectError(await spawn('test', {stdio: [{other: 'test'} as const, 'pipe', 'pipe'] as const} as const)); +expectError(await spawn('test', {stdio: [true, true, true] as const} as const)); +await spawn('test', {stdio: 'pipe'} as const); +expectError(await spawn('test', {stdio: true} as const)); +expectError(await spawn('test', {other: 'test'} as const)); -expectError(await nanoSpawn()); -expectError(await nanoSpawn(true)); -await nanoSpawn('test', [] as const); -await nanoSpawn('test', ['one'] as const); -expectError(await nanoSpawn('test', [true] as const)); -await nanoSpawn('test', {} as const); -expectError(await nanoSpawn('test', true)); -await nanoSpawn('test', ['one'] as const, {} as const); -expectError(await nanoSpawn('test', ['one'] as const, true)); -expectError(await nanoSpawn('test', ['one'] as const, {} as const, true)); +expectError(await spawn()); +expectError(await spawn(true)); +await spawn('test', [] as const); +await spawn('test', ['one'] as const); +expectError(await spawn('test', [true] as const)); +await spawn('test', {} as const); +expectError(await spawn('test', true)); +await spawn('test', ['one'] as const, {} as const); +expectError(await spawn('test', ['one'] as const, true)); +expectError(await spawn('test', ['one'] as const, {} as const, true)); -expectError(await nanoSpawn('test').pipe()); -expectError(await nanoSpawn('test').pipe(true)); -await nanoSpawn('test').pipe('test', [] as const); -await nanoSpawn('test').pipe('test', ['one'] as const); -expectError(await nanoSpawn('test').pipe('test', [true] as const)); -await nanoSpawn('test').pipe('test', {} as const); -expectError(await nanoSpawn('test').pipe('test', true)); -await nanoSpawn('test').pipe('test', ['one'] as const, {} as const); -expectError(await nanoSpawn('test').pipe('test', ['one'] as const, true)); -expectError(await nanoSpawn('test').pipe('test', ['one'] as const, {} as const, true)); +expectError(await spawn('test').pipe()); +expectError(await spawn('test').pipe(true)); +await spawn('test').pipe('test', [] as const); +await spawn('test').pipe('test', ['one'] as const); +expectError(await spawn('test').pipe('test', [true] as const)); +await spawn('test').pipe('test', {} as const); +expectError(await spawn('test').pipe('test', true)); +await spawn('test').pipe('test', ['one'] as const, {} as const); +expectError(await spawn('test').pipe('test', ['one'] as const, true)); +expectError(await spawn('test').pipe('test', ['one'] as const, {} as const, true)); -expectError(await nanoSpawn('test').pipe('test').pipe()); -expectError(await nanoSpawn('test').pipe('test').pipe(true)); -await nanoSpawn('test').pipe('test').pipe('test', [] as const); -await nanoSpawn('test').pipe('test').pipe('test', ['one'] as const); -expectError(await nanoSpawn('test').pipe('test').pipe('test', [true] as const)); -await nanoSpawn('test').pipe('test').pipe('test', {} as const); -expectError(await nanoSpawn('test').pipe('test').pipe('test', true)); -await nanoSpawn('test').pipe('test').pipe('test', ['one'] as const, {} as const); -expectError(await nanoSpawn('test').pipe('test').pipe('test', ['one'] as const, true)); -expectError(await nanoSpawn('test').pipe('test').pipe('test', ['one'] as const, {} as const, true)); +expectError(await spawn('test').pipe('test').pipe()); +expectError(await spawn('test').pipe('test').pipe(true)); +await spawn('test').pipe('test').pipe('test', [] as const); +await spawn('test').pipe('test').pipe('test', ['one'] as const); +expectError(await spawn('test').pipe('test').pipe('test', [true] as const)); +await spawn('test').pipe('test').pipe('test', {} as const); +expectError(await spawn('test').pipe('test').pipe('test', true)); +await spawn('test').pipe('test').pipe('test', ['one'] as const, {} as const); +expectError(await spawn('test').pipe('test').pipe('test', ['one'] as const, true)); +expectError(await spawn('test').pipe('test').pipe('test', ['one'] as const, {} as const, true)); -expectType(nanoSpawn('test').pipe('test')); -expectType(nanoSpawn('test').pipe('test').pipe('test')); -expectType(await nanoSpawn('test').pipe('test')); -expectType(await nanoSpawn('test').pipe('test').pipe('test')); +expectType(spawn('test').pipe('test')); +expectType(spawn('test').pipe('test').pipe('test')); +expectType(await spawn('test').pipe('test')); +expectType(await spawn('test').pipe('test').pipe('test')); -for await (const line of nanoSpawn('test')) { +for await (const line of spawn('test')) { expectType(line); } -for await (const line of nanoSpawn('test').pipe('test')) { +for await (const line of spawn('test').pipe('test')) { expectType(line); } -for await (const line of nanoSpawn('test').stdout) { +for await (const line of spawn('test').stdout) { expectType(line); } -for await (const line of nanoSpawn('test').pipe('test').stdout) { +for await (const line of spawn('test').pipe('test').stdout) { expectType(line); } -for await (const line of nanoSpawn('test').stderr) { +for await (const line of spawn('test').stderr) { expectType(line); } -for await (const line of nanoSpawn('test').pipe('test').stderr) { +for await (const line of spawn('test').pipe('test').stderr) { expectType(line); } -const subprocess = nanoSpawn('test'); +const subprocess = spawn('test'); expectType(subprocess); const nodeChildProcess = await subprocess.nodeChildProcess; diff --git a/source/iterable.js b/source/iterable.js index 4baf0a7..db0b256 100644 --- a/source/iterable.js +++ b/source/iterable.js @@ -3,7 +3,7 @@ export const lineIterator = async function * (subprocess, {state}, streamName) { // This would defeat one of the main goals of iterating: low memory consumption. if (state.isIterating === false) { throw new Error(`The subprocess must be iterated right away, for example: - for await (const line of nanoSpawn(...)) { ... }`); + for await (const line of spawn(...)) { ... }`); } state.isIterating = true; diff --git a/source/pipe.js b/source/pipe.js index 82310c6..ed01cff 100644 --- a/source/pipe.js +++ b/source/pipe.js @@ -21,11 +21,11 @@ const pipeStreams = async subprocesses => { try { const [{stdout}, {stdin}] = await Promise.all(subprocesses.map(({nodeChildProcess}) => nodeChildProcess)); if (stdin === null) { - throw new Error('The "stdin" option must be set on the first "nanoSpawn()" call in the pipeline.'); + throw new Error('The "stdin" option must be set on the first "spawn()" call in the pipeline.'); } if (stdout === null) { - throw new Error('The "stdout" option must be set on the last "nanoSpawn()" call in the pipeline.'); + throw new Error('The "stdout" option must be set on the last "spawn()" call in the pipeline.'); } // Do not `await` nor handle stream errors since this is already done by each subprocess diff --git a/test/context.js b/test/context.js index 32123ef..786802a 100644 --- a/test/context.js +++ b/test/context.js @@ -1,17 +1,17 @@ import test from 'ava'; import {red} from 'yoctocolors'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import {testString} from './helpers/arguments.js'; import {assertDurationMs} from './helpers/assert.js'; import {nodePrint, nodePrintFail, nodePrintStdout} from './helpers/commands.js'; test('result.command does not quote normal arguments', async t => { - const {command} = await nanoSpawn('node', ['--version']); + const {command} = await spawn('node', ['--version']); t.is(command, 'node --version'); }); const testCommandEscaping = async (t, input, expectedCommand) => { - const {command, stdout} = await nanoSpawn(...nodePrint(`"${input}"`)); + const {command, stdout} = await spawn(...nodePrint(`"${input}"`)); t.is(command, `node -p '"${expectedCommand}"'`); t.is(stdout, input); }; @@ -22,11 +22,11 @@ test('result.command quotes unusual characters', testCommandEscaping, ',', ','); test('result.command strips ANSI sequences', testCommandEscaping, red(testString), testString); test('result.durationMs is set', async t => { - const {durationMs} = await nanoSpawn(...nodePrintStdout); + const {durationMs} = await spawn(...nodePrintStdout); assertDurationMs(t, durationMs); }); test('error.durationMs is set', async t => { - const {durationMs} = await t.throwsAsync(nanoSpawn(...nodePrintFail)); + const {durationMs} = await t.throwsAsync(spawn(...nodePrintFail)); assertDurationMs(t, durationMs); }); diff --git a/test/fixtures/node-flags-path.js b/test/fixtures/node-flags-path.js index e99d6e9..8c13669 100755 --- a/test/fixtures/node-flags-path.js +++ b/test/fixtures/node-flags-path.js @@ -1,5 +1,5 @@ #!/usr/bin/env node import process from 'node:process'; -import nanoSpawn from '../../source/index.js'; +import spawn from '../../source/index.js'; -await nanoSpawn(process.execPath, ['-p', 'process.execArgv'], {stdout: 'inherit'}); +await spawn(process.execPath, ['-p', 'process.execArgv'], {stdout: 'inherit'}); diff --git a/test/fixtures/node-flags.js b/test/fixtures/node-flags.js index c85a756..29ad86b 100755 --- a/test/fixtures/node-flags.js +++ b/test/fixtures/node-flags.js @@ -1,4 +1,4 @@ #!/usr/bin/env node -import nanoSpawn from '../../source/index.js'; +import spawn from '../../source/index.js'; -await nanoSpawn('node', ['-p', 'process.execArgv'], {stdout: 'inherit'}); +await spawn('node', ['-p', 'process.execArgv'], {stdout: 'inherit'}); diff --git a/test/fixtures/node-version.js b/test/fixtures/node-version.js index 3f80b76..6532e77 100755 --- a/test/fixtures/node-version.js +++ b/test/fixtures/node-version.js @@ -1,4 +1,4 @@ #!/usr/bin/env node -import nanoSpawn from '../../source/index.js'; +import spawn from '../../source/index.js'; -await nanoSpawn('node', ['--version'], {stdout: 'inherit'}); +await spawn('node', ['--version'], {stdout: 'inherit'}); diff --git a/test/index.js b/test/index.js index 0611410..54a28b3 100644 --- a/test/index.js +++ b/test/index.js @@ -1,15 +1,15 @@ import test from 'ava'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import {assertSigterm} from './helpers/assert.js'; import {nodePrintStdout, nodeHanging, nodePrint} from './helpers/commands.js'; test('Can pass no arguments', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeHanging, {timeout: 1})); + const error = await t.throwsAsync(spawn(...nodeHanging, {timeout: 1})); assertSigterm(t, error); }); test('Can pass no arguments nor options', async t => { - const subprocess = nanoSpawn(...nodeHanging); + const subprocess = spawn(...nodeHanging); const nodeChildProcess = await subprocess.nodeChildProcess; nodeChildProcess.kill(); const error = await t.throwsAsync(subprocess); @@ -17,7 +17,7 @@ test('Can pass no arguments nor options', async t => { }); test('Returns a promise', async t => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); t.false(Object.prototype.propertyIsEnumerable.call(subprocess, 'then')); t.false(Object.hasOwn(subprocess, 'then')); t.true(subprocess instanceof Promise); @@ -25,7 +25,7 @@ test('Returns a promise', async t => { }); test('subprocess.nodeChildProcess is set', async t => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); const nodeChildProcess = await subprocess.nodeChildProcess; t.true(Number.isInteger(nodeChildProcess.pid)); await subprocess; @@ -35,6 +35,6 @@ const PARALLEL_COUNT = 100; test.serial('Can run many times at once', async t => { const inputs = Array.from({length: PARALLEL_COUNT}, (_, index) => `${index}`); - const results = await Promise.all(inputs.map(input => nanoSpawn(...nodePrint(input)))); + const results = await Promise.all(inputs.map(input => spawn(...nodePrint(input)))); t.deepEqual(results.map(({output}) => output), inputs); }); diff --git a/test/iterable.js b/test/iterable.js index 9d0c8fd..1c42add 100644 --- a/test/iterable.js +++ b/test/iterable.js @@ -1,5 +1,5 @@ import test from 'ava'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import {arrayFromAsync, destroySubprocessStream, writeMultibyte} from './helpers/main.js'; import { testString, @@ -26,7 +26,7 @@ const getIterable = (subprocess, iterableType) => iterableType === '' : subprocess[iterableType]; test('subprocess.stdout can be iterated', async t => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); const lines = await arrayFromAsync(subprocess.stdout); t.deepEqual(lines, [testString]); const {stdout, output} = await subprocess; @@ -35,7 +35,7 @@ test('subprocess.stdout can be iterated', async t => { }); test('subprocess.stderr can be iterated', async t => { - const subprocess = nanoSpawn(...nodePrintStderr); + const subprocess = spawn(...nodePrintStderr); const lines = await arrayFromAsync(subprocess.stderr); t.deepEqual(lines, [testString]); const {stderr, output} = await subprocess; @@ -44,7 +44,7 @@ test('subprocess.stderr can be iterated', async t => { }); test('subprocess[Symbol.asyncIterator] can be iterated', async t => { - const subprocess = nanoSpawn(...nodeEval(`console.log("${testString}"); + const subprocess = spawn(...nodeEval(`console.log("${testString}"); console.log("${secondTestString}"); console.error("${thirdTestString}"); console.error("${fourthTestString}");`)); @@ -60,7 +60,7 @@ console.error("${fourthTestString}");`)); test.serial('subprocess iteration can be interleaved', async t => { const length = 10; - const subprocess = nanoSpawn('node', ['--input-type=module', '-e', ` + const subprocess = spawn('node', ['--input-type=module', '-e', ` import {setTimeout} from 'node:timers/promises'; for (let index = 0; index < ${length}; index += 1) { @@ -80,7 +80,7 @@ for (let index = 0; index < ${length}; index += 1) { }); test('subprocess.stdout has no iterations if options.stdout "ignore"', async t => { - const subprocess = nanoSpawn(...nodePrintBoth, {stdout: 'ignore'}); + const subprocess = spawn(...nodePrintBoth, {stdout: 'ignore'}); const [stdoutLines, stderrLines] = await Promise.all([arrayFromAsync(subprocess.stdout), arrayFromAsync(subprocess.stderr)]); t.deepEqual(stdoutLines, []); t.deepEqual(stderrLines, [secondTestString]); @@ -91,7 +91,7 @@ test('subprocess.stdout has no iterations if options.stdout "ignore"', async t = }); test('subprocess.stderr has no iterations if options.stderr "ignore"', async t => { - const subprocess = nanoSpawn(...nodePrintBoth, {stderr: 'ignore'}); + const subprocess = spawn(...nodePrintBoth, {stderr: 'ignore'}); const [stdoutLines, stderrLines] = await Promise.all([arrayFromAsync(subprocess.stdout), arrayFromAsync(subprocess.stderr)]); t.deepEqual(stdoutLines, [testString]); t.deepEqual(stderrLines, []); @@ -102,7 +102,7 @@ test('subprocess.stderr has no iterations if options.stderr "ignore"', async t = }); test('subprocess[Symbol.asyncIterator] has iterations if only options.stdout "ignore"', async t => { - const subprocess = nanoSpawn(...nodePrintBoth, {stdout: 'ignore'}); + const subprocess = spawn(...nodePrintBoth, {stdout: 'ignore'}); const lines = await arrayFromAsync(subprocess); t.deepEqual(lines, [secondTestString]); const {stdout, stderr, output} = await subprocess; @@ -112,7 +112,7 @@ test('subprocess[Symbol.asyncIterator] has iterations if only options.stdout "ig }); test('subprocess[Symbol.asyncIterator] has iterations if only options.stderr "ignore"', async t => { - const subprocess = nanoSpawn(...nodePrintBoth, {stderr: 'ignore'}); + const subprocess = spawn(...nodePrintBoth, {stderr: 'ignore'}); const lines = await arrayFromAsync(subprocess); t.deepEqual(lines, [testString]); const {stdout, stderr, output} = await subprocess; @@ -122,7 +122,7 @@ test('subprocess[Symbol.asyncIterator] has iterations if only options.stderr "ig }); test('subprocess[Symbol.asyncIterator] has no iterations if only options.stdout + options.stderr "ignore"', async t => { - const subprocess = nanoSpawn(...nodePrintBoth, {stdout: 'ignore', stderr: 'ignore'}); + const subprocess = spawn(...nodePrintBoth, {stdout: 'ignore', stderr: 'ignore'}); const lines = await arrayFromAsync(subprocess); t.deepEqual(lines, []); const {stdout, stderr, output} = await subprocess; @@ -132,7 +132,7 @@ test('subprocess[Symbol.asyncIterator] has no iterations if only options.stdout }); test('subprocess.stdout has no iterations but waits for the subprocess if options.stdout "ignore"', async t => { - const subprocess = nanoSpawn(...nodePrintBothFail, {stdout: 'ignore'}); + const subprocess = spawn(...nodePrintBothFail, {stdout: 'ignore'}); const error = await t.throwsAsync(arrayFromAsync(subprocess.stdout)); assertFail(t, error); const promiseError = await t.throwsAsync(subprocess); @@ -143,7 +143,7 @@ test('subprocess.stdout has no iterations but waits for the subprocess if option }); const testIterationLate = async (t, iterableType) => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); await subprocess.nodeChildProcess; await t.throwsAsync(arrayFromAsync(getIterable(subprocess, iterableType)), {message: /must be iterated right away/}); }; @@ -153,7 +153,7 @@ test('subprocess.stderr must be called right away', testIterationLate, 'stderr') test('subprocess[Symbol.asyncIterator] must be called right away', testIterationLate, ''); test('subprocess[Symbol.asyncIterator] is line-wise', async t => { - const subprocess = nanoSpawn('node', ['--input-type=module', '-e', ` + const subprocess = spawn('node', ['--input-type=module', '-e', ` import {setTimeout} from 'node:timers/promises'; process.stdout.write("a\\nb\\n"); @@ -164,7 +164,7 @@ process.stderr.write("c\\nd\\n");`]); }); const testNewlineIteration = async (t, input, expectedLines) => { - const subprocess = nanoSpawn(...nodePrintNoNewline(input)); + const subprocess = spawn(...nodePrintNoNewline(input)); const lines = await arrayFromAsync(subprocess.stdout); t.deepEqual(lines, expectedLines); }; @@ -183,7 +183,7 @@ test('subprocess.stdout handles 2 Windows newlines in the middle', testNewlineIt test('subprocess.stdout handles 2 Windows newlines at the end', testNewlineIteration, 'a\r\nb\r\n\r\n', ['a', 'b', '']); test.serial('subprocess.stdout works with multibyte sequences', async t => { - const subprocess = nanoSpawn(...nodePassThrough); + const subprocess = spawn(...nodePassThrough); writeMultibyte(subprocess); const lines = await arrayFromAsync(subprocess.stdout); t.deepEqual(lines, [multibyteString]); @@ -193,7 +193,7 @@ test.serial('subprocess.stdout works with multibyte sequences', async t => { }); const testStreamIterateError = async (t, streamName) => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); const cause = new Error(testString); destroySubprocessStream(subprocess, cause, streamName); const error = await t.throwsAsync(arrayFromAsync(subprocess[streamName])); @@ -208,7 +208,7 @@ test('Handles subprocess.stdout error', testStreamIterateError, 'stdout'); test('Handles subprocess.stderr error', testStreamIterateError, 'stderr'); const testStreamIterateAllError = async (t, streamName) => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); const cause = new Error(testString); destroySubprocessStream(subprocess, cause, streamName); const error = await t.throwsAsync(arrayFromAsync(subprocess)); @@ -245,7 +245,7 @@ const iterateOnOutput = async (t, subprocess, state, cause, shouldThrow, iterabl }; const testIteration = async (t, shouldThrow, iterableType) => { - const subprocess = nanoSpawn(...nodePassThroughPrint); + const subprocess = spawn(...nodePassThroughPrint); const state = {done: false}; const cause = new Error(testString); @@ -268,7 +268,7 @@ test.serial('subprocess.stdout iteration exception waits for the subprocess succ test.serial('subprocess[Symbol.asyncIterator] iteration exception waits for the subprocess success', testIteration, true, ''); const testIterationFail = async (t, shouldThrow, iterableType) => { - const subprocess = nanoSpawn(...nodePassThroughPrintFail); + const subprocess = spawn(...nodePassThroughPrintFail); const state = {done: false}; const cause = new Error(testString); let caughtError; diff --git a/test/options.js b/test/options.js index 2f85f18..49a3318 100644 --- a/test/options.js +++ b/test/options.js @@ -3,7 +3,7 @@ import process from 'node:process'; import {fileURLToPath} from 'node:url'; import test from 'ava'; import pathKey from 'path-key'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import { isWindows, FIXTURES_URL, @@ -31,14 +31,14 @@ const VERSION_REGEXP = /^\d+\.\d+\.\d+$/; test.serial('options.env augments process.env', async t => { process.env.ONE = 'one'; process.env.TWO = 'two'; - const {stdout} = await nanoSpawn(...nodePrint('process.env.ONE + process.env.TWO'), {env: {TWO: testString}}); + const {stdout} = await spawn(...nodePrint('process.env.ONE + process.env.TWO'), {env: {TWO: testString}}); t.is(stdout, `${process.env.ONE}${testString}`); delete process.env.ONE; delete process.env.TWO; }); const testArgv0 = async (t, shell) => { - const {stdout} = await nanoSpawn(...nodePrintArgv0, {argv0: testString, shell}); + const {stdout} = await spawn(...nodePrintArgv0, {argv0: testString, shell}); t.is(stdout, shell ? process.execPath : testString); }; @@ -46,7 +46,7 @@ test('Can pass options.argv0', testArgv0, false); test('Can pass options.argv0, shell', testArgv0, true); const testCwd = async (t, cwd) => { - const {stdout} = await nanoSpawn(...nodePrint('process.cwd()'), {cwd}); + const {stdout} = await spawn(...nodePrint('process.cwd()'), {cwd}); t.is(stdout, fixturesPath.replace(/[\\/]$/, '')); }; @@ -54,7 +54,7 @@ test('Can pass options.cwd string', testCwd, fixturesPath); test('Can pass options.cwd URL', testCwd, FIXTURES_URL); const testStdOption = async (t, optionName) => { - const subprocess = nanoSpawn(...nodePrintStdout, {[optionName]: 'ignore'}); + const subprocess = spawn(...nodePrintStdout, {[optionName]: 'ignore'}); const nodeChildProcess = await subprocess.nodeChildProcess; t.is(nodeChildProcess[optionName], null); await subprocess; @@ -65,7 +65,7 @@ test('Can pass options.stdout', testStdOption, 'stdout'); test('Can pass options.stderr', testStdOption, 'stderr'); const testStdOptionDefault = async (t, optionName) => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); const nodeChildProcess = await subprocess.nodeChildProcess; t.not(nodeChildProcess[optionName], null); await subprocess; @@ -76,7 +76,7 @@ test('options.stdout defaults to "pipe"', testStdOptionDefault, 'stdout'); test('options.stderr defaults to "pipe"', testStdOptionDefault, 'stderr'); test('Can pass options.stdio array', async t => { - const subprocess = nanoSpawn(...nodePrintStdout, {stdio: ['ignore', 'pipe', 'pipe', 'pipe']}); + const subprocess = spawn(...nodePrintStdout, {stdio: ['ignore', 'pipe', 'pipe', 'pipe']}); const {stdin, stdout, stderr, stdio} = await subprocess.nodeChildProcess; t.is(stdin, null); t.not(stdout, null); @@ -86,7 +86,7 @@ test('Can pass options.stdio array', async t => { }); test('Can pass options.stdio string', async t => { - const subprocess = nanoSpawn(...nodePrintStdout, {stdio: 'ignore'}); + const subprocess = spawn(...nodePrintStdout, {stdio: 'ignore'}); const {stdin, stdout, stderr, stdio} = await subprocess.nodeChildProcess; t.is(stdin, null); t.is(stdout, null); @@ -96,7 +96,7 @@ test('Can pass options.stdio string', async t => { }); const testStdioPriority = async (t, stdio) => { - const subprocess = nanoSpawn(...nodePrintStdout, {stdio, stdout: 'ignore'}); + const subprocess = spawn(...nodePrintStdout, {stdio, stdout: 'ignore'}); const {stdout} = await subprocess.nodeChildProcess; t.not(stdout, null); await subprocess; @@ -106,7 +106,7 @@ test('options.stdio array has priority over options.stdout', testStdioPriority, test('options.stdio string has priority over options.stdout', testStdioPriority, 'pipe'); const testInput = async (t, options, expectedStdout) => { - const {stdout} = await nanoSpawn(...nodePassThrough, options); + const {stdout} = await spawn(...nodePassThrough, options); t.is(stdout, expectedStdout); }; @@ -116,7 +116,7 @@ test('options.stdin can be {string: ""}', testInput, {stdin: {string: ''}}, ''); test('options.stdio[0] can be {string: ""}', testInput, {stdio: [{string: ''}, 'pipe', 'pipe']}, ''); const testLocalBinaryExec = async (t, cwd) => { - const {stdout} = await nanoSpawn(...localBinary, {preferLocal: true, cwd}); + const {stdout} = await spawn(...localBinary, {preferLocal: true, cwd}); t.regex(stdout, VERSION_REGEXP); }; @@ -125,7 +125,7 @@ test('options.preferLocal true runs local npm binaries with options.cwd string', test('options.preferLocal true runs local npm binaries with options.cwd URL', testLocalBinaryExec, FIXTURES_URL); const testPathVariable = async (t, pathName) => { - const {stdout} = await nanoSpawn(...localBinary, {preferLocal: true, env: {PATH: undefined, Path: undefined, [pathName]: isWindows ? process.env[pathKey()] : nodeDirectory}}); + const {stdout} = await spawn(...localBinary, {preferLocal: true, env: {PATH: undefined, Path: undefined, [pathName]: isWindows ? process.env[pathKey()] : nodeDirectory}}); t.regex(stdout, VERSION_REGEXP); }; @@ -137,7 +137,7 @@ const testNoLocal = async (t, preferLocal) => { .split(path.delimiter) .filter(pathPart => !pathPart.includes(path.join('node_modules', '.bin'))) .join(path.delimiter); - const error = await t.throwsAsync(nanoSpawn(...localBinary, {preferLocal, env: {Path: undefined, PATH}})); + const error = await t.throwsAsync(spawn(...localBinary, {preferLocal, env: {Path: undefined, PATH}})); if (isWindows) { assertWindowsNonExistent(t, error, localBinaryCommand); } else { @@ -149,7 +149,7 @@ test('options.preferLocal undefined does not run local npm binaries', testNoLoca test('options.preferLocal false does not run local npm binaries', testNoLocal, false); test('options.preferLocal true uses options.env when empty', async t => { - const error = await t.throwsAsync(nanoSpawn(...localBinary, {preferLocal: true, env: {PATH: undefined, Path: undefined}})); + const error = await t.throwsAsync(spawn(...localBinary, {preferLocal: true, env: {PATH: undefined, Path: undefined}})); if (isWindows) { assertNonExistent(t, error, 'cmd.exe', localBinaryCommand); } else { @@ -158,7 +158,7 @@ test('options.preferLocal true uses options.env when empty', async t => { }); test('options.preferLocal true can use an empty PATH', async t => { - const {stdout} = await nanoSpawn(process.execPath, ['--version'], {preferLocal: true, env: {PATH: undefined, Path: undefined}}); + const {stdout} = await spawn(process.execPath, ['--version'], {preferLocal: true, env: {PATH: undefined, Path: undefined}}); t.is(stdout, process.version); }); @@ -166,7 +166,7 @@ test('options.preferLocal true does not add node_modules/.bin if already present const localDirectory = fileURLToPath(new URL('node_modules/.bin', import.meta.url)); const currentPath = process.env[pathKey()]; const pathValue = `${localDirectory}${path.delimiter}${currentPath}`; - const {stdout} = await nanoSpawn(...nodePrint(`process.env.${pathKey()}`), {preferLocal: true, env: {[pathKey()]: pathValue}}); + const {stdout} = await spawn(...nodePrint(`process.env.${pathKey()}`), {preferLocal: true, env: {[pathKey()]: pathValue}}); t.is( stdout.split(path.delimiter).filter(pathPart => pathPart === localDirectory).length - currentPath.split(path.delimiter).filter(pathPart => pathPart === localDirectory).length, @@ -175,7 +175,7 @@ test('options.preferLocal true does not add node_modules/.bin if already present }); const testLocalBinary = async (t, input) => { - const {stderr} = await nanoSpawn('ava', ['test.js', '--', input], {preferLocal: true, cwd: FIXTURES_URL}); + const {stderr} = await spawn('ava', ['test.js', '--', input], {preferLocal: true, cwd: FIXTURES_URL}); t.is(stderr, input); }; @@ -208,22 +208,22 @@ test('options.preferLocal true can pass arguments to local npm binaries, ?', tes if (!isWindows) { test('options.preferLocal true prefer local binaries over global ones', async t => { - const {stdout} = await nanoSpawn('git', {preferLocal: true, cwd: FIXTURES_URL}); + const {stdout} = await spawn('git', {preferLocal: true, cwd: FIXTURES_URL}); t.is(stdout, testString); }); test('options.preferLocal true prefer subdirectories over parent directories', async t => { - const {stdout} = await nanoSpawn('git', {preferLocal: true, cwd: new URL('subdir', FIXTURES_URL)}); + const {stdout} = await spawn('git', {preferLocal: true, cwd: new URL('subdir', FIXTURES_URL)}); t.is(stdout, secondTestString); }); } test('Can run global npm binaries', async t => { - const {stdout} = await nanoSpawn('npm', ['--version']); + const {stdout} = await spawn('npm', ['--version']); t.regex(stdout, VERSION_REGEXP); }); test('Can run OS binaries', async t => { - const {stdout} = await nanoSpawn('git', ['--version']); + const {stdout} = await spawn('git', ['--version']); t.regex(stdout, /^git version \d+\.\d+\.\d+/); }); diff --git a/test/pipe.js b/test/pipe.js index ea153e4..05a70bd 100644 --- a/test/pipe.js +++ b/test/pipe.js @@ -3,7 +3,7 @@ import {readFile} from 'node:fs/promises'; import {once} from 'node:events'; import {temporaryWriteTask} from 'tempy'; import test from 'ava'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import { isWindows, FIXTURES_URL, @@ -41,7 +41,7 @@ import { const testFixtureUrl = new URL('test.txt', FIXTURES_URL); test('.pipe() success', async t => { - const first = nanoSpawn(...nodePrintStdout); + const first = spawn(...nodePrintStdout); const {stdout, output, durationMs, pipedFrom} = await first.pipe(...nodeToUpperCase); const firstResult = await first; t.is(firstResult.pipedFrom, undefined); @@ -52,7 +52,7 @@ test('.pipe() success', async t => { }); test('.pipe() source fails', async t => { - const first = nanoSpawn(...nodePrintFail); + const first = spawn(...nodePrintFail); const secondError = await t.throwsAsync(first.pipe(...nodeToUpperCase)); const firstError = await t.throwsAsync(first); t.is(firstError, secondError); @@ -63,7 +63,7 @@ test('.pipe() source fails', async t => { }); test('.pipe() source fails due to child_process invalid option', async t => { - const first = nanoSpawn(...nodePrintStdout, earlyErrorOptions); + const first = spawn(...nodePrintStdout, earlyErrorOptions); const secondError = await t.throwsAsync(first.pipe(...nodeToUpperCase)); const firstError = await t.throwsAsync(first); assertEarlyError(t, secondError); @@ -72,7 +72,7 @@ test('.pipe() source fails due to child_process invalid option', async t => { }); test('.pipe() source fails due to stream error', async t => { - const first = nanoSpawn(...nodePrintStdout); + const first = spawn(...nodePrintStdout); const second = first.pipe(...nodeToUpperCase); const cause = new Error(testString); const nodeChildProcess = await first.nodeChildProcess; @@ -86,7 +86,7 @@ test('.pipe() source fails due to stream error', async t => { }); test('.pipe() destination fails', async t => { - const first = nanoSpawn(...nodePrintStdout); + const first = spawn(...nodePrintStdout); const secondError = await t.throwsAsync(first.pipe(...nodeToUpperCaseFail)); const firstResult = await first; assertFail(t, secondError); @@ -97,7 +97,7 @@ test('.pipe() destination fails', async t => { }); test('.pipe() destination fails due to child_process invalid option', async t => { - const first = nanoSpawn(...nodePrintStdout); + const first = spawn(...nodePrintStdout); const secondError = await t.throwsAsync(first.pipe(...nodeToUpperCase, earlyErrorOptions)); const firstResult = await first; assertEarlyError(t, secondError); @@ -107,7 +107,7 @@ test('.pipe() destination fails due to child_process invalid option', async t => }); test('.pipe() destination fails due to stream error', async t => { - const first = nanoSpawn(...nodePrintStdout); + const first = spawn(...nodePrintStdout); const second = first.pipe(...nodeToUpperCase); const cause = new Error(testString); const nodeChildProcess = await second.nodeChildProcess; @@ -121,7 +121,7 @@ test('.pipe() destination fails due to stream error', async t => { }); test('.pipe() source and destination fail', async t => { - const first = nanoSpawn(...nodePrintFail); + const first = spawn(...nodePrintFail); const secondError = await t.throwsAsync(first.pipe(...nodeToUpperCaseFail)); const firstError = await t.throwsAsync(first); assertFail(t, firstError); @@ -135,7 +135,7 @@ test('.pipe() source and destination fail', async t => { }); test('.pipe().pipe() success', async t => { - const first = nanoSpawn(...nodePrintStdout).pipe(...nodeToUpperCase); + const first = spawn(...nodePrintStdout).pipe(...nodeToUpperCase); const secondResult = await first.pipe(...nodeDouble); const firstResult = await first; t.is(firstResult.stdout, testUpperCase); @@ -146,7 +146,7 @@ test('.pipe().pipe() success', async t => { }); test('.pipe().pipe() first source fail', async t => { - const first = nanoSpawn(...nodePrintFail).pipe(...nodeToUpperCase); + const first = spawn(...nodePrintFail).pipe(...nodeToUpperCase); const secondError = await t.throwsAsync(first.pipe(...nodeDouble)); const firstError = await t.throwsAsync(first); assertFail(t, firstError); @@ -156,7 +156,7 @@ test('.pipe().pipe() first source fail', async t => { }); test('.pipe().pipe() second source fail', async t => { - const first = nanoSpawn(...nodePrintStdout).pipe(...nodeToUpperCaseFail); + const first = spawn(...nodePrintStdout).pipe(...nodeToUpperCaseFail); const secondError = await t.throwsAsync(first.pipe(...nodeDouble)); const firstError = await t.throwsAsync(first); assertFail(t, firstError); @@ -166,7 +166,7 @@ test('.pipe().pipe() second source fail', async t => { }); test('.pipe().pipe() destination fail', async t => { - const first = nanoSpawn(...nodePrintStdout).pipe(...nodeToUpperCase); + const first = spawn(...nodePrintStdout).pipe(...nodeToUpperCase); const secondError = await t.throwsAsync(first.pipe(...nodeDoubleFail)); const firstResult = await first; assertFail(t, secondError); @@ -178,7 +178,7 @@ test('.pipe().pipe() destination fail', async t => { }); test('.pipe().pipe() all fail', async t => { - const first = nanoSpawn(...nodePrintFail).pipe(...nodeToUpperCaseFail); + const first = spawn(...nodePrintFail).pipe(...nodeToUpperCaseFail); const secondError = await t.throwsAsync(first.pipe(...nodeDoubleFail)); const firstError = await t.throwsAsync(first); assertFail(t, firstError); @@ -193,47 +193,47 @@ test('.pipe().pipe() all fail', async t => { // Cannot guarantee that `cat` exists on Windows if (!isWindows) { test('.pipe() without arguments', async t => { - const {stdout} = await nanoSpawn(...nodePrintStdout).pipe('cat'); + const {stdout} = await spawn(...nodePrintStdout).pipe('cat'); t.is(stdout, testString); }); } test('.pipe() with options', async t => { const argv0 = 'Foo'; - const {stdout} = await nanoSpawn(...nodePrintStdout).pipe(...nodeEval(`process.stdin.on("data", chunk => { + const {stdout} = await spawn(...nodePrintStdout).pipe(...nodeEval(`process.stdin.on("data", chunk => { console.log(chunk.toString().trim() + process.argv0); });`), {argv0}); t.is(stdout, `${testString}${argv0}`); }); test.serial('.pipe() which does not read stdin, source ends first', async t => { - const {stdout, output} = await nanoSpawn(...nodePrintStdout).pipe(...nodePrintSleep); + const {stdout, output} = await spawn(...nodePrintStdout).pipe(...nodePrintSleep); t.is(stdout, testString); t.is(output, stdout); }); test.serial('.pipe() which does not read stdin, source fails first', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodePrintFail).pipe(...nodePrintSleep)); + const error = await t.throwsAsync(spawn(...nodePrintFail).pipe(...nodePrintSleep)); assertFail(t, error); t.is(error.stdout, testString); t.is(error.output, error.stdout); }); test.serial('.pipe() which does not read stdin, source ends last', async t => { - const {stdout, output} = await nanoSpawn(...nodePrintSleep).pipe(...nodePrintStdout); + const {stdout, output} = await spawn(...nodePrintSleep).pipe(...nodePrintStdout); t.is(stdout, testString); t.is(output, stdout); }); test.serial('.pipe() which does not read stdin, source fails last', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodePrintStdout).pipe(...nodePrintSleepFail)); + const error = await t.throwsAsync(spawn(...nodePrintStdout).pipe(...nodePrintSleepFail)); assertFail(t, error); t.is(error.stdout, testString); t.is(error.output, error.stdout); }); test('.pipe() which has hanging stdin', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeHanging, {timeout: 1e3}).pipe(...nodePassThrough)); + const error = await t.throwsAsync(spawn(...nodeHanging, {timeout: 1e3}).pipe(...nodePassThrough)); assertSigterm(t, error); t.is(error.stdout, ''); t.is(error.output, ''); @@ -242,7 +242,7 @@ test('.pipe() which has hanging stdin', async t => { test('.pipe() with stdin stream in source', async t => { const stream = createReadStream(testFixtureUrl); await once(stream, 'open'); - const {stdout} = await nanoSpawn(...nodePassThrough, {stdin: stream}).pipe(...nodeToUpperCase); + const {stdout} = await spawn(...nodePassThrough, {stdin: stream}).pipe(...nodeToUpperCase); t.is(stdout, testUpperCase); }); @@ -250,15 +250,15 @@ test('.pipe() with stdin stream in destination', async t => { const stream = createReadStream(testFixtureUrl); await once(stream, 'open'); await t.throwsAsync( - nanoSpawn(...nodePassThrough).pipe(...nodeToUpperCase, {stdin: stream}), - {message: 'The "stdin" option must be set on the first "nanoSpawn()" call in the pipeline.'}); + spawn(...nodePassThrough).pipe(...nodeToUpperCase, {stdin: stream}), + {message: 'The "stdin" option must be set on the first "spawn()" call in the pipeline.'}); }); test('.pipe() with stdout stream in destination', async t => { await temporaryWriteTask('', async temporaryPath => { const stream = createWriteStream(temporaryPath); await once(stream, 'open'); - const {stdout} = await nanoSpawn(...nodePrintStdout).pipe(...nodePassThrough, {stdout: stream}); + const {stdout} = await spawn(...nodePrintStdout).pipe(...nodePassThrough, {stdout: stream}); t.is(stdout, ''); t.is(await readFile(temporaryPath, 'utf8'), `${testString}\n`); }); @@ -269,14 +269,14 @@ test('.pipe() with stdout stream in source', async t => { const stream = createWriteStream(temporaryPath); await once(stream, 'open'); await t.throwsAsync( - nanoSpawn(...nodePrintStdout, {stdout: stream}).pipe(...nodePassThrough), - {message: 'The "stdout" option must be set on the last "nanoSpawn()" call in the pipeline.'}, + spawn(...nodePrintStdout, {stdout: stream}).pipe(...nodePassThrough), + {message: 'The "stdout" option must be set on the last "spawn()" call in the pipeline.'}, ); }); }); test('.pipe() + stdout/stderr iteration', async t => { - const subprocess = nanoSpawn(...nodePrintStdout).pipe(...nodeToUpperCase); + const subprocess = spawn(...nodePrintStdout).pipe(...nodeToUpperCase); const lines = await arrayFromAsync(subprocess); t.deepEqual(lines, [testUpperCase]); const {stdout, stderr, output} = await subprocess; @@ -286,7 +286,7 @@ test('.pipe() + stdout/stderr iteration', async t => { }); test('.pipe() + stdout iteration', async t => { - const subprocess = nanoSpawn(...nodePrintStdout).pipe(...nodeToUpperCase); + const subprocess = spawn(...nodePrintStdout).pipe(...nodeToUpperCase); const lines = await arrayFromAsync(subprocess.stdout); t.deepEqual(lines, [testUpperCase]); const {stdout, output} = await subprocess; @@ -295,7 +295,7 @@ test('.pipe() + stdout iteration', async t => { }); test('.pipe() + stderr iteration', async t => { - const subprocess = nanoSpawn(...nodePrintStdout).pipe(...nodeToUpperCaseStderr); + const subprocess = spawn(...nodePrintStdout).pipe(...nodeToUpperCaseStderr); const lines = await arrayFromAsync(subprocess.stderr); t.deepEqual(lines, [testUpperCase]); const {stderr, output} = await subprocess; @@ -304,7 +304,7 @@ test('.pipe() + stderr iteration', async t => { }); test('.pipe() + stdout iteration, source fail', async t => { - const subprocess = nanoSpawn(...nodePrintFail).pipe(...nodeToUpperCase); + const subprocess = spawn(...nodePrintFail).pipe(...nodeToUpperCase); const error = await t.throwsAsync(arrayFromAsync(subprocess.stdout)); assertFail(t, error); t.is(error.stdout, testString); @@ -314,7 +314,7 @@ test('.pipe() + stdout iteration, source fail', async t => { }); test('.pipe() + stdout iteration, destination fail', async t => { - const subprocess = nanoSpawn(...nodePrintStdout).pipe(...nodeToUpperCaseFail); + const subprocess = spawn(...nodePrintStdout).pipe(...nodeToUpperCaseFail); const error = await t.throwsAsync(arrayFromAsync(subprocess.stdout)); assertFail(t, error); t.is(error.stdout, ''); @@ -324,7 +324,7 @@ test('.pipe() + stdout iteration, destination fail', async t => { }); test('.pipe() with EPIPE', async t => { - const subprocess = nanoSpawn(...nodeEval(`setInterval(() => { + const subprocess = spawn(...nodeEval(`setInterval(() => { console.log("${testString}"); }, 0); process.stdout.on("error", () => { @@ -338,7 +338,7 @@ process.stdout.on("error", () => { }); test('.pipe() one source to multiple destinations', async t => { - const first = nanoSpawn(...nodePrintStdout); + const first = spawn(...nodePrintStdout); const [firstResult, secondResult, thirdResult] = await Promise.all([ first, first.pipe(...nodeToUpperCase), diff --git a/test/result.js b/test/result.js index b16a38a..d7749b8 100644 --- a/test/result.js +++ b/test/result.js @@ -1,5 +1,5 @@ import test from 'ava'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import { isWindows, isLinux, @@ -28,28 +28,28 @@ import { } from './helpers/commands.js'; test('result.exitCode|signalName on success', async t => { - const {exitCode, signalName} = await nanoSpawn(...nodePrintStdout); + const {exitCode, signalName} = await spawn(...nodePrintStdout); t.is(exitCode, undefined); t.is(signalName, undefined); }); test('Error on non-0 exit code', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeEval('process.exit(2)'))); + const error = await t.throwsAsync(spawn(...nodeEval('process.exit(2)'))); assertFail(t, error); }); test('Error on signal termination', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeHanging, {timeout: 1})); + const error = await t.throwsAsync(spawn(...nodeHanging, {timeout: 1})); assertSigterm(t, error); }); test('Error on invalid child_process options', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodePrintStdout, earlyErrorOptions)); + const error = await t.throwsAsync(spawn(...nodePrintStdout, earlyErrorOptions)); assertEarlyError(t, error); }); test('Error on "error" event before spawn', async t => { - const error = await t.throwsAsync(nanoSpawn(nonExistentCommand)); + const error = await t.throwsAsync(spawn(nonExistentCommand)); if (isWindows) { assertWindowsNonExistent(t, error); @@ -59,12 +59,12 @@ test('Error on "error" event before spawn', async t => { }); test('Error on "error" event during spawn', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeHanging, {signal: AbortSignal.abort()})); + const error = await t.throwsAsync(spawn(...nodeHanging, {signal: AbortSignal.abort()})); assertSigterm(t, error); }); test('Error on "error" event during spawn, with iteration', async t => { - const subprocess = nanoSpawn(...nodeHanging, {signal: AbortSignal.abort()}); + const subprocess = spawn(...nodeHanging, {signal: AbortSignal.abort()}); const error = await t.throwsAsync(arrayFromAsync(subprocess.stdout)); assertSigterm(t, error); }); @@ -75,7 +75,7 @@ if (isLinux) { test('Error on "error" event after spawn', async t => { const cause = new Error(testString); const controller = new AbortController(); - const subprocess = nanoSpawn(...nodeHanging, {signal: controller.signal}); + const subprocess = spawn(...nodeHanging, {signal: controller.signal}); await subprocess.nodeChildProcess; controller.abort(cause); const error = await t.throwsAsync(subprocess); @@ -84,28 +84,28 @@ if (isLinux) { } test('result.stdout is set', async t => { - const {stdout, stderr, output} = await nanoSpawn(...nodePrintStdout); + const {stdout, stderr, output} = await spawn(...nodePrintStdout); t.is(stdout, testString); t.is(stderr, ''); t.is(output, stdout); }); test('result.stderr is set', async t => { - const {stdout, stderr, output} = await nanoSpawn(...nodePrintStderr); + const {stdout, stderr, output} = await spawn(...nodePrintStderr); t.is(stdout, ''); t.is(stderr, testString); t.is(output, stderr); }); test('result.output is set', async t => { - const {stdout, stderr, output} = await nanoSpawn(...nodePrintBoth); + const {stdout, stderr, output} = await spawn(...nodePrintBoth); t.is(stdout, testString); t.is(stderr, secondTestString); t.is(output, `${stdout}\n${stderr}`); }); test('error.stdout is set', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeEval(`console.log("${testString}"); + const error = await t.throwsAsync(spawn(...nodeEval(`console.log("${testString}"); process.exit(2);`))); assertFail(t, error); t.is(error.stdout, testString); @@ -114,7 +114,7 @@ process.exit(2);`))); }); test('error.stderr is set', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeEval(`console.error("${testString}"); + const error = await t.throwsAsync(spawn(...nodeEval(`console.error("${testString}"); process.exit(2);`))); assertFail(t, error); t.is(error.stdout, ''); @@ -123,7 +123,7 @@ process.exit(2);`))); }); test('error.output is set', async t => { - const error = await t.throwsAsync(nanoSpawn(...nodeEval(`console.log("${testString}"); + const error = await t.throwsAsync(spawn(...nodeEval(`console.log("${testString}"); setTimeout(() => { console.error("${secondTestString}"); process.exit(2); @@ -135,7 +135,7 @@ setTimeout(() => { }); const testStreamError = async (t, streamName) => { - const subprocess = nanoSpawn(...nodePrintStdout); + const subprocess = spawn(...nodePrintStdout); const cause = new Error(testString); destroySubprocessStream(subprocess, cause, streamName); const error = await t.throwsAsync(subprocess); @@ -147,7 +147,7 @@ test('Handles subprocess.stdout error', testStreamError, 'stdout'); test('Handles subprocess.stderr error', testStreamError, 'stderr'); const testNewline = async (t, input, expectedOutput) => { - const {stdout, output} = await nanoSpawn(...nodePrintNoNewline(input)); + const {stdout, output} = await spawn(...nodePrintNoNewline(input)); t.is(stdout, expectedOutput); t.is(output, stdout); }; diff --git a/test/spawn.js b/test/spawn.js index 0ce3dc0..210cc5f 100644 --- a/test/spawn.js +++ b/test/spawn.js @@ -1,7 +1,7 @@ import process from 'node:process'; import test from 'ava'; import getNode from 'get-node'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import {isWindows, FIXTURES_URL, writeMultibyte} from './helpers/main.js'; import { assertWindowsNonExistent, @@ -15,7 +15,7 @@ const nodeCliFlag = '--jitless'; const inspectCliFlag = '--inspect-port=8091'; const testNodeFlags = async (t, binaryName, fixtureName, hasFlag) => { - const {stdout} = await nanoSpawn(binaryName, [nodeCliFlag, fixtureName], {cwd: FIXTURES_URL}); + const {stdout} = await spawn(binaryName, [nodeCliFlag, fixtureName], {cwd: FIXTURES_URL}); t.is(stdout.includes(nodeCliFlag), hasFlag); }; @@ -28,7 +28,7 @@ if (isWindows) { } test('Does not keep --inspect* Node flags', async t => { - const {stdout} = await nanoSpawn('node', [nodeCliFlag, inspectCliFlag, 'node-flags.js'], {cwd: FIXTURES_URL}); + const {stdout} = await spawn('node', [nodeCliFlag, inspectCliFlag, 'node-flags.js'], {cwd: FIXTURES_URL}); t.true(stdout.includes(nodeCliFlag)); t.false(stdout.includes(inspectCliFlag)); }); @@ -38,12 +38,12 @@ const TEST_NODE_VERSION = '18.0.0'; test.serial('Keeps Node version', async t => { const {path: nodePath} = await getNode(TEST_NODE_VERSION); t.not(nodePath, process.execPath); - const {stdout} = await nanoSpawn(nodePath, ['node-version.js'], {cwd: FIXTURES_URL}); + const {stdout} = await spawn(nodePath, ['node-version.js'], {cwd: FIXTURES_URL}); t.is(stdout, `v${TEST_NODE_VERSION}`); }); test('Handles non-existing command', async t => { - const error = await t.throwsAsync(nanoSpawn(nonExistentCommand)); + const error = await t.throwsAsync(spawn(nonExistentCommand)); if (isWindows) { assertWindowsNonExistent(t, error); @@ -53,7 +53,7 @@ test('Handles non-existing command', async t => { }); test('Handles non-existing command, shell', async t => { - const error = await t.throwsAsync(nanoSpawn(nonExistentCommand, {shell: true})); + const error = await t.throwsAsync(spawn(nonExistentCommand, {shell: true})); if (isWindows) { assertWindowsNonExistent(t, error); @@ -63,28 +63,28 @@ test('Handles non-existing command, shell', async t => { }); test('result.stdout is an empty string if options.stdout "ignore"', async t => { - const {stdout, stderr, output} = await nanoSpawn(...nodePrintBoth, {stdout: 'ignore'}); + const {stdout, stderr, output} = await spawn(...nodePrintBoth, {stdout: 'ignore'}); t.is(stdout, ''); t.is(stderr, secondTestString); t.is(output, stderr); }); test('result.stderr is an empty string if options.stderr "ignore"', async t => { - const {stdout, stderr, output} = await nanoSpawn(...nodePrintBoth, {stderr: 'ignore'}); + const {stdout, stderr, output} = await spawn(...nodePrintBoth, {stderr: 'ignore'}); t.is(stdout, testString); t.is(stderr, ''); t.is(output, stdout); }); test('result.output is an empty string if options.stdout and options.stderr "ignore"', async t => { - const {stdout, stderr, output} = await nanoSpawn(...nodePrintBoth, {stdout: 'ignore', stderr: 'ignore'}); + const {stdout, stderr, output} = await spawn(...nodePrintBoth, {stdout: 'ignore', stderr: 'ignore'}); t.is(stdout, ''); t.is(stderr, ''); t.is(output, ''); }); test.serial('result.stdout works with multibyte sequences', async t => { - const subprocess = nanoSpawn(...nodePassThrough); + const subprocess = spawn(...nodePassThrough); writeMultibyte(subprocess); const {stdout, output} = await subprocess; t.is(stdout, multibyteString); diff --git a/test/windows.js b/test/windows.js index 40bbd22..3ed67cd 100644 --- a/test/windows.js +++ b/test/windows.js @@ -2,7 +2,7 @@ import process from 'node:process'; import {fileURLToPath} from 'node:url'; import test from 'ava'; import pathKey from 'path-key'; -import nanoSpawn from '../source/index.js'; +import spawn from '../source/index.js'; import { isWindows, FIXTURES_URL, @@ -19,7 +19,7 @@ if (isWindows) { }); const testExe = async (t, shell) => { - const {stdout} = await nanoSpawn(process.execPath, ['--version'], {shell}); + const {stdout} = await spawn(process.execPath, ['--version'], {shell}); t.is(stdout, process.version); }; @@ -28,17 +28,17 @@ if (isWindows) { test('Can run .exe file, shell', testExe, true); test('.exe does not use shell by default', async t => { - const {stdout} = await nanoSpawn(...nodePrintArgv0, {argv0: testString}); + const {stdout} = await spawn(...nodePrintArgv0, {argv0: testString}); t.is(stdout, testString); }); test('.exe can use shell', async t => { - const {stdout} = await nanoSpawn(...nodePrintArgv0, {argv0: testString, shell: true}); + const {stdout} = await spawn(...nodePrintArgv0, {argv0: testString, shell: true}); t.is(stdout, process.execPath); }); const testExeDetection = async (t, execPath) => { - const {stdout} = await nanoSpawn(execPath, ['-p', 'process.argv0'], {argv0: testString}); + const {stdout} = await spawn(execPath, ['-p', 'process.argv0'], {argv0: testString}); t.is(stdout, testString); }; @@ -48,7 +48,7 @@ if (isWindows) { test('.exe detection with Unix slashes', testExeDetection, process.execPath.replace('\\node.exe', '/node.exe')); const testPathValue = async (t, pathValue) => { - const {stdout} = await nanoSpawn(...nodePrintArgv0, {argv0: testString, env: {[pathKey()]: pathValue}}); + const {stdout} = await spawn(...nodePrintArgv0, {argv0: testString, env: {[pathKey()]: pathValue}}); t.is(stdout, testString); }; @@ -57,7 +57,7 @@ if (isWindows) { test('.exe detection with custom Path and double quoting', testPathValue, `"${nodeDirectory}"`); const testCom = async (t, shell) => { - const {stdout} = await nanoSpawn('tree.com', [fileURLToPath(FIXTURES_URL), '/f'], {shell}); + const {stdout} = await spawn('tree.com', [fileURLToPath(FIXTURES_URL), '/f'], {shell}); t.true(stdout.includes('spawnecho.cmd')); }; @@ -66,7 +66,7 @@ if (isWindows) { test('Can run .com file, shell', testCom, true); const testCmd = async (t, shell) => { - const {stdout} = await nanoSpawn('spawnecho.cmd', [testString], {cwd: FIXTURES_URL, shell}); + const {stdout} = await spawn('spawnecho.cmd', [testString], {cwd: FIXTURES_URL, shell}); t.is(stdout, testString); }; @@ -75,23 +75,23 @@ if (isWindows) { test('Can run .cmd file, shell', testCmd, true); test('Memoize .cmd file logic', async t => { - await nanoSpawn('spawnecho.cmd', [testString], {cwd: FIXTURES_URL}); - const {stdout} = await nanoSpawn('spawnecho.cmd', [testString], {cwd: FIXTURES_URL}); + await spawn('spawnecho.cmd', [testString], {cwd: FIXTURES_URL}); + const {stdout} = await spawn('spawnecho.cmd', [testString], {cwd: FIXTURES_URL}); t.is(stdout, testString); }); test('Uses PATHEXT by default', async t => { - const {stdout} = await nanoSpawn('spawnecho', [testString], {cwd: FIXTURES_URL}); + const {stdout} = await spawn('spawnecho', [testString], {cwd: FIXTURES_URL}); t.is(stdout, testString); }); test('Uses cwd as string', async t => { - const {stdout} = await nanoSpawn('spawnecho', [testString], {cwd: fixturesPath}); + const {stdout} = await spawn('spawnecho', [testString], {cwd: fixturesPath}); t.is(stdout, testString); }); const testPathExtension = async (t, shell) => { - const error = await t.throwsAsync(nanoSpawn('spawnecho', [testString], { + const error = await t.throwsAsync(spawn('spawnecho', [testString], { env: {PATHEXT: '.COM'}, cwd: FIXTURES_URL, shell, @@ -105,12 +105,12 @@ if (isWindows) { test('Escapes file when setting shell option', async t => { const file = '()[]%0!`'; - const {stdout} = await nanoSpawn(file, {cwd: FIXTURES_URL}); + const {stdout} = await spawn(file, {cwd: FIXTURES_URL}); t.is(stdout, `${file}\r\n${file}`); }); const testEscape = async (t, input) => { - const {stdout} = await nanoSpawn('spawnecho', [input], {cwd: FIXTURES_URL}); + const {stdout} = await spawn('spawnecho', [input], {cwd: FIXTURES_URL}); t.is(stdout, input); }; @@ -161,22 +161,22 @@ if (isWindows) { test('Escapes argument when setting shell option, "(foo|bar>baz|foz)"', testEscape, '"(foo|bar>baz|foz)"'); test('Cannot run shebangs', async t => { - const error = await t.throwsAsync(nanoSpawn('./shebang.js', {cwd: FIXTURES_URL})); + const error = await t.throwsAsync(spawn('./shebang.js', {cwd: FIXTURES_URL})); assertWindowsNonExistent(t, error, './shebang.js'); }); } else { test('Can run shebangs', async t => { - const {stdout} = await nanoSpawn('./shebang.js', {cwd: FIXTURES_URL}); + const {stdout} = await spawn('./shebang.js', {cwd: FIXTURES_URL}); t.is(stdout, testString); }); } test('Can run Bash', async t => { - const {stdout} = await nanoSpawn(`echo ${testString}`, {cwd: FIXTURES_URL, shell: 'bash'}); + const {stdout} = await spawn(`echo ${testString}`, {cwd: FIXTURES_URL, shell: 'bash'}); t.is(stdout, testString); }); test('Does not double escape shell strings', async t => { - const {stdout} = await nanoSpawn('node -p "0"', {shell: true}); + const {stdout} = await spawn('node -p "0"', {shell: true}); t.is(stdout, '0'); });