Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): only collect coverage from files …
Browse files Browse the repository at this point in the history
…under `sourceRoot` (#11974)

In some cases when having libraries within the workspace this is causing a `Maximum call stack size exceeded`, Also for libraries coverage should be collected with the respective `ng test`

Closes #11934
  • Loading branch information
alan-agius4 authored and vikerman committed Aug 28, 2018
1 parent 7f67c64 commit 7eb0803
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export interface WebpackTestOptions extends BuildOptions {
export interface WebpackConfigOptions<T = BuildOptions> {
root: string;
projectRoot: string;
sourceRoot?: string;
buildOptions: T;
tsConfig: ts.ParsedCommandLine;
tsConfigPath: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { WebpackConfigOptions, WebpackTestOptions } from '../build-options';
export function getTestConfig(
wco: WebpackConfigOptions<WebpackTestOptions>,
): webpack.Configuration {
const { root, buildOptions } = wco;
const { root, buildOptions, sourceRoot: include } = wco;

const extraRules: webpack.Rule[] = [];
const extraPlugins: webpack.Plugin[] = [];
Expand All @@ -46,10 +46,12 @@ export function getTestConfig(
}

extraRules.push({
test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader',
test: /\.(js|ts)$/,
loader: 'istanbul-instrumenter-loader',
options: { esModules: true },
enforce: 'post',
exclude,
include,
});
}

Expand Down
6 changes: 5 additions & 1 deletion packages/angular_devkit/build_angular/src/karma/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,13 @@ export class KarmaBuilder implements Builder<KarmaBuilderSchema> {
karmaOptions.browsers = options.browsers.split(',');
}

const sourceRoot = builderConfig.sourceRoot && resolve(root, builderConfig.sourceRoot);

karmaOptions.buildWebpack = {
root: getSystemPath(root),
projectRoot: getSystemPath(projectRoot),
options: options as NormalizedKarmaBuilderSchema,
webpackConfig: this._buildWebpackConfig(root, projectRoot, host,
webpackConfig: this._buildWebpackConfig(root, projectRoot, sourceRoot, host,
options as NormalizedKarmaBuilderSchema),
// Pass onto Karma to emit BuildEvents.
successCb: () => obs.next({ success: true }),
Expand Down Expand Up @@ -108,6 +110,7 @@ export class KarmaBuilder implements Builder<KarmaBuilderSchema> {
private _buildWebpackConfig(
root: Path,
projectRoot: Path,
sourceRoot: Path | undefined,
host: virtualFs.Host<fs.Stats>,
options: NormalizedKarmaBuilderSchema,
) {
Expand All @@ -130,6 +133,7 @@ export class KarmaBuilder implements Builder<KarmaBuilderSchema> {
wco = {
root: getSystemPath(root),
projectRoot: getSystemPath(projectRoot),
sourceRoot: sourceRoot && getSystemPath(sourceRoot),
// TODO: use only this.options, it contains all flags and configs items already.
buildOptions: compatOptions,
tsConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,52 @@ describe('Karma Builder code coverage', () => {
}),
).toPromise().then(done, done.fail);
}, 120000);

it(`should collect coverage from paths in 'sourceRoot'`, (done) => {
const overrides: Partial<NormalizedKarmaBuilderSchema> = { codeCoverage: true };

const files: { [path: string]: string } = {
'./dist/my-lib/index.d.ts': `
export declare const title = 'app';
`,
'./dist/my-lib/index.js': `
export const title = 'app';
`,
'./src/app/app.component.ts': `
import { Component } from '@angular/core';
import { title } from 'my-lib';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = title;
}
`,
};

host.writeMultipleFiles(files);

host.replaceInFile('tsconfig.json', /"baseUrl": ".\/",/, `
"baseUrl": "./",
"paths": {
"my-lib": [
"./dist/my-lib"
]
},
`);

runTargetSpec(host, karmaTargetSpec, overrides).pipe(
// It seems like the coverage files take a while being written to disk, so we wait 500ms here.
debounceTime(500),
tap(buildEvent => {
expect(buildEvent.success).toBe(true);
expect(host.scopedSync().exists(coverageFilePath)).toBe(true);
const content = virtualFs.fileBufferToString(host.scopedSync().read(coverageFilePath));
expect(content).not.toContain('my-lib');
}),
).toPromise().then(done, done.fail);
}, 120000);
});

0 comments on commit 7eb0803

Please sign in to comment.