126 lines
3.9 KiB
TypeScript
126 lines
3.9 KiB
TypeScript
|
/**
|
||
|
* @license
|
||
|
* Copyright Google Inc. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by an MIT-style license that can be
|
||
|
* found in the LICENSE file at https://angular.io/license
|
||
|
*/
|
||
|
|
||
|
import * as fs from 'fs';
|
||
|
import * as path from 'path';
|
||
|
import * as ts from 'typescript';
|
||
|
|
||
|
import {main, mainDiagnosticsForTest} from '../../src/main';
|
||
|
import {TestSupport, isInBazel, setup} from '../test_support';
|
||
|
|
||
|
function setupFakeCore(support: TestSupport): void {
|
||
|
if (!process.env.TEST_SRCDIR) {
|
||
|
throw new Error('`setupFakeCore` must be run within a Bazel test');
|
||
|
}
|
||
|
const fakeCore = path.join(
|
||
|
process.env.TEST_SRCDIR, 'angular/packages/compiler-cli/test/ngtsc/fake_core/npm_package');
|
||
|
|
||
|
const nodeModulesPath = path.join(support.basePath, 'node_modules');
|
||
|
const angularCoreDirectory = path.join(nodeModulesPath, '@angular/core');
|
||
|
|
||
|
fs.symlinkSync(fakeCore, angularCoreDirectory);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Manages a temporary testing directory structure and environment for testing ngtsc by feeding it
|
||
|
* TypeScript code.
|
||
|
*/
|
||
|
export class NgtscTestEnvironment {
|
||
|
private constructor(private support: TestSupport, readonly outDir: string) {}
|
||
|
|
||
|
get basePath(): string { return this.support.basePath; }
|
||
|
|
||
|
/**
|
||
|
* Set up a new testing environment.
|
||
|
*/
|
||
|
static setup(): NgtscTestEnvironment {
|
||
|
if (!NgtscTestEnvironment.supported) {
|
||
|
throw new Error(`Attempting to setup ngtsc tests in an unsupported environment`);
|
||
|
}
|
||
|
|
||
|
const support = setup();
|
||
|
const outDir = path.join(support.basePath, 'built');
|
||
|
process.chdir(support.basePath);
|
||
|
|
||
|
setupFakeCore(support);
|
||
|
|
||
|
const env = new NgtscTestEnvironment(support, outDir);
|
||
|
|
||
|
env.write('tsconfig-base.json', `{
|
||
|
"compilerOptions": {
|
||
|
"experimentalDecorators": true,
|
||
|
"skipLibCheck": true,
|
||
|
"noImplicitAny": true,
|
||
|
"strictNullChecks": true,
|
||
|
"types": [],
|
||
|
"outDir": "built",
|
||
|
"rootDir": ".",
|
||
|
"baseUrl": ".",
|
||
|
"declaration": true,
|
||
|
"target": "es5",
|
||
|
"module": "es2015",
|
||
|
"moduleResolution": "node",
|
||
|
"lib": ["es6", "dom"],
|
||
|
"typeRoots": ["node_modules/@types"]
|
||
|
},
|
||
|
"angularCompilerOptions": {
|
||
|
"enableIvy": "ngtsc"
|
||
|
}
|
||
|
}`);
|
||
|
|
||
|
return env;
|
||
|
}
|
||
|
|
||
|
assertExists(fileName: string) {
|
||
|
if (!fs.existsSync(path.resolve(this.outDir, fileName))) {
|
||
|
throw new Error(`Expected ${fileName} to be emitted (outDir: ${this.outDir})`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
assertDoesNotExist(fileName: string) {
|
||
|
if (fs.existsSync(path.resolve(this.outDir, fileName))) {
|
||
|
throw new Error(`Did not expect ${fileName} to be emitted (outDir: ${this.outDir})`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
getContents(fileName: string): string {
|
||
|
this.assertExists(fileName);
|
||
|
const modulePath = path.resolve(this.outDir, fileName);
|
||
|
return fs.readFileSync(modulePath, 'utf8');
|
||
|
}
|
||
|
|
||
|
write(fileName: string, content: string) { this.support.write(fileName, content); }
|
||
|
|
||
|
tsconfig(extraOpts: {[key: string]: string | boolean} = {}): void {
|
||
|
const opts = JSON.stringify({...extraOpts, 'enableIvy': 'ngtsc'});
|
||
|
const tsconfig: string =
|
||
|
`{"extends": "./tsconfig-base.json", "angularCompilerOptions": ${opts}}`;
|
||
|
this.write('tsconfig.json', tsconfig);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Run the compiler to completion, and assert that no errors occurred.
|
||
|
*/
|
||
|
driveMain(): void {
|
||
|
const errorSpy = jasmine.createSpy('consoleError').and.callFake(console.error);
|
||
|
const exitCode = main(['-p', this.basePath], errorSpy);
|
||
|
expect(errorSpy).not.toHaveBeenCalled();
|
||
|
expect(exitCode).toBe(0);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Run the compiler to completion, and return any `ts.Diagnostic` errors that may have occurred.
|
||
|
*/
|
||
|
driveDiagnostics(): ReadonlyArray<ts.Diagnostic> {
|
||
|
// Cast is safe as ngtsc mode only produces ts.Diagnostics.
|
||
|
return mainDiagnosticsForTest(['-p', this.basePath]) as ReadonlyArray<ts.Diagnostic>;
|
||
|
}
|
||
|
|
||
|
static get supported(): boolean { return isInBazel(); }
|
||
|
}
|