-
Notifications
You must be signed in to change notification settings - Fork 1
/
test.command.js
49 lines (46 loc) · 1.57 KB
/
test.command.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const childProcess = require('child_process')
/**
* @type {
function(string, childProcess.ExecOptionsWithBufferEncoding):
childProcess.PromiseWithChild<{ stdout: string, stderr: string }>
}
*/
const exec = require('util').promisify(childProcess.exec)
/**
* @typedef {childProcess.ExecException & { stdout: string, stderr: string }} CommandResponse
*/
/**
* Execute a shell command async.
* The promise is always resolved to simplify writing tests.
*
* @param {string} cmd the command to execute
* @param {childProcess.ExecOptions} [opts={encoding: 'utf8', windowsHide: true}]
*
* @return {Promise<CommandResponse>}
*/
export const command = async (cmd, opts) => exec(
cmd, {encoding: 'utf8', windowsHide: true, ...opts}
).catch(it => it)
/**
* Creates a function that:
* Uses `test` to compare `stdout` to `stdoutAssertion`.
* Also checks values of `it.code` and `it.stderr` to provide more helpful messages
* in case of test failures.
*
* @param {import('tap').Test} t
* @param {function(string, string|RegExp, string?): Promise<void>} test
* @param {string | RegExp} stdoutAssertion
*/
export const assertStdout = (
t, test, stdoutAssertion
) =>
/** @param {CommandResponse} it */
({code, killed, signal, stderr, stdout}) => {
t.assertNot((killed || signal), `expected no kill signal (was '${signal}')`);
t.assertNot(code, `expected no exit code (was '${code}')`);
stderr = stderr.trim();
t.equals(
stderr, '', `expected empty stderr (1st line: "${stderr.split('\n')[0]}")`
);
test(stdout.trim(), stdoutAssertion, 'expected stdout');
}