1namespace ts { 2 describe("unittests:: tsbuild:: outFile:: on amd modules with --out", () => { 3 let outFileFs: vfs.FileSystem; 4 const enum Project { lib, app } 5 function relName(path: string) { return path.slice(1); } 6 type Sources = [string, readonly string[]]; 7 const enum Source { config, ts } 8 const sources: [Sources, Sources] = [ 9 [ 10 "/src/lib/tsconfig.json", 11 [ 12 "/src/lib/file0.ts", 13 "/src/lib/file1.ts", 14 "/src/lib/file2.ts", 15 "/src/lib/global.ts", 16 ] 17 ], 18 [ 19 "/src/app/tsconfig.json", 20 [ 21 "/src/app/file3.ts", 22 "/src/app/file4.ts" 23 ] 24 ] 25 ]; 26 before(() => { 27 outFileFs = loadProjectFromDisk("tests/projects/amdModulesWithOut"); 28 }); 29 after(() => { 30 outFileFs = undefined!; 31 }); 32 33 interface VerifyOutFileScenarioInput { 34 subScenario: string; 35 modifyFs?: (fs: vfs.FileSystem) => void; 36 modifyAgainFs?: (fs: vfs.FileSystem) => void; 37 } 38 39 function verifyOutFileScenario({ 40 subScenario, 41 modifyFs, 42 modifyAgainFs 43 }: VerifyOutFileScenarioInput) { 44 verifyTscIncrementalEdits({ 45 scenario: "amdModulesWithOut", 46 subScenario, 47 fs: () => outFileFs, 48 commandLineArgs: ["--b", "/src/app", "--verbose"], 49 baselineSourceMap: true, 50 modifyFs, 51 incrementalScenarios: [ 52 { 53 buildKind: BuildKind.IncrementalDtsUnchanged, 54 modifyFs: fs => appendText(fs, relName(sources[Project.lib][Source.ts][1]), "console.log(x);") 55 }, 56 ...(modifyAgainFs ? [{ 57 buildKind: BuildKind.IncrementalHeadersChange, 58 modifyFs: modifyAgainFs 59 }] : emptyArray), 60 ] 61 }); 62 } 63 64 describe("Prepend output with .tsbuildinfo", () => { 65 verifyOutFileScenario({ 66 subScenario: "modules and globals mixed in amd", 67 }); 68 69 // Prologues 70 describe("Prologues", () => { 71 verifyOutFileScenario({ 72 subScenario: "multiple prologues in all projects", 73 modifyFs: fs => { 74 enableStrict(fs, sources[Project.lib][Source.config]); 75 addTestPrologue(fs, sources[Project.lib][Source.ts][0], `"myPrologue"`); 76 addTestPrologue(fs, sources[Project.lib][Source.ts][2], `"myPrologueFile"`); 77 addTestPrologue(fs, sources[Project.lib][Source.ts][3], `"myPrologue3"`); 78 enableStrict(fs, sources[Project.app][Source.config]); 79 addTestPrologue(fs, sources[Project.app][Source.ts][0], `"myPrologue"`); 80 addTestPrologue(fs, sources[Project.app][Source.ts][1], `"myPrologue2";`); 81 }, 82 modifyAgainFs: fs => addTestPrologue(fs, relName(sources[Project.lib][Source.ts][1]), `"myPrologue5"`) 83 }); 84 }); 85 86 // Shebang 87 describe("Shebang", () => { 88 // changes declaration because its emitted in .d.ts file 89 verifyOutFileScenario({ 90 subScenario: "shebang in all projects", 91 modifyFs: fs => { 92 addShebang(fs, "lib", "file0"); 93 addShebang(fs, "lib", "file1"); 94 addShebang(fs, "app", "file3"); 95 }, 96 }); 97 }); 98 99 // emitHelpers 100 describe("emitHelpers", () => { 101 verifyOutFileScenario({ 102 subScenario: "multiple emitHelpers in all projects", 103 modifyFs: fs => { 104 addSpread(fs, "lib", "file0"); 105 addRest(fs, "lib", "file1"); 106 addRest(fs, "app", "file3"); 107 addSpread(fs, "app", "file4"); 108 }, 109 modifyAgainFs: fs => removeRest(fs, "lib", "file1") 110 }); 111 }); 112 113 // triple slash refs 114 describe("triple slash refs", () => { 115 // changes declaration because its emitted in .d.ts file 116 verifyOutFileScenario({ 117 subScenario: "triple slash refs in all projects", 118 modifyFs: fs => { 119 addTripleSlashRef(fs, "lib", "file0"); 120 addTripleSlashRef(fs, "app", "file4"); 121 } 122 }); 123 }); 124 125 describe("stripInternal", () => { 126 function stripInternalScenario(fs: vfs.FileSystem) { 127 const internal = "/*@internal*/"; 128 replaceText(fs, sources[Project.app][Source.config], `"composite": true,`, `"composite": true, 129"stripInternal": true,`); 130 replaceText(fs, sources[Project.lib][Source.ts][0], "const", `${internal} const`); 131 appendText(fs, sources[Project.lib][Source.ts][1], ` 132export class normalC { 133 ${internal} constructor() { } 134 ${internal} prop: string; 135 ${internal} method() { } 136 ${internal} get c() { return 10; } 137 ${internal} set c(val: number) { } 138} 139export namespace normalN { 140 ${internal} export class C { } 141 ${internal} export function foo() {} 142 ${internal} export namespace someNamespace { export class C {} } 143 ${internal} export namespace someOther.something { export class someClass {} } 144 ${internal} export import someImport = someNamespace.C; 145 ${internal} export type internalType = internalC; 146 ${internal} export const internalConst = 10; 147 ${internal} export enum internalEnum { a, b, c } 148} 149${internal} export class internalC {} 150${internal} export function internalfoo() {} 151${internal} export namespace internalNamespace { export class someClass {} } 152${internal} export namespace internalOther.something { export class someClass {} } 153${internal} export import internalImport = internalNamespace.someClass; 154${internal} export type internalType = internalC; 155${internal} export const internalConst = 10; 156${internal} export enum internalEnum { a, b, c }`); 157 } 158 159 // Verify initial + incremental edits 160 verifyOutFileScenario({ 161 subScenario: "stripInternal", 162 modifyFs: stripInternalScenario, 163 modifyAgainFs: fs => replaceText(fs, sources[Project.lib][Source.ts][1], `export const`, `/*@internal*/ export const`), 164 }); 165 }); 166 167 describe("when the module resolution finds original source file", () => { 168 function modifyFs(fs: vfs.FileSystem) { 169 // Make lib to output to parent dir 170 replaceText(fs, sources[Project.lib][Source.config], `"outFile": "module.js"`, `"outFile": "../module.js", "rootDir": "../"`); 171 // Change reference to file1 module to resolve to lib/file1 172 replaceText(fs, sources[Project.app][Source.ts][0], "file1", "lib/file1"); 173 } 174 175 verifyTsc({ 176 scenario: "amdModulesWithOut", 177 subScenario: "when the module resolution finds original source file", 178 fs: () => outFileFs, 179 commandLineArgs: ["-b", "/src/app", "--verbose"], 180 modifyFs, 181 baselineSourceMap: true, 182 }); 183 }); 184 }); 185 }); 186} 187