ci(compiler-cli): run compiler-cli tests in bazel (#22997)
PR Close #22997
This commit is contained in:
parent
d9dc46e651
commit
4e004f3783
|
@ -266,9 +266,6 @@ export interface TsEmitArguments {
|
|||
export interface TsEmitCallback { (args: TsEmitArguments): ts.EmitResult; }
|
||||
export interface TsMergeEmitResultsCallback { (results: ts.EmitResult[]): ts.EmitResult; }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface LibrarySummary {
|
||||
fileName: string;
|
||||
text: string;
|
||||
|
@ -371,8 +368,6 @@ export interface Program {
|
|||
* Returns the .d.ts / .ngsummary.json / .ngfactory.d.ts files of libraries that have been emitted
|
||||
* in this program or previous programs with paths that emulate the fact that these libraries
|
||||
* have been compiled before with no outDir.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getLibrarySummaries(): Map<string, LibrarySummary>;
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
load("//tools:defaults.bzl", "ts_library", "ts_web_test")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
|
||||
|
||||
# Uses separate test rules to allow the tests to run in parallel
|
||||
|
||||
ts_library(
|
||||
name = "test_utils",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"mocks.ts",
|
||||
"test_support.ts",
|
||||
],
|
||||
visibility = [":__subpackages__"],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
],
|
||||
)
|
||||
|
||||
# extract_18n_spec
|
||||
ts_library(
|
||||
name = "extract_i18n_lib",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"extract_i18n_spec.ts",
|
||||
],
|
||||
deps = [
|
||||
":test_utils",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "extract_i18n",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
"//packages/core:npm_package",
|
||||
],
|
||||
deps = [
|
||||
":extract_i18n_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
||||
|
||||
# ngc_spec
|
||||
ts_library(
|
||||
name = "ngc_lib",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"ngc_spec.ts",
|
||||
],
|
||||
deps = [
|
||||
":test_utils",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "ngc",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
"//packages/common:npm_package",
|
||||
"//packages/core:npm_package",
|
||||
"//packages/platform-browser:npm_package",
|
||||
],
|
||||
deps = [
|
||||
":ngc_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
||||
|
||||
# ngctools_api_spec
|
||||
ts_library(
|
||||
name = "ngtools_api_lib",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"ngtools_api_spec.ts",
|
||||
],
|
||||
deps = [
|
||||
":test_utils",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "ngtools_api",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
"//packages/core:npm_package",
|
||||
"//packages/router:npm_package",
|
||||
],
|
||||
deps = [
|
||||
":ngtools_api_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
||||
|
||||
# perform_watch_spec
|
||||
ts_library(
|
||||
name = "perform_watch_lib",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"perform_watch_spec.ts",
|
||||
],
|
||||
deps = [
|
||||
":test_utils",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "perform_watch",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
"//packages/core:npm_package",
|
||||
],
|
||||
deps = [
|
||||
":perform_watch_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,99 @@
|
|||
load("//tools:defaults.bzl", "ts_library", "ts_web_test")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
|
||||
|
||||
ts_library(
|
||||
name = "mocks",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"mocks.ts",
|
||||
],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
"//packages/compiler-cli/test:test_utils",
|
||||
"//packages/core",
|
||||
],
|
||||
)
|
||||
|
||||
# check_types_spec
|
||||
ts_library(
|
||||
name = "check_types_lib",
|
||||
testonly = 1,
|
||||
srcs = ["check_types_spec.ts"],
|
||||
deps = [
|
||||
":mocks",
|
||||
"//packages/compiler-cli",
|
||||
"//packages/compiler-cli/test:test_utils",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "check_types",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
"//packages/common:npm_package",
|
||||
"//packages/core:npm_package",
|
||||
],
|
||||
deps = [
|
||||
":check_types_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
||||
|
||||
# expression_diagnostics_spec
|
||||
ts_library(
|
||||
name = "expression_diagnostics_lib",
|
||||
testonly = 1,
|
||||
srcs = ["expression_diagnostics_spec.ts"],
|
||||
deps = [
|
||||
":mocks",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
"//packages/compiler-cli/test:test_utils",
|
||||
"//packages/language-service",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "expression_diagnostics",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
"//packages/common:npm_package",
|
||||
"//packages/core:npm_package",
|
||||
"//packages/forms:npm_package",
|
||||
],
|
||||
deps = [
|
||||
":expression_diagnostics_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
||||
|
||||
# symbol_query_spec
|
||||
ts_library(
|
||||
name = "symbol_query_lib",
|
||||
testonly = 1,
|
||||
srcs = ["symbol_query_spec.ts"],
|
||||
deps = [
|
||||
":mocks",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
"//packages/compiler-cli/test:test_utils",
|
||||
"//packages/compiler/test:test_utils",
|
||||
"//packages/language-service",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "symbol_query",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
],
|
||||
deps = [
|
||||
":symbol_query_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
|
@ -19,6 +19,7 @@ import {DiagnosticContext, MockLanguageServiceHost, getDiagnosticTemplateInfo} f
|
|||
|
||||
describe('expression diagnostics', () => {
|
||||
let registry: ts.DocumentRegistry;
|
||||
|
||||
let host: MockLanguageServiceHost;
|
||||
let service: ts.LanguageService;
|
||||
let context: DiagnosticContext;
|
||||
|
|
|
@ -15,11 +15,17 @@ import * as ts from 'typescript';
|
|||
import {DiagnosticTemplateInfo} from '../../src/diagnostics/expression_diagnostics';
|
||||
import {getClassFromStaticSymbol, getClassMembers, getPipesTable, getSymbolQuery} from '../../src/diagnostics/typescript_symbols';
|
||||
import {Directory, MockAotContext} from '../mocks';
|
||||
import {isInBazel, setup} from '../test_support';
|
||||
|
||||
function calcRootPath() {
|
||||
const moduleFilename = module.filename.replace(/\\/g, '/');
|
||||
const distIndex = moduleFilename.indexOf('/dist/all');
|
||||
return moduleFilename.substr(0, distIndex);
|
||||
function calculateAngularPath() {
|
||||
if (isInBazel()) {
|
||||
const support = setup();
|
||||
return path.join(support.basePath, 'node_modules/@angular/*');
|
||||
} else {
|
||||
const moduleFilename = module.filename.replace(/\\/g, '/');
|
||||
const distIndex = moduleFilename.indexOf('/dist/all');
|
||||
return moduleFilename.substr(0, distIndex) + '/packages/*';
|
||||
}
|
||||
}
|
||||
|
||||
const realFiles = new Map<string, string>();
|
||||
|
@ -43,7 +49,7 @@ export class MockLanguageServiceHost implements ts.LanguageServiceHost {
|
|||
strictNullChecks: true,
|
||||
baseUrl: currentDirectory,
|
||||
lib: ['lib.es2015.d.ts', 'lib.dom.d.ts'],
|
||||
paths: {'@angular/*': [calcRootPath() + '/packages/*']}
|
||||
paths: {'@angular/*': [calculateAngularPath()]}
|
||||
};
|
||||
this.context = new MockAotContext(currentDirectory, files);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import * as ts from 'typescript';
|
|||
|
||||
import {mainXi18n} from '../src/extract_i18n';
|
||||
|
||||
import {makeTempDir} from './test_support';
|
||||
import {isInBazel, makeTempDir, setup} from './test_support';
|
||||
|
||||
function getNgRootDir() {
|
||||
const moduleFilename = module.filename.replace(/\\/g, '/');
|
||||
|
@ -110,15 +110,31 @@ describe('extract_i18n command line', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
errorSpy = jasmine.createSpy('consoleError').and.callFake(console.error);
|
||||
basePath = makeTempDir();
|
||||
write = (fileName: string, content: string) => {
|
||||
const dir = path.dirname(fileName);
|
||||
if (dir != '.') {
|
||||
const newDir = path.join(basePath, dir);
|
||||
if (!fs.existsSync(newDir)) fs.mkdirSync(newDir);
|
||||
}
|
||||
fs.writeFileSync(path.join(basePath, fileName), content, {encoding: 'utf-8'});
|
||||
};
|
||||
if (isInBazel()) {
|
||||
const support = setup();
|
||||
write = (fileName: string, content: string) => { support.write(fileName, content); };
|
||||
basePath = support.basePath;
|
||||
outDir = path.join(basePath, 'built');
|
||||
} else {
|
||||
basePath = makeTempDir();
|
||||
write = (fileName: string, content: string) => {
|
||||
const dir = path.dirname(fileName);
|
||||
if (dir != '.') {
|
||||
const newDir = path.join(basePath, dir);
|
||||
if (!fs.existsSync(newDir)) fs.mkdirSync(newDir);
|
||||
}
|
||||
fs.writeFileSync(path.join(basePath, fileName), content, {encoding: 'utf-8'});
|
||||
};
|
||||
outDir = path.resolve(basePath, 'built');
|
||||
const ngRootDir = getNgRootDir();
|
||||
const nodeModulesPath = path.resolve(basePath, 'node_modules');
|
||||
fs.mkdirSync(nodeModulesPath);
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'dist', 'all', '@angular'),
|
||||
path.resolve(nodeModulesPath, '@angular'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'rxjs'), path.resolve(nodeModulesPath, 'rxjs'));
|
||||
}
|
||||
write('tsconfig-base.json', `{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
|
@ -136,15 +152,6 @@ describe('extract_i18n command line', () => {
|
|||
"typeRoots": ["node_modules/@types"]
|
||||
}
|
||||
}`);
|
||||
outDir = path.resolve(basePath, 'built');
|
||||
const ngRootDir = getNgRootDir();
|
||||
const nodeModulesPath = path.resolve(basePath, 'node_modules');
|
||||
fs.mkdirSync(nodeModulesPath);
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'dist', 'all', '@angular'),
|
||||
path.resolve(nodeModulesPath, '@angular'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'rxjs'), path.resolve(nodeModulesPath, 'rxjs'));
|
||||
});
|
||||
|
||||
function writeSources() {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
load("//tools:defaults.bzl", "ts_library", "ts_web_test")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
|
||||
|
||||
ts_library(
|
||||
name = "test_lib",
|
||||
testonly = 1,
|
||||
srcs = glob(["**/*.ts"]),
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
"//packages/core",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "test",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
],
|
||||
deps = [
|
||||
":test_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
|
@ -877,7 +877,7 @@ describe('Collector', () => {
|
|||
export const InjectionToken: {new<T>(desc: string): InjectionToken<T>;} = class {
|
||||
constructor(protected _desc: string) {}
|
||||
|
||||
toString(): string { return \`InjectionToken ${this._desc}\`; }
|
||||
toString(): string { return \`InjectionToken \${this._desc}\`; }
|
||||
} as any;`,
|
||||
ts.ScriptTarget.Latest, true);
|
||||
const metadata = collector.getMetadata(source) !;
|
||||
|
|
|
@ -11,7 +11,8 @@ import * as path from 'path';
|
|||
import * as ts from 'typescript';
|
||||
|
||||
import {main, readCommandLineAndConfiguration, watchMode} from '../src/main';
|
||||
import {makeTempDir} from './test_support';
|
||||
|
||||
import {isInBazel, makeTempDir, setup} from './test_support';
|
||||
|
||||
function getNgRootDir() {
|
||||
const moduleFilename = module.filename.replace(/\\/g, '/');
|
||||
|
@ -43,16 +44,33 @@ describe('ngc transformer command-line', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
errorSpy = jasmine.createSpy('consoleError').and.callFake(console.error);
|
||||
basePath = makeTempDir();
|
||||
process.chdir(basePath);
|
||||
write = (fileName: string, content: string) => {
|
||||
const dir = path.dirname(fileName);
|
||||
if (dir != '.') {
|
||||
const newDir = path.join(basePath, dir);
|
||||
if (!fs.existsSync(newDir)) fs.mkdirSync(newDir);
|
||||
}
|
||||
fs.writeFileSync(path.join(basePath, fileName), content, {encoding: 'utf-8'});
|
||||
};
|
||||
if (isInBazel) {
|
||||
const support = setup();
|
||||
basePath = support.basePath;
|
||||
outDir = path.join(basePath, 'built');
|
||||
process.chdir(basePath);
|
||||
write = (fileName: string, content: string) => { support.write(fileName, content); };
|
||||
} else {
|
||||
basePath = makeTempDir();
|
||||
process.chdir(basePath);
|
||||
write = (fileName: string, content: string) => {
|
||||
const dir = path.dirname(fileName);
|
||||
if (dir != '.') {
|
||||
const newDir = path.join(basePath, dir);
|
||||
if (!fs.existsSync(newDir)) fs.mkdirSync(newDir);
|
||||
}
|
||||
fs.writeFileSync(path.join(basePath, fileName), content, {encoding: 'utf-8'});
|
||||
};
|
||||
outDir = path.resolve(basePath, 'built');
|
||||
const ngRootDir = getNgRootDir();
|
||||
const nodeModulesPath = path.resolve(basePath, 'node_modules');
|
||||
fs.mkdirSync(nodeModulesPath);
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'dist', 'all', '@angular'),
|
||||
path.resolve(nodeModulesPath, '@angular'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'rxjs'), path.resolve(nodeModulesPath, 'rxjs'));
|
||||
}
|
||||
write('tsconfig-base.json', `{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
|
@ -70,15 +88,6 @@ describe('ngc transformer command-line', () => {
|
|||
"typeRoots": ["node_modules/@types"]
|
||||
}
|
||||
}`);
|
||||
outDir = path.resolve(basePath, 'built');
|
||||
const ngRootDir = getNgRootDir();
|
||||
const nodeModulesPath = path.resolve(basePath, 'node_modules');
|
||||
fs.mkdirSync(nodeModulesPath);
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'dist', 'all', '@angular'),
|
||||
path.resolve(nodeModulesPath, '@angular'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'rxjs'), path.resolve(nodeModulesPath, 'rxjs'));
|
||||
});
|
||||
|
||||
it('should compile without errors', () => {
|
||||
|
@ -243,10 +252,19 @@ describe('ngc transformer command-line', () => {
|
|||
expect(exitCode).toEqual(0);
|
||||
|
||||
expect(fs.existsSync(path.resolve(outDir, 'mymodule.ngfactory.js'))).toBe(true);
|
||||
expect(fs.existsSync(path.resolve(
|
||||
outDir, 'node_modules', '@angular', 'core', 'src',
|
||||
'application_module.ngfactory.js')))
|
||||
.toBe(true);
|
||||
|
||||
if (isInBazel()) {
|
||||
// In bazel we use the packaged version so the factory is at the root and we
|
||||
// get the flattened factory.
|
||||
expect(fs.existsSync(
|
||||
path.resolve(outDir, 'node_modules', '@angular', 'core', 'core.ngfactory.js')))
|
||||
.toBe(true);
|
||||
} else {
|
||||
expect(fs.existsSync(path.resolve(
|
||||
outDir, 'node_modules', '@angular', 'core', 'src',
|
||||
'application_module.ngfactory.js')))
|
||||
.toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
describe('comments', () => {
|
||||
|
@ -351,10 +369,18 @@ describe('ngc transformer command-line', () => {
|
|||
const exitCode = main(['-p', path.join(basePath, 'tsconfig.json')], errorSpy);
|
||||
expect(exitCode).toEqual(0);
|
||||
expect(fs.existsSync(path.resolve(outDir, 'mymodule.ngfactory.js'))).toBe(true);
|
||||
expect(fs.existsSync(path.resolve(
|
||||
outDir, 'node_modules', '@angular', 'core', 'src',
|
||||
'application_module.ngfactory.js')))
|
||||
.toBe(true);
|
||||
if (isInBazel()) {
|
||||
// In bazel we use the packaged version so the factory is at the root and we
|
||||
// get the flattened factory.
|
||||
expect(fs.existsSync(
|
||||
path.resolve(outDir, 'node_modules', '@angular', 'core', 'core.ngfactory.js')))
|
||||
.toBe(true);
|
||||
} else {
|
||||
expect(fs.existsSync(path.resolve(
|
||||
outDir, 'node_modules', '@angular', 'core', 'src',
|
||||
'application_module.ngfactory.js')))
|
||||
.toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
describe(`emit generated files depending on the source file`, () => {
|
||||
|
@ -1124,7 +1150,10 @@ describe('ngc transformer command-line', () => {
|
|||
}
|
||||
`);
|
||||
|
||||
expect(main(['-p', path.join(basePath, 'tsconfig-ng.json')], errorSpy)).toBe(0);
|
||||
if (!isInBazel()) {
|
||||
// This is not necessary in bazel as it uses the npm_package
|
||||
expect(main(['-p', path.join(basePath, 'tsconfig-ng.json')], errorSpy)).toBe(0);
|
||||
}
|
||||
expect(main(['-p', path.join(basePath, 'lib1', 'tsconfig-lib1.json')], errorSpy)).toBe(0);
|
||||
expect(main(['-p', path.join(basePath, 'lib2', 'tsconfig-lib2.json')], errorSpy)).toBe(0);
|
||||
expect(main(['-p', path.join(basePath, 'app', 'tsconfig-app.json')], errorSpy)).toBe(0);
|
||||
|
@ -1161,106 +1190,109 @@ describe('ngc transformer command-line', () => {
|
|||
shouldExist('app/main.js');
|
||||
});
|
||||
|
||||
it('should be able to compile libraries with summaries and flat modules', () => {
|
||||
writeFiles();
|
||||
compile();
|
||||
if (!isInBazel()) {
|
||||
// This is an unnecessary test bazel as it always uses flat modules
|
||||
it('should be able to compile libraries with summaries and flat modules', () => {
|
||||
writeFiles();
|
||||
compile();
|
||||
|
||||
// libraries
|
||||
// make `shouldExist` / `shouldNotExist` relative to `node_modules`
|
||||
outDir = path.resolve(basePath, 'node_modules');
|
||||
shouldExist('flat_module/index.ngfactory.js');
|
||||
shouldExist('flat_module/index.ngsummary.json');
|
||||
// libraries
|
||||
// make `shouldExist` / `shouldNotExist` relative to `node_modules`
|
||||
outDir = path.resolve(basePath, 'node_modules');
|
||||
shouldExist('flat_module/index.ngfactory.js');
|
||||
shouldExist('flat_module/index.ngsummary.json');
|
||||
|
||||
// app
|
||||
// make `shouldExist` / `shouldNotExist` relative to `built`
|
||||
outDir = path.resolve(basePath, 'built');
|
||||
shouldExist('app/main.ngfactory.js');
|
||||
// app
|
||||
// make `shouldExist` / `shouldNotExist` relative to `built`
|
||||
outDir = path.resolve(basePath, 'built');
|
||||
shouldExist('app/main.ngfactory.js');
|
||||
|
||||
const factory = fs.readFileSync(path.resolve(outDir, 'app/main.ngfactory.js')).toString();
|
||||
// reference to the module itself
|
||||
expect(factory).toMatch(/from "flat_module"/);
|
||||
// no reference to a deep file
|
||||
expect(factory).not.toMatch(/from "flat_module\//);
|
||||
const factory = fs.readFileSync(path.resolve(outDir, 'app/main.ngfactory.js')).toString();
|
||||
// reference to the module itself
|
||||
expect(factory).toMatch(/from "flat_module"/);
|
||||
// no reference to a deep file
|
||||
expect(factory).not.toMatch(/from "flat_module\//);
|
||||
|
||||
function writeFiles() {
|
||||
createFlatModuleInNodeModules();
|
||||
function writeFiles() {
|
||||
createFlatModuleInNodeModules();
|
||||
|
||||
// Angular + flat module
|
||||
write('tsconfig-lib.json', `{
|
||||
"extends": "./tsconfig-base.json",
|
||||
"angularCompilerOptions": {
|
||||
"generateCodeForLibraries": true
|
||||
},
|
||||
"compilerOptions": {
|
||||
"outDir": "."
|
||||
},
|
||||
"include": ["node_modules/@angular/core/**/*", "node_modules/flat_module/**/*"],
|
||||
"exclude": [
|
||||
"node_modules/@angular/core/test/**",
|
||||
"node_modules/@angular/core/testing/**"
|
||||
]
|
||||
}`);
|
||||
// Angular + flat module
|
||||
write('tsconfig-lib.json', `{
|
||||
"extends": "./tsconfig-base.json",
|
||||
"angularCompilerOptions": {
|
||||
"generateCodeForLibraries": true
|
||||
},
|
||||
"compilerOptions": {
|
||||
"outDir": "."
|
||||
},
|
||||
"include": ["node_modules/@angular/core/**/*", "node_modules/flat_module/**/*"],
|
||||
"exclude": [
|
||||
"node_modules/@angular/core/test/**",
|
||||
"node_modules/@angular/core/testing/**"
|
||||
]
|
||||
}`);
|
||||
|
||||
// Application
|
||||
write('app/tsconfig-app.json', `{
|
||||
"extends": "../tsconfig-base.json",
|
||||
"angularCompilerOptions": {
|
||||
"generateCodeForLibraries": false
|
||||
},
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"outDir": "../built/app"
|
||||
}
|
||||
}`);
|
||||
write('app/main.ts', `
|
||||
import {NgModule} from '@angular/core';
|
||||
import {FlatModule} from 'flat_module';
|
||||
|
||||
@NgModule({
|
||||
imports: [FlatModule]
|
||||
})
|
||||
export class AppModule {}
|
||||
`);
|
||||
}
|
||||
|
||||
function createFlatModuleInNodeModules() {
|
||||
// compile the flat module
|
||||
writeFlatModule('index.js');
|
||||
expect(main(['-p', basePath], errorSpy)).toBe(0);
|
||||
|
||||
// move the flat module output into node_modules
|
||||
const flatModuleNodeModulesPath = path.resolve(basePath, 'node_modules', 'flat_module');
|
||||
fs.renameSync(outDir, flatModuleNodeModulesPath);
|
||||
fs.renameSync(
|
||||
path.resolve(basePath, 'src/flat.component.html'),
|
||||
path.resolve(flatModuleNodeModulesPath, 'src/flat.component.html'));
|
||||
// and remove the sources.
|
||||
fs.renameSync(path.resolve(basePath, 'src'), path.resolve(basePath, 'flat_module_src'));
|
||||
fs.unlinkSync(path.resolve(basePath, 'public-api.ts'));
|
||||
|
||||
// add a flatModuleIndexRedirect
|
||||
write('node_modules/flat_module/redirect.metadata.json', `{
|
||||
"__symbolic": "module",
|
||||
"version": 3,
|
||||
"metadata": {},
|
||||
"exports": [
|
||||
{
|
||||
"from": "./index"
|
||||
// Application
|
||||
write('app/tsconfig-app.json', `{
|
||||
"extends": "../tsconfig-base.json",
|
||||
"angularCompilerOptions": {
|
||||
"generateCodeForLibraries": false
|
||||
},
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"outDir": "../built/app"
|
||||
}
|
||||
],
|
||||
"flatModuleIndexRedirect": true,
|
||||
"importAs": "flat_module"
|
||||
}`);
|
||||
write('node_modules/flat_module/redirect.d.ts', `export * from './index';`);
|
||||
// add a package.json to use the redirect
|
||||
write('node_modules/flat_module/package.json', `{"typings": "./redirect.d.ts"}`);
|
||||
}
|
||||
}`);
|
||||
write('app/main.ts', `
|
||||
import {NgModule} from '@angular/core';
|
||||
import {FlatModule} from 'flat_module';
|
||||
|
||||
function compile() {
|
||||
expect(main(['-p', path.join(basePath, 'tsconfig-lib.json')], errorSpy)).toBe(0);
|
||||
expect(main(['-p', path.join(basePath, 'app', 'tsconfig-app.json')], errorSpy)).toBe(0);
|
||||
}
|
||||
});
|
||||
@NgModule({
|
||||
imports: [FlatModule]
|
||||
})
|
||||
export class AppModule {}
|
||||
`);
|
||||
}
|
||||
|
||||
function createFlatModuleInNodeModules() {
|
||||
// compile the flat module
|
||||
writeFlatModule('index.js');
|
||||
expect(main(['-p', basePath], errorSpy)).toBe(0);
|
||||
|
||||
// move the flat module output into node_modules
|
||||
const flatModuleNodeModulesPath = path.resolve(basePath, 'node_modules', 'flat_module');
|
||||
fs.renameSync(outDir, flatModuleNodeModulesPath);
|
||||
fs.renameSync(
|
||||
path.resolve(basePath, 'src/flat.component.html'),
|
||||
path.resolve(flatModuleNodeModulesPath, 'src/flat.component.html'));
|
||||
// and remove the sources.
|
||||
fs.renameSync(path.resolve(basePath, 'src'), path.resolve(basePath, 'flat_module_src'));
|
||||
fs.unlinkSync(path.resolve(basePath, 'public-api.ts'));
|
||||
|
||||
// add a flatModuleIndexRedirect
|
||||
write('node_modules/flat_module/redirect.metadata.json', `{
|
||||
"__symbolic": "module",
|
||||
"version": 3,
|
||||
"metadata": {},
|
||||
"exports": [
|
||||
{
|
||||
"from": "./index"
|
||||
}
|
||||
],
|
||||
"flatModuleIndexRedirect": true,
|
||||
"importAs": "flat_module"
|
||||
}`);
|
||||
write('node_modules/flat_module/redirect.d.ts', `export * from './index';`);
|
||||
// add a package.json to use the redirect
|
||||
write('node_modules/flat_module/package.json', `{"typings": "./redirect.d.ts"}`);
|
||||
}
|
||||
|
||||
function compile() {
|
||||
expect(main(['-p', path.join(basePath, 'tsconfig-lib.json')], errorSpy)).toBe(0);
|
||||
expect(main(['-p', path.join(basePath, 'app', 'tsconfig-app.json')], errorSpy)).toBe(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('enableResourceInlining', () => {
|
||||
it('should inline templateUrl and styleUrl in JS and metadata', () => {
|
||||
|
@ -1308,6 +1340,7 @@ describe('ngc transformer command-line', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('expression lowering', () => {
|
||||
const shouldExist = (fileName: string) => {
|
||||
if (!fs.existsSync(path.resolve(basePath, fileName))) {
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {__NGTOOLS_PRIVATE_API_2 as NgTools_InternalApi_NG_2} from '@angular/compiler-cli';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {NgTools_InternalApi_NG_2} from '../src/ngtools_api';
|
||||
|
||||
import {TestSupport, setup} from './test_support';
|
||||
|
||||
describe('ngtools_api (deprecated)', () => {
|
||||
|
|
|
@ -48,21 +48,7 @@ export interface TestSupport {
|
|||
shouldNotExist(fileName: string): void;
|
||||
}
|
||||
|
||||
export function setup(): TestSupport {
|
||||
const basePath = makeTempDir();
|
||||
|
||||
const ngRootDir = getNgRootDir();
|
||||
const nodeModulesPath = path.resolve(basePath, 'node_modules');
|
||||
fs.mkdirSync(nodeModulesPath);
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'dist', 'all', '@angular'),
|
||||
path.resolve(nodeModulesPath, '@angular'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'rxjs'), path.resolve(nodeModulesPath, 'rxjs'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'typescript'),
|
||||
path.resolve(nodeModulesPath, 'typescript'));
|
||||
|
||||
function createTestSupportFor(basePath: string) {
|
||||
return {basePath, write, writeFiles, createCompilerOptions, shouldExist, shouldNotExist};
|
||||
|
||||
function write(fileName: string, content: string) {
|
||||
|
@ -114,6 +100,69 @@ export function setup(): TestSupport {
|
|||
}
|
||||
}
|
||||
|
||||
export function setupBazelTo(basePath: string) {
|
||||
const sources = process.env.TEST_SRCDIR;
|
||||
const packages = path.join(sources, 'angular/packages');
|
||||
const nodeModulesPath = path.join(basePath, 'node_modules');
|
||||
const angularDirectory = path.join(nodeModulesPath, '@angular');
|
||||
fs.mkdirSync(nodeModulesPath);
|
||||
|
||||
// Link the built angular packages
|
||||
fs.mkdirSync(angularDirectory);
|
||||
const packageNames = fs.readdirSync(packages).filter(
|
||||
name => fs.statSync(path.join(packages, name)).isDirectory() &&
|
||||
fs.existsSync(path.join(packages, name, 'npm_package')));
|
||||
for (const pkg of packageNames) {
|
||||
fs.symlinkSync(path.join(packages, `${pkg}/npm_package`), path.join(angularDirectory, pkg));
|
||||
}
|
||||
|
||||
// Link rxjs
|
||||
const rxjsSource = path.join(sources, 'rxjs');
|
||||
const rxjsDest = path.join(nodeModulesPath, 'rxjs');
|
||||
if (fs.existsSync(rxjsSource)) {
|
||||
fs.symlinkSync(rxjsSource, rxjsDest);
|
||||
}
|
||||
|
||||
// Link typescript
|
||||
const typescriptSource = path.join(sources, 'angular/node_modules/typescript');
|
||||
const typescriptDest = path.join(nodeModulesPath, 'typescript');
|
||||
if (fs.existsSync(typescriptSource)) {
|
||||
fs.symlinkSync(typescriptSource, typescriptDest);
|
||||
}
|
||||
}
|
||||
|
||||
function setupBazel(): TestSupport {
|
||||
const basePath = makeTempDir();
|
||||
setupBazelTo(basePath);
|
||||
return createTestSupportFor(basePath);
|
||||
}
|
||||
|
||||
function setupTestSh(): TestSupport {
|
||||
const basePath = makeTempDir();
|
||||
|
||||
const ngRootDir = getNgRootDir();
|
||||
const nodeModulesPath = path.resolve(basePath, 'node_modules');
|
||||
fs.mkdirSync(nodeModulesPath);
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'dist', 'all', '@angular'),
|
||||
path.resolve(nodeModulesPath, '@angular'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'rxjs'), path.resolve(nodeModulesPath, 'rxjs'));
|
||||
fs.symlinkSync(
|
||||
path.resolve(ngRootDir, 'node_modules', 'typescript'),
|
||||
path.resolve(nodeModulesPath, 'typescript'));
|
||||
|
||||
return createTestSupportFor(basePath);
|
||||
}
|
||||
|
||||
export function isInBazel() {
|
||||
return process.env.TEST_SRCDIR != null;
|
||||
}
|
||||
|
||||
export function setup(): TestSupport {
|
||||
return isInBazel() ? setupBazel() : setupTestSh();
|
||||
}
|
||||
|
||||
export function expectNoDiagnostics(options: ng.CompilerOptions, diags: ng.Diagnostics) {
|
||||
const errorDiags = diags.filter(d => d.category !== ts.DiagnosticCategory.Message);
|
||||
if (errorDiags.length) {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
load("//tools:defaults.bzl", "ts_library", "ts_web_test")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
|
||||
|
||||
ts_library(
|
||||
name = "test_lib",
|
||||
testonly = 1,
|
||||
srcs = glob(["**/*.ts"]),
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
"//packages/compiler-cli/test:test_utils",
|
||||
"//packages/compiler/test:test_utils",
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "test",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
data = [
|
||||
"//packages/common:npm_package",
|
||||
"//packages/core:npm_package",
|
||||
"//packages/router:npm_package",
|
||||
],
|
||||
deps = [
|
||||
":test_lib",
|
||||
"//packages/core",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
|
@ -15,7 +15,7 @@ import {formatDiagnostics} from '../../src/perform_compile';
|
|||
import {CompilerHost, EmitFlags, LazyRoute} from '../../src/transformers/api';
|
||||
import {createSrcToOutPathMapper} from '../../src/transformers/program';
|
||||
import {GENERATED_FILES, StructureIsReused, tsStructureIsReused} from '../../src/transformers/util';
|
||||
import {TestSupport, expectNoDiagnosticsInProgram, setup} from '../test_support';
|
||||
import {TestSupport, expectNoDiagnosticsInProgram, isInBazel, setup} from '../test_support';
|
||||
|
||||
describe('ng program', () => {
|
||||
let testSupport: TestSupport;
|
||||
|
@ -267,56 +267,59 @@ describe('ng program', () => {
|
|||
.toBe(false);
|
||||
});
|
||||
|
||||
it('should reuse the old ts program completely if nothing changed', () => {
|
||||
testSupport.writeFiles({'src/index.ts': createModuleAndCompSource('main')});
|
||||
// Note: the second compile drops factories for library files,
|
||||
// and therefore changes the structure again
|
||||
const p1 = compile().program;
|
||||
const p2 = compile(p1).program;
|
||||
compile(p2);
|
||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.Completely);
|
||||
});
|
||||
if (!isInBazel()) {
|
||||
it('should reuse the old ts program completely if nothing changed', () => {
|
||||
testSupport.writeFiles({'src/index.ts': createModuleAndCompSource('main')});
|
||||
// Note: the second compile drops factories for library files,
|
||||
// and therefore changes the structure again
|
||||
const p1 = compile().program;
|
||||
const p2 = compile(p1).program;
|
||||
compile(p2);
|
||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.Completely);
|
||||
});
|
||||
|
||||
it('should reuse the old ts program completely if a template or a ts file changed', () => {
|
||||
testSupport.writeFiles({
|
||||
'src/main.ts': createModuleAndCompSource('main', 'main.html'),
|
||||
'src/main.html': `Some template`,
|
||||
'src/util.ts': `export const x = 1`,
|
||||
'src/index.ts': `
|
||||
export * from './main';
|
||||
export * from './util';
|
||||
`
|
||||
it('should reuse the old ts program completely if a template or a ts file changed', () => {
|
||||
testSupport.writeFiles({
|
||||
'src/main.ts': createModuleAndCompSource('main', 'main.html'),
|
||||
'src/main.html': `Some template`,
|
||||
'src/util.ts': `export const x = 1`,
|
||||
'src/index.ts': `
|
||||
export * from './main';
|
||||
export * from './util';
|
||||
`
|
||||
});
|
||||
// Note: the second compile drops factories for library files,
|
||||
// and therefore changes the structure again
|
||||
const p1 = compile().program;
|
||||
const p2 = compile(p1).program;
|
||||
testSupport.writeFiles({
|
||||
'src/main.html': `Another template`,
|
||||
'src/util.ts': `export const x = 2`,
|
||||
});
|
||||
compile(p2);
|
||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.Completely);
|
||||
});
|
||||
// Note: the second compile drops factories for library files,
|
||||
// and therefore changes the structure again
|
||||
const p1 = compile().program;
|
||||
const p2 = compile(p1).program;
|
||||
testSupport.writeFiles({
|
||||
'src/main.html': `Another template`,
|
||||
'src/util.ts': `export const x = 2`,
|
||||
});
|
||||
compile(p2);
|
||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.Completely);
|
||||
});
|
||||
|
||||
it('should not reuse the old ts program if an import changed', () => {
|
||||
testSupport.writeFiles({
|
||||
'src/main.ts': createModuleAndCompSource('main'),
|
||||
'src/util.ts': `export const x = 1`,
|
||||
'src/index.ts': `
|
||||
export * from './main';
|
||||
export * from './util';
|
||||
`
|
||||
it('should not reuse the old ts program if an import changed', () => {
|
||||
testSupport.writeFiles({
|
||||
'src/main.ts': createModuleAndCompSource('main'),
|
||||
'src/util.ts': `export const x = 1`,
|
||||
'src/index.ts': `
|
||||
export * from './main';
|
||||
export * from './util';
|
||||
`
|
||||
});
|
||||
// Note: the second compile drops factories for library files,
|
||||
// and therefore changes the structure again
|
||||
const p1 = compile().program;
|
||||
const p2 = compile(p1).program;
|
||||
testSupport.writeFiles(
|
||||
{'src/util.ts': `import {Injectable} from '@angular/core'; export const x = 1;`});
|
||||
compile(p2);
|
||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.SafeModules);
|
||||
});
|
||||
// Note: the second compile drops factories for library files,
|
||||
// and therefore changes the structure again
|
||||
const p1 = compile().program;
|
||||
const p2 = compile(p1).program;
|
||||
testSupport.writeFiles(
|
||||
{'src/util.ts': `import {Injectable} from '@angular/core'; export const x = 1;`});
|
||||
compile(p2);
|
||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.SafeModules);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it('should not typecheck templates if skipTemplateCodegen is set but fullTemplateTypeCheck is not',
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
import {PartialModule} from '@angular/compiler';
|
||||
import * as o from '@angular/compiler/src/output/output_ast';
|
||||
import {MockAotCompilerHost} from 'compiler/test/aot/test_util';
|
||||
import {initDomAdapter} from 'platform-browser/src/browser';
|
||||
import {MockAotCompilerHost} from '@angular/compiler/test/aot/test_util';
|
||||
import {initDomAdapter} from '@angular/platform-browser/src/browser';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {getAngularClassTransformerFactory} from '../../src/transformers/r3_transform';
|
||||
|
|
|
@ -8,12 +8,27 @@ NODE_ONLY = [
|
|||
"render3/**/*.ts",
|
||||
]
|
||||
|
||||
UTILS = [
|
||||
"aot/test_util.ts",
|
||||
]
|
||||
|
||||
ts_library(
|
||||
name = "test_utils",
|
||||
srcs = UTILS,
|
||||
visibility = ["//packages/compiler-cli/test:__subpackages__"],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "test_lib",
|
||||
testonly = 1,
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = NODE_ONLY,
|
||||
exclude = NODE_ONLY + UTILS,
|
||||
),
|
||||
deps = [
|
||||
"//packages:types",
|
||||
|
@ -31,9 +46,13 @@ ts_library(
|
|||
ts_library(
|
||||
name = "test_node_only_lib",
|
||||
testonly = 1,
|
||||
srcs = glob(NODE_ONLY),
|
||||
srcs = glob(
|
||||
NODE_ONLY,
|
||||
exclude = UTILS,
|
||||
),
|
||||
deps = [
|
||||
":test_lib",
|
||||
":test_utils",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli",
|
||||
"//packages/compiler/testing",
|
||||
|
|
Loading…
Reference in New Issue