Add tests to verify output of --out with modules as output

This commit is contained in:
Sheetal Nandi
2019-03-05 09:53:00 -08:00
parent 276cb583b4
commit b879b435ef
27 changed files with 25554 additions and 75 deletions

View File

@@ -89,6 +89,7 @@
"unittests/services/preProcessFile.ts",
"unittests/services/textChanges.ts",
"unittests/services/transpile.ts",
"unittests/tsbuild/amdModulesWithOut.ts",
"unittests/tsbuild/emptyFiles.ts",
"unittests/tsbuild/graphOrdering.ts",
"unittests/tsbuild/missingExtendedFile.ts",

View File

@@ -0,0 +1,202 @@
namespace ts {
describe("unittests:: tsbuild:: outFile:: on amd modules with --out", () => {
let outFileFs: vfs.FileSystem;
const { time, tick } = getTime();
const enum ext { js, jsmap, dts, dtsmap, buildinfo }
const enum project { lib, app }
type OutputFile = [string, string, string, string, string];
function relName(path: string) { return path.slice(1); }
const outputFiles: [OutputFile, OutputFile] = [
[
"/src/lib/module.js",
"/src/lib/module.js.map",
"/src/lib/module.d.ts",
"/src/lib/module.d.ts.map",
"/src/lib/module.tsbuildinfo"
],
[
"/src/app/module.js",
"/src/app/module.js.map",
"/src/app/module.d.ts",
"/src/app/module.d.ts.map",
"/src/app/module.tsbuildinfo"
]
];
type Sources = [string, ReadonlyArray<string>];
const enum source { config, ts }
const sources: [Sources, Sources] = [
[
"/src/lib/tsconfig.json",
[
"/src/lib/file0.ts",
"/src/lib/file1.ts",
"/src/lib/file2.ts",
"/src/lib/global.ts",
]
],
[
"/src/app/tsconfig.json",
[
"/src/app/file3.ts",
"/src/app/file4.ts"
]
]
];
before(() => {
outFileFs = loadProjectFromDisk("tests/projects/amdModulesWithOut", time);
});
after(() => {
outFileFs = undefined!;
});
interface VerifyOutFileScenarioInput {
scenario: string;
modifyFs: (fs: vfs.FileSystem) => void;
modifyAgainFs?: (fs: vfs.FileSystem) => void;
}
function verifyOutFileScenario({
scenario,
modifyFs,
modifyAgainFs
}: VerifyOutFileScenarioInput) {
verifyTsbuildOutput({
scenario,
projFs: () => outFileFs,
time,
tick,
proj: "amdModulesWithOut",
rootNames: ["/src/app"],
expectedMapFileNames: [
outputFiles[project.lib][ext.jsmap],
outputFiles[project.lib][ext.dtsmap],
outputFiles[project.app][ext.jsmap],
outputFiles[project.app][ext.dtsmap],
],
expectedBuildInfoFilesForSectionBaselines: [
[outputFiles[project.lib][ext.buildinfo], outputFiles[project.lib][ext.js], outputFiles[project.lib][ext.dts]],
[outputFiles[project.app][ext.buildinfo], outputFiles[project.app][ext.js], outputFiles[project.app][ext.dts]]
],
lastProjectOutputJs: outputFiles[project.app][ext.js],
initialBuild: {
modifyFs
},
incrementalDtsUnchangedBuild: {
modifyFs: fs => appendText(fs, relName(sources[project.lib][source.ts][1]), "console.log(x);")
},
incrementalHeaderChangedBuild: modifyAgainFs ? {
modifyFs: modifyAgainFs
} : undefined,
outputFiles: [
...outputFiles[project.lib],
...outputFiles[project.app]
],
baselineOnly: true
});
}
describe("Prepend output with .tsbuildinfo", () => {
verifyOutFileScenario({
scenario: "modules and globals mixed in amd",
modifyFs: noop
});
// Prologues
describe("Prologues", () => {
verifyOutFileScenario({
scenario: "multiple prologues in all projects",
modifyFs: fs => {
enableStrict(fs, sources[project.lib][source.config]);
addTestPrologue(fs, sources[project.lib][source.ts][0], `"myPrologue"`);
addTestPrologue(fs, sources[project.lib][source.ts][2], `"myPrologueFile"`);
enableStrict(fs, sources[project.app][source.config]);
addTestPrologue(fs, sources[project.app][source.ts][0], `"myPrologue"`);
addTestPrologue(fs, sources[project.app][source.ts][1], `"myPrologue2";`);
},
modifyAgainFs: fs => addTestPrologue(fs, relName(sources[project.lib][source.ts][1]), `"myPrologue5"`)
});
});
// Shebang
describe("Shebang", () => {
// changes declaration because its emitted in .d.ts file
verifyOutFileScenario({
scenario: "shebang in all projects",
modifyFs: fs => {
addShebang(fs, "lib", "file0");
addShebang(fs, "lib", "file1");
addShebang(fs, "app", "file3");
},
});
});
// emitHelpers
describe("emitHelpers", () => {
verifyOutFileScenario({
scenario: "multiple emitHelpers in all projects",
modifyFs: fs => {
addSpread(fs, "lib", "file0");
addRest(fs, "lib", "file1");
addRest(fs, "app", "file3");
addSpread(fs, "app", "file4");
},
modifyAgainFs: fs => removeRest(fs, "lib", "file1")
});
});
// triple slash refs
describe("triple slash refs", () => {
// changes declaration because its emitted in .d.ts file
verifyOutFileScenario({
scenario: "triple slash refs in all projects",
modifyFs: fs => {
addTripleSlashRef(fs, "lib", "file0");
addTripleSlashRef(fs, "app", "file4");
}
});
});
describe("stripInternal", () => {
function stripInternalScenario(fs: vfs.FileSystem) {
const internal = "/*@internal*/";
replaceText(fs, sources[project.app][source.config], `"composite": true,`, `"composite": true,
"stripInternal": true,`);;
replaceText(fs, sources[project.lib][source.ts][0], "const", `${internal} const`);
appendText(fs, sources[project.lib][source.ts][1], `
export class normalC {
${internal} constructor() { }
${internal} prop: string;
${internal} method() { }
${internal} get c() { return 10; }
${internal} set c(val: number) { }
}
export namespace normalN {
${internal} export class C { }
${internal} export function foo() {}
${internal} export namespace someNamespace { export class C {} }
${internal} export namespace someOther.something { export class someClass {} }
${internal} export import someImport = someNamespace.C;
${internal} export type internalType = internalC;
${internal} export const internalConst = 10;
${internal} export enum internalEnum { a, b, c }
}
${internal} export class internalC {}
${internal} export function internalfoo() {}
${internal} export namespace internalNamespace { export class someClass {} }
${internal} export namespace internalOther.something { export class someClass {} }
${internal} export import internalImport = internalNamespace.someClass;
${internal} export type internalType = internalC;
${internal} export const internalConst = 10;
${internal} export enum internalEnum { a, b, c }`);
}
// Verify initial + incremental edits
verifyOutFileScenario({
scenario: "stripInternal",
modifyFs: stripInternalScenario,
modifyAgainFs: fs => replaceText(fs, sources[project.lib][source.ts][1], `export const`, `/*@internal*/ export const`),
});
});
});
});
}

View File

@@ -359,4 +359,66 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt
}
});
}
export function enableStrict(fs: vfs.FileSystem, path: string) {
replaceText(fs, path, `"strict": false`, `"strict": true`);
}
export function addTestPrologue(fs: vfs.FileSystem, path: string, prologue: string) {
prependText(fs, path, `${prologue}
`);
}
export function addShebang(fs: vfs.FileSystem, project: string, file: string) {
prependText(fs, `src/${project}/${file}.ts`, `#!someshebang ${project} ${file}
`);
}
export function restContent(project: string, file: string) {
return `function for${project}${file}Rest() {
const { b, ...rest } = { a: 10, b: 30, yy: 30 };
}`;
}
function nonrestContent(project: string, file: string) {
return `function for${project}${file}Rest() { }`;
}
export function addRest(fs: vfs.FileSystem, project: string, file: string) {
appendText(fs, `src/${project}/${file}.ts`, restContent(project, file));
}
export function removeRest(fs: vfs.FileSystem, project: string, file: string) {
replaceText(fs, `src/${project}/${file}.ts`, restContent(project, file), nonrestContent(project, file));
}
export function addStubFoo(fs: vfs.FileSystem, project: string, file: string) {
appendText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file));
}
export function changeStubToRest(fs: vfs.FileSystem, project: string, file: string) {
replaceText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file), restContent(project, file));
}
export function addSpread(fs: vfs.FileSystem, project: string, file: string) {
const path = `src/${project}/${file}.ts`;
const content = fs.readFileSync(path, "utf8");
fs.writeFileSync(path, `${content}
function ${project}${file}Spread(...b: number[]) { }
${project}${file}Spread(...[10, 20, 30]);`);
replaceText(fs, `src/${project}/tsconfig.json`, `"strict": false,`, `"strict": false,
"downlevelIteration": true,`);
}
export function getTripleSlashRef(project: string) {
return `/src/${project}/tripleRef.d.ts`;
}
export function addTripleSlashRef(fs: vfs.FileSystem, project: string, file: string) {
fs.writeFileSync(getTripleSlashRef(project), `declare class ${project}${file} { }`);
prependText(fs, `src/${project}/${file}.ts`, `///<reference path="./tripleRef.d.ts"/>
const ${file}Const = new ${project}${file}();
`);
}
}

View File

@@ -1,4 +1,3 @@
namespace ts {
describe("unittests:: tsbuild:: outFile::", () => {
let outFileFs: vfs.FileSystem;
@@ -174,7 +173,6 @@ namespace ts {
...outputFiles[project.first],
...outputFiles[project.second],
...outputFiles[project.third],
outputFiles[project.third][ext.buildinfo],
],
outputFiles[project.first][ext.buildinfo], // since first build info changes
);
@@ -443,10 +441,6 @@ namespace ts {
describe("Prepend output with .tsbuildinfo", () => {
// Prologues
describe("Prologues", () => {
function enableStrict(fs: vfs.FileSystem, path: string) {
replaceText(fs, path, `"strict": false`, `"strict": true`);
}
// Verify initial + incremental edits
verifyOutFileScenario({
scenario: "strict in all projects",
@@ -455,37 +449,32 @@ namespace ts {
enableStrict(fs, sources[project.second][source.config]);
enableStrict(fs, sources[project.third][source.config]);
},
modifyAgainFs: fs => addPrologue(fs, relSources[project.first][source.ts][part.one], `"myPrologue"`)
modifyAgainFs: fs => addTestPrologue(fs, relSources[project.first][source.ts][part.one], `"myPrologue"`)
});
// Verify ignore dtsChanged
verifyOutFileScenario({
scenario: "strict in one dependency",
modifyFs: fs => enableStrict(fs, sources[project.second][source.config]),
modifyAgainFs: fs => addPrologue(fs, "src/first/first_PART1.ts", `"myPrologue"`),
modifyAgainFs: fs => addTestPrologue(fs, "src/first/first_PART1.ts", `"myPrologue"`),
ignoreDtsChanged: true,
baselineOnly: true
});
function addPrologue(fs: vfs.FileSystem, path: string, prologue: string) {
prependText(fs, path, `${prologue}
`);
}
// Verify initial + incremental edits - sourcemap verification
verifyOutFileScenario({
scenario: "multiple prologues in all projects",
modifyFs: fs => {
enableStrict(fs, sources[project.first][source.config]);
addPrologue(fs, sources[project.first][source.ts][part.one], `"myPrologue"`);
addTestPrologue(fs, sources[project.first][source.ts][part.one], `"myPrologue"`);
enableStrict(fs, sources[project.second][source.config]);
addPrologue(fs, sources[project.second][source.ts][part.one], `"myPrologue"`);
addPrologue(fs, sources[project.second][source.ts][part.two], `"myPrologue2";`);
addTestPrologue(fs, sources[project.second][source.ts][part.one], `"myPrologue"`);
addTestPrologue(fs, sources[project.second][source.ts][part.two], `"myPrologue2";`);
enableStrict(fs, sources[project.third][source.config]);
addPrologue(fs, sources[project.third][source.ts][part.one], `"myPrologue";`);
addPrologue(fs, sources[project.third][source.ts][part.one], `"myPrologue3";`);
addTestPrologue(fs, sources[project.third][source.ts][part.one], `"myPrologue";`);
addTestPrologue(fs, sources[project.third][source.ts][part.one], `"myPrologue3";`);
},
modifyAgainFs: fs => addPrologue(fs, relSources[project.first][source.ts][part.one], `"myPrologue5"`)
modifyAgainFs: fs => addTestPrologue(fs, relSources[project.first][source.ts][part.one], `"myPrologue5"`)
});
// Verify ignore dtsChanged
@@ -493,11 +482,11 @@ namespace ts {
scenario: "multiple prologues in different projects",
modifyFs: fs => {
enableStrict(fs, sources[project.first][source.config]);
addPrologue(fs, sources[project.second][source.ts][part.one], `"myPrologue"`);
addPrologue(fs, sources[project.second][source.ts][part.two], `"myPrologue2";`);
addTestPrologue(fs, sources[project.second][source.ts][part.one], `"myPrologue"`);
addTestPrologue(fs, sources[project.second][source.ts][part.two], `"myPrologue2";`);
enableStrict(fs, sources[project.third][source.config]);
},
modifyAgainFs: fs => addPrologue(fs, sources[project.first][source.ts][part.one], `"myPrologue5"`),
modifyAgainFs: fs => addTestPrologue(fs, sources[project.first][source.ts][part.one], `"myPrologue5"`),
ignoreDtsChanged: true,
baselineOnly: true
});
@@ -505,11 +494,6 @@ namespace ts {
// Shebang
describe("Shebang", () => {
function addShebang(fs: vfs.FileSystem, project: string, file: string) {
prependText(fs, `src/${project}/${file}.ts`, `#!someshebang ${project} ${file}
`);
}
// changes declaration because its emitted in .d.ts file
// Verify initial + incremental edits
verifyOutFileScenario({
@@ -533,32 +517,6 @@ namespace ts {
// emitHelpers
describe("emitHelpers", () => {
function restContent(project: string, file: string) {
return `function for${project}${file}Rest() {
const { b, ...rest } = { a: 10, b: 30, yy: 30 };
}`;
}
function nonrestContent(project: string, file: string) {
return `function for${project}${file}Rest() { }`;
}
function addRest(fs: vfs.FileSystem, project: string, file: string) {
appendText(fs, `src/${project}/${file}.ts`, restContent(project, file));
}
function removeRest(fs: vfs.FileSystem, project: string, file: string) {
replaceText(fs, `src/${project}/${file}.ts`, restContent(project, file), nonrestContent(project, file));
}
function addStubFoo(fs: vfs.FileSystem, project: string, file: string) {
appendText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file));
}
function changeStubToRest(fs: vfs.FileSystem, project: string, file: string) {
replaceText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file), restContent(project, file));
}
// Verify initial + incremental edits
verifyOutFileScenario({
scenario: "emitHelpers in all projects",
@@ -582,17 +540,6 @@ const { b, ...rest } = { a: 10, b: 30, yy: 30 };
baselineOnly: true
});
function addSpread(fs: vfs.FileSystem, project: string, file: string) {
const path = `src/${project}/${file}.ts`;
const content = fs.readFileSync(path, "utf8");
fs.writeFileSync(path, `${content}
function ${project}${file}Spread(...b: number[]) { }
${project}${file}Spread(...[10, 20, 30]);`);
replaceText(fs, `src/${project}/tsconfig.json`, `"strict": false,`, `"strict": false,
"downlevelIteration": true,`);
}
// Verify ignore dtsChanged
verifyOutFileScenario({
scenario: "multiple emitHelpers in all projects",
@@ -626,17 +573,6 @@ ${project}${file}Spread(...[10, 20, 30]);`);
// triple slash refs
describe("triple slash refs", () => {
// changes declaration because its emitted in .d.ts file
function getTripleSlashRef(project: string) {
return `/src/${project}/tripleRef.d.ts`;
}
function addTripleSlashRef(fs: vfs.FileSystem, project: string, file: string) {
fs.writeFileSync(getTripleSlashRef(project), `declare class ${project}${file} { }`);
prependText(fs, `src/${project}/${file}.ts`, `///<reference path="./tripleRef.d.ts"/>
const ${file}Const = new ${project}${file}();
`);
}
// Verify initial + incremental edits
verifyOutFileScenario({
scenario: "triple slash refs in all projects",