Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(coverage): global coverage includes files in glob pattern coverage rules (fix #6165) #6172

Merged
merged 4 commits into from
Jul 21, 2024
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
5 changes: 5 additions & 0 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,11 @@ Shortcut for `--coverage.thresholds.lines 100 --coverage.thresholds.functions 10

Sets thresholds for files matching the glob pattern.

::: tip NOTE
Vitest counts all files, including those covered by glob-patterns, into the global coverage thresholds.
This is different from Jest behavior.
:::

<!-- eslint-skip -->
```ts
{
Expand Down
8 changes: 2 additions & 6 deletions packages/vitest/src/utils/coverage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ export class BaseCoverageProvider {
}): ResolvedThreshold[] {
const resolvedThresholds: ResolvedThreshold[] = []
const files = coverageMap.files()
const filesMatchedByGlobs: string[] = []
const globalCoverageMap = createCoverageMap()

for (const key of Object.keys(
Expand All @@ -204,7 +203,6 @@ export class BaseCoverageProvider {
const matchingFiles = files.filter(file =>
mm.isMatch(relative(root, file), glob),
)
filesMatchedByGlobs.push(...matchingFiles)

for (const file of matchingFiles) {
const fileCoverage = coverageMap.fileCoverageFor(file)
Expand All @@ -218,10 +216,8 @@ export class BaseCoverageProvider {
})
}

// Global threshold is for all files that were not included by glob patterns
for (const file of files.filter(
file => !filesMatchedByGlobs.includes(file),
)) {
// Global threshold is for all files, even if they are included by glob patterns
for (const file of files) {
const fileCoverage = coverageMap.fileCoverageFor(file)
globalCoverageMap.addFileCoverage(fileCoverage)
}
Expand Down
12 changes: 6 additions & 6 deletions test/coverage-test/test/threshold-auto-update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ test('thresholds.autoUpdate updates thresholds', async () => {
autoUpdate: true,

// Global ones
lines: 66.66,
functions: 50,
lines: 55.55,
functions: 33.33,
branches: 100,
statements: 66.66,
statements: 55.55,

'**/src/math.ts': {
branches: 100,
Expand All @@ -81,10 +81,10 @@ test('thresholds.autoUpdate updates thresholds', async () => {
autoUpdate: true,

// Global ones
lines: 50,
functions: 50,
lines: 33.33,
functions: 33.33,
branches: 100,
statements: 50,
statements: 33.33,

'**/src/math.ts': {
branches: 100,
Expand Down
33 changes: 33 additions & 0 deletions test/coverage-test/test/threshold-glob.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { expect } from 'vitest'
import { coverageTest, isV8Provider, normalizeURL, runVitest, test } from '../utils'
import { sum } from '../fixtures/src/math'
import { isEven, isOdd } from '../fixtures/src/even'

test('threshold glob patterns count in global coverage', async () => {
await runVitest({
include: [normalizeURL(import.meta.url)],
coverage: {
all: false,
include: ['**/fixtures/src/**'],
thresholds: {
'branches': 100,
'functions': 50,
'lines': isV8Provider() ? 66 : 50,
'statements': isV8Provider() ? 66 : 50,

'**/fixtures/src/even.ts': {
branches: 100,
functions: 100,
lines: 100,
statements: 100,
},
},
Comment on lines +12 to +24
Copy link
Member

@AriPerkkio AriPerkkio Jul 20, 2024

Choose a reason for hiding this comment

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

I've adjusted these now so that following error is shown when the fix is reverted.

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   66.66 |      100 |      50 |   66.66 |                   
 even.ts  |     100 |      100 |     100 |     100 |                   
 math.ts  |      50 |      100 |      25 |      50 | 6-7,10-11,14-15   
----------|---------|----------|---------|---------|-------------------
FAIL  |v8| test/threshold-glob.test.ts > threshold glob patterns count in global coverage
Error: ERROR: Coverage for lines (50%) does not meet global threshold (66%)
ERROR: Coverage for functions (25%) does not meet global threshold (50%)
ERROR: Coverage for statements (50%) does not meet global threshold (66%)


----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |      50 |      100 |      50 |      50 |                   
 even.ts  |     100 |      100 |     100 |     100 |                   
 math.ts  |      25 |      100 |      25 |      25 | 6-14              
----------|---------|----------|---------|---------|-------------------
FAIL  |istanbul| test/threshold-glob.test.ts > threshold glob patterns count in global coverage
Error: ERROR: Coverage for lines (25%) does not meet global threshold (50%)
ERROR: Coverage for functions (25%) does not meet global threshold (50%)
ERROR: Coverage for statements (25%) does not meet global threshold (50%)

},
})
})

coverageTest('cover some lines, but not too much', () => {
expect(sum(1, 2)).toBe(3)
expect(isEven(4)).toBe(true)
expect(isOdd(4)).toBe(false)
})