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