ci(compiler): run compiler tests in bazel (#22900)

PR Close #22900
This commit is contained in:
Chuck Jazdzewski 2018-03-20 17:02:50 -07:00 committed by Matias Niemelä
parent e44f69c387
commit 8ca26a9ebb
3 changed files with 113 additions and 30 deletions

View File

@ -1,18 +1,24 @@
load("//tools:defaults.bzl", "ts_library", "ts_web_test")
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
# Test that should only be run in node
NODE_ONLY = [
"**/*_node_only_spec.ts",
"aot/**/*.ts",
"render3/**/*.ts",
]
ts_library(
name = "test_lib",
testonly = 1,
srcs = glob(
["**/*.ts"],
exclude = ["**/*_node_only_spec.ts"],
exclude = NODE_ONLY,
),
deps = [
"//packages:types",
"//packages/common",
"//packages/compiler",
"//packages/compiler-cli",
"//packages/compiler/testing",
"//packages/core",
"//packages/core/testing",
@ -25,19 +31,25 @@ ts_library(
ts_library(
name = "test_node_only_lib",
testonly = 1,
srcs = glob(["**/*_node_only_spec.ts"]),
srcs = glob(NODE_ONLY),
deps = [
":test_lib",
"//packages/compiler",
"//packages/compiler-cli",
"//packages/compiler/testing",
"//packages/core",
],
)
jasmine_node_test(
name = "test",
bootstrap = ["angular/tools/testing/init_node_spec.js"],
data = [
"//packages/animations:npm_package",
"//packages/common:npm_package",
"//packages/core:npm_package",
],
# dissable since tests are running but not yet passing
tags = ["manual"],
deps = [
":test_lib",
":test_node_only_lib",
@ -49,7 +61,6 @@ jasmine_node_test(
ts_web_test(
name = "test_web",
# disable since tests are running but not yet passing
tags = ["manual"],
deps = [
":test_lib",
],

View File

@ -13,7 +13,7 @@ import {extractSourceMap, originalPositionFor} from '@angular/compiler/testing/s
import {NodeFlags} from '@angular/core/src/view/index';
import * as ts from 'typescript';
import {EmittingCompilerHost, MockAotCompilerHost, MockCompilerHost, MockDirectory, MockMetadataBundlerHost, arrayToMockDir, compile, expectNoDiagnostics, settings, setup, toMockFileArray} from './test_util';
import {EmittingCompilerHost, MockAotCompilerHost, MockCompilerHost, MockDirectory, MockMetadataBundlerHost, arrayToMockDir, compile, expectNoDiagnostics, isInBazel, settings, setup, toMockFileArray} from './test_util';
describe('compiler (unbundled Angular)', () => {
let angularFiles = setup();
@ -872,30 +872,31 @@ describe('compiler (unbundled Angular)', () => {
});
describe('compiler (bundled Angular)', () => {
setup({compileAngular: false, compileAnimations: false});
let angularFiles: Map<string, string>;
let angularFiles: Map<string, string> = setup();
beforeAll(() => {
const emittingHost = new EmittingCompilerHost(['@angular/core/index'], {emitMetadata: false});
if (!isInBazel()) {
// If we are not using Bazel then we need to build these files explicitly
const emittingHost = new EmittingCompilerHost(['@angular/core/index'], {emitMetadata: false});
// Create the metadata bundled
const indexModule = emittingHost.effectiveName('@angular/core/index');
const bundler = new MetadataBundler(
indexModule, '@angular/core', new MockMetadataBundlerHost(emittingHost));
const bundle = bundler.getMetadataBundle();
const metadata = JSON.stringify(bundle.metadata, null, ' ');
const bundleIndexSource = privateEntriesToIndex('./index', bundle.privates);
emittingHost.override('@angular/core/bundle_index.ts', bundleIndexSource);
emittingHost.addWrittenFile(
'@angular/core/package.json', JSON.stringify({typings: 'bundle_index.d.ts'}));
emittingHost.addWrittenFile('@angular/core/bundle_index.metadata.json', metadata);
// Create the metadata bundled
const indexModule = emittingHost.effectiveName('@angular/core/index');
const bundler = new MetadataBundler(
indexModule, '@angular/core', new MockMetadataBundlerHost(emittingHost));
const bundle = bundler.getMetadataBundle();
const metadata = JSON.stringify(bundle.metadata, null, ' ');
const bundleIndexSource = privateEntriesToIndex('./index', bundle.privates);
emittingHost.override('@angular/core/bundle_index.ts', bundleIndexSource);
emittingHost.addWrittenFile(
'@angular/core/package.json', JSON.stringify({typings: 'bundle_index.d.ts'}));
emittingHost.addWrittenFile('@angular/core/bundle_index.metadata.json', metadata);
// Emit the sources
const bundleIndexName = emittingHost.effectiveName('@angular/core/bundle_index.ts');
const emittingProgram = ts.createProgram([bundleIndexName], settings, emittingHost);
emittingProgram.emit();
angularFiles = emittingHost.writtenAngularFiles();
// Emit the sources
const bundleIndexName = emittingHost.effectiveName('@angular/core/bundle_index.ts');
const emittingProgram = ts.createProgram([bundleIndexName], settings, emittingHost);
emittingProgram.emit();
angularFiles = emittingHost.writtenAngularFiles();
}
});
describe('Quickstart', () => {
@ -922,6 +923,11 @@ describe('compiler (bundled Angular)', () => {
const emittingHost =
new EmittingCompilerHost(['/bolder/index.ts'], {emitMetadata: false, mockData: LIBRARY});
if (isInBazel()) {
// In bazel we can just add the angular files from the ones read during setup.
emittingHost.addFiles(angularFiles);
}
// Create the metadata bundled
const indexModule = '/bolder/public-api';
const bundler =

View File

@ -60,8 +60,6 @@ export interface EmitterOptions {
function calcPathsOnDisc() {
const moduleFilename = module.filename.replace(/\\/g, '/');
// TODO(i): this is suspicious because it relies on build.sh output
// which is problematic when we are running tests under bazel - review with Chuck
const distIndex = moduleFilename.indexOf('/dist/all');
if (distIndex >= 0) {
rootPath = moduleFilename.substr(0, distIndex);
@ -83,7 +81,7 @@ export class EmittingCompilerHost implements ts.CompilerHost {
// Rewrite references to scripts with '@angular' to its corresponding location in
// the source tree.
this.scriptNames = scriptNames.map(f => this.effectiveName(f));
this.root = rootPath;
this.root = rootPath || this.root;
if (options.context) {
this.addedFiles = mergeMaps(options.context);
}
@ -110,6 +108,12 @@ export class EmittingCompilerHost implements ts.CompilerHost {
this.cachedAddedDirectories = undefined;
}
public addFiles(map: Map<string, string>) {
for (const [name, content] of Array.from(map.entries())) {
this.addedFiles.set(name, content);
}
}
public addWrittenFile(fileName: string, content: string) {
this.writtenFiles.set(this.effectiveName(fileName), content);
}
@ -124,7 +128,7 @@ export class EmittingCompilerHost implements ts.CompilerHost {
public effectiveName(fileName: string): string {
const prefix = '@angular/';
return fileName.startsWith('@angular/') ?
return angularSourcePath && fileName.startsWith(prefix) ?
path.join(angularSourcePath, fileName.substr(prefix.length)) :
fileName;
}
@ -566,6 +570,38 @@ const minCoreIndex = `
export * from './src/codegen_private_exports';
`;
function readBazelWrittenFilesFrom(
bazelPackageRoot: string, packageName: string, map: Map<string, string>,
skip: (name: string, fullName: string) => boolean = () => false) {
function processDirectory(dir: string, dest: string) {
const entries = fs.readdirSync(dir);
for (const name of entries) {
const fullName = path.join(dir, name);
const destName = path.join(dest, name);
const stat = fs.statSync(fullName);
if (!skip(name, fullName)) {
if (stat.isDirectory()) {
processDirectory(fullName, destName);
} else {
const content = fs.readFileSync(fullName, 'utf8');
map.set(destName, content);
}
}
}
}
try {
processDirectory(bazelPackageRoot, path.join('/node_modules/@angular', packageName));
} catch (e) {
console.error(
`Consider adding //packages/${packageName} as a data dependency in the BUILD.bazel rule for the failing test`);
throw e;
}
}
export function isInBazel(): boolean {
return process.env.TEST_SRCDIR != null;
}
export function setup(
options: {compileAngular: boolean, compileAnimations: boolean, compileCommon?: boolean} = {
compileAngular: true,
@ -575,6 +611,36 @@ export function setup(
let angularFiles = new Map<string, string>();
beforeAll(() => {
const sources = process.env.TEST_SRCDIR;
if (sources) {
// If running under bazel then we get the compiled version of the files from the bazel package
// output.
const bundles = new Set([
'bundles', 'esm2015', 'esm5', 'testing', 'testing.d.ts', 'testing.metadata.json', 'browser',
'browser.d.ts'
]);
const skipDirs = (name: string) => bundles.has(name);
if (options.compileAngular) {
// If this fails please add //packages/core:npm_package as a test data dependency.
readBazelWrittenFilesFrom(
path.join(sources, 'angular/packages/core/npm_package'), 'core', angularFiles,
skipDirs);
}
if (options.compileAnimations) {
// If this fails please add //packages/animations:npm_package as a test data dependency.
readBazelWrittenFilesFrom(
path.join(sources, 'angular/packages/animations/npm_package'), 'animations',
angularFiles, skipDirs);
}
if (options.compileCommon) {
// If this fails please add //packages/common:npm_package as a test data dependency.
readBazelWrittenFilesFrom(
path.join(sources, 'angular/packages/common/npm_package'), 'common', angularFiles,
skipDirs);
}
return;
}
if (options.compileAngular) {
const emittingHost = new EmittingCompilerHost([], {emitMetadata: true});
emittingHost.addScript('@angular/core/index.ts', minCoreIndex);