80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC 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 {PluginObj, transformSync} from '@babel/core';
|
|
|
|
import {createEs2015LinkerPlugin} from '../../../linker/babel';
|
|
import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
|
|
import {getBuildOutputDirectory} from '../test_helpers/compile_test';
|
|
import {ComplianceTest} from '../test_helpers/get_compliance_tests';
|
|
import {parseGoldenPartial} from '../test_helpers/golden_partials';
|
|
import {runTests} from '../test_helpers/test_runner';
|
|
|
|
runTests('partial compile + link', linkPartials);
|
|
|
|
/**
|
|
* Link all the partials specified in the given `test`.
|
|
*
|
|
* @param fs The mock file-system to use for linking the partials.
|
|
* @param test The compliance test whose partials will be linked.
|
|
*/
|
|
function linkPartials(fs: FileSystem, test: ComplianceTest): void {
|
|
const builtDirectory = getBuildOutputDirectory(fs);
|
|
const linkerPlugin = createEs2015LinkerPlugin(test.angularCompilerOptions);
|
|
const goldenPartialPath = fs.resolve('/GOLDEN_PARTIAL.js');
|
|
if (!fs.exists(goldenPartialPath)) {
|
|
throw new Error(
|
|
'Golden partial does not exist for this test\n' +
|
|
'Try generating it by running:\n' +
|
|
`bazel run //packages/compiler-cli/test/compliance/test_cases:${
|
|
test.relativePath}.golden.update`);
|
|
}
|
|
const partialFile = fs.readFile(goldenPartialPath);
|
|
const partials = parseGoldenPartial(partialFile).filter(f => f.path.endsWith('.js'));
|
|
for (const partial of partials) {
|
|
const linkedSource =
|
|
applyLinker({fileName: partial.path, source: partial.content}, linkerPlugin);
|
|
safeWrite(fs, fs.resolve(builtDirectory, partial.path), linkedSource);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run the file through the Babel linker plugin.
|
|
*
|
|
* It will ignore files that do not have a `.js` extension.
|
|
*
|
|
* @param file The file name and its source to be transformed using the linker.
|
|
* @param linkerPlugin The linker plugin to apply.
|
|
* @returns The file's source content, which has been transformed using the linker if necessary.
|
|
*/
|
|
function applyLinker(file: {fileName: string; source: string}, linkerPlugin: PluginObj): string {
|
|
if (!file.fileName.endsWith('.js')) {
|
|
return file.source;
|
|
}
|
|
const result = transformSync(file.source, {
|
|
filename: file.fileName,
|
|
plugins: [linkerPlugin],
|
|
parserOpts: {sourceType: 'unambiguous'},
|
|
});
|
|
if (result === null) {
|
|
throw fail('Babel transform did not have output');
|
|
}
|
|
if (result.code == null) {
|
|
throw fail('Babel transform result does not have any code');
|
|
}
|
|
return result.code;
|
|
}
|
|
|
|
/**
|
|
* Write the `content` to the `path` on the `fs` file-system, first ensuring that the containing
|
|
* directory exists.
|
|
*/
|
|
function safeWrite(fs: FileSystem, path: AbsoluteFsPath, content: string): void {
|
|
fs.ensureDir(fs.dirname(path));
|
|
fs.writeFile(path, content);
|
|
}
|