Skip to content

Commit 725ea16

Browse files
committed
feat(@angular-devkit/build-angular): providing a karma config is now optional
Karma will now use a builtin config when the `karmaConfig` is not specified.
1 parent f567ffa commit 725ea16

File tree

2 files changed

+60
-13
lines changed

2 files changed

+60
-13
lines changed

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

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
*/
88

99
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
10-
import { Config, ConfigOptions } from 'karma';
10+
import { strings } from '@angular-devkit/core';
11+
import { Config, ConfigOptions, config, constants } from 'karma';
12+
import { createRequire } from 'module';
1113
import * as path from 'path';
1214
import { Observable, from } from 'rxjs';
1315
import { defaultIfEmpty, switchMap } from 'rxjs/operators';
@@ -90,9 +92,17 @@ export function execute(
9092

9193
return from(initialize(options, context, transforms.webpackConfiguration)).pipe(
9294
switchMap(async ([karma, webpackConfig]) => {
93-
const karmaOptions: KarmaConfigOptions = {
94-
singleRun,
95-
};
95+
// Determine project name from builder context target
96+
const projectName = context.target?.project;
97+
if (!projectName) {
98+
throw new Error(`The 'karma' builder requires a target to be specified.`);
99+
}
100+
101+
const karmaOptions: KarmaConfigOptions = options.main
102+
? getBuiltInKarmaConfig(context.workspaceRoot, projectName)
103+
: {};
104+
105+
karmaOptions.singleRun = singleRun;
96106

97107
// Convert browsers from a string to an array
98108
if (options.browsers) {
@@ -112,11 +122,6 @@ export function execute(
112122

113123
// prepend special webpack loader that will transform test.ts
114124
if (options.include?.length) {
115-
const projectName = context.target?.project;
116-
if (!projectName) {
117-
throw new Error('The builder requires a target.');
118-
}
119-
120125
const projectMetadata = await context.getProjectMetadata(projectName);
121126
const sourceRoot = (projectMetadata.sourceRoot ?? projectMetadata.root ?? '') as string;
122127
const projectSourceRoot = path.join(context.workspaceRoot, sourceRoot);
@@ -156,13 +161,13 @@ export function execute(
156161
logger: context.logger,
157162
};
158163

159-
const config = await karma.config.parseConfig(
160-
path.resolve(context.workspaceRoot, options.karmaConfig),
164+
const parsedKarmaConfig = await config.parseConfig(
165+
options.karmaConfig && path.resolve(context.workspaceRoot, options.karmaConfig),
161166
transforms.karmaOptions ? transforms.karmaOptions(karmaOptions) : karmaOptions,
162167
{ promiseConfig: true, throwErrors: true },
163168
);
164169

165-
return [karma, config] as [typeof karma, KarmaConfigOptions];
170+
return [karma, parsedKarmaConfig] as [typeof karma, KarmaConfigOptions];
166171
}),
167172
switchMap(
168173
([karma, karmaConfig]) =>
@@ -194,5 +199,47 @@ export function execute(
194199
);
195200
}
196201

202+
function getBuiltInKarmaConfig(
203+
workspaceRoot: string,
204+
projectName: string,
205+
): ConfigOptions & Record<string, unknown> {
206+
let coverageFolderName = projectName.charAt(0) === '@' ? projectName.slice(1) : projectName;
207+
if (/[A-Z]/.test(coverageFolderName)) {
208+
coverageFolderName = strings.dasherize(coverageFolderName);
209+
}
210+
211+
const workspaceRootRequire = createRequire(workspaceRoot + '/');
212+
213+
return {
214+
basePath: '',
215+
frameworks: ['jasmine', '@angular-devkit/build-angular'],
216+
plugins: [
217+
'karma-jasmine',
218+
'karma-chrome-launcher',
219+
'karma-jasmine-html-reporter',
220+
'karma-coverage',
221+
'@angular-devkit/build-angular/plugins/karma',
222+
].map((p) => workspaceRootRequire(p)),
223+
client: {
224+
clearContext: false, // leave Jasmine Spec Runner output visible in browser
225+
},
226+
jasmineHtmlReporter: {
227+
suppressAll: true, // removes the duplicated traces
228+
},
229+
coverageReporter: {
230+
dir: path.join(workspaceRoot, 'coverage', coverageFolderName),
231+
subdir: '.',
232+
reporters: [{ type: 'html' }, { type: 'text-summary' }],
233+
},
234+
reporters: ['progress', 'kjhtml'],
235+
port: 9876,
236+
colors: true,
237+
logLevel: constants.LOG_INFO,
238+
autoWatch: true,
239+
browsers: ['Chrome'],
240+
restartOnFileChange: true,
241+
};
242+
}
243+
197244
export { KarmaBuilderOptions };
198245
export default createBuilder<Record<string, string> & KarmaBuilderOptions>(execute);

packages/angular_devkit/build_angular/src/builders/karma/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@
240240
}
241241
},
242242
"additionalProperties": false,
243-
"required": ["main", "tsConfig", "karmaConfig"],
243+
"required": ["main", "tsConfig"],
244244
"definitions": {
245245
"assetPattern": {
246246
"oneOf": [

0 commit comments

Comments
 (0)