UNPKG

4.41 kBPlain TextView Raw
1import execa from 'execa';
2import { ArgList, Arguments, Argv } from '@boost/args';
3import { Path } from '@boost/common';
4import { mockDebugger } from '@boost/debug/test';
5import {
6 ConfigContext,
7 ConfigFile,
8 Context,
9 Driver,
10 DriverContext,
11 DriverContextOptions,
12 DriverMetadata,
13 ScaffoldContext,
14 ScaffoldContextOptions,
15 Script,
16 ScriptContext,
17 ScriptContextOptions,
18 Tool,
19} from '.';
20
21export { mockDebugger };
22
23const TEST_ROOT = new Path(process.env.BEEMO_TEST_ROOT ?? process.cwd());
24
25export class TestDriver<O extends object = {}> extends Driver<O> {
26 override readonly name = 'test-driver';
27}
28
29export class TestScript<O extends object = {}> extends Script<O> {
30 override readonly name = 'test-script';
31
32 execute(): any {
33 return Promise.resolve();
34 }
35}
36
37export function mockConsole<K extends keyof Console>(name: K): jest.SpyInstance {
38 return jest.spyOn(console, name as 'log').mockImplementation(() => {});
39}
40
41export function mockToolConfig(): ConfigFile {
42 return {
43 configure: {
44 cleanup: false,
45 parallel: true,
46 },
47 debug: false,
48 drivers: [],
49 execute: {
50 concurrency: 1,
51 graph: true,
52 output: '',
53 },
54 module: '@local',
55 scripts: [],
56 settings: {},
57 };
58}
59
60export function mockTool(argv: Argv = []): Tool {
61 const tool = new Tool({
62 argv,
63 cwd: TEST_ROOT,
64 });
65
66 // @ts-expect-error Allow readonly
67 tool.debug = mockDebugger();
68
69 tool.config = mockToolConfig();
70
71 return tool;
72}
73
74export function mockDriver<C extends object = {}>(
75 name: string,
76 tool: Tool | null = null,
77 metadata: Partial<DriverMetadata> = {},
78): Driver<C> {
79 const driver = new TestDriver<C>();
80
81 // @ts-expect-error For testing purposes
82 driver.name = name;
83 driver.tool = tool ?? mockTool();
84
85 driver.setMetadata({
86 bin: name.toLowerCase(),
87 configName: `${name}.json`,
88 title: name,
89 ...metadata,
90 });
91
92 return driver;
93}
94
95export function mockScript(name: string, tool: Tool | null = null): Script<{}> {
96 const script = new TestScript<{}>();
97
98 // @ts-expect-error For testing purposes
99 script.name = name;
100 script.tool = tool ?? mockTool();
101
102 return script;
103}
104
105export function stubArgs<T extends object>(options: T, params: ArgList = []): Arguments<T> {
106 return {
107 command: [],
108 errors: [],
109 options,
110 params,
111 rest: [],
112 unknown: {},
113 };
114}
115
116export function stubConfigArgs(): Arguments<{}> {
117 return stubArgs({});
118}
119
120export function stubDriverArgs(
121 fields?: Partial<DriverContextOptions>,
122): Arguments<DriverContextOptions> {
123 return stubArgs({
124 concurrency: 1,
125 graph: false,
126 workspaces: '',
127 ...fields,
128 });
129}
130
131export function stubScaffoldArgs(
132 fields?: Partial<ScaffoldContextOptions>,
133): Arguments<ScaffoldContextOptions> {
134 return stubArgs({
135 dry: false,
136 ...fields,
137 });
138}
139
140export function stubScriptArgs(
141 fields?: Partial<ScriptContextOptions>,
142): Arguments<ScriptContextOptions> {
143 return stubArgs({
144 concurrency: 1,
145 graph: false,
146 workspaces: '',
147 ...fields,
148 });
149}
150
151export function applyContext<T extends Context>(context: T): T {
152 context.args = stubArgs({ a: true, foo: 'bar' }, ['baz']);
153 context.argv = ['-a', '--foo', 'bar', 'baz'];
154 context.cwd = TEST_ROOT;
155 context.configModuleRoot = TEST_ROOT;
156 context.workspaceRoot = TEST_ROOT;
157 context.workspaces = [];
158
159 return context;
160}
161
162export function stubConfigContext(): ConfigContext {
163 return applyContext(new ConfigContext(stubArgs({})));
164}
165
166export function stubDriverContext(driver?: Driver): DriverContext {
167 return applyContext(new DriverContext(stubDriverArgs(), driver ?? new TestDriver()));
168}
169
170export function stubScriptContext(script?: Script): ScriptContext {
171 const context = applyContext(new ScriptContext(stubScriptArgs(), 'script'));
172
173 if (script) {
174 context.setScript(script);
175 }
176
177 return context;
178}
179
180export function stubScaffoldContext(
181 generator: string = 'generator',
182 action: string = 'action',
183 name: string = '',
184): ScaffoldContext {
185 return applyContext(new ScaffoldContext(stubScaffoldArgs(), generator, action, name));
186}
187
188export function prependRoot(part: string): Path {
189 return TEST_ROOT.append(part);
190}
191
192export function getRoot(): Path {
193 return TEST_ROOT;
194}
195
196export function stubExecResult(fields?: Partial<execa.ExecaReturnValue>): execa.ExecaReturnValue {
197 return {
198 all: '',
199 command: '',
200 escapedCommand: '',
201 exitCode: 0,
202 failed: false,
203 isCanceled: false,
204 killed: false,
205 signal: undefined,
206 stderr: '',
207 stdout: '',
208 timedOut: false,
209 ...fields,
210 };
211}