From 1201298bc286da0b6808358f51b213377d7af0b4 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 13:23:25 +0100 Subject: [PATCH 01/13] Improve `result.error` --- index.js | 76 +++++++++++++++++++++++++++++++++++++------------------- test.js | 8 +++--- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/index.js b/index.js index b4b5e340e1..ddca7da9a8 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ 'use strict'; const path = require('path'); +const os = require('os'); const childProcess = require('child_process'); const crossSpawn = require('cross-spawn'); const stripFinalNewline = require('strip-final-newline'); @@ -120,43 +121,68 @@ function getStream(process, stream, {encoding, buffer, maxBuffer}) { } function makeError(result, options) { - const {stdout, stderr} = result; + const {stdout, stderr, code, signal} = result; + let {error} = result + const {joinedCommand, timedOut, parsed:{options:{timeout}}} = options; - let {error} = result; - const {code, signal} = result; + const [codeString, codeNumber] = getCode(result, code) - const {parsed, joinedCommand} = options; - const timedOut = options.timedOut || false; - - if (!error) { - let output = ''; - - if (Array.isArray(parsed.options.stdio)) { - if (parsed.options.stdio[2] !== 'inherit') { - output += output.length > 0 ? stderr : `\n${stderr}`; - } - - if (parsed.options.stdio[1] !== 'inherit') { - output += `\n${stdout}`; - } - } else if (parsed.options.stdio !== 'inherit') { - output = `\n${stderr}${stdout}`; - } - - error = new Error(`Command failed: ${joinedCommand}${output}`); - error.code = code < 0 ? errname(code) : code; + if (!(error instanceof Error)) { + const message = [joinedCommand, stderr, stdout].filter(Boolean).join('\n') + error = new Error(message); } + const prefix = getErrorPrefix({ timedOut, timeout, signal, codeString, codeNumber }) + error.message = `Command ${prefix}: ${error.message}` + console.log(error.message) + + error.code = codeNumber || codeString error.stdout = stdout; error.stderr = stderr; error.failed = true; - error.signal = signal || null; + error.signal = signal; error.cmd = joinedCommand; - error.timedOut = timedOut; + error.timedOut = Boolean(timedOut); return error; } +function getCode({ error = {} }, code) { + if (error.code) { + return [error.code, os.constants.errno[error.code]] + } + + if (Number.isInteger(code)) { + return [errname(-Math.abs(code)), Math.abs(code)] + } + + return [] +} + +function getErrorPrefix({ timedOut, timeout, signal, codeString, codeNumber }) { + if (timedOut) { + return `timed out after ${timeout} milliseconds` + } + + if (signal) { + return `was killed by ${signal}` + } + + if (codeString !== undefined && codeNumber !== undefined) { + return `failed with exit code ${codeNumber} (${codeString})` + } + + if (codeString !== undefined) { + return `failed with exit code ${codeString}` + } + + if (codeNumber !== undefined) { + return `failed with exit code ${codeNumber}` + } + + return `failed` +} + function joinCommand(command, args) { let joinedCommand = command; diff --git a/test.js b/test.js index 91fd135a7a..34501e9165 100644 --- a/test.js +++ b/test.js @@ -99,7 +99,7 @@ test('execa.sync()', t => { }); test('execa.sync() throws error if written to stderr', t => { - t.throws(() => m.sync('foo'), process.platform === 'win32' ? /'foo' is not recognized as an internal or external command/ : 'spawnSync foo ENOENT'); + t.throws(() => m.sync('foo'), process.platform === 'win32' ? /'foo' is not recognized as an internal or external command/ : /spawnSync foo ENOENT/); }); test('execa.sync() includes stdout and stderr in errors for improved debugging', t => { @@ -388,8 +388,8 @@ async function errorMessage(t, expected, ...args) { errorMessage.title = (message, expected) => `error.message matches: ${expected}`; -test(errorMessage, /Command failed: exit 2 foo bar/, 2, 'foo', 'bar'); -test(errorMessage, /Command failed: exit 3 baz quz/, 3, 'baz', 'quz'); +test(errorMessage, /Command failed with exit code 2 \(ENOENT\): exit 2 foo bar/, 2, 'foo', 'bar'); +test(errorMessage, /Command failed with exit code 3 \(ESRCH\): exit 3 baz quz/, 3, 'baz', 'quz'); async function cmd(t, expected, ...args) { const error = await t.throwsAsync(m('fail', args)); @@ -455,7 +455,7 @@ if (process.platform !== 'win32') { await m(`fast-exit-${process.platform}`, [], {input: 'data'}); t.pass(); } catch (error) { - t.is(error.code, 'EPIPE'); + t.is(error.code, 32); } }); } From 4e8c0070def319eea61b4c13a6261c30ff466273 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 13:59:05 +0100 Subject: [PATCH 02/13] Improve error message --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index ddca7da9a8..f5f28184a5 100644 --- a/index.js +++ b/index.js @@ -165,7 +165,7 @@ function getErrorPrefix({ timedOut, timeout, signal, codeString, codeNumber }) { } if (signal) { - return `was killed by ${signal}` + return `was killed with ${signal}` } if (codeString !== undefined && codeNumber !== undefined) { From ffe0abcd1131104f032fb68654411b11422de707 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 13:59:21 +0100 Subject: [PATCH 03/13] Add tests --- test.js | 31 ++++++++++++++++++------------- test/errname.js | 4 ++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/test.js b/test.js index 34501e9165..9d58a6203b 100644 --- a/test.js +++ b/test.js @@ -14,6 +14,11 @@ process.env.FOO = 'foo'; const NO_NEWLINES_REGEXP = /^[^\n]*$/; const STDERR_STDOUT_REGEXP = /stderr[^]*stdout/; +const TIMEOUT_REGEXP = /timed out after/ + +function getExitRegExp(exitMessage) { + return new RegExp(`failed with exit code ${exitMessage}`) +} test('execa()', async t => { const {stdout} = await m('noop', ['foo']); @@ -45,7 +50,7 @@ test('execa.stderr()', async t => { }); test('stdout/stderr available on errors', async t => { - const err = await t.throwsAsync(m('exit', ['2'])); + const err = await t.throwsAsync(m('exit', ['2']), { message: getExitRegExp('2 \\(ENOENT\\)') }); t.is(typeof err.stdout, 'string'); t.is(typeof err.stderr, 'string'); }); @@ -258,7 +263,7 @@ test('skip throwing when using reject option', async t => { test('execa() returns code and failed properties', async t => { const {code, failed} = await m('noop', ['foo']); - const error = await t.throwsAsync(m('exit', ['2']), {code: 2}); + const error = await t.throwsAsync(m('exit', ['2']), {code: 2, message: getExitRegExp('2 \\(ENOENT\\)')}); t.is(code, 0); t.false(failed); t.true(error.failed); @@ -273,7 +278,7 @@ test('use relative path with \'..\' chars', async t => { if (process.platform !== 'win32') { test('execa() rejects if running non-executable', async t => { const cp = m('non-executable'); - await t.throwsAsync(cp); + await t.throwsAsync(cp, { message: getExitRegExp('13 \\(EACCES\\)') }); }); } @@ -284,7 +289,7 @@ test('error.killed is true if process was killed directly', async t => { cp.kill(); }, 100); - const error = await t.throwsAsync(cp); + const error = await t.throwsAsync(cp, { message: /was killed with SIGTERM/ }); t.true(error.killed); }); @@ -296,7 +301,7 @@ test('error.killed is false if process was killed indirectly', async t => { process.kill(cp.pid, 'SIGINT'); }, 100); - const error = await t.throwsAsync(cp); + const error = await t.throwsAsync(cp, { message: /was killed with SIGINT/ }); t.false(error.killed); }); @@ -322,7 +327,7 @@ if (process.platform !== 'win32') { process.kill(cp.pid, 'SIGINT'); }, 100); - const error = await t.throwsAsync(cp); + const error = await t.throwsAsync(cp, { message: /was killed with SIGINT/ }); t.is(error.signal, 'SIGINT'); }); @@ -333,12 +338,12 @@ if (process.platform !== 'win32') { process.kill(cp.pid, 'SIGTERM'); }, 100); - const error = await t.throwsAsync(cp); + const error = await t.throwsAsync(cp, { message: /was killed with SIGTERM/ }); t.is(error.signal, 'SIGTERM'); }); test('custom error.signal', async t => { - const error = await t.throwsAsync(m('delay', ['3000', '0'], {killSignal: 'SIGHUP', timeout: 1500})); + const error = await t.throwsAsync(m('delay', ['3000', '0'], {killSignal: 'SIGHUP', timeout: 1500, message: TIMEOUT_REGEXP })); t.is(error.signal, 'SIGHUP'); }); } @@ -348,12 +353,12 @@ test('result.signal is null for successful execution', async t => { }); test('result.signal is null if process failed, but was not killed', async t => { - const error = await t.throwsAsync(m('exit', [2])); + const error = await t.throwsAsync(m('exit', [2]), { message: getExitRegExp('2 \\(ENOENT\\)') }); t.is(error.signal, null); }); async function code(t, num) { - await t.throwsAsync(m('exit', [`${num}`]), {code: num}); + await t.throwsAsync(m('exit', [`${num}`]), {code: num, message: getExitRegExp(num)}); } test('error.code is 2', code, 2); @@ -361,14 +366,14 @@ test('error.code is 3', code, 3); test('error.code is 4', code, 4); test('timeout will kill the process early', async t => { - const error = await t.throwsAsync(m('delay', ['60000', '0'], {timeout: 1500})); + const error = await t.throwsAsync(m('delay', ['60000', '0'], {timeout: 1500, message: TIMEOUT_REGEXP })); t.true(error.timedOut); t.not(error.code, 22); }); test('timeout will not kill the process early', async t => { - const error = await t.throwsAsync(m('delay', ['3000', '22'], {timeout: 30000}), {code: 22}); + const error = await t.throwsAsync(m('delay', ['3000', '22'], {timeout: 30000}), {code: 22, message: getExitRegExp('22 \\(EINVAL\\)')}); t.false(error.timedOut); }); @@ -378,7 +383,7 @@ test('timedOut will be false if no timeout was set and zero exit code', async t }); test('timedOut will be false if no timeout was set and non-zero exit code', async t => { - const error = await t.throwsAsync(m('delay', ['1000', '3'])); + const error = await t.throwsAsync(m('delay', ['1000', '3']), { message: getExitRegExp('3 \\(ESRCH\\)') }); t.false(error.timedOut); }); diff --git a/test/errname.js b/test/errname.js index 97dafb3d8e..a9251b3b13 100644 --- a/test/errname.js +++ b/test/errname.js @@ -24,3 +24,7 @@ const unknown = 'Unknown system error -2'; makeTests('native', errname, isWin ? unknown : 'ENOENT'); makeTests('fallback', fallback, unknown); + +test('allow unknown exit code', async t => { + await t.throwsAsync(m('exit', ['255']), { message: /exit code 255 \(Unknown system error -255\)/ }); +}); From aaa64967f717fb357cc187e14cd5324c1ef12517 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 13:59:47 +0100 Subject: [PATCH 04/13] Fix linting --- index.js | 38 +++++++++++++++++++------------------- test.js | 24 ++++++++++++------------ test/errname.js | 2 +- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/index.js b/index.js index f5f28184a5..9a9553bdc1 100644 --- a/index.js +++ b/index.js @@ -122,21 +122,21 @@ function getStream(process, stream, {encoding, buffer, maxBuffer}) { function makeError(result, options) { const {stdout, stderr, code, signal} = result; - let {error} = result - const {joinedCommand, timedOut, parsed:{options:{timeout}}} = options; + let {error} = result; + const {joinedCommand, timedOut, parsed: {options: {timeout}}} = options; - const [codeString, codeNumber] = getCode(result, code) + const [codeString, codeNumber] = getCode(result, code); if (!(error instanceof Error)) { - const message = [joinedCommand, stderr, stdout].filter(Boolean).join('\n') + const message = [joinedCommand, stderr, stdout].filter(Boolean).join('\n'); error = new Error(message); } - const prefix = getErrorPrefix({ timedOut, timeout, signal, codeString, codeNumber }) - error.message = `Command ${prefix}: ${error.message}` - console.log(error.message) + const prefix = getErrorPrefix({timedOut, timeout, signal, codeString, codeNumber}); + error.message = `Command ${prefix}: ${error.message}`; + console.log(error.message); - error.code = codeNumber || codeString + error.code = codeNumber || codeString; error.stdout = stdout; error.stderr = stderr; error.failed = true; @@ -147,40 +147,40 @@ function makeError(result, options) { return error; } -function getCode({ error = {} }, code) { +function getCode({error = {}}, code) { if (error.code) { - return [error.code, os.constants.errno[error.code]] + return [error.code, os.constants.errno[error.code]]; } if (Number.isInteger(code)) { - return [errname(-Math.abs(code)), Math.abs(code)] + return [errname(-Math.abs(code)), Math.abs(code)]; } - return [] + return []; } -function getErrorPrefix({ timedOut, timeout, signal, codeString, codeNumber }) { +function getErrorPrefix({timedOut, timeout, signal, codeString, codeNumber}) { if (timedOut) { - return `timed out after ${timeout} milliseconds` + return `timed out after ${timeout} milliseconds`; } if (signal) { - return `was killed with ${signal}` + return `was killed with ${signal}`; } if (codeString !== undefined && codeNumber !== undefined) { - return `failed with exit code ${codeNumber} (${codeString})` + return `failed with exit code ${codeNumber} (${codeString})`; } if (codeString !== undefined) { - return `failed with exit code ${codeString}` + return `failed with exit code ${codeString}`; } if (codeNumber !== undefined) { - return `failed with exit code ${codeNumber}` + return `failed with exit code ${codeNumber}`; } - return `failed` + return 'failed'; } function joinCommand(command, args) { diff --git a/test.js b/test.js index 9d58a6203b..c1114e2524 100644 --- a/test.js +++ b/test.js @@ -14,10 +14,10 @@ process.env.FOO = 'foo'; const NO_NEWLINES_REGEXP = /^[^\n]*$/; const STDERR_STDOUT_REGEXP = /stderr[^]*stdout/; -const TIMEOUT_REGEXP = /timed out after/ +const TIMEOUT_REGEXP = /timed out after/; function getExitRegExp(exitMessage) { - return new RegExp(`failed with exit code ${exitMessage}`) + return new RegExp(`failed with exit code ${exitMessage}`); } test('execa()', async t => { @@ -50,7 +50,7 @@ test('execa.stderr()', async t => { }); test('stdout/stderr available on errors', async t => { - const err = await t.throwsAsync(m('exit', ['2']), { message: getExitRegExp('2 \\(ENOENT\\)') }); + const err = await t.throwsAsync(m('exit', ['2']), {message: getExitRegExp('2 \\(ENOENT\\)')}); t.is(typeof err.stdout, 'string'); t.is(typeof err.stderr, 'string'); }); @@ -278,7 +278,7 @@ test('use relative path with \'..\' chars', async t => { if (process.platform !== 'win32') { test('execa() rejects if running non-executable', async t => { const cp = m('non-executable'); - await t.throwsAsync(cp, { message: getExitRegExp('13 \\(EACCES\\)') }); + await t.throwsAsync(cp, {message: getExitRegExp('13 \\(EACCES\\)')}); }); } @@ -289,7 +289,7 @@ test('error.killed is true if process was killed directly', async t => { cp.kill(); }, 100); - const error = await t.throwsAsync(cp, { message: /was killed with SIGTERM/ }); + const error = await t.throwsAsync(cp, {message: /was killed with SIGTERM/}); t.true(error.killed); }); @@ -301,7 +301,7 @@ test('error.killed is false if process was killed indirectly', async t => { process.kill(cp.pid, 'SIGINT'); }, 100); - const error = await t.throwsAsync(cp, { message: /was killed with SIGINT/ }); + const error = await t.throwsAsync(cp, {message: /was killed with SIGINT/}); t.false(error.killed); }); @@ -327,7 +327,7 @@ if (process.platform !== 'win32') { process.kill(cp.pid, 'SIGINT'); }, 100); - const error = await t.throwsAsync(cp, { message: /was killed with SIGINT/ }); + const error = await t.throwsAsync(cp, {message: /was killed with SIGINT/}); t.is(error.signal, 'SIGINT'); }); @@ -338,12 +338,12 @@ if (process.platform !== 'win32') { process.kill(cp.pid, 'SIGTERM'); }, 100); - const error = await t.throwsAsync(cp, { message: /was killed with SIGTERM/ }); + const error = await t.throwsAsync(cp, {message: /was killed with SIGTERM/}); t.is(error.signal, 'SIGTERM'); }); test('custom error.signal', async t => { - const error = await t.throwsAsync(m('delay', ['3000', '0'], {killSignal: 'SIGHUP', timeout: 1500, message: TIMEOUT_REGEXP })); + const error = await t.throwsAsync(m('delay', ['3000', '0'], {killSignal: 'SIGHUP', timeout: 1500, message: TIMEOUT_REGEXP})); t.is(error.signal, 'SIGHUP'); }); } @@ -353,7 +353,7 @@ test('result.signal is null for successful execution', async t => { }); test('result.signal is null if process failed, but was not killed', async t => { - const error = await t.throwsAsync(m('exit', [2]), { message: getExitRegExp('2 \\(ENOENT\\)') }); + const error = await t.throwsAsync(m('exit', [2]), {message: getExitRegExp('2 \\(ENOENT\\)')}); t.is(error.signal, null); }); @@ -366,7 +366,7 @@ test('error.code is 3', code, 3); test('error.code is 4', code, 4); test('timeout will kill the process early', async t => { - const error = await t.throwsAsync(m('delay', ['60000', '0'], {timeout: 1500, message: TIMEOUT_REGEXP })); + const error = await t.throwsAsync(m('delay', ['60000', '0'], {timeout: 1500, message: TIMEOUT_REGEXP})); t.true(error.timedOut); t.not(error.code, 22); @@ -383,7 +383,7 @@ test('timedOut will be false if no timeout was set and zero exit code', async t }); test('timedOut will be false if no timeout was set and non-zero exit code', async t => { - const error = await t.throwsAsync(m('delay', ['1000', '3']), { message: getExitRegExp('3 \\(ESRCH\\)') }); + const error = await t.throwsAsync(m('delay', ['1000', '3']), {message: getExitRegExp('3 \\(ESRCH\\)')}); t.false(error.timedOut); }); diff --git a/test/errname.js b/test/errname.js index a9251b3b13..02e658a04a 100644 --- a/test/errname.js +++ b/test/errname.js @@ -26,5 +26,5 @@ makeTests('native', errname, isWin ? unknown : 'ENOENT'); makeTests('fallback', fallback, unknown); test('allow unknown exit code', async t => { - await t.throwsAsync(m('exit', ['255']), { message: /exit code 255 \(Unknown system error -255\)/ }); + await t.throwsAsync(m('exit', ['255']), {message: /exit code 255 \(Unknown system error -255\)/}); }); From bd0f7e9730087af322ba8593767a0cba56895c51 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:00:45 +0100 Subject: [PATCH 05/13] Fix tests --- test.js | 4 ++++ test/errname.js | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test.js b/test.js index c1114e2524..6504031cca 100644 --- a/test.js +++ b/test.js @@ -261,6 +261,10 @@ test('skip throwing when using reject option', async t => { t.is(typeof error.stderr, 'string'); }); +test('allow unknown exit code', async t => { + await t.throwsAsync(m('exit', ['255']), {message: /exit code 255 \(Unknown system error -255\)/}); +}); + test('execa() returns code and failed properties', async t => { const {code, failed} = await m('noop', ['foo']); const error = await t.throwsAsync(m('exit', ['2']), {code: 2, message: getExitRegExp('2 \\(ENOENT\\)')}); diff --git a/test/errname.js b/test/errname.js index 02e658a04a..97dafb3d8e 100644 --- a/test/errname.js +++ b/test/errname.js @@ -24,7 +24,3 @@ const unknown = 'Unknown system error -2'; makeTests('native', errname, isWin ? unknown : 'ENOENT'); makeTests('fallback', fallback, unknown); - -test('allow unknown exit code', async t => { - await t.throwsAsync(m('exit', ['255']), {message: /exit code 255 \(Unknown system error -255\)/}); -}); From 4a4e5a9e99a14b1c0cbc4ea7fdf378b81826cf51 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:06:59 +0100 Subject: [PATCH 06/13] Remove console.log() --- index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/index.js b/index.js index 9a9553bdc1..08cd79e922 100644 --- a/index.js +++ b/index.js @@ -134,7 +134,6 @@ function makeError(result, options) { const prefix = getErrorPrefix({timedOut, timeout, signal, codeString, codeNumber}); error.message = `Command ${prefix}: ${error.message}`; - console.log(error.message); error.code = codeNumber || codeString; error.stdout = stdout; From 0de950b55851410ae02ce550536df9f47513258f Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:07:24 +0100 Subject: [PATCH 07/13] Add signal null fallback --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 08cd79e922..db5dbd052c 100644 --- a/index.js +++ b/index.js @@ -139,7 +139,7 @@ function makeError(result, options) { error.stdout = stdout; error.stderr = stderr; error.failed = true; - error.signal = signal; + error.signal = signal || null; error.cmd = joinedCommand; error.timedOut = Boolean(timedOut); From dfa7a610db8bf9b81b3eb93b63d1c2b1c9a31cff Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:12:48 +0100 Subject: [PATCH 08/13] Fix test --- test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.js b/test.js index 6504031cca..64ca6c3e9d 100644 --- a/test.js +++ b/test.js @@ -282,7 +282,7 @@ test('use relative path with \'..\' chars', async t => { if (process.platform !== 'win32') { test('execa() rejects if running non-executable', async t => { const cp = m('non-executable'); - await t.throwsAsync(cp, {message: getExitRegExp('13 \\(EACCES\\)')}); + await t.throwsAsync(cp) }); } From 3311ba440c67705ff3eb8477176f56c7583a3d8b Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:14:57 +0100 Subject: [PATCH 09/13] Fix Windows tests --- test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test.js b/test.js index 64ca6c3e9d..5b68f8af51 100644 --- a/test.js +++ b/test.js @@ -50,7 +50,7 @@ test('execa.stderr()', async t => { }); test('stdout/stderr available on errors', async t => { - const err = await t.throwsAsync(m('exit', ['2']), {message: getExitRegExp('2 \\(ENOENT\\)')}); + const err = await t.throwsAsync(m('exit', ['2']), {message: getExitRegExp('2')}); t.is(typeof err.stdout, 'string'); t.is(typeof err.stderr, 'string'); }); @@ -267,7 +267,7 @@ test('allow unknown exit code', async t => { test('execa() returns code and failed properties', async t => { const {code, failed} = await m('noop', ['foo']); - const error = await t.throwsAsync(m('exit', ['2']), {code: 2, message: getExitRegExp('2 \\(ENOENT\\)')}); + const error = await t.throwsAsync(m('exit', ['2']), {code: 2, message: getExitRegExp('2')}); t.is(code, 0); t.false(failed); t.true(error.failed); @@ -357,7 +357,7 @@ test('result.signal is null for successful execution', async t => { }); test('result.signal is null if process failed, but was not killed', async t => { - const error = await t.throwsAsync(m('exit', [2]), {message: getExitRegExp('2 \\(ENOENT\\)')}); + const error = await t.throwsAsync(m('exit', [2]), {message: getExitRegExp('2')}); t.is(error.signal, null); }); @@ -377,7 +377,7 @@ test('timeout will kill the process early', async t => { }); test('timeout will not kill the process early', async t => { - const error = await t.throwsAsync(m('delay', ['3000', '22'], {timeout: 30000}), {code: 22, message: getExitRegExp('22 \\(EINVAL\\)')}); + const error = await t.throwsAsync(m('delay', ['3000', '22'], {timeout: 30000}), {code: 22, message: getExitRegExp('22')}); t.false(error.timedOut); }); @@ -387,7 +387,7 @@ test('timedOut will be false if no timeout was set and zero exit code', async t }); test('timedOut will be false if no timeout was set and non-zero exit code', async t => { - const error = await t.throwsAsync(m('delay', ['1000', '3']), {message: getExitRegExp('3 \\(ESRCH\\)')}); + const error = await t.throwsAsync(m('delay', ['1000', '3']), {message: getExitRegExp('3')}); t.false(error.timedOut); }); From f8af59d78f498111dbde6cac3eb9161b01a3d652 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:15:45 +0100 Subject: [PATCH 10/13] Fix linting --- test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.js b/test.js index 5b68f8af51..8f432cccb7 100644 --- a/test.js +++ b/test.js @@ -282,7 +282,7 @@ test('use relative path with \'..\' chars', async t => { if (process.platform !== 'win32') { test('execa() rejects if running non-executable', async t => { const cp = m('non-executable'); - await t.throwsAsync(cp) + await t.throwsAsync(cp); }); } From bbb2b693e79adf73179cfb5c2d6d6f9e29835e2e Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:24:07 +0100 Subject: [PATCH 11/13] Fix Windows tests --- test.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test.js b/test.js index 8f432cccb7..8c19c44b8d 100644 --- a/test.js +++ b/test.js @@ -305,7 +305,10 @@ test('error.killed is false if process was killed indirectly', async t => { process.kill(cp.pid, 'SIGINT'); }, 100); - const error = await t.throwsAsync(cp, {message: /was killed with SIGINT/}); + // `process.kill()` is emulated by Node.js on Windows + const message = process.platform === 'windows' ? /failed with exit code 1/ : /was killed with SIGINT/; + + const error = await t.throwsAsync(cp, {message}); t.false(error.killed); }); @@ -397,8 +400,8 @@ async function errorMessage(t, expected, ...args) { errorMessage.title = (message, expected) => `error.message matches: ${expected}`; -test(errorMessage, /Command failed with exit code 2 \(ENOENT\): exit 2 foo bar/, 2, 'foo', 'bar'); -test(errorMessage, /Command failed with exit code 3 \(ESRCH\): exit 3 baz quz/, 3, 'baz', 'quz'); +test(errorMessage, /Command failed with exit code 2.*: exit 2 foo bar/, 2, 'foo', 'bar'); +test(errorMessage, /Command failed with exit code 3.*: exit 3 baz quz/, 3, 'baz', 'quz'); async function cmd(t, expected, ...args) { const error = await t.throwsAsync(m('fail', args)); From d3fb9cb4414ca38fdabd91da24d9873bb2cd6208 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:38:24 +0100 Subject: [PATCH 12/13] Fix typo --- test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.js b/test.js index 8c19c44b8d..595b4c4528 100644 --- a/test.js +++ b/test.js @@ -306,7 +306,7 @@ test('error.killed is false if process was killed indirectly', async t => { }, 100); // `process.kill()` is emulated by Node.js on Windows - const message = process.platform === 'windows' ? /failed with exit code 1/ : /was killed with SIGINT/; + const message = process.platform === 'win32' ? /failed with exit code 1/ : /was killed with SIGINT/; const error = await t.throwsAsync(cp, {message}); t.false(error.killed); From 844d1136e7ad8f2663f3204f73e7cbfadca24d73 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 28 Feb 2019 14:48:40 +0100 Subject: [PATCH 13/13] Remove empty line --- test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test.js b/test.js index 595b4c4528..b9c5f0809a 100644 --- a/test.js +++ b/test.js @@ -307,7 +307,6 @@ test('error.killed is false if process was killed indirectly', async t => { // `process.kill()` is emulated by Node.js on Windows const message = process.platform === 'win32' ? /failed with exit code 1/ : /was killed with SIGINT/; - const error = await t.throwsAsync(cp, {message}); t.false(error.killed); });