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