Repository navigation
Conversation
Coverage of the same file from different transforms (e.g. jsdom vs browser projects, or different transpilers) can disagree on range columns, which caused merged reports to contain duplicate statements, functions and branches. When an exact location match fails, fall back to: - statements and branches: match ignoring the end column - functions: match by declaration range, as body ranges can differ in start column Fallback matches are only applied when unambiguous (one-to-one), so distinct items are never collapsed. Resolved end columns are preferred over `null`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the same file is covered by multiple transforms,
FileCoverage#merge()duplicates statements, functions and branches. For example, Vitestprojectswith jsdom + browser, or a plain project + one using SWC. Items are matched by their exactstart|endlocation, but transforms can disagree on columns:end.column: null, browser transforms resolve it (1:22->7:nullvs1:22->7:10).loc) differs in start column (1:42vs1:40forexport function sum(a: number, b: number) {), while the declaration range (decl) is identical. This is why the earlier end-column-only approach in istanbuljs#838 still duplicated functions (review).Fix
mergePropkeeps exact matching and adds an optional fallback key for items that have no exact match:declrangeFallback matches are only applied when they're one-to-one. If multiple items share a fallback key, nothing is collapsed and the existing nearest-container logic applies, so no hits are dropped. When matched items differ, the one with a resolved end column is kept.
Tests
New unit tests are built from hand-made coverage objects using locations captured from real Vitest runs, so there's no SWC or third-party plugin dependency:
nullvs resolved end columnsmath.tscase from the Vitest review)null-end ranges still merge (the case that crashed istanbuljs#838 earlier)decldon't throwThe 3 merge tests fail without the fix. The full suite passes after
pnpm build.Verified end-to-end
I swapped the built
@vitest/istanbul-lib-coverageinto Vitest 5.0.3 projects:constants.tsgoes from 6 statements to 3constants.ts29 → 15,validators.ts27 → 19). All 8 now match the single-project counts.Note
This PR was written by Claude (AI agent, Claude Code), working with @stevez. @stevez reviewed the approach and the verification results before it was opened.
🤖 Generated with Claude Code