186 lines
5.2 KiB
TypeScript
186 lines
5.2 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 {runOneBuild} from '@angular/bazel';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import * as ts from 'typescript';
|
|
|
|
import {createTsConfig} from './tsconfig_template';
|
|
|
|
export interface TestSupport {
|
|
basePath: string;
|
|
runfilesPath: string;
|
|
angularCorePath: string;
|
|
typesRoots: string;
|
|
writeConfig({
|
|
srcTargetPath,
|
|
depPaths,
|
|
pathMapping,
|
|
}: {
|
|
srcTargetPath: string,
|
|
depPaths?: string[],
|
|
pathMapping?: Array<{moduleName: string; path: string;}>,
|
|
}): {compilerOptions: ts.CompilerOptions};
|
|
read(fileName: string): string;
|
|
write(fileName: string, content: string): void;
|
|
writeFiles(...mockDirs: {[fileName: string]: string}[]): void;
|
|
shouldExist(fileName: string): void;
|
|
shouldNotExist(fileName: string): void;
|
|
runOneBuild(): boolean;
|
|
}
|
|
|
|
export function setup({
|
|
bazelBin = 'bazel-bin',
|
|
tsconfig = 'tsconfig.json',
|
|
}: {
|
|
bazelBin?: string,
|
|
tsconfig?: string,
|
|
} = {}): TestSupport {
|
|
const runfilesPath = process.env['TEST_SRCDIR'];
|
|
|
|
const basePath = makeTempDir(runfilesPath);
|
|
|
|
const bazelBinPath = path.resolve(basePath, bazelBin);
|
|
fs.mkdirSync(bazelBinPath);
|
|
|
|
const angularCorePath = path.dirname(require.resolve('angular/packages/core'));
|
|
const tsConfigJsonPath = path.resolve(basePath, tsconfig);
|
|
|
|
const emptyTsConfig = ts.readConfigFile(
|
|
require.resolve('angular/packages/bazel/test/ngc-wrapped/empty/empty_tsconfig.json'), read);
|
|
const typesRoots = (emptyTsConfig as any).config.compilerOptions.typeRoots[0];
|
|
|
|
return {
|
|
basePath,
|
|
runfilesPath,
|
|
angularCorePath,
|
|
typesRoots,
|
|
write,
|
|
read,
|
|
writeFiles,
|
|
writeConfig,
|
|
shouldExist,
|
|
shouldNotExist,
|
|
runOneBuild: runOneBuildImpl,
|
|
};
|
|
|
|
// -----------------
|
|
// helpers
|
|
|
|
function mkdirp(dirname: string) {
|
|
const parent = path.dirname(dirname);
|
|
if (!fs.existsSync(parent)) {
|
|
mkdirp(parent);
|
|
}
|
|
fs.mkdirSync(dirname);
|
|
}
|
|
|
|
function write(fileName: string, content: string) {
|
|
const dir = path.dirname(fileName);
|
|
if (dir != '.') {
|
|
const newDir = path.resolve(basePath, dir);
|
|
if (!fs.existsSync(newDir)) mkdirp(newDir);
|
|
}
|
|
fs.writeFileSync(path.resolve(basePath, fileName), content, {encoding: 'utf-8'});
|
|
}
|
|
|
|
function read(fileName: string) {
|
|
return fs.readFileSync(path.resolve(basePath, fileName), {encoding: 'utf-8'});
|
|
}
|
|
|
|
function writeFiles(...mockDirs: {[fileName: string]: string}[]) {
|
|
mockDirs.forEach((dir) => {
|
|
Object.keys(dir).forEach((fileName) => {
|
|
write(fileName, dir[fileName]);
|
|
});
|
|
});
|
|
}
|
|
|
|
function writeConfig({
|
|
srcTargetPath,
|
|
depPaths = [],
|
|
pathMapping = [],
|
|
}: {
|
|
srcTargetPath: string,
|
|
depPaths?: string[],
|
|
pathMapping?: Array<{moduleName: string; path: string;}>,
|
|
}) {
|
|
srcTargetPath = path.resolve(basePath, srcTargetPath);
|
|
const compilationTargetSrc = listFilesRecursive(srcTargetPath);
|
|
const target = '//' + path.relative(basePath, srcTargetPath);
|
|
const files = [...compilationTargetSrc];
|
|
|
|
depPaths = depPaths.concat([angularCorePath]);
|
|
pathMapping = pathMapping.concat([
|
|
{moduleName: '@angular/core', path: angularCorePath},
|
|
{moduleName: 'angular/packages/core', path: angularCorePath}
|
|
]);
|
|
|
|
for (const depPath of depPaths) {
|
|
files.push(...listFilesRecursive(depPath).filter(f => f.endsWith('.d.ts')));
|
|
}
|
|
|
|
const pathMappingObj = {};
|
|
for (const mapping of pathMapping) {
|
|
pathMappingObj[mapping.moduleName] = [mapping.path];
|
|
pathMappingObj[path.posix.join(mapping.moduleName, '*')] =
|
|
[path.posix.join(mapping.path, '*')];
|
|
}
|
|
|
|
const emptyTsConfig = ts.readConfigFile(
|
|
require.resolve('angular/packages/bazel/test/ngc-wrapped/empty/empty_tsconfig.json'), read);
|
|
|
|
const tsconfig = createTsConfig({
|
|
defaultTsConfig: emptyTsConfig.config,
|
|
rootDir: basePath,
|
|
target: target,
|
|
outDir: bazelBinPath,
|
|
compilationTargetSrc,
|
|
files: files,
|
|
pathMapping: pathMappingObj,
|
|
});
|
|
write(path.resolve(basePath, tsConfigJsonPath), JSON.stringify(tsconfig, null, 2));
|
|
return tsconfig;
|
|
}
|
|
|
|
function shouldExist(fileName: string) {
|
|
if (!fs.existsSync(path.resolve(basePath, fileName))) {
|
|
throw new Error(`Expected ${fileName} to be emitted (basePath: ${basePath})`);
|
|
}
|
|
}
|
|
|
|
function shouldNotExist(fileName: string) {
|
|
if (fs.existsSync(path.resolve(basePath, fileName))) {
|
|
throw new Error(`Did not expect ${fileName} to be emitted (basePath: ${basePath})`);
|
|
}
|
|
}
|
|
|
|
function runOneBuildImpl(): boolean {
|
|
return runOneBuild(['@' + tsConfigJsonPath]);
|
|
}
|
|
}
|
|
|
|
function makeTempDir(baseDir: string): string {
|
|
const id = (Math.random() * 1000000).toFixed(0);
|
|
const dir = path.join(baseDir, `tmp.${id}`);
|
|
fs.mkdirSync(dir);
|
|
return dir;
|
|
}
|
|
|
|
export function listFilesRecursive(dir: string, fileList: string[] = []) {
|
|
fs.readdirSync(dir).forEach(file => {
|
|
if (fs.statSync(path.join(dir, file)).isDirectory()) {
|
|
listFilesRecursive(path.join(dir, file), fileList);
|
|
} else {
|
|
fileList.push(path.join(dir, file));
|
|
}
|
|
});
|
|
return fileList;
|
|
}
|