Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guide/cli-generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ Path to a custom tsconfig file
- **CLI:** `--project <name>`
- **Config:** [project](/config/#project)

The name of the project to run if you are using Vitest workspace feature. This can be repeated for multiple projects: `--project=1 --project=2`. You can also filter projects using wildcards like `--project=packages*`
The name of the project to run if you are using Vitest workspace feature. This can be repeated for multiple projects: `--project=1 --project=2`. You can also filter projects using wildcards like `--project=packages*`, and exclude projects with `--project=!pattern`.

### slowTestThreshold

Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/cli/cli-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ export const cliOptionsConfig: VitestCLIOptions = {
},
project: {
description:
'The name of the project to run if you are using Vitest workspace feature. This can be repeated for multiple projects: `--project=1 --project=2`. You can also filter projects using wildcards like `--project=packages*`',
'The name of the project to run if you are using Vitest workspace feature. This can be repeated for multiple projects: `--project=1 --project=2`. You can also filter projects using wildcards like `--project=packages*`, and exclude projects with `--project=!pattern`.',
argument: '<name>',
array: true,
},
Expand Down
17 changes: 13 additions & 4 deletions packages/vitest/src/utils/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,17 @@ export function escapeRegExp(s: string) {
}

export function wildcardPatternToRegExp(pattern: string): RegExp {
return new RegExp(
`^${pattern.split('*').map(escapeRegExp).join('.*')}$`,
'i',
)
const negated = pattern.startsWith('!')

if (negated) {
pattern = pattern.slice(1)
}

let regexp = `${pattern.split('*').map(escapeRegExp).join('.*')}$`

if (negated) {
regexp = `(?!${regexp})`
}

return new RegExp(`^${regexp}`, 'i')
}
10 changes: 5 additions & 5 deletions test/config/test/project.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ test.each([
{ pattern: '*j*', expected: ['project_1', 'project_2'] },
{ pattern: 'project*', expected: ['project_1', 'project_2'] },
{ pattern: 'space*', expected: ['space_1'] },
{ pattern: '!project_1', expected: ['project_2', 'space_1'] },
{ pattern: '!project*', expected: ['space_1'] },
{ pattern: '!project', expected: ['project_1', 'project_2', 'space_1'] },
])('should match projects correctly: $pattern', async ({ pattern, expected }) => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, this test seems a bit flawed. What about adding something like this?

expect(ctx.projects.map(p => p.name)).toEqual(expected)

Note: await runVitest returns ctx

const { stdout, stderr } = await runVitest({
const { ctx } = await runVitest({
root: 'fixtures/project',
reporters: ['basic'],
project: pattern,
})

expect(stderr).toBeFalsy()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to remove other assertions - they assert the reporter behaviour (what users see). stderr is especially important - we should be able to see what's wrong without reruning the test

expect(stdout).toBeTruthy()

expected.forEach(name => expect(stdout).toContain(name))
expect(ctx?.projects.map(p => p.name).sort()).toEqual(expected)
})