1namespace ts.tscWatch { 2 describe("unittests:: tsc-watch:: watchAPI:: tsc-watch with custom module resolution", () => { 3 it("verify that module resolution with json extension works when returned without extension", () => { 4 const configFileJson: any = { 5 compilerOptions: { module: "commonjs", resolveJsonModule: true }, 6 files: ["index.ts"] 7 }; 8 const mainFile: File = { 9 path: `${projectRoot}/index.ts`, 10 content: "import settings from './settings.json';" 11 }; 12 const config: File = { 13 path: `${projectRoot}/tsconfig.json`, 14 content: JSON.stringify(configFileJson) 15 }; 16 const settingsJson: File = { 17 path: `${projectRoot}/settings.json`, 18 content: JSON.stringify({ content: "Print this" }) 19 }; 20 const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem( 21 [libFile, mainFile, config, settingsJson], 22 { currentDirectory: projectRoot }), 23 ); 24 const host = createWatchCompilerHostOfConfigFileForBaseline({ 25 configFileName: config.path, 26 system: sys, 27 cb, 28 }); 29 const parsedCommandResult = parseJsonConfigFileContent(configFileJson, sys, config.path); 30 host.resolveModuleNames = (moduleNames, containingFile) => moduleNames.map(m => { 31 const result = resolveModuleName(m, containingFile, parsedCommandResult.options, host); 32 const resolvedModule = result.resolvedModule!; 33 return { 34 resolvedFileName: resolvedModule.resolvedFileName, 35 isExternalLibraryImport: resolvedModule.isExternalLibraryImport, 36 originalFileName: resolvedModule.originalPath, 37 }; 38 }); 39 const watch = createWatchProgram(host); 40 runWatchBaseline({ 41 scenario: "watchApi", 42 subScenario: "verify that module resolution with json extension works when returned without extension", 43 commandLineArgs: ["--w", "--p", config.path], 44 sys, 45 baseline, 46 oldSnap, 47 getPrograms, 48 changes: emptyArray, 49 watchOrSolution: watch 50 }); 51 }); 52 53 describe("hasInvalidatedResolutions", () => { 54 function verifyWatch(subScenario: string, implementHasInvalidatedResolution: boolean) { 55 it(subScenario, () => { 56 const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem({ 57 [`${projectRoot}/tsconfig.json`]: JSON.stringify({ 58 compilerOptions: { traceResolution: true, extendedDiagnostics: true }, 59 files: ["main.ts"] 60 }), 61 [`${projectRoot}/main.ts`]: `import { foo } from "./other";`, 62 [`${projectRoot}/other.d.ts`]: "export function foo(): void;", 63 [libFile.path]: libFile.content, 64 }, { currentDirectory: projectRoot })); 65 const host = createWatchCompilerHostOfConfigFileForBaseline({ 66 configFileName: `${projectRoot}/tsconfig.json`, 67 system: sys, 68 cb, 69 }); 70 host.resolveModuleNames = (moduleNames, containingFile, _reusedNames, _redirectedReference, options) => 71 moduleNames.map(m => resolveModuleName(m, containingFile, options, host).resolvedModule); 72 // Invalidate resolutions only when ts file is created 73 if (implementHasInvalidatedResolution) host.hasInvalidatedResolutions = () => sys.fileExists(`${projectRoot}/other.ts`); 74 const watch = createWatchProgram(host); 75 runWatchBaseline({ 76 scenario: "watchApi", 77 subScenario, 78 commandLineArgs: ["--w"], 79 sys, 80 baseline, 81 oldSnap, 82 getPrograms, 83 changes: [ 84 { 85 caption: "write other with same contents", 86 change: sys => sys.appendFile(`${projectRoot}/other.d.ts`, ""), 87 timeouts: sys => sys.runQueuedTimeoutCallbacks(), 88 }, 89 { 90 caption: "change other file", 91 change: sys => sys.appendFile(`${projectRoot}/other.d.ts`, "export function bar(): void;"), 92 timeouts: sys => sys.runQueuedTimeoutCallbacks(), 93 }, 94 { 95 caption: "write other with same contents but write ts file", 96 change: sys => { 97 sys.appendFile(`${projectRoot}/other.d.ts`, ""); 98 sys.writeFile(`${projectRoot}/other.ts`, "export function foo() {}"); 99 }, 100 timeouts: sys => sys.runQueuedTimeoutCallbacks(), 101 }, 102 ], 103 watchOrSolution: watch 104 }); 105 }); 106 } 107 verifyWatch("host implements does not implement hasInvalidatedResolutions", /*implementHasInvalidatedResolution*/ false); 108 verifyWatch("host implements hasInvalidatedResolutions", /*implementHasInvalidatedResolution*/ true); 109 }); 110 }); 111 112 describe("unittests:: tsc-watch:: watchAPI:: tsc-watch expose error count to watch status reporter", () => { 113 it("verify that the error count is correctly passed down to the watch status reporter", () => { 114 const config: File = { 115 path: `${projectRoot}/tsconfig.json`, 116 content: JSON.stringify({ 117 compilerOptions: { module: "commonjs" }, 118 files: ["index.ts"] 119 }) 120 }; 121 const mainFile: File = { 122 path: `${projectRoot}/index.ts`, 123 content: "let compiler = new Compiler(); for (let i = 0; j < 5; i++) {}" 124 }; 125 const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem( 126 [libFile, mainFile, config], 127 { currentDirectory: projectRoot }), 128 ); 129 const host = createWatchCompilerHostOfConfigFileForBaseline({ 130 configFileName: config.path, 131 system: sys, 132 cb, 133 }); 134 const existing = host.onWatchStatusChange!; 135 let watchedErrorCount; 136 host.onWatchStatusChange = (diagnostic, newLine, options, errorCount) => { 137 existing.call(host, diagnostic, newLine, options, errorCount); 138 watchedErrorCount = errorCount; 139 }; 140 const watch = createWatchProgram(host); 141 assert.equal(watchedErrorCount, 2, "The error count was expected to be 2 for the file change"); 142 runWatchBaseline({ 143 scenario: "watchApi", 144 subScenario: "verify that the error count is correctly passed down to the watch status reporter", 145 commandLineArgs: ["--w", "--p", config.path], 146 sys, 147 baseline, 148 oldSnap, 149 getPrograms, 150 changes: emptyArray, 151 watchOrSolution: watch 152 }); 153 }); 154 }); 155 156 describe("unittests:: tsc-watch:: watchAPI:: when watchHost does not implement setTimeout or clearTimeout", () => { 157 it("verifies that getProgram gets updated program if new file is added to the program", () => { 158 const config: File = { 159 path: `${projectRoot}/tsconfig.json`, 160 content: "{}" 161 }; 162 const mainFile: File = { 163 path: `${projectRoot}/main.ts`, 164 content: "const x = 10;" 165 }; 166 const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([config, mainFile, libFile])); 167 const host = createWatchCompilerHostOfConfigFileForBaseline({ 168 configFileName: config.path, 169 system: sys, 170 cb, 171 }); 172 host.setTimeout = undefined; 173 host.clearTimeout = undefined; 174 const watch = createWatchProgram(host); 175 runWatchBaseline({ 176 scenario: "watchApi", 177 subScenario: "without timesouts on host program gets updated", 178 commandLineArgs: ["--w", "--p", config.path], 179 sys, 180 baseline, 181 oldSnap, 182 getPrograms, 183 changes: [{ 184 caption: "Write a file", 185 change: sys => sys.writeFile(`${projectRoot}/bar.ts`, "const y =10;"), 186 timeouts: sys => { 187 sys.checkTimeoutQueueLength(0); 188 watch.getProgram(); 189 } 190 }], 191 watchOrSolution: watch 192 }); 193 }); 194 }); 195 196 describe("unittests:: tsc-watch:: watchAPI:: when watchHost can add extraFileExtensions to process", () => { 197 it("verifies that extraFileExtensions are supported to get the program with other extensions", () => { 198 const config: File = { 199 path: `${projectRoot}/tsconfig.json`, 200 content: "{}" 201 }; 202 const mainFile: File = { 203 path: `${projectRoot}/main.ts`, 204 content: "const x = 10;" 205 }; 206 const otherFile: File = { 207 path: `${projectRoot}/other.vue`, 208 content: "" 209 }; 210 const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline( 211 createWatchedSystem([config, mainFile, otherFile, libFile]) 212 ); 213 const host = createWatchCompilerHostOfConfigFileForBaseline({ 214 configFileName: config.path, 215 optionsToExtend: { allowNonTsExtensions: true }, 216 extraFileExtensions: [{ extension: ".vue", isMixedContent: true, scriptKind: ScriptKind.Deferred }], 217 system: sys, 218 cb, 219 }); 220 const watch = createWatchProgram(host); 221 runWatchBaseline({ 222 scenario: "watchApi", 223 subScenario: "extraFileExtensions are supported", 224 commandLineArgs: ["--w", "--p", config.path], 225 sys, 226 baseline, 227 oldSnap, 228 getPrograms, 229 changes: [{ 230 caption: "Write a file", 231 change: sys => sys.writeFile(`${projectRoot}/other2.vue`, otherFile.content), 232 timeouts: checkSingleTimeoutQueueLengthAndRun, 233 }], 234 watchOrSolution: watch 235 }); 236 }); 237 }); 238 239 describe("unittests:: tsc-watch:: watchAPI:: when watchHost uses createSemanticDiagnosticsBuilderProgram", () => { 240 function createSystem(configText: string, mainText: string) { 241 const config: File = { 242 path: `${projectRoot}/tsconfig.json`, 243 content: configText 244 }; 245 const mainFile: File = { 246 path: `${projectRoot}/main.ts`, 247 content: mainText 248 }; 249 const otherFile: File = { 250 path: `${projectRoot}/other.ts`, 251 content: "export const y = 10;" 252 }; 253 return { 254 ...createBaseline(createWatchedSystem([config, mainFile, otherFile, libFile])), 255 config, 256 mainFile, 257 otherFile, 258 }; 259 } 260 261 function createWatch<T extends BuilderProgram>( 262 baseline: string[], 263 config: File, 264 sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, 265 createProgram: CreateProgram<T>, 266 optionsToExtend?: CompilerOptions, 267 ) { 268 const { cb, getPrograms } = commandLineCallbacks(sys); 269 baseline.push(`tsc --w${optionsToExtend?.noEmit ? " --noEmit" : ""}`); 270 const oldSnap = sys.snap(); 271 const host = createWatchCompilerHostOfConfigFileForBaseline<T>({ 272 configFileName: config.path, 273 optionsToExtend, 274 createProgram, 275 system: sys, 276 cb, 277 }); 278 const watch = createWatchProgram(host); 279 watchBaseline({ 280 baseline, 281 getPrograms, 282 oldPrograms: emptyArray, 283 sys, 284 oldSnap, 285 }); 286 watch.close(); 287 } 288 289 function verifyOutputs(baseline: string[], sys: System, emitSys: System) { 290 baseline.push("Checking if output is same as EmitAndSemanticDiagnosticsBuilderProgram::"); 291 for (const output of [`${projectRoot}/main.js`, `${projectRoot}/main.d.ts`, `${projectRoot}/other.js`, `${projectRoot}/other.d.ts`, `${projectRoot}/tsconfig.tsbuildinfo`]) { 292 baseline.push(`Output file text for ${output} is same:: ${sys.readFile(output) === emitSys.readFile(output)}`); 293 } 294 baseline.push(""); 295 } 296 297 function createSystemForBuilderTest(configText: string, mainText: string) { 298 const result = createSystem(configText, mainText); 299 const { sys: emitSys, baseline: emitBaseline } = createSystem(configText, mainText); 300 return { ...result, emitSys, emitBaseline }; 301 } 302 303 function applyChangeForBuilderTest( 304 baseline: string[], 305 emitBaseline: string[], 306 sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, 307 emitSys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, 308 change: (sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles) => void, 309 caption: string 310 ) { 311 // Change file 312 applyChange(sys, baseline, change, caption); 313 applyChange(emitSys, emitBaseline, change, caption); 314 } 315 316 function verifyBuilder<T extends BuilderProgram>( 317 baseline: string[], 318 emitBaseline: string[], 319 config: File, 320 sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, 321 emitSys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, 322 createProgram: CreateProgram<T>, 323 optionsToExtend?: CompilerOptions) { 324 createWatch(baseline, config, sys, createProgram, optionsToExtend); 325 createWatch(emitBaseline, config, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram, optionsToExtend); 326 verifyOutputs(baseline, sys, emitSys); 327 } 328 329 it("verifies that noEmit is handled on createSemanticDiagnosticsBuilderProgram and typechecking happens only on affected files", () => { 330 const { sys, baseline, oldSnap, cb, getPrograms, config, mainFile } = createSystem("{}", "export const x = 10;"); 331 const host = createWatchCompilerHostOfConfigFileForBaseline({ 332 configFileName: config.path, 333 optionsToExtend: { noEmit: true }, 334 createProgram: createSemanticDiagnosticsBuilderProgram, 335 system: sys, 336 cb, 337 }); 338 const watch = createWatchProgram(host); 339 runWatchBaseline({ 340 scenario: "watchApi", 341 subScenario: "verifies that noEmit is handled on createSemanticDiagnosticsBuilderProgram", 342 commandLineArgs: ["--w", "--p", config.path], 343 sys, 344 baseline, 345 oldSnap, 346 getPrograms, 347 changes: [{ 348 caption: "Modify a file", 349 change: sys => sys.appendFile(mainFile.path, "\n// SomeComment"), 350 timeouts: runQueuedTimeoutCallbacks, 351 }], 352 watchOrSolution: watch 353 }); 354 }); 355 356 describe("noEmit with composite writes the tsbuildinfo with pending affected files correctly", () => { 357 let baseline: string[]; 358 let emitBaseline: string[]; 359 before(() => { 360 const configText = JSON.stringify({ compilerOptions: { composite: true } }); 361 const mainText = "export const x = 10;"; 362 const result = createSystemForBuilderTest(configText, mainText); 363 baseline = result.baseline; 364 emitBaseline = result.emitBaseline; 365 const { sys, config, mainFile, emitSys } = result; 366 367 // No Emit 368 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram, { noEmit: true }); 369 370 // Emit on both sys should result in same output 371 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram); 372 373 // Change file 374 applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.appendFile(mainFile.path, "\n// SomeComment"), "Add comment"); 375 376 // Verify noEmit results in same output 377 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram, { noEmit: true }); 378 379 // Emit on both sys should result in same output 380 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram); 381 382 // Change file 383 applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.appendFile(mainFile.path, "\n// SomeComment"), "Add comment"); 384 385 // Emit on both the builders should result in same files 386 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); 387 }); 388 after(() => { 389 baseline = undefined!; 390 emitBaseline = undefined!; 391 }); 392 it("noEmit with composite writes the tsbuildinfo with pending affected files correctly", () => { 393 Harness.Baseline.runBaseline(`tscWatch/watchApi/noEmit-with-composite-with-semantic-builder.js`, baseline.join("\r\n")); 394 }); 395 it("baseline in createEmitAndSemanticDiagnosticsBuilderProgram:: noEmit with composite writes the tsbuildinfo with pending affected files correctly", () => { 396 Harness.Baseline.runBaseline(`tscWatch/watchApi/noEmit-with-composite-with-emit-builder.js`, emitBaseline.join("\r\n")); 397 }); 398 }); 399 400 describe("noEmitOnError with composite writes the tsbuildinfo with pending affected files correctly", () => { 401 let baseline: string[]; 402 let emitBaseline: string[]; 403 before(() => { 404 const configText = JSON.stringify({ compilerOptions: { composite: true, noEmitOnError: true } }); 405 const mainText = "export const x: string = 10;"; 406 const result = createSystemForBuilderTest(configText, mainText); 407 baseline = result.baseline; 408 emitBaseline = result.emitBaseline; 409 const { sys, config, mainFile, emitSys } = result; 410 411 // Verify noEmit results in same output 412 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); 413 414 // Change file 415 applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.appendFile(mainFile.path, "\n// SomeComment"), "Add comment"); 416 417 // Verify noEmit results in same output 418 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); 419 420 // Fix error 421 const fixed = "export const x = 10;"; 422 applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.writeFile(mainFile.path, fixed), "Fix error"); 423 424 // Emit on both the builders should result in same files 425 verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); 426 }); 427 428 it("noEmitOnError with composite writes the tsbuildinfo with pending affected files correctly", () => { 429 Harness.Baseline.runBaseline(`tscWatch/watchApi/noEmitOnError-with-composite-with-semantic-builder.js`, baseline.join("\r\n")); 430 }); 431 it("baseline in createEmitAndSemanticDiagnosticsBuilderProgram:: noEmitOnError with composite writes the tsbuildinfo with pending affected files correctly", () => { 432 Harness.Baseline.runBaseline(`tscWatch/watchApi/noEmitOnError-with-composite-with-emit-builder.js`, emitBaseline.join("\r\n")); 433 }); 434 }); 435 436 it("SemanticDiagnosticsBuilderProgram emitDtsOnly does not update affected files pending emit", () => { 437 // Initial 438 const { sys, baseline, config, mainFile } = createSystem(JSON.stringify({ compilerOptions: { composite: true, noEmitOnError: true } }), "export const x: string = 10;"); 439 createWatch(baseline, config, sys, createSemanticDiagnosticsBuilderProgram); 440 441 // Fix error and emit 442 applyChange(sys, baseline, sys => sys.writeFile(mainFile.path, "export const x = 10;"), "Fix error"); 443 444 const { cb, getPrograms } = commandLineCallbacks(sys); 445 const oldSnap = sys.snap(); 446 const reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true); 447 const reportWatchStatus = createWatchStatusReporter(sys, /*pretty*/ true); 448 const host = createWatchCompilerHostOfConfigFile({ 449 configFileName: config.path, 450 createProgram: createSemanticDiagnosticsBuilderProgram, 451 system: sys, 452 reportDiagnostic, 453 reportWatchStatus, 454 }); 455 host.afterProgramCreate = program => { 456 const diagnostics = sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics()); 457 diagnostics.forEach(reportDiagnostic); 458 // Buildinfo should still have affectedFilesPendingEmit since we are only emitting dts files 459 program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDts*/ true); 460 reportWatchStatus( 461 createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(diagnostics.length), diagnostics.length), 462 sys.newLine, 463 program.getCompilerOptions(), 464 diagnostics.length 465 ); 466 cb(program); 467 }; 468 createWatchProgram(host); 469 watchBaseline({ 470 baseline, 471 getPrograms, 472 oldPrograms: emptyArray, 473 sys, 474 oldSnap, 475 }); 476 Harness.Baseline.runBaseline(`tscWatch/watchApi/semantic-builder-emitOnlyDts.js`, baseline.join("\r\n")); 477 }); 478 }); 479 480 describe("unittests:: tsc-watch:: watchAPI:: when getParsedCommandLine is implemented", () => { 481 function setup(useSourceOfProjectReferenceRedirect?: () => boolean) { 482 const config1: File = { 483 path: `${projectRoot}/projects/project1/tsconfig.json`, 484 content: JSON.stringify({ 485 compilerOptions: { 486 module: "none", 487 composite: true 488 }, 489 exclude: ["temp"] 490 }) 491 }; 492 const class1: File = { 493 path: `${projectRoot}/projects/project1/class1.ts`, 494 content: `class class1 {}` 495 }; 496 const class1Dts: File = { 497 path: `${projectRoot}/projects/project1/class1.d.ts`, 498 content: `declare class class1 {}` 499 }; 500 const config2: File = { 501 path: `${projectRoot}/projects/project2/tsconfig.json`, 502 content: JSON.stringify({ 503 compilerOptions: { 504 module: "none", 505 composite: true 506 }, 507 references: [ 508 { path: "../project1" } 509 ] 510 }) 511 }; 512 const class2: File = { 513 path: `${projectRoot}/projects/project2/class2.ts`, 514 content: `class class2 {}` 515 }; 516 const system = createWatchedSystem([config1, class1, class1Dts, config2, class2, libFile]); 517 const baseline = createBaseline(system); 518 const compilerHost = createWatchCompilerHostOfConfigFileForBaseline({ 519 cb: baseline.cb, 520 system, 521 configFileName: config2.path, 522 optionsToExtend: { extendedDiagnostics: true } 523 }); 524 compilerHost.useSourceOfProjectReferenceRedirect = useSourceOfProjectReferenceRedirect; 525 const calledGetParsedCommandLine = new Set<string>(); 526 compilerHost.getParsedCommandLine = fileName => { 527 assert.isFalse(calledGetParsedCommandLine.has(fileName), `Already called on ${fileName}`); 528 calledGetParsedCommandLine.add(fileName); 529 return getParsedCommandLineOfConfigFile(fileName, /*optionsToExtend*/ undefined, { 530 useCaseSensitiveFileNames: true, 531 fileExists: path => system.fileExists(path), 532 readFile: path => system.readFile(path), 533 getCurrentDirectory: () => system.getCurrentDirectory(), 534 readDirectory: (path, extensions, excludes, includes, depth) => system.readDirectory(path, extensions, excludes, includes, depth), 535 onUnRecoverableConfigFileDiagnostic: noop, 536 }); 537 }; 538 const watch = createWatchProgram(compilerHost); 539 return { watch, baseline, config2, calledGetParsedCommandLine }; 540 } 541 542 it("when new file is added to the referenced project with host implementing getParsedCommandLine", () => { 543 const { watch, baseline, config2, calledGetParsedCommandLine } = setup(returnTrue); 544 runWatchBaseline({ 545 scenario: "watchApi", 546 subScenario: "when new file is added to the referenced project with host implementing getParsedCommandLine", 547 commandLineArgs: ["--w", "-p", config2.path, "--extendedDiagnostics"], 548 ...baseline, 549 changes: [ 550 { 551 caption: "Add class3 to project1", 552 change: sys => { 553 calledGetParsedCommandLine.clear(); 554 sys.writeFile(`${projectRoot}/projects/project1/class3.ts`, `class class3 {}`); 555 }, 556 timeouts: checkSingleTimeoutQueueLengthAndRun, 557 }, 558 { 559 caption: "Add excluded file to project1", 560 change: sys => sys.ensureFileOrFolder({ path: `${projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), 561 timeouts: sys => sys.checkTimeoutQueueLength(0), 562 }, 563 { 564 caption: "Add output of class3", 565 change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), 566 timeouts: sys => sys.checkTimeoutQueueLength(0), 567 }, 568 ], 569 watchOrSolution: watch 570 }); 571 }); 572 573 it("when new file is added to the referenced project with host implementing getParsedCommandLine without implementing useSourceOfProjectReferenceRedirect", () => { 574 const { watch, baseline, config2, calledGetParsedCommandLine } = setup(); 575 runWatchBaseline({ 576 scenario: "watchApi", 577 subScenario: "when new file is added to the referenced project with host implementing getParsedCommandLine without implementing useSourceOfProjectReferenceRedirect", 578 commandLineArgs: ["--w", "-p", config2.path, "--extendedDiagnostics"], 579 ...baseline, 580 changes: [ 581 { 582 caption: "Add class3 to project1", 583 change: sys => { 584 calledGetParsedCommandLine.clear(); 585 sys.writeFile(`${projectRoot}/projects/project1/class3.ts`, `class class3 {}`); 586 }, 587 timeouts: checkSingleTimeoutQueueLengthAndRun, 588 }, 589 { 590 caption: "Add class3 output to project1", 591 change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), 592 timeouts: checkSingleTimeoutQueueLengthAndRun, 593 }, 594 { 595 caption: "Add excluded file to project1", 596 change: sys => sys.ensureFileOrFolder({ path: `${projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), 597 timeouts: sys => sys.checkTimeoutQueueLength(0), 598 }, 599 { 600 caption: "Delete output of class3", 601 change: sys => sys.deleteFile(`${projectRoot}/projects/project1/class3.d.ts`), 602 timeouts: checkSingleTimeoutQueueLengthAndRun, 603 }, 604 { 605 caption: "Add output of class3", 606 change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), 607 timeouts: checkSingleTimeoutQueueLengthAndRun, 608 }, 609 ], 610 watchOrSolution: watch 611 }); 612 }); 613 }); 614} 615