Skip to content

Commit cad1642

Browse files
committed
fix(@angular/build): normalize code coverage include paths to POSIX
Ensures that code coverage `include` patterns are converted to a POSIX-style format. Closes #30698
1 parent af3b14c commit cad1642

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

packages/angular/build/src/builders/unit-test/builder.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import path from 'node:path';
1414
import { createVirtualModulePlugin } from '../../tools/esbuild/virtual-module-plugin';
1515
import { assertIsError } from '../../utils/error';
1616
import { loadEsmModule } from '../../utils/load-esm';
17+
import { toPosixPath } from '../../utils/path';
1718
import { buildApplicationInternal } from '../application';
1819
import type {
1920
ApplicationBuilderExtensions,
@@ -117,7 +118,7 @@ export async function* execute(
117118

118119
buildTargetOptions.polyfills = injectTestingPolyfills(buildTargetOptions.polyfills);
119120

120-
const outputPath = path.join(context.workspaceRoot, generateOutputPath());
121+
const outputPath = toPosixPath(path.join(context.workspaceRoot, generateOutputPath()));
121122
const buildOptions: ApplicationBuilderInternalOptions = {
122123
...buildTargetOptions,
123124
watch: normalizedOptions.watch,
@@ -156,10 +157,11 @@ export async function* execute(
156157
`import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';`,
157158
'',
158159
normalizedOptions.providersFile
159-
? `import providers from './${path
160-
.relative(projectSourceRoot, normalizedOptions.providersFile)
161-
.replace(/.[mc]?ts$/, '')
162-
.replace(/\\/g, '/')}'`
160+
? `import providers from './${toPosixPath(
161+
path
162+
.relative(projectSourceRoot, normalizedOptions.providersFile)
163+
.replace(/.[mc]?ts$/, ''),
164+
)}'`
163165
: 'const providers = [];',
164166
'',
165167
// Same as https://github.com/angular/angular/blob/05a03d3f975771bb59c7eefd37c01fa127ee2229/packages/core/testing/src/test_hooks.ts#L21-L29
@@ -406,7 +408,7 @@ function generateCoverageOption(
406408
return {
407409
enabled: true,
408410
excludeAfterRemap: true,
409-
include: [`${path.relative(workspaceRoot, outputPath)}/**`],
411+
include: [`${toPosixPath(path.relative(workspaceRoot, outputPath))}/**`],
410412
// Special handling for `reporter` due to an undefined value causing upstream failures
411413
...(codeCoverage.reporters
412414
? ({ reporter: codeCoverage.reporters } satisfies VitestCoverageOption)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import { posix } from 'node:path';
10+
import { platform } from 'node:process';
11+
12+
const WINDOWS_PATH_SEPERATOR_REGEXP = /\\/g;
13+
14+
/**
15+
* Converts a Windows-style file path to a POSIX-compliant path.
16+
*
17+
* This function replaces all backslashes (`\`) with forward slashes (`/`).
18+
* It is a no-op on POSIX systems (e.g., Linux, macOS), as the conversion
19+
* only runs on Windows (`win32`).
20+
*
21+
* @param path - The file path to convert.
22+
* @returns The POSIX-compliant file path.
23+
*
24+
* @example
25+
* ```ts
26+
* // On a Windows system:
27+
* toPosixPath('C:\\Users\\Test\\file.txt');
28+
* // => 'C:/Users/Test/file.txt'
29+
*
30+
* // On a POSIX system (Linux/macOS):
31+
* toPosixPath('/home/user/file.txt');
32+
* // => '/home/user/file.txt'
33+
* ```
34+
*/
35+
export function toPosixPath(path: string): string {
36+
return platform === 'win32' ? path.replace(WINDOWS_PATH_SEPERATOR_REGEXP, posix.sep) : path;
37+
}

0 commit comments

Comments
 (0)