Skip to content

fix(@angular-devkit/build-angular): ensure vitest code coverage handles virtual files correctly#31615

Merged
clydin merged 1 commit intoangular:mainfrom
clydin:unit-test/vitest-coverage-v4
Oct 28, 2025
Merged

fix(@angular-devkit/build-angular): ensure vitest code coverage handles virtual files correctly#31615
clydin merged 1 commit intoangular:mainfrom
clydin:unit-test/vitest-coverage-v4

Conversation

@clydin
Copy link
Member

@clydin clydin commented Oct 28, 2025

Vitest's default coverage provider checks for the physical existence of files to determine inclusion in the coverage report. This behavior excludes in-memory files generated by the build process from the final report. This change patches the isIncluded method of Vitest's BaseCoverageProvider to correctly account for these virtual files, ensuring they are included in the coverage analysis.

Additionally, bundler-generated helper code chunks without any original source code can have empty sourcemaps. Vitest includes files with such sourcemaps in the coverage report, which is incorrect. This change adds a virtual source to these sourcemaps to prevent them from being included in the final coverage output.

Closes #31601

@clydin clydin added the target: rc This PR is targeted for the next release-candidate label Oct 28, 2025
@clydin clydin requested a review from alan-agius4 October 28, 2025 01:50
@clydin clydin force-pushed the unit-test/vitest-coverage-v4 branch from 33c9979 to d9767f9 Compare October 28, 2025 01:51
@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Oct 28, 2025
…es virtual files correctly

Vitest's default coverage provider checks for the physical existence of files to determine inclusion in the coverage report. This behavior excludes in-memory files generated by the build process from the final report. This change patches the `isIncluded` method of Vitest's `BaseCoverageProvider` to correctly account for these virtual files, ensuring they are included in the coverage analysis.

Additionally, bundler-generated helper code chunks without any original source code can have empty sourcemaps. Vitest includes files with such sourcemaps in the coverage report, which is incorrect. This change adds a virtual source to these sourcemaps to prevent them from being included in the final coverage output.
@clydin clydin force-pushed the unit-test/vitest-coverage-v4 branch from d9767f9 to 21a98b7 Compare October 28, 2025 05:43
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Oct 28, 2025
// Temporary workaround to avoid the direct filesystem checks in the base provider that
// were introduced in v4. Also ensures that all built virtual files are available.
const builtVirtualFiles = this.buildResultFiles;
vitestCoverageModule.BaseCoverageProvider.prototype.isIncluded = function (filename) {

Choose a reason for hiding this comment

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

Patching private APIs instead of filing bug report on upstream is not recommended, ever.

I'm not sure why exactly Angular requires such hacky patch but it might as well be real bug on Vitest.

Copy link
Member Author

@clydin clydin Oct 28, 2025

Choose a reason for hiding this comment

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

Understood. It's temporary and we will be filing a bug and investigating further. This is intended to unblock downstream integration testing and allows us to test for potential breakage across a wider array of user projects in the interim. Additionally, in this case isIncluded is a public method on a public class that if it were changed upstream would cause breakage for all concrete providers so could not effectively be changed outside a major version.

Copy link
Contributor

Choose a reason for hiding this comment

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

Btw, @clydin, is there any design doc or anything that highlights the pros and cons of separate build + virtual files vs. a vite transform plugin?

I am myself passionate about symmetry and would love to have everything built and bundled the same way but I feel that this is also breaking some of Vitest assumptions.

@clydin clydin merged commit 2c846fb into angular:main Oct 28, 2025
32 checks passed
@clydin
Copy link
Member Author

clydin commented Oct 28, 2025

This PR was merged into the repository. The changes were merged into the following branches:

@clydin clydin deleted the unit-test/vitest-coverage-v4 branch October 28, 2025 11:45
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker area: @angular-devkit/build-angular target: rc This PR is targeted for the next release-candidate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vitest code coverage is always 0

4 participants