Description
When using @vitest/coverage-v8 in a React/TypeScript project, the text reporter counts approximately 2× more branches than what is reported in coverage-final.json for the same codebase. This causes the text reporter to show ~94–95% branch coverage while the JSON canonical file shows 100% branch coverage.
Environment
- Vitest: 4.1.6
- @vitest/coverage-v8: 4.1.6
- ast-v8-to-istanbul: 1.0.0 (latest — already includes fix from PR Setup Tests Global Describe? #138)
- Node.js: 22.x
- Framework: React 18 + TypeScript
- Not Vue SFC — plain React/TypeScript project
Reproduction
The discrepancy appears on nested ternary chains such as:
const normalizedQty = isCashDirectDeposit
? (direction === 'depot' ? Math.abs(form.quantity) : -Math.abs(form.quantity))
: form.type === 'Frais'
? forfait ? -1 : -Math.abs(form.quantity)
: form.type === 'Revenu'
? Math.abs(form.quantity)
: form.quantity;
Observed behavior
Text reporter output:
All files | % Stmts | % Branch | % Funcs | % Lines
| 100 | 94.79 | 100 | 100
Branches: 94.79% ( 1348/1424 )
JSON coverage (coverage-final.json) analysis:
Total uncovered branches: 0/689 (100.00%)
The text reporter counts 1424 branches, while the JSON counts 689 — roughly 2×.
All 689 branches are covered (0 uncovered in JSON). The ~735 extra "branches" in the text reporter appear to come from nested ternary expressions being counted multiple times.
Expected behavior
Text reporter branch count should match the JSON coverage file count, or at minimum produce the same covered/total ratio.
Additional notes
Workaround
Currently setting the coverage threshold to 94% instead of 100% to accommodate the false count. The JSON canonical output confirms true 100% coverage.
Description
When using
@vitest/coverage-v8in a React/TypeScript project, the text reporter counts approximately 2× more branches than what is reported incoverage-final.jsonfor the same codebase. This causes the text reporter to show ~94–95% branch coverage while the JSON canonical file shows 100% branch coverage.Environment
Reproduction
The discrepancy appears on nested ternary chains such as:
Observed behavior
Text reporter output:
JSON coverage (
coverage-final.json) analysis:The text reporter counts 1424 branches, while the JSON counts 689 — roughly 2×.
All 689 branches are covered (0 uncovered in JSON). The ~735 extra "branches" in the text reporter appear to come from nested ternary expressions being counted multiple times.
Expected behavior
Text reporter branch count should match the JSON coverage file count, or at minimum produce the same covered/total ratio.
Additional notes
@vitest/coverage-v8v4 producesNaNin BRDA entries of lcov reports, breaking Codecov integration #9725 — that was fixed in ast-v8-to-istanbul v0.3.12/v1.0.0, which we already have installedprovider: 'istanbul'via--coverage.provider=istanbulCLI flag shows the same 1424 branch count in the text reporter, suggesting the bug is in the text reporter logic, not the v8/istanbul provider itselfcoverage-final.jsoncorrectly reports 100% branch coverage — only the text reporter is wrongWorkaround
Currently setting the coverage threshold to 94% instead of 100% to accommodate the false count. The JSON canonical output confirms true 100% coverage.