Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ jobs:

- name: Install
run: |
yq -i '.overrides.vite = "npm:vite@beta"' pnpm-workspace.yaml
yq -i '.overrides.vite = "npm:vite@8"' pnpm-workspace.yaml
git add . && git commit -m "ci" && pnpm i --prefer-offline --no-frozen-lockfile

- uses: ./.github/actions/setup-playwright
Expand Down
2 changes: 1 addition & 1 deletion packages/mocker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
},
"peerDependencies": {
"msw": "^2.4.9",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0"
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"msw": {
Expand Down
4 changes: 2 additions & 2 deletions packages/vitest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
"@vitest/ui": "workspace:*",
"happy-dom": "*",
"jsdom": "*",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0"
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"@edge-runtime/vm": {
Expand Down Expand Up @@ -192,7 +192,7 @@
"tinyexec": "^1.0.2",
"tinyglobby": "catalog:",
"tinyrainbow": "catalog:",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
"why-is-node-running": "^2.3.0"
},
"devDependencies": {
Expand Down
4 changes: 4 additions & 0 deletions packages/vitest/src/node/ast-collect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ function astParseFile(filepath: string, code: string) {
if (property && ['each', 'for', 'skipIf', 'runIf', 'extend', 'scoped', 'override'].includes(property)) {
return
}
// skip properties on return values of calls - e.g., test('name', fn).skip()
if (callee.type === 'MemberExpression' && callee.object?.type === 'CallExpression') {
return
}
// derive mode from the full chain (handles any order like .skip.concurrent or .concurrent.skip)
let mode: 'run' | 'skip' | 'only' | 'todo' = 'run'
for (const prop of properties) {
Expand Down
153 changes: 153 additions & 0 deletions test/cli/test/static-collect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,159 @@ test('invalid @module-tag throws and error', async () => {
`)
})

test('collects tests with runIf modifier', async () => {
const testModule = await collectTests(`
import { test } from 'vitest'

describe('runIf tests', () => {
test.runIf(true)('runs conditionally', () => {})
test.runIf(false)('also conditional', () => {})
})
`)
expect(testModule).toMatchInlineSnapshot(`
{
"runIf tests": {
"also conditional": {
"errors": [],
"fullName": "runIf tests > also conditional",
"id": "-1732721377_0_1",
"location": "6:22",
"mode": "skip",
"state": "skipped",
},
"runs conditionally": {
"errors": [],
"fullName": "runIf tests > runs conditionally",
"id": "-1732721377_0_0",
"location": "5:21",
"mode": "skip",
"state": "skipped",
},
},
}
`)
})

test('collects tests with skipIf modifier', async () => {
const testModule = await collectTests(`
import { test } from 'vitest'

describe('skipIf tests', () => {
test.skipIf(true)('skips conditionally', () => {})
test.skipIf(false)('also conditional skip', () => {})
})
`)
expect(testModule).toMatchInlineSnapshot(`
{
"skipIf tests": {
"also conditional skip": {
"errors": [],
"fullName": "skipIf tests > also conditional skip",
"id": "-1732721377_0_1",
"location": "6:23",
"mode": "skip",
"state": "skipped",
},
"skips conditionally": {
"errors": [],
"fullName": "skipIf tests > skips conditionally",
"id": "-1732721377_0_0",
"location": "5:22",
"mode": "skip",
"state": "skipped",
},
},
}
`)
})

test('collects tests with for modifier', async () => {
const testModule = await collectTests(`
import { test } from 'vitest'

describe('for tests', () => {
test.for([1, 2, 3])('test with for %i', (num) => {})
test.skip.for([1, 2])('skipped for %i', (num) => {})
})
`)
expect(testModule).toMatchInlineSnapshot(`
{
"for tests": {
"skipped for %i": {
"dynamic": true,
"each": true,
"errors": [],
"fullName": "for tests > skipped for %i",
"id": "-1732721377_0_1-dynamic",
"location": "6:26",
"mode": "skip",
"state": "skipped",
},
"test with for %i": {
"dynamic": true,
"each": true,
"errors": [],
"fullName": "for tests > test with for %i",
"id": "-1732721377_0_0-dynamic",
"location": "5:24",
"mode": "run",
"state": "pending",
},
},
}
`)
})

test('properties on test don\'t generate tests', async () => {
const testModule = await collectTests(`
import { test, describe } from 'vitest'

test('actual test', () => {}).withProp(true).withProp(false)
test.for([])('actual 2 test', () => {}).withProp('a2').withProp('a3')
testContext('actual 3 test', () => {}).withProp('q4').withProp('q5')
test('actual 4 test', () => {}).skip('hello world')
testContext().withProp('q6').withProp('q7')
`)
expect(testModule).toMatchInlineSnapshot(`
{
"actual 2 test": {
"dynamic": true,
"each": true,
"errors": [],
"fullName": "actual 2 test",
"id": "-1732721377_1-dynamic",
"location": "5:15",
"mode": "run",
"state": "pending",
},
"actual 3 test": {
"errors": [],
"fullName": "actual 3 test",
"id": "-1732721377_2",
"location": "6:4",
"mode": "run",
"state": "pending",
},
"actual 4 test": {
"errors": [],
"fullName": "actual 4 test",
"id": "-1732721377_3",
"location": "7:4",
"mode": "run",
"state": "pending",
},
"actual test": {
"errors": [],
"fullName": "actual test",
"id": "-1732721377_0",
"location": "4:4",
"mode": "run",
"state": "pending",
},
}
`)
})

async function collectTestModule(code: string, options?: CliOptions) {
const vitest = await createVitest(
'test',
Expand Down
Loading