2019-01-21 14:03:30 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2018-10-11 17:23:13 -04:00
|
|
|
// Run this manually with:
|
|
|
|
//
|
|
|
|
// ./node_modules/.bin/ts-node --project tools/ts_library_builder/tsconfig.json tools/ts_library_builder/test.ts
|
|
|
|
|
2019-02-12 15:22:43 -05:00
|
|
|
import * as assert from "assert";
|
2019-03-07 08:53:56 -05:00
|
|
|
import { Project, ts } from "ts-morph";
|
2019-04-01 15:09:59 -04:00
|
|
|
import { flatten, mergeGlobals, prepareFileForMerge } from "./build_library";
|
2019-02-05 08:12:58 -05:00
|
|
|
import { inlineFiles, loadDtsFiles } from "./ast_util";
|
2018-10-11 17:23:13 -04:00
|
|
|
|
2018-10-15 12:47:48 -04:00
|
|
|
const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts;
|
|
|
|
|
2018-10-11 17:23:13 -04:00
|
|
|
/** setups and returns the fixtures for testing */
|
2019-04-01 12:47:25 -04:00
|
|
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
2018-10-11 17:23:13 -04:00
|
|
|
function setupFixtures() {
|
|
|
|
const basePath = process.cwd();
|
|
|
|
const buildPath = `${basePath}/tools/ts_library_builder/testdata`;
|
|
|
|
const outputFile = `${buildPath}/lib.output.d.ts`;
|
|
|
|
const inputProject = new Project({
|
|
|
|
compilerOptions: {
|
|
|
|
baseUrl: basePath,
|
|
|
|
declaration: true,
|
|
|
|
emitDeclarationOnly: true,
|
2019-03-07 08:53:56 -05:00
|
|
|
module: ModuleKind.ESNext,
|
2018-10-11 17:23:13 -04:00
|
|
|
moduleResolution: ModuleResolutionKind.NodeJs,
|
|
|
|
strict: true,
|
|
|
|
stripInternal: true,
|
|
|
|
target: ScriptTarget.ESNext
|
|
|
|
}
|
|
|
|
});
|
|
|
|
inputProject.addExistingSourceFiles([
|
|
|
|
`${buildPath}/globals.ts`,
|
|
|
|
`${buildPath}/api.ts`
|
|
|
|
]);
|
|
|
|
const declarationProject = new Project({
|
|
|
|
compilerOptions: {},
|
|
|
|
useVirtualFileSystem: true
|
|
|
|
});
|
2019-04-01 12:47:25 -04:00
|
|
|
loadDtsFiles(declarationProject, {});
|
2018-10-11 17:23:13 -04:00
|
|
|
for (const { filePath, text } of inputProject.emitToMemory().getFiles()) {
|
|
|
|
declarationProject.createSourceFile(filePath, text);
|
|
|
|
}
|
|
|
|
const outputProject = new Project({
|
|
|
|
compilerOptions: {},
|
|
|
|
useVirtualFileSystem: true
|
|
|
|
});
|
2019-04-01 12:47:25 -04:00
|
|
|
loadDtsFiles(outputProject, {});
|
2018-10-11 17:23:13 -04:00
|
|
|
const outputSourceFile = outputProject.createSourceFile(outputFile);
|
|
|
|
const debug = true;
|
|
|
|
|
|
|
|
return {
|
|
|
|
basePath,
|
|
|
|
buildPath,
|
|
|
|
inputProject,
|
|
|
|
outputFile,
|
|
|
|
declarationProject,
|
|
|
|
outputProject,
|
|
|
|
outputSourceFile,
|
|
|
|
debug
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-04-01 12:47:25 -04:00
|
|
|
function buildLibraryFlatten(): void {
|
2018-10-11 17:23:13 -04:00
|
|
|
const {
|
|
|
|
basePath,
|
|
|
|
buildPath,
|
|
|
|
debug,
|
|
|
|
declarationProject,
|
|
|
|
outputSourceFile: targetSourceFile
|
|
|
|
} = setupFixtures();
|
|
|
|
|
|
|
|
flatten({
|
|
|
|
basePath,
|
|
|
|
customSources: {},
|
|
|
|
debug,
|
|
|
|
declarationProject,
|
|
|
|
filePath: `${buildPath}/api.d.ts`,
|
2019-02-12 10:08:56 -05:00
|
|
|
moduleName: `"api"`,
|
|
|
|
namespaceName: "Api",
|
2018-10-11 17:23:13 -04:00
|
|
|
targetSourceFile
|
|
|
|
});
|
|
|
|
|
|
|
|
assert(targetSourceFile.getNamespace(`"api"`) != null);
|
2019-02-12 10:08:56 -05:00
|
|
|
assert(targetSourceFile.getNamespace("Api") != null);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(targetSourceFile.getNamespaces().length, 2);
|
2019-02-12 10:08:56 -05:00
|
|
|
const moduleApi = targetSourceFile.getNamespaceOrThrow(`"api"`);
|
|
|
|
const functions = moduleApi.getFunctions();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(functions[0].getName(), "foo");
|
|
|
|
assert.equal(
|
2018-10-11 17:23:13 -04:00
|
|
|
functions[0]
|
|
|
|
.getJsDocs()
|
|
|
|
.map(jsdoc => jsdoc.getInnerText())
|
|
|
|
.join("\n"),
|
|
|
|
"jsdoc for foo"
|
|
|
|
);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(functions[1].getName(), "bar");
|
|
|
|
assert.equal(
|
2018-10-11 17:23:13 -04:00
|
|
|
functions[1]
|
|
|
|
.getJsDocs()
|
|
|
|
.map(jsdoc => jsdoc.getInnerText())
|
|
|
|
.join("\n"),
|
|
|
|
""
|
|
|
|
);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(functions.length, 2);
|
2019-02-12 10:08:56 -05:00
|
|
|
const classes = moduleApi.getClasses();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(classes[0].getName(), "Foo");
|
|
|
|
assert.equal(classes.length, 1);
|
2019-02-12 10:08:56 -05:00
|
|
|
const variableDeclarations = moduleApi.getVariableDeclarations();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(variableDeclarations[0].getName(), "arr");
|
|
|
|
assert.equal(variableDeclarations.length, 1);
|
2019-02-12 10:08:56 -05:00
|
|
|
|
|
|
|
const namespaceApi = targetSourceFile.getNamespaceOrThrow(`"api"`);
|
|
|
|
const functionsNs = namespaceApi.getFunctions();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(functionsNs[0].getName(), "foo");
|
|
|
|
assert.equal(
|
2019-02-12 10:08:56 -05:00
|
|
|
functionsNs[0]
|
|
|
|
.getJsDocs()
|
|
|
|
.map(jsdoc => jsdoc.getInnerText())
|
|
|
|
.join("\n"),
|
|
|
|
"jsdoc for foo"
|
|
|
|
);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(functionsNs[1].getName(), "bar");
|
|
|
|
assert.equal(
|
2019-02-12 10:08:56 -05:00
|
|
|
functionsNs[1]
|
|
|
|
.getJsDocs()
|
|
|
|
.map(jsdoc => jsdoc.getInnerText())
|
|
|
|
.join("\n"),
|
|
|
|
""
|
|
|
|
);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(functionsNs.length, 2);
|
2019-02-12 10:08:56 -05:00
|
|
|
const classesNs = namespaceApi.getClasses();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(classesNs[0].getName(), "Foo");
|
|
|
|
assert.equal(classesNs.length, 1);
|
2019-02-12 10:08:56 -05:00
|
|
|
const variableDeclarationsNs = namespaceApi.getVariableDeclarations();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(variableDeclarationsNs[0].getName(), "arr");
|
|
|
|
assert.equal(variableDeclarationsNs.length, 1);
|
|
|
|
}
|
2018-10-11 17:23:13 -04:00
|
|
|
|
2019-04-01 12:47:25 -04:00
|
|
|
function buildLibraryMerge(): void {
|
2018-10-11 17:23:13 -04:00
|
|
|
const {
|
|
|
|
basePath,
|
|
|
|
buildPath,
|
|
|
|
declarationProject,
|
|
|
|
debug,
|
|
|
|
inputProject,
|
|
|
|
outputSourceFile: targetSourceFile
|
|
|
|
} = setupFixtures();
|
|
|
|
|
2019-04-01 15:09:59 -04:00
|
|
|
const prepareForMergeOpts = {
|
|
|
|
globalVarName: "foobarbaz",
|
|
|
|
interfaceName: "FooBar",
|
|
|
|
targetSourceFile
|
|
|
|
};
|
|
|
|
|
|
|
|
const prepareReturn = prepareFileForMerge(prepareForMergeOpts);
|
|
|
|
|
|
|
|
mergeGlobals({
|
2018-10-11 17:23:13 -04:00
|
|
|
basePath,
|
|
|
|
declarationProject,
|
|
|
|
debug,
|
|
|
|
filePath: `${buildPath}/globals.ts`,
|
|
|
|
inputProject,
|
2019-04-01 15:09:59 -04:00
|
|
|
...prepareForMergeOpts,
|
|
|
|
prepareReturn
|
2018-10-11 17:23:13 -04:00
|
|
|
});
|
|
|
|
|
2018-10-22 01:08:14 -04:00
|
|
|
assert(targetSourceFile.getNamespace("moduleC") != null);
|
2018-11-03 19:45:06 -04:00
|
|
|
assert(targetSourceFile.getNamespace("moduleD") != null);
|
|
|
|
assert(targetSourceFile.getNamespace("moduleE") != null);
|
|
|
|
assert(targetSourceFile.getNamespace("moduleF") != null);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(targetSourceFile.getNamespaces().length, 4);
|
2018-10-22 01:08:14 -04:00
|
|
|
assert(targetSourceFile.getInterface("FooBar") != null);
|
2019-03-25 00:23:24 -04:00
|
|
|
assert.equal(targetSourceFile.getInterfaces().length, 2);
|
2018-10-22 01:08:14 -04:00
|
|
|
const variableDeclarations = targetSourceFile.getVariableDeclarations();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(variableDeclarations[0].getType().getText(), `FooBar`);
|
2019-06-01 11:13:36 -04:00
|
|
|
assert.equal(variableDeclarations[1].getType().getText(), `moduleC.Bar`);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(
|
2019-06-01 11:13:36 -04:00
|
|
|
variableDeclarations[2].getType().getText(),
|
2018-10-22 01:08:14 -04:00
|
|
|
`typeof moduleC.qat`
|
2018-10-11 17:23:13 -04:00
|
|
|
);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(
|
2019-06-01 11:13:36 -04:00
|
|
|
variableDeclarations[3].getType().getText(),
|
2018-11-03 19:45:06 -04:00
|
|
|
`typeof moduleE.process`
|
|
|
|
);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(
|
2019-06-01 11:13:36 -04:00
|
|
|
variableDeclarations[4].getType().getText(),
|
2018-11-03 19:45:06 -04:00
|
|
|
`typeof moduleD.reprocess`
|
|
|
|
);
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(
|
2019-06-01 11:13:36 -04:00
|
|
|
variableDeclarations[5].getType().getText(),
|
2018-11-08 19:09:18 -05:00
|
|
|
`typeof moduleC.Bar`
|
|
|
|
);
|
2019-06-01 11:13:36 -04:00
|
|
|
assert.equal(variableDeclarations.length, 6);
|
2018-11-08 19:09:18 -05:00
|
|
|
const typeAliases = targetSourceFile.getTypeAliases();
|
2019-02-12 15:22:43 -05:00
|
|
|
assert.equal(typeAliases[0].getName(), "Bar");
|
|
|
|
assert.equal(typeAliases[0].getType().getText(), "moduleC.Bar");
|
|
|
|
assert.equal(typeAliases.length, 1);
|
2019-03-25 00:23:24 -04:00
|
|
|
const exportedInterface = targetSourceFile.getInterfaceOrThrow("FizzBuzz");
|
|
|
|
const interfaceProperties = exportedInterface.getStructure().properties;
|
|
|
|
assert(interfaceProperties != null);
|
|
|
|
assert.equal(interfaceProperties!.length, 2);
|
|
|
|
assert.equal(interfaceProperties![0].name, "foo");
|
|
|
|
assert.equal(interfaceProperties![0].type, "string");
|
|
|
|
assert.equal(interfaceProperties![1].name, "bar");
|
|
|
|
assert.equal(interfaceProperties![1].type, "number");
|
2019-02-12 15:22:43 -05:00
|
|
|
}
|
2018-10-11 17:23:13 -04:00
|
|
|
|
2019-04-01 12:47:25 -04:00
|
|
|
function testInlineFiles(): void {
|
2019-02-05 08:12:58 -05:00
|
|
|
const {
|
|
|
|
basePath,
|
|
|
|
buildPath,
|
|
|
|
debug,
|
|
|
|
outputSourceFile: targetSourceFile
|
|
|
|
} = setupFixtures();
|
|
|
|
|
|
|
|
inlineFiles({
|
|
|
|
basePath,
|
|
|
|
debug,
|
|
|
|
inline: [`${buildPath}/lib.extra.d.ts`],
|
|
|
|
targetSourceFile
|
|
|
|
});
|
|
|
|
|
|
|
|
assert(targetSourceFile.getNamespace("Qat") != null);
|
|
|
|
const qatNamespace = targetSourceFile.getNamespaceOrThrow("Qat");
|
|
|
|
assert(qatNamespace.getClass("Foo") != null);
|
2019-02-12 15:22:43 -05:00
|
|
|
}
|
2019-02-05 08:12:58 -05:00
|
|
|
|
2018-10-11 17:23:13 -04:00
|
|
|
// TODO author unit tests for `ast_util.ts`
|
2019-01-31 18:11:37 -05:00
|
|
|
|
2019-04-01 12:47:25 -04:00
|
|
|
function main(): void {
|
2019-02-12 15:22:43 -05:00
|
|
|
console.log("ts_library_builder buildLibraryFlatten");
|
|
|
|
buildLibraryFlatten();
|
|
|
|
console.log("ts_library_builder buildLibraryMerge");
|
|
|
|
buildLibraryMerge();
|
|
|
|
console.log("ts_library_builder testInlineFiles");
|
|
|
|
testInlineFiles();
|
|
|
|
console.log("ts_library_builder ok");
|
|
|
|
}
|
|
|
|
|
|
|
|
main();
|