1namespace ts.tscWatch { 2 describe("unittests:: tsc-watch:: projects with references: invoking when references are already built", () => { 3 verifyTscWatch({ 4 scenario: "projectsWithReferences", 5 subScenario: "on sample project", 6 sys: () => createSystemWithSolutionBuild( 7 ["tests"], 8 [ 9 libFile, 10 TestFSWithWatch.getTsBuildProjectFile("sample1", "core/tsconfig.json"), 11 TestFSWithWatch.getTsBuildProjectFile("sample1", "core/index.ts"), 12 TestFSWithWatch.getTsBuildProjectFile("sample1", "core/anotherModule.ts"), 13 TestFSWithWatch.getTsBuildProjectFile("sample1", "core/some_decl.d.ts"), 14 TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/tsconfig.json"), 15 TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/index.ts"), 16 TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/tsconfig.json"), 17 TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/index.ts"), 18 ], 19 { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/sample1` } 20 ), 21 commandLineArgs: ["-w", "-p", "tests"], 22 changes: [ 23 { 24 caption: "local edit in logic ts, and build logic", 25 change: sys => { 26 sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `function foo() { }`); 27 const solutionBuilder = createSolutionBuilder(sys, ["logic"]); 28 solutionBuilder.build(); 29 }, 30 // not ideal, but currently because of d.ts but no new file is written 31 // There will be timeout queued even though file contents are same 32 timeouts: sys => sys.checkTimeoutQueueLength(0), 33 }, 34 { 35 caption: "non local edit in logic ts, and build logic", 36 change: sys => { 37 sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `export function gfoo() { }`); 38 const solutionBuilder = createSolutionBuilder(sys, ["logic"]); 39 solutionBuilder.build(); 40 }, 41 timeouts: checkSingleTimeoutQueueLengthAndRun 42 }, 43 { 44 caption: "change in project reference config file builds correctly", 45 change: sys => { 46 sys.writeFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/tsconfig.json"), JSON.stringify({ 47 compilerOptions: { composite: true, declaration: true, declarationDir: "decls" }, 48 references: [{ path: "../core" }] 49 })); 50 const solutionBuilder = createSolutionBuilder(sys, ["logic"]); 51 solutionBuilder.build(); 52 }, 53 timeouts: checkSingleTimeoutQueueLengthAndRun 54 }, 55 ], 56 baselineDependencies: true 57 }); 58 59 function changeCompilerOpitonsPaths(sys: WatchedSystem, config: string, newPaths: object) { 60 const configJson = JSON.parse(sys.readFile(config)!); 61 configJson.compilerOptions.paths = newPaths; 62 sys.writeFile(config, JSON.stringify(configJson)); 63 } 64 65 verifyTscWatch({ 66 scenario: "projectsWithReferences", 67 subScenario: "on transitive references", 68 sys: () => createSystemWithSolutionBuild( 69 ["tsconfig.c.json"], 70 [ 71 libFile, 72 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"), 73 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json"), 74 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"), 75 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"), 76 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "b.ts"), 77 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"), 78 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), 79 ], 80 { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } 81 ), 82 commandLineArgs: ["-w", "-p", "tsconfig.c.json"], 83 changes: [ 84 { 85 caption: "non local edit b ts, and build b", 86 change: sys => { 87 sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"), `export function gfoo() { }`); 88 const solutionBuilder = createSolutionBuilder(sys, ["tsconfig.b.json"]); 89 solutionBuilder.build(); 90 }, 91 timeouts: checkSingleTimeoutQueueLengthAndRun 92 }, 93 { 94 caption: "edit on config file", 95 change: sys => { 96 sys.ensureFileOrFolder({ 97 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), 98 content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! 99 }); 100 changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./nrefs/*"] }); 101 }, 102 timeouts: checkSingleTimeoutQueueLengthAndRun 103 }, 104 { 105 caption: "Revert config file edit", 106 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./refs/*"] }), 107 timeouts: checkSingleTimeoutQueueLengthAndRun 108 }, 109 { 110 caption: "edit in referenced config file", 111 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./nrefs/*"] }), 112 timeouts: checkSingleTimeoutQueueLengthAndRun 113 }, 114 { 115 caption: "Revert referenced config file edit", 116 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./refs/*"] }), 117 timeouts: checkSingleTimeoutQueueLengthAndRun 118 }, 119 { 120 caption: "deleting referenced config file", 121 change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json")), 122 timeouts: checkSingleTimeoutQueueLengthAndRun 123 }, 124 { 125 caption: "Revert deleting referenced config file", 126 change: sys => sys.ensureFileOrFolder(TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json")), 127 timeouts: checkSingleTimeoutQueueLengthAndRun 128 }, 129 { 130 caption: "deleting transitively referenced config file", 131 change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.a.json")), 132 timeouts: checkSingleTimeoutQueueLengthAndRun 133 }, 134 { 135 caption: "Revert deleting transitively referenced config file", 136 change: sys => sys.ensureFileOrFolder(TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json")), 137 timeouts: checkSingleTimeoutQueueLengthAndRun 138 }, 139 ], 140 baselineDependencies: true, 141 }); 142 143 verifyTscWatch({ 144 scenario: "projectsWithReferences", 145 subScenario: "when referenced project uses different module resolution", 146 sys: () => createSystemWithSolutionBuild( 147 ["tsconfig.c.json"], 148 [ 149 libFile, 150 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"), 151 { 152 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), 153 content: JSON.stringify({ 154 compilerOptions: { composite: true, moduleResolution: "classic" }, 155 files: ["b.ts"], 156 references: [{ path: "tsconfig.a.json" }] 157 }) 158 }, 159 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"), 160 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"), 161 { 162 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"), 163 content: `import {A} from "a";export const b = new A();` 164 }, 165 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"), 166 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), 167 ], 168 { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } 169 ), 170 commandLineArgs: ["-w", "-p", "tsconfig.c.json"], 171 changes: emptyArray, 172 baselineDependencies: true, 173 }); 174 175 verifyTscWatch({ 176 scenario: "projectsWithReferences", 177 subScenario: "on transitive references in different folders", 178 sys: () => createSystemWithSolutionBuild( 179 ["c"], 180 [ 181 libFile, 182 { 183 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), 184 content: JSON.stringify({ 185 compilerOptions: { composite: true }, 186 files: ["index.ts"] 187 }), 188 }, 189 { 190 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), 191 content: JSON.stringify({ 192 compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, 193 files: ["index.ts"], 194 references: [{ path: `../a` }] 195 }), 196 }, 197 { 198 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), 199 content: JSON.stringify({ 200 compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } }, 201 files: ["index.ts"], 202 references: [{ path: `../b` }] 203 }), 204 }, 205 { 206 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"), 207 content: `export class A {}`, 208 }, 209 { 210 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), 211 content: `import {A} from '@ref/a'; 212export const b = new A();`, 213 }, 214 { 215 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"), 216 content: `import {b} from '../b'; 217import {X} from "@ref/a"; 218b; 219X;`, 220 }, 221 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), 222 ], 223 { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } 224 ), 225 commandLineArgs: ["-w", "-p", "c"], 226 changes: [ 227 { 228 caption: "non local edit b ts, and build b", 229 change: sys => { 230 sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`); 231 const solutionBuilder = createSolutionBuilder(sys, ["b"]); 232 solutionBuilder.build(); 233 }, 234 timeouts: checkSingleTimeoutQueueLengthAndRun 235 }, 236 { 237 caption: "edit on config file", 238 change: sys => { 239 sys.ensureFileOrFolder({ 240 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), 241 content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! 242 }); 243 changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }); 244 }, 245 timeouts: checkSingleTimeoutQueueLengthAndRun 246 }, 247 { 248 caption: "Revert config file edit", 249 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }), 250 timeouts: checkSingleTimeoutQueueLengthAndRun 251 }, 252 { 253 caption: "edit in referenced config file", 254 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }), 255 timeouts: checkSingleTimeoutQueueLengthAndRun 256 }, 257 { 258 caption: "Revert referenced config file edit", 259 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }), 260 timeouts: checkSingleTimeoutQueueLengthAndRun 261 }, 262 { 263 caption: "deleting referenced config file", 264 change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")), 265 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 266 }, 267 { 268 caption: "Revert deleting referenced config file", 269 change: sys => sys.writeFile( 270 TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), 271 JSON.stringify({ 272 compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, 273 files: ["index.ts"], 274 references: [{ path: `../a` }] 275 }) 276 ), 277 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 278 }, 279 { 280 caption: "deleting transitively referenced config file", 281 change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")), 282 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 283 }, 284 { 285 caption: "Revert deleting transitively referenced config file", 286 change: sys => sys.writeFile( 287 TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), 288 JSON.stringify({ 289 compilerOptions: { composite: true }, 290 files: ["index.ts"] 291 }), 292 ), 293 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 294 }, 295 ], 296 baselineDependencies: true, 297 }); 298 299 verifyTscWatch({ 300 scenario: "projectsWithReferences", 301 subScenario: "on transitive references in different folders with no files clause", 302 sys: () => createSystemWithSolutionBuild( 303 ["c"], 304 [ 305 libFile, 306 { 307 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), 308 content: JSON.stringify({ compilerOptions: { composite: true } }), 309 }, 310 { 311 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), 312 content: JSON.stringify({ 313 compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, 314 references: [{ path: `../a` }] 315 }), 316 }, 317 { 318 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), 319 content: JSON.stringify({ 320 compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } }, 321 references: [{ path: `../b` }] 322 }), 323 }, 324 { 325 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"), 326 content: `export class A {}`, 327 }, 328 { 329 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), 330 content: `import {A} from '@ref/a'; 331export const b = new A();`, 332 }, 333 { 334 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"), 335 content: `import {b} from '../b'; 336import {X} from "@ref/a"; 337b; 338X;`, 339 }, 340 TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), 341 ], 342 { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } 343 ), 344 commandLineArgs: ["-w", "-p", "c"], 345 changes: [ 346 { 347 caption: "non local edit b ts, and build b", 348 change: sys => { 349 sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`); 350 const solutionBuilder = createSolutionBuilder(sys, ["b"]); 351 solutionBuilder.build(); 352 }, 353 timeouts: checkSingleTimeoutQueueLengthAndRun 354 }, 355 { 356 caption: "edit on config file", 357 change: sys => { 358 sys.ensureFileOrFolder({ 359 path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), 360 content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! 361 }); 362 changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }); 363 }, 364 timeouts: checkSingleTimeoutQueueLengthAndRun 365 }, 366 { 367 caption: "Revert config file edit", 368 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }), 369 timeouts: checkSingleTimeoutQueueLengthAndRun 370 }, 371 { 372 caption: "edit in referenced config file", 373 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }), 374 timeouts: checkSingleTimeoutQueueLengthAndRun 375 }, 376 { 377 caption: "Revert referenced config file edit", 378 change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }), 379 timeouts: checkSingleTimeoutQueueLengthAndRun 380 }, 381 { 382 caption: "deleting referenced config file", 383 change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")), 384 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 385 }, 386 { 387 caption: "Revert deleting referenced config file", 388 change: sys => sys.writeFile( 389 TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), 390 JSON.stringify({ 391 compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, 392 references: [{ path: `../a` }] 393 }) 394 ), 395 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 396 }, 397 { 398 caption: "deleting transitively referenced config file", 399 change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")), 400 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 401 }, 402 { 403 caption: "Revert deleting transitively referenced config file", 404 change: sys => sys.writeFile( 405 TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), 406 JSON.stringify({ compilerOptions: { composite: true } }), 407 ), 408 timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) 409 }, 410 ], 411 baselineDependencies: true, 412 }); 413 }); 414}