@@ -123,4 +123,119 @@ namespace ts.tscWatch {
123
123
checkProgramActualFiles ( watch . getProgram ( ) . getProgram ( ) , [ mainFile . path , otherFile . path , libFile . path ] ) ;
124
124
} ) ;
125
125
} ) ;
126
+
127
+ describe ( "unittests:: tsc-watch:: watchAPI:: when watchHost uses createSemanticDiagnosticsBuilderProgram" , ( ) => {
128
+ function getWatch < T extends BuilderProgram > ( config : File , optionsToExtend : CompilerOptions | undefined , sys : System , createProgram : CreateProgram < T > ) {
129
+ const watchCompilerHost = createWatchCompilerHost ( config . path , optionsToExtend , sys , createProgram ) ;
130
+ return createWatchProgram ( watchCompilerHost ) ;
131
+ }
132
+
133
+ function setup < T extends BuilderProgram > ( createProgram : CreateProgram < T > , configText : string ) {
134
+ const config : File = {
135
+ path : `${ projectRoot } /tsconfig.json` ,
136
+ content : configText
137
+ } ;
138
+ const mainFile : File = {
139
+ path : `${ projectRoot } /main.ts` ,
140
+ content : "export const x = 10;"
141
+ } ;
142
+ const otherFile : File = {
143
+ path : `${ projectRoot } /other.ts` ,
144
+ content : "export const y = 10;"
145
+ } ;
146
+ const sys = createWatchedSystem ( [ config , mainFile , otherFile , libFile ] ) ;
147
+ const watch = getWatch ( config , { noEmit : true } , sys , createProgram ) ;
148
+ return { sys, watch, mainFile, otherFile, config } ;
149
+ }
150
+
151
+ function verifyOutputs ( sys : System , emitSys : System ) {
152
+ for ( const output of [ `${ projectRoot } /main.js` , `${ projectRoot } /main.d.ts` , `${ projectRoot } /other.js` , `${ projectRoot } /other.d.ts` , `${ projectRoot } /tsconfig.tsbuildinfo` ] ) {
153
+ assert . strictEqual ( sys . readFile ( output ) , emitSys . readFile ( output ) , `Output file text for ${ output } ` ) ;
154
+ }
155
+ }
156
+
157
+ function verifyBuilder < T extends BuilderProgram , U extends BuilderProgram > ( config : File , sys : System , emitSys : System , createProgram : CreateProgram < T > , createEmitProgram : CreateProgram < U > , optionsToExtend ?: CompilerOptions ) {
158
+ const watch = getWatch ( config , /*optionsToExtend*/ optionsToExtend , sys , createProgram ) ;
159
+ const emitWatch = getWatch ( config , /*optionsToExtend*/ optionsToExtend , emitSys , createEmitProgram ) ;
160
+ verifyOutputs ( sys , emitSys ) ;
161
+ watch . close ( ) ;
162
+ emitWatch . close ( ) ;
163
+ }
164
+
165
+ it ( "verifies that noEmit is handled on createSemanticDiagnosticsBuilderProgram and typechecking happens only on affected files" , ( ) => {
166
+ const { sys, watch, mainFile, otherFile } = setup ( createSemanticDiagnosticsBuilderProgram , "{}" ) ;
167
+ checkProgramActualFiles ( watch . getProgram ( ) . getProgram ( ) , [ mainFile . path , otherFile . path , libFile . path ] ) ;
168
+ sys . appendFile ( mainFile . path , "\n// SomeComment" ) ;
169
+ sys . runQueuedTimeoutCallbacks ( ) ;
170
+ const program = watch . getProgram ( ) . getProgram ( ) ;
171
+ assert . deepEqual ( program . getCachedSemanticDiagnostics ( program . getSourceFile ( mainFile . path ) ) , [ ] ) ;
172
+ // Should not retrieve diagnostics for other file thats not changed
173
+ assert . deepEqual ( program . getCachedSemanticDiagnostics ( program . getSourceFile ( otherFile . path ) ) , /*expected*/ undefined ) ;
174
+ } ) ;
175
+
176
+ it ( "noEmit with composite writes the tsbuildinfo with pending affected files correctly" , ( ) => {
177
+ const configText = JSON . stringify ( { compilerOptions : { composite : true } } ) ;
178
+ const { sys, watch, config, mainFile } = setup ( createSemanticDiagnosticsBuilderProgram , configText ) ;
179
+ const { sys : emitSys , watch : emitWatch } = setup ( createEmitAndSemanticDiagnosticsBuilderProgram , configText ) ;
180
+ verifyOutputs ( sys , emitSys ) ;
181
+
182
+ watch . close ( ) ;
183
+ emitWatch . close ( ) ;
184
+
185
+ // Emit on both sys should result in same output
186
+ verifyBuilder ( config , sys , emitSys , createEmitAndSemanticDiagnosticsBuilderProgram , createEmitAndSemanticDiagnosticsBuilderProgram ) ;
187
+
188
+ // Change file
189
+ sys . appendFile ( mainFile . path , "\n// SomeComment" ) ;
190
+ emitSys . appendFile ( mainFile . path , "\n// SomeComment" ) ;
191
+
192
+ // Verify noEmit results in same output
193
+ verifyBuilder ( config , sys , emitSys , createSemanticDiagnosticsBuilderProgram , createEmitAndSemanticDiagnosticsBuilderProgram , { noEmit : true } ) ;
194
+
195
+ // Emit on both sys should result in same output
196
+ verifyBuilder ( config , sys , emitSys , createEmitAndSemanticDiagnosticsBuilderProgram , createEmitAndSemanticDiagnosticsBuilderProgram ) ;
197
+
198
+ // Change file
199
+ sys . appendFile ( mainFile . path , "\n// SomeComment" ) ;
200
+ emitSys . appendFile ( mainFile . path , "\n// SomeComment" ) ;
201
+
202
+ // Emit on both the builders should result in same files
203
+ verifyBuilder ( config , sys , emitSys , createSemanticDiagnosticsBuilderProgram , createEmitAndSemanticDiagnosticsBuilderProgram ) ;
204
+ } ) ;
205
+
206
+ it ( "noEmitOnError with composite writes the tsbuildinfo with pending affected files correctly" , ( ) => {
207
+ const config : File = {
208
+ path : `${ projectRoot } /tsconfig.json` ,
209
+ content : JSON . stringify ( { compilerOptions : { composite : true } } )
210
+ } ;
211
+ const mainFile : File = {
212
+ path : `${ projectRoot } /main.ts` ,
213
+ content : "export const x: string = 10;"
214
+ } ;
215
+ const otherFile : File = {
216
+ path : `${ projectRoot } /other.ts` ,
217
+ content : "export const y = 10;"
218
+ } ;
219
+ const sys = createWatchedSystem ( [ config , mainFile , otherFile , libFile ] ) ;
220
+ const emitSys = createWatchedSystem ( [ config , mainFile , otherFile , libFile ] ) ;
221
+
222
+ // Verify noEmit results in same output
223
+ verifyBuilder ( config , sys , emitSys , createSemanticDiagnosticsBuilderProgram , createEmitAndSemanticDiagnosticsBuilderProgram , { noEmitOnError : true } ) ;
224
+
225
+ // Change file
226
+ sys . appendFile ( mainFile . path , "\n// SomeComment" ) ;
227
+ emitSys . appendFile ( mainFile . path , "\n// SomeComment" ) ;
228
+
229
+ // Verify noEmit results in same output
230
+ verifyBuilder ( config , sys , emitSys , createSemanticDiagnosticsBuilderProgram , createEmitAndSemanticDiagnosticsBuilderProgram , { noEmitOnError : true } ) ;
231
+
232
+ // Fix error
233
+ const fixed = "export const x = 10;" ;
234
+ sys . appendFile ( mainFile . path , fixed ) ;
235
+ emitSys . appendFile ( mainFile . path , fixed ) ;
236
+
237
+ // Emit on both the builders should result in same files
238
+ verifyBuilder ( config , sys , emitSys , createSemanticDiagnosticsBuilderProgram , createEmitAndSemanticDiagnosticsBuilderProgram , { noEmitOnError : true } ) ;
239
+ } ) ;
240
+ } ) ;
126
241
}
0 commit comments