fix(@angular-devkit/build-angular): only collect coverage from files 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
This commit is contained in:
Alan Agius 2018-08-28 22:50:25 +02:00 committed by vikerman
parent 7f67c64be1
commit 7eb080362f
4 changed files with 58 additions and 3 deletions

View File

@ -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;

View File

@ -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[] = [];
@ -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,
});
}

View File

@ -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 }),
@ -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,
) {
@ -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,

View File

@ -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);
});