test('stdout/stderr/all on process errors', async t => { const {stdout, stderr, all} = await t.throwsAsync(execa('wrong command', {all: true})); t.is(stdout, ''); t.is(stderr, WRONG_COMMAND); t.is(all, WRONG_COMMAND); });
test.serial('should fail when git tag already exists', async t => { execaStub.createStub([ { command: 'git rev-parse --quiet --verify refs/tags/v2.0.0', stdout: 'vvb' } ]); await t.throwsAsync(run(testedModule('2.0.0', {name: 'test', version: '1.0.0'}, {yarn: false})), {message: 'Git tag `v2.0.0` already exists.'}); t.true(SilentRenderer.tasks.some(task => task.title === 'Check git tag existence' && task.hasFailed())); });
test('error.killed is false if process was killed indirectly', async t => { const subprocess = execa('noop'); process.kill(subprocess.pid, 'SIGINT'); // `process.kill()` is emulated by Node.js on Windows const message = process.platform === 'win32' ? /failed with exit code 1/ : /was killed with SIGINT/; const {killed} = await t.throwsAsync(subprocess, {message}); t.false(killed); });
test.serial('should fail when version is lower as latest version', async t => { await t.throwsAsync(run(testedModule('0.1.0', {name: 'test', version: '1.0.0'}, {yarn: false})), {message: 'New version `0.1.0` should be higher than current version `1.0.0`'}); t.true(SilentRenderer.tasks.some(task => task.title === 'Validate version' && task.hasFailed())); });
test('child process errors are handled', async t => { const subprocess = execa('noop'); subprocess.emit('error', new Error('test')); await t.throwsAsync(subprocess, /test/); });
test('version is invalid', async t => { const message = 'Version should be either patch, minor, major, prepatch, preminor, premajor, prerelease, or a valid semver version.'; await t.throwsAsync(np('foo', defaultOptions), message); await t.throwsAsync(np('4.x.3', defaultOptions), message); });
test('throw in finally bubbles up on error', async t => { const {message} = await t.throwsAsync(execa('exit', ['2']).finally(() => { throw new Error('called'); })); t.is(message, 'called'); });
test('error.isCanceled is true when cancel method is used', async t => { const subprocess = execa('noop'); subprocess.cancel(); const {isCanceled} = await t.throwsAsync(subprocess); t.true(isCanceled); });
test('kill("SIGKILL") should terminate cleanly', async t => { const subprocess = execa('node', ['./test/fixtures/no-killable'], {stdio: ['ipc']}); await pEvent(subprocess, 'message'); subprocess.kill('SIGKILL'); const {signal} = await t.throwsAsync(subprocess); t.is(signal, 'SIGKILL'); });
test('buffer: false > promise rejects when process returns non-zero', async t => { const subprocess = execa('fail', {buffer: false}); const {exitCode} = await t.throwsAsync(subprocess); t.is(exitCode, 2); });
test('stdout/stderr/all available on errors', async t => { const {stdout, stderr, all} = await t.throwsAsync(execa('exit', ['2'], {all: true}), {message: getExitRegExp('2')}); t.is(typeof stdout, 'string'); t.is(typeof stderr, 'string'); t.is(typeof all, 'string'); });
test('execa() rejects with correct error and doesn\'t throw if running non-executable with input', async t => { // On Node <12.6.0, `EACCESS` is emitted on `childProcess`. // On Node >=12.6.0, `EPIPE` is emitted on `childProcess.stdin`. await t.throwsAsync(execa('non-executable', {input: 'Hey!'}), /EACCES|EPIPE/); });
test('exitCode is undefined on signal termination', async t => { const subprocess = execa('noop'); process.kill(subprocess.pid); const {exitCode} = await t.throwsAsync(subprocess); t.is(exitCode, undefined); });
test('`forceKillAfterTimeout: number` should kill after a timeout', async t => { const subprocess = execa('node', ['./test/fixtures/no-killable'], {stdio: ['ipc']}); await pEvent(subprocess, 'message'); subprocess.kill('SIGTERM', {forceKillAfterTimeout: 50}); const {signal} = await t.throwsAsync(subprocess); t.is(signal, 'SIGKILL'); });
test('`forceKillAfterTimeout: true` should kill after a timeout', async t => { const subprocess = execa('node', ['./test/fixtures/no-killable'], {stdio: ['ipc']}); await pEvent(subprocess, 'message'); subprocess.kill('SIGTERM', {forceKillAfterTimeout: true}); const {signal} = await t.throwsAsync(subprocess); t.is(signal, 'SIGKILL'); });