diff --git a/src/testRunner/unittests/tscWatch/watchApi.ts b/src/testRunner/unittests/tscWatch/watchApi.ts index 01172b983ca30..d93383b173c0a 100644 --- a/src/testRunner/unittests/tscWatch/watchApi.ts +++ b/src/testRunner/unittests/tscWatch/watchApi.ts @@ -125,10 +125,15 @@ namespace ts.tscWatch { }); describe("unittests:: tsc-watch:: watchAPI:: when watchHost uses createSemanticDiagnosticsBuilderProgram", () => { - it("verifies that noEmit is handled on createSemanticDiagnosticsBuilderProgram and typechecking happens only on affected files", () => { + function getWatch(config: File, optionsToExtend: CompilerOptions | undefined, sys: System, createProgram: CreateProgram) { + const watchCompilerHost = createWatchCompilerHost(config.path, optionsToExtend, sys, createProgram); + return createWatchProgram(watchCompilerHost); + } + + function setup(createProgram: CreateProgram, configText: string) { const config: File = { path: `${projectRoot}/tsconfig.json`, - content: "{}" + content: configText }; const mainFile: File = { path: `${projectRoot}/main.ts`, @@ -139,13 +144,11 @@ namespace ts.tscWatch { content: "export const y = 10;" }; const sys = createWatchedSystem([config, mainFile, otherFile, libFile]); - const watchCompilerHost = createWatchCompilerHost( - config.path, - { noEmit: true }, - sys, - createSemanticDiagnosticsBuilderProgram - ); - const watch = createWatchProgram(watchCompilerHost); + const watch = getWatch(config, { noEmit: true }, sys, createProgram); + return { sys, watch, mainFile, otherFile, config }; + } + it("verifies that noEmit is handled on createSemanticDiagnosticsBuilderProgram and typechecking happens only on affected files", () => { + const { sys, watch, mainFile, otherFile } = setup(createSemanticDiagnosticsBuilderProgram, "{}"); checkProgramActualFiles(watch.getProgram().getProgram(), [mainFile.path, otherFile.path, libFile.path]); sys.appendFile(mainFile.path, "\n// SomeComment"); sys.runQueuedTimeoutCallbacks(); @@ -154,5 +157,49 @@ namespace ts.tscWatch { // Should not retrieve diagnostics for other file thats not changed assert.deepEqual(program.getCachedSemanticDiagnostics(program.getSourceFile(otherFile.path)), /*expected*/ undefined); }); + + it("noEmit with composite writes the tsbuildinfo with pending affected files correctly", () => { + const configText = JSON.stringify({ compilerOptions: { composite: true } }); + const { sys, watch, config, mainFile } = setup(createSemanticDiagnosticsBuilderProgram, configText); + const { sys: emitSys, watch: emitWatch } = setup(createEmitAndSemanticDiagnosticsBuilderProgram, configText); + verifyOutputs(sys, emitSys); + + watch.close(); + emitWatch.close(); + + // Emit on both sys should result in same output + verifyBuilder(createEmitAndSemanticDiagnosticsBuilderProgram, createEmitAndSemanticDiagnosticsBuilderProgram); + + // Change file + sys.appendFile(mainFile.path, "\n// SomeComment"); + emitSys.appendFile(mainFile.path, "\n// SomeComment"); + + // Verify noEmit results in same output + verifyBuilder(createSemanticDiagnosticsBuilderProgram, createEmitAndSemanticDiagnosticsBuilderProgram, { noEmit: true }); + + // Emit on both sys should result in same output + verifyBuilder(createEmitAndSemanticDiagnosticsBuilderProgram, createEmitAndSemanticDiagnosticsBuilderProgram); + + // Change file + sys.appendFile(mainFile.path, "\n// SomeComment"); + emitSys.appendFile(mainFile.path, "\n// SomeComment"); + + // Emit on both the builders should result in same files + verifyBuilder(createSemanticDiagnosticsBuilderProgram, createEmitAndSemanticDiagnosticsBuilderProgram); + + function verifyOutputs(sys: System, emitSys: System) { + for (const output of [`${projectRoot}/main.js`, `${projectRoot}/main.d.ts`, `${projectRoot}/other.js`, `${projectRoot}/other.d.ts`, `${projectRoot}/tsconfig.tsbuildinfo`]) { + assert.strictEqual(sys.readFile(output), emitSys.readFile(output), `Output file text for ${output}`); + } + } + + function verifyBuilder(createProgram: CreateProgram, createEmitProgram: CreateProgram, optionsToExtend?: CompilerOptions) { + const watch = getWatch(config, /*optionsToExtend*/ optionsToExtend, sys, createProgram); + const emitWatch = getWatch(config, /*optionsToExtend*/ optionsToExtend, emitSys, createEmitProgram); + verifyOutputs(sys, emitSys); + watch.close(); + emitWatch.close(); + } + }); }); }