Skip to content

Commit b879b43

Browse files
committed
Add tests to verify output of --out with modules as output
1 parent 276cb58 commit b879b43

27 files changed

+25554
-75
lines changed

src/testRunner/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"unittests/services/preProcessFile.ts",
9090
"unittests/services/textChanges.ts",
9191
"unittests/services/transpile.ts",
92+
"unittests/tsbuild/amdModulesWithOut.ts",
9293
"unittests/tsbuild/emptyFiles.ts",
9394
"unittests/tsbuild/graphOrdering.ts",
9495
"unittests/tsbuild/missingExtendedFile.ts",
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
namespace ts {
2+
describe("unittests:: tsbuild:: outFile:: on amd modules with --out", () => {
3+
let outFileFs: vfs.FileSystem;
4+
const { time, tick } = getTime();
5+
const enum ext { js, jsmap, dts, dtsmap, buildinfo }
6+
const enum project { lib, app }
7+
type OutputFile = [string, string, string, string, string];
8+
function relName(path: string) { return path.slice(1); }
9+
const outputFiles: [OutputFile, OutputFile] = [
10+
[
11+
"/src/lib/module.js",
12+
"/src/lib/module.js.map",
13+
"/src/lib/module.d.ts",
14+
"/src/lib/module.d.ts.map",
15+
"/src/lib/module.tsbuildinfo"
16+
],
17+
[
18+
"/src/app/module.js",
19+
"/src/app/module.js.map",
20+
"/src/app/module.d.ts",
21+
"/src/app/module.d.ts.map",
22+
"/src/app/module.tsbuildinfo"
23+
]
24+
];
25+
type Sources = [string, ReadonlyArray<string>];
26+
const enum source { config, ts }
27+
const sources: [Sources, Sources] = [
28+
[
29+
"/src/lib/tsconfig.json",
30+
[
31+
"/src/lib/file0.ts",
32+
"/src/lib/file1.ts",
33+
"/src/lib/file2.ts",
34+
"/src/lib/global.ts",
35+
]
36+
],
37+
[
38+
"/src/app/tsconfig.json",
39+
[
40+
"/src/app/file3.ts",
41+
"/src/app/file4.ts"
42+
]
43+
]
44+
];
45+
before(() => {
46+
outFileFs = loadProjectFromDisk("tests/projects/amdModulesWithOut", time);
47+
});
48+
after(() => {
49+
outFileFs = undefined!;
50+
});
51+
52+
interface VerifyOutFileScenarioInput {
53+
scenario: string;
54+
modifyFs: (fs: vfs.FileSystem) => void;
55+
modifyAgainFs?: (fs: vfs.FileSystem) => void;
56+
}
57+
58+
function verifyOutFileScenario({
59+
scenario,
60+
modifyFs,
61+
modifyAgainFs
62+
}: VerifyOutFileScenarioInput) {
63+
verifyTsbuildOutput({
64+
scenario,
65+
projFs: () => outFileFs,
66+
time,
67+
tick,
68+
proj: "amdModulesWithOut",
69+
rootNames: ["/src/app"],
70+
expectedMapFileNames: [
71+
outputFiles[project.lib][ext.jsmap],
72+
outputFiles[project.lib][ext.dtsmap],
73+
outputFiles[project.app][ext.jsmap],
74+
outputFiles[project.app][ext.dtsmap],
75+
],
76+
expectedBuildInfoFilesForSectionBaselines: [
77+
[outputFiles[project.lib][ext.buildinfo], outputFiles[project.lib][ext.js], outputFiles[project.lib][ext.dts]],
78+
[outputFiles[project.app][ext.buildinfo], outputFiles[project.app][ext.js], outputFiles[project.app][ext.dts]]
79+
],
80+
lastProjectOutputJs: outputFiles[project.app][ext.js],
81+
initialBuild: {
82+
modifyFs
83+
},
84+
incrementalDtsUnchangedBuild: {
85+
modifyFs: fs => appendText(fs, relName(sources[project.lib][source.ts][1]), "console.log(x);")
86+
},
87+
incrementalHeaderChangedBuild: modifyAgainFs ? {
88+
modifyFs: modifyAgainFs
89+
} : undefined,
90+
outputFiles: [
91+
...outputFiles[project.lib],
92+
...outputFiles[project.app]
93+
],
94+
baselineOnly: true
95+
});
96+
}
97+
98+
describe("Prepend output with .tsbuildinfo", () => {
99+
verifyOutFileScenario({
100+
scenario: "modules and globals mixed in amd",
101+
modifyFs: noop
102+
});
103+
104+
// Prologues
105+
describe("Prologues", () => {
106+
verifyOutFileScenario({
107+
scenario: "multiple prologues in all projects",
108+
modifyFs: fs => {
109+
enableStrict(fs, sources[project.lib][source.config]);
110+
addTestPrologue(fs, sources[project.lib][source.ts][0], `"myPrologue"`);
111+
addTestPrologue(fs, sources[project.lib][source.ts][2], `"myPrologueFile"`);
112+
enableStrict(fs, sources[project.app][source.config]);
113+
addTestPrologue(fs, sources[project.app][source.ts][0], `"myPrologue"`);
114+
addTestPrologue(fs, sources[project.app][source.ts][1], `"myPrologue2";`);
115+
},
116+
modifyAgainFs: fs => addTestPrologue(fs, relName(sources[project.lib][source.ts][1]), `"myPrologue5"`)
117+
});
118+
});
119+
120+
// Shebang
121+
describe("Shebang", () => {
122+
// changes declaration because its emitted in .d.ts file
123+
verifyOutFileScenario({
124+
scenario: "shebang in all projects",
125+
modifyFs: fs => {
126+
addShebang(fs, "lib", "file0");
127+
addShebang(fs, "lib", "file1");
128+
addShebang(fs, "app", "file3");
129+
},
130+
});
131+
});
132+
133+
// emitHelpers
134+
describe("emitHelpers", () => {
135+
verifyOutFileScenario({
136+
scenario: "multiple emitHelpers in all projects",
137+
modifyFs: fs => {
138+
addSpread(fs, "lib", "file0");
139+
addRest(fs, "lib", "file1");
140+
addRest(fs, "app", "file3");
141+
addSpread(fs, "app", "file4");
142+
},
143+
modifyAgainFs: fs => removeRest(fs, "lib", "file1")
144+
});
145+
});
146+
147+
// triple slash refs
148+
describe("triple slash refs", () => {
149+
// changes declaration because its emitted in .d.ts file
150+
verifyOutFileScenario({
151+
scenario: "triple slash refs in all projects",
152+
modifyFs: fs => {
153+
addTripleSlashRef(fs, "lib", "file0");
154+
addTripleSlashRef(fs, "app", "file4");
155+
}
156+
});
157+
});
158+
159+
describe("stripInternal", () => {
160+
function stripInternalScenario(fs: vfs.FileSystem) {
161+
const internal = "/*@internal*/";
162+
replaceText(fs, sources[project.app][source.config], `"composite": true,`, `"composite": true,
163+
"stripInternal": true,`);;
164+
replaceText(fs, sources[project.lib][source.ts][0], "const", `${internal} const`);
165+
appendText(fs, sources[project.lib][source.ts][1], `
166+
export class normalC {
167+
${internal} constructor() { }
168+
${internal} prop: string;
169+
${internal} method() { }
170+
${internal} get c() { return 10; }
171+
${internal} set c(val: number) { }
172+
}
173+
export namespace normalN {
174+
${internal} export class C { }
175+
${internal} export function foo() {}
176+
${internal} export namespace someNamespace { export class C {} }
177+
${internal} export namespace someOther.something { export class someClass {} }
178+
${internal} export import someImport = someNamespace.C;
179+
${internal} export type internalType = internalC;
180+
${internal} export const internalConst = 10;
181+
${internal} export enum internalEnum { a, b, c }
182+
}
183+
${internal} export class internalC {}
184+
${internal} export function internalfoo() {}
185+
${internal} export namespace internalNamespace { export class someClass {} }
186+
${internal} export namespace internalOther.something { export class someClass {} }
187+
${internal} export import internalImport = internalNamespace.someClass;
188+
${internal} export type internalType = internalC;
189+
${internal} export const internalConst = 10;
190+
${internal} export enum internalEnum { a, b, c }`);
191+
}
192+
193+
// Verify initial + incremental edits
194+
verifyOutFileScenario({
195+
scenario: "stripInternal",
196+
modifyFs: stripInternalScenario,
197+
modifyAgainFs: fs => replaceText(fs, sources[project.lib][source.ts][1], `export const`, `/*@internal*/ export const`),
198+
});
199+
});
200+
});
201+
});
202+
}

src/testRunner/unittests/tsbuild/helpers.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,4 +359,66 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt
359359
}
360360
});
361361
}
362+
363+
export function enableStrict(fs: vfs.FileSystem, path: string) {
364+
replaceText(fs, path, `"strict": false`, `"strict": true`);
365+
}
366+
367+
export function addTestPrologue(fs: vfs.FileSystem, path: string, prologue: string) {
368+
prependText(fs, path, `${prologue}
369+
`);
370+
}
371+
372+
export function addShebang(fs: vfs.FileSystem, project: string, file: string) {
373+
prependText(fs, `src/${project}/${file}.ts`, `#!someshebang ${project} ${file}
374+
`);
375+
}
376+
377+
export function restContent(project: string, file: string) {
378+
return `function for${project}${file}Rest() {
379+
const { b, ...rest } = { a: 10, b: 30, yy: 30 };
380+
}`;
381+
}
382+
383+
function nonrestContent(project: string, file: string) {
384+
return `function for${project}${file}Rest() { }`;
385+
}
386+
387+
export function addRest(fs: vfs.FileSystem, project: string, file: string) {
388+
appendText(fs, `src/${project}/${file}.ts`, restContent(project, file));
389+
}
390+
391+
export function removeRest(fs: vfs.FileSystem, project: string, file: string) {
392+
replaceText(fs, `src/${project}/${file}.ts`, restContent(project, file), nonrestContent(project, file));
393+
}
394+
395+
export function addStubFoo(fs: vfs.FileSystem, project: string, file: string) {
396+
appendText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file));
397+
}
398+
399+
export function changeStubToRest(fs: vfs.FileSystem, project: string, file: string) {
400+
replaceText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file), restContent(project, file));
401+
}
402+
403+
export function addSpread(fs: vfs.FileSystem, project: string, file: string) {
404+
const path = `src/${project}/${file}.ts`;
405+
const content = fs.readFileSync(path, "utf8");
406+
fs.writeFileSync(path, `${content}
407+
function ${project}${file}Spread(...b: number[]) { }
408+
${project}${file}Spread(...[10, 20, 30]);`);
409+
410+
replaceText(fs, `src/${project}/tsconfig.json`, `"strict": false,`, `"strict": false,
411+
"downlevelIteration": true,`);
412+
}
413+
414+
export function getTripleSlashRef(project: string) {
415+
return `/src/${project}/tripleRef.d.ts`;
416+
}
417+
418+
export function addTripleSlashRef(fs: vfs.FileSystem, project: string, file: string) {
419+
fs.writeFileSync(getTripleSlashRef(project), `declare class ${project}${file} { }`);
420+
prependText(fs, `src/${project}/${file}.ts`, `///<reference path="./tripleRef.d.ts"/>
421+
const ${file}Const = new ${project}${file}();
422+
`);
423+
}
362424
}

0 commit comments

Comments
 (0)