Skip to content

Commit fd500f7

Browse files
authored
fix(core): normalize mixed nested CLI options (#1290)
1 parent 7938535 commit fd500f7

3 files changed

Lines changed: 192 additions & 3 deletions

File tree

e2e/cli/index.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,53 @@ describe.concurrent('test exit code', () => {
7070
await expectExecSuccess();
7171
});
7272

73+
it('should support --pool shorthand with nested pool options', async ({
74+
onTestFinished,
75+
}) => {
76+
const { expectExecSuccess } = await runRstestCli({
77+
command: 'rstest',
78+
args: [
79+
'run',
80+
'success.test.ts',
81+
'--pool',
82+
'forks',
83+
'--pool.maxWorkers',
84+
'1',
85+
],
86+
onTestFinished,
87+
options: {
88+
nodeOptions: {
89+
cwd: __dirname,
90+
},
91+
},
92+
});
93+
94+
await expectExecSuccess();
95+
});
96+
97+
it('should support browser shorthand with nested browser options', async ({
98+
onTestFinished,
99+
}) => {
100+
const { expectExecSuccess } = await runRstestCli({
101+
command: 'rstest',
102+
args: [
103+
'run',
104+
'success.test.ts',
105+
'--no-browser',
106+
'--browser.name',
107+
'chromium',
108+
],
109+
onTestFinished,
110+
options: {
111+
nodeOptions: {
112+
cwd: __dirname,
113+
},
114+
},
115+
});
116+
117+
await expectExecSuccess();
118+
});
119+
73120
it('should return code 1 and print error correctly when test config error', async ({
74121
onTestFinished,
75122
}) => {

packages/core/src/cli/commands.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,58 @@ const normalizeCoverageCliArgs = (argv: string[]): string[] => {
220220
});
221221
};
222222

223-
const allowMixedCoverageCliOptions = (cli: CAC): void => {
223+
const normalizePoolCliArgs = (argv: string[]): string[] => {
224+
const hasPoolNestedOption = argv.some((arg) => arg.startsWith('--pool.'));
225+
226+
if (!hasPoolNestedOption) {
227+
return argv;
228+
}
229+
230+
return argv.map((arg) => {
231+
if (arg === '--pool') {
232+
return '--pool.type';
233+
}
234+
if (arg.startsWith('--pool=')) {
235+
return `--pool.type=${arg.slice('--pool='.length)}`;
236+
}
237+
238+
return arg;
239+
});
240+
};
241+
242+
const normalizeBrowserCliArgs = (argv: string[]): string[] => {
243+
const hasBrowserNestedOption = argv.some((arg) =>
244+
arg.startsWith('--browser.'),
245+
);
246+
247+
if (!hasBrowserNestedOption) {
248+
return argv;
249+
}
250+
251+
return argv.map((arg) => {
252+
if (arg === '--browser') {
253+
return '--browser.enabled';
254+
}
255+
if (arg.startsWith('--browser=')) {
256+
return `--browser.enabled=${arg.slice('--browser='.length)}`;
257+
}
258+
if (arg === '--no-browser') {
259+
return '--browser.enabled=false';
260+
}
261+
262+
return arg;
263+
});
264+
};
265+
266+
const normalizeCliArgs = (argv: string[]): string[] =>
267+
normalizePoolCliArgs(normalizeBrowserCliArgs(normalizeCoverageCliArgs(argv)));
268+
269+
const normalizeMixedCliOptions = (cli: CAC): void => {
224270
const originalParse = cli.parse.bind(cli);
225271

226272
cli.parse = ((argv, options) =>
227273
originalParse(
228-
normalizeCoverageCliArgs(argv ?? process.argv),
274+
normalizeCliArgs(argv ?? process.argv),
229275
options,
230276
)) as CAC['parse'];
231277
};
@@ -861,7 +907,7 @@ export function createCli(): CAC {
861907
}
862908
});
863909

864-
allowMixedCoverageCliOptions(cli);
910+
normalizeMixedCliOptions(cli);
865911

866912
return cli;
867913
}

packages/core/tests/cli/commands.test.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,102 @@ describe('CLI help output', () => {
8080
changed: 'HEAD',
8181
});
8282
});
83+
84+
it('preserves nested coverage options when followed by --coverage', () => {
85+
const parsed = createCli().parse(
86+
['node', 'rstest', 'run', '--coverage.changed=HEAD', '--coverage'],
87+
{ run: false },
88+
);
89+
90+
expect(parsed.options.coverage).toEqual({
91+
changed: 'HEAD',
92+
enabled: true,
93+
});
94+
});
95+
96+
it('allows --coverage=false to be mixed with nested coverage options', () => {
97+
const parsed = createCli().parse(
98+
['node', 'rstest', 'run', '--coverage=false', '--coverage.changed=HEAD'],
99+
{ run: false },
100+
);
101+
102+
expect(parsed.options.coverage).toEqual({
103+
enabled: 'false',
104+
changed: 'HEAD',
105+
});
106+
});
107+
108+
it('allows --pool shorthand to be mixed with nested pool options', () => {
109+
const parsed = createCli().parse(
110+
['node', 'rstest', 'run', '--pool', 'forks', '--pool.maxWorkers', '1'],
111+
{ run: false },
112+
);
113+
114+
expect(parsed.options.pool).toEqual({
115+
type: 'forks',
116+
maxWorkers: 1,
117+
});
118+
});
119+
120+
it('preserves nested pool options when followed by --pool shorthand', () => {
121+
const parsed = createCli().parse(
122+
['node', 'rstest', 'run', '--pool.maxWorkers', '1', '--pool', 'forks'],
123+
{ run: false },
124+
);
125+
126+
expect(parsed.options.pool).toEqual({
127+
maxWorkers: 1,
128+
type: 'forks',
129+
});
130+
});
131+
132+
it('allows --pool= shorthand to be mixed with nested pool options', () => {
133+
const parsed = createCli().parse(
134+
['node', 'rstest', 'run', '--pool=forks', '--pool.maxWorkers=1'],
135+
{ run: false },
136+
);
137+
138+
expect(parsed.options.pool).toEqual({
139+
type: 'forks',
140+
maxWorkers: 1,
141+
});
142+
});
143+
144+
it('allows --browser shorthand to be mixed with nested browser options', () => {
145+
const parsed = createCli().parse(
146+
['node', 'rstest', 'run', '--browser', '--browser.name', 'chromium'],
147+
{ run: false },
148+
);
149+
150+
expect(parsed.options.browser).toEqual({
151+
enabled: true,
152+
name: 'chromium',
153+
});
154+
});
155+
156+
it('preserves nested browser options when followed by --browser', () => {
157+
const parsed = createCli().parse(
158+
['node', 'rstest', 'run', '--browser.name', 'chromium', '--browser'],
159+
{ run: false },
160+
);
161+
162+
expect(parsed.options.browser).toEqual({
163+
name: 'chromium',
164+
enabled: true,
165+
});
166+
});
167+
168+
it('allows browser disabling shorthand to be mixed with nested browser options', () => {
169+
const parsed = createCli().parse(
170+
['node', 'rstest', 'run', '--no-browser', '--browser.name', 'chromium'],
171+
{ run: false },
172+
);
173+
174+
expect(parsed.options.browser).toEqual({
175+
enabled: false,
176+
name: 'chromium',
177+
});
178+
});
83179
});
84180

85181
describe('normalizeCliFilters', () => {

0 commit comments

Comments
 (0)