Skip to content

Commit ab6e19e

Browse files
jkremsdgp1130
authored andcommitted
fix(@angular-devkit/build-angular): handle main field
1 parent 7de93e5 commit ab6e19e

File tree

3 files changed

+78
-9
lines changed

3 files changed

+78
-9
lines changed

packages/angular_devkit/build_angular/src/builders/karma/application_builder.ts

+26-8
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,7 @@ async function collectEntrypoints(
186186
projectSourceRoot,
187187
);
188188

189-
const entryPoints = new Set([
190-
...testFiles,
191-
'@angular-devkit/build-angular/src/builders/karma/init_test_bed.js',
192-
]);
193-
194-
return entryPoints;
189+
return new Set(testFiles);
195190
}
196191

197192
async function initializeApplication(
@@ -218,6 +213,14 @@ async function initializeApplication(
218213
fs.rm(outputPath, { recursive: true, force: true }),
219214
]);
220215

216+
let mainName = 'init_test_bed';
217+
if (options.main) {
218+
entryPoints.add(options.main);
219+
mainName = path.basename(options.main, path.extname(options.main));
220+
} else {
221+
entryPoints.add('@angular-devkit/build-angular/src/builders/karma/init_test_bed.js');
222+
}
223+
221224
const instrumentForCoverage = options.codeCoverage
222225
? createInstrumentationFilter(
223226
projectSourceRoot,
@@ -261,10 +264,19 @@ async function initializeApplication(
261264
karmaOptions.files.push(
262265
// Serve polyfills first.
263266
{ pattern: `${outputPath}/polyfills.js`, type: 'module' },
264-
// Allow loading of chunk-* files but don't include them all on load.
265-
{ pattern: `${outputPath}/{chunk,worker}-*.js`, type: 'module', included: false },
267+
// Serve global setup script.
268+
{ pattern: `${outputPath}/${mainName}.js`, type: 'module' },
269+
// Serve all source maps.
270+
{ pattern: `${outputPath}/*.map`, included: false },
266271
);
267272

273+
if (hasChunkOrWorkerFiles(buildOutput.files)) {
274+
karmaOptions.files.push(
275+
// Allow loading of chunk-* files but don't include them all on load.
276+
{ pattern: `${outputPath}/{chunk,worker}-*.js`, type: 'module', included: false },
277+
);
278+
}
279+
268280
karmaOptions.files.push(
269281
// Serve remaining JS on page load, these are the test entrypoints.
270282
{ pattern: `${outputPath}/*.js`, type: 'module' },
@@ -316,6 +328,12 @@ async function initializeApplication(
316328
return [karma, parsedKarmaConfig, buildOptions];
317329
}
318330

331+
function hasChunkOrWorkerFiles(files: Record<string, unknown>): boolean {
332+
return Object.keys(files).some((filename) => {
333+
return /(?:^|\/)(?:worker|chunk)[^/]+\.js$/.test(filename);
334+
});
335+
}
336+
319337
export async function writeTestFiles(files: Record<string, ResultFile>, testDir: string) {
320338
const directoryExists = new Set<string>();
321339
// Writes the test related output files to disk and ensures the containing directories are present

packages/angular_devkit/build_angular/src/builders/karma/tests/behavior/fake-async_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import { execute } from '../../index';
1010
import { BASE_OPTIONS, KARMA_BUILDER_INFO, describeKarmaBuilder } from '../setup';
1111

12-
describeKarmaBuilder(execute, KARMA_BUILDER_INFO, (harness, setupTarget, isApp) => {
12+
describeKarmaBuilder(execute, KARMA_BUILDER_INFO, (harness, setupTarget) => {
1313
describe('Behavior: "fakeAsync"', () => {
1414
beforeEach(async () => {
1515
await setupTarget(harness);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 { execute } from '../../index';
10+
import { BASE_OPTIONS, KARMA_BUILDER_INFO, describeKarmaBuilder } from '../setup';
11+
12+
describeKarmaBuilder(execute, KARMA_BUILDER_INFO, (harness, setupTarget) => {
13+
describe('Option: "main"', () => {
14+
beforeEach(async () => {
15+
await setupTarget(harness);
16+
});
17+
18+
beforeEach(async () => {
19+
await harness.writeFiles({
20+
'src/magic.ts': `Object.assign(globalThis, {MAGIC_IS_REAL: true});`,
21+
'src/magic.spec.ts': `
22+
declare const MAGIC_IS_REAL: boolean;
23+
describe('Magic', () => {
24+
it('can be scientificially proven to be true', () => {
25+
expect(typeof MAGIC_IS_REAL).toBe('boolean');
26+
});
27+
});`,
28+
});
29+
// Remove this test, we don't expect it to pass with our setup script.
30+
await harness.removeFile('src/app/app.component.spec.ts');
31+
32+
// Add src/magic.ts to tsconfig.
33+
interface TsConfig {
34+
files: string[];
35+
}
36+
const tsConfig = JSON.parse(harness.readFile('src/tsconfig.spec.json')) as TsConfig;
37+
tsConfig.files.push('magic.ts');
38+
await harness.writeFile('src/tsconfig.spec.json', JSON.stringify(tsConfig));
39+
});
40+
41+
it('uses custom setup file', async () => {
42+
harness.useTarget('test', {
43+
...BASE_OPTIONS,
44+
main: './src/magic.ts',
45+
});
46+
47+
const { result } = await harness.executeOnce();
48+
expect(result?.success).toBeTrue();
49+
});
50+
});
51+
});

0 commit comments

Comments
 (0)