mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-23 18:48:40 -05:00
Add tests to verify output of --out with modules as output
This commit is contained in:
@@ -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",
|
||||
|
||||
202
src/testRunner/unittests/tsbuild/amdModulesWithOut.ts
Normal file
202
src/testRunner/unittests/tsbuild/amdModulesWithOut.ts
Normal 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`),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -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}();
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user