Skip to content

Commit

Permalink
fix(cli): improve cac errors when mixing boolean and dot notation
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed May 4, 2023
1 parent a93be56 commit 2d1b745
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
28 changes: 27 additions & 1 deletion packages/vitest/src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,33 @@ cli
.command('[...filters]')
.action((filters, options) => start('test', filters, options))

cli.parse()
try {
cli.parse()
}
catch (originalError) {
// CAC may fail to parse arguments when boolean flags and dot notation are mixed
// e.g. "--coverage --coverage.reporter text" will fail, when "--coverage.enabled --coverage.reporter text" will pass
const fullArguments = cli.rawArgs.join(' ')
const conflictingArgs: { arg: string; dotArgs: string[] }[] = []

for (const arg of cli.rawArgs) {
if (arg.startsWith('--') && !arg.includes('.') && fullArguments.includes(`${arg}.`)) {
const dotArgs = cli.rawArgs.filter(rawArg => rawArg.startsWith(arg) && rawArg.includes('.'))
conflictingArgs.push({ arg, dotArgs })
}
}

if (conflictingArgs.length === 0)
throw originalError

const error = conflictingArgs
.map(({ arg, dotArgs }) =>
`A boolean argument "${arg}" was used with dot notation arguments "${dotArgs.join(' ')}".`
+ `\nPlease specify the "${arg}" argument with dot notation as well: "${arg}.enabled"`)
.join('\n')

throw new Error(error)
}

async function runRelated(relatedFiles: string[] | string, argv: CliOptions): Promise<void> {
argv.related = relatedFiles
Expand Down
14 changes: 14 additions & 0 deletions test/config/test/failures.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,17 @@ test('c8 coverage provider cannot be used with browser', async () => {

expect(error).toMatch('Error: @vitest/coverage-c8 does not work with --browser. Use @vitest/coverage-istanbul instead')
})

test('boolean coverage flag without dot notation, with more dot notation options', async () => {
const { error } = await runVitest('run', ['--coverage', '--coverage.reporter', 'text'])

expect(error).toMatch('Error: A boolean argument "--coverage" was used with dot notation arguments "--coverage.reporter".')
expect(error).toMatch('Please specify the "--coverage" argument with dot notation as well: "--coverage.enabled"')
})

test('boolean browser flag without dot notation, with more dot notation options', async () => {
const { error } = await runVitest('run', ['--browser', '--browser.name', 'chrome'])

expect(error).toMatch('Error: A boolean argument "--browser" was used with dot notation arguments "--browser.name".')
expect(error).toMatch('Please specify the "--browser" argument with dot notation as well: "--browser.enabled"')
})
2 changes: 1 addition & 1 deletion test/config/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export async function runVitest(mode: 'run' | 'watch', cliArguments: string[]) {
let error = ''

subprocess.stderr?.on('data', (data) => {
error = stripAnsi(data.toString())
error += stripAnsi(data.toString())

// Sometimes on Windows CI execa doesn't exit properly. Force exit when stderr is caught.
subprocess.kill()
Expand Down
3 changes: 3 additions & 0 deletions test/config/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
testTimeout: 60_000,
chaiConfig: {
truncateThreshold: 999,
},
},
})

0 comments on commit 2d1b745

Please sign in to comment.