Skip to content

Commit

Permalink
test: add unhandled error case
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Jun 18, 2024
1 parent 7659647 commit 9c63073
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 80
max_line_length = 100
indent_brace_style = 1TBS
spaces_around_operators = true
quote_type = auto
Expand Down
49 changes: 24 additions & 25 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,30 @@
const { spawn } = require('child_process')
const { EOL } = require('os')

const EE_PROPS = Object.getOwnPropertyNames(
require('events').EventEmitter.prototype
)
const EE_PROPS = Object.getOwnPropertyNames(require('events').EventEmitter.prototype)
.filter(name => !name.startsWith('_'))
.concat(['kill', 'ref', 'unref'])

const eos = (stream, listener, buffer = []) =>
stream[listener]
? stream[listener].on('data', data => buffer.push(data)) && buffer
: buffer
stream[listener] ? stream[listener].on('data', data => buffer.push(data)) && buffer : buffer

const createChildProcessError = ({ cmd, cmdArgs, exitCode, stderr, childProcess }) => {
const command = `${cmd} ${cmdArgs.join(' ')}`
let message = `The command spawned as:${EOL}${EOL}`
message += ` ${command}${EOL}${EOL}`
message += `exited with \`{ code: ${exitCode} }\` and the following trace:${EOL}${EOL}`
message += String(stderr)
.split(EOL)
.map(line => ` ${line}`)
.join(EOL)
const error = new Error(message)
error.command = command
error.name = 'ChildProcessError'
Object.keys(childProcess).forEach(key => {
error[key] = childProcess[key]
})
return error
}

const clean = str => str.trim().replace(/\n$/, '')

Expand Down Expand Up @@ -42,30 +56,15 @@ const extend = defaults => (input, args, options) => {
get: parse(stdout, opts)
})
Object.defineProperty(childProcess, 'stderr', { get: parse(stderr) })
if (exitCode === 0) return resolve(childProcess)
const command = `${cmd} ${cmdArgs.join(' ')}`
let message = `The command spawned as:${EOL}${EOL}`
message += ` ${command}${EOL}${EOL}`
message += `exited with \`{ code: ${exitCode} }\` and the following trace:${EOL}${EOL}`
message += String(stderr)
.split(EOL)
.map(line => ` ${line}`)
.join(EOL)
const error = new Error(message)
error.command = command
error.name = 'ChildProcessError'
Object.keys(childProcess).forEach(key => {
error[key] = childProcess[key]
})
reject(error)
return exitCode === 0
? resolve(childProcess)
: reject(createChildProcessError({ cmd, cmdArgs, exitCode, stderr, childProcess }))
})
})

const subprocess = Object.assign(promise, childProcess)
if (childProcess) {
EE_PROPS.forEach(
name => (subprocess[name] = childProcess[name].bind(childProcess))
)
EE_PROPS.forEach(name => (subprocess[name] = childProcess[name].bind(childProcess)))
}
return subprocess
}
Expand Down
30 changes: 21 additions & 9 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

const { setTimeout } = require('timers/promises')
const { execSync } = require('child_process')
const { Writable } = require('stream')
const { EOL } = require('os')
Expand All @@ -21,6 +22,23 @@ test('meaningful errors', async t => {
t.is(error.killed, false)
})

test.skip('control process lifecycle', async t => {
t.plan(2)
try {
const subprocess = $('sleep 100')

;(async () => {
await setTimeout(500)
subprocess.kill('SIGKILL')
})()

await subprocess
} catch (error) {
t.is(error.killed, true)
t.is(error.signalCode, 'SIGKILL')
}
})

test.serial('run a command', async t => {
{
const result = await $('echo hello world')
Expand All @@ -39,9 +57,7 @@ test.serial('run a command', async t => {
t.is(result.spawnfile, SHELL)
t.deepEqual(
result.spawnargs,
isWindows
? ['hello world', '/d', '/s', '/c', '"echo $0"']
: ['hello world', '-c', 'echo $0']
isWindows ? ['hello world', '/d', '/s', '/c', '"echo $0"'] : ['hello world', '-c', 'echo $0']
)
}
{
Expand All @@ -61,9 +77,7 @@ test.serial('run a command', async t => {
t.is(result.spawnfile, SHELL)
t.deepEqual(
result.spawnargs,
isWindows
? ['world', '/d', '/s', '/c', '"echo hello $0"']
: ['world', '-c', 'echo hello $0']
isWindows ? ['world', '/d', '/s', '/c', '"echo hello $0"'] : ['world', '-c', 'echo hello $0']
)
}
})
Expand Down Expand Up @@ -100,9 +114,7 @@ test('output is child_process', async t => {
})

test('$.json', async t => {
const { stdout } = await require('..').json(
'curl https://geolocation.microlink.io'
)
const { stdout } = await require('..').json('curl https://geolocation.microlink.io')
t.true(!!stdout.ip.address)
})

Expand Down

0 comments on commit 9c63073

Please sign in to comment.