-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.ts
More file actions
142 lines (116 loc) · 3.33 KB
/
index.ts
File metadata and controls
142 lines (116 loc) · 3.33 KB
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { writeFileSync, unlinkSync } from "fs";
import { v4 as uuidv4 } from "uuid";
import debugCreator from "debug";
import execBashCommand from "@node-cli-toolkit/exec-bash-command";
import {
DEFAULT_TIMEOUT_BETWEEN_INPUTS,
CLIInputs
} from "@node-cli-toolkit/send-inputs-to-cli";
import importNodeScriptPath from "./importNodeScriptPath";
// if we don't pass a cwd, we will create the temporary node file in the tmp directory
const TMP_DIR = "/tmp/";
export type ITestCLIReturn = {
// Exit code of the process
code: number;
error: jest.Mock;
output: jest.Mock;
};
export interface ITestCLIOpts {
// used if you need to test a CLI command/npm package
// ex: `run-my-tool --someoption`
bashCommand?: string;
// this is a list of inputs that need to be sent to cli
// if a string is passed then it will use the default
// timeoutBetweenInputs
// if an object is passed, you can specify the time to
// wait before the input
// ex:
// [
// 'hello',
// '\x20',
// {
// input: 'test'
// timeoutBeforeInput: 1000
// }
// ]
//
inputs?: CLIInputs;
// you can specify the path to the script you would like to run
nodeScriptPath?: string;
// a file exporting an executable default function with the mocks
// for a script. Use for mocking APIs
// you can also pass multiple file paths and they will be loaded in
// order
mockScriptPath?: string | string[];
// specify arguments (when using with nodeScriptPath or nodeScript)
// ex: --input1=hello --input2=bye
args?: string;
// this is a stringified node script to run as a child process
// ex:
// `
// import myCLI from '../';
// myCLI(someOpts: true);
// `
nodeScript?: string;
// if using nodeScript, this is the command used to run the script
// by default it's node (will run `node tmpFile.js`)
// ex: 'tsnode'
nodeCommand?: string;
// file extension (ex: change to ts if using ts-node)
extension?: string;
// time to wait in between sending inputs
// if one of your commands takes longer than the default
// 100 ms increase this parameter
timeoutBetweenInputs?: number;
// Which directory should the CLI execute in
cwd?: string;
// Should we print out all the calls to the output and error mocks
// otherwise use
debug?: boolean;
}
export default ({
bashCommand,
inputs,
nodeScriptPath,
mockScriptPath,
args,
nodeScript,
nodeCommand = "node",
extension = "js",
timeoutBetweenInputs = DEFAULT_TIMEOUT_BETWEEN_INPUTS,
cwd,
debug = false
}: ITestCLIOpts = {}): Promise<ITestCLIReturn> => {
const debugCommand = debugCreator("@node-cli-toolkit/test-cli");
// we handle debugging here by watching the functions we pass through
const outputCB = jest.fn();
const errorCB = jest.fn();
let tmpFile;
if (nodeScript) {
tmpFile = `${TMP_DIR}/${uuidv4()}.${extension}`;
writeFileSync(tmpFile, nodeScript);
bashCommand = `${nodeCommand} "${tmpFile}" ${args}`;
}
if (nodeScriptPath) {
({ tmpFile, bashCommand } = importNodeScriptPath({
nodeScriptPath,
extension,
mockScriptPath,
nodeCommand,
args,
debugCommand
}));
}
return execBashCommand({
bashCommand,
cwd,
outputCB,
errorCB,
inputs,
timeoutBetweenInputs
}).finally(() => {
if (nodeScript && !debug) {
unlinkSync(tmpFile);
}
});
};