1
1
/// <reference path="harness.ts" />
2
2
/// <reference path="runnerbase.ts" />
3
3
/// <reference path="typeWriter.ts" />
4
- // In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`.
5
- /* tslint:disable:no-null-keyword */
6
4
7
5
const enum CompilerTestType {
8
6
Conformance ,
@@ -136,21 +134,10 @@ class CompilerBaselineRunner extends RunnerBase {
136
134
otherFiles = undefined ;
137
135
} ) ;
138
136
139
- function getByteOrderMarkText ( file : Harness . Compiler . GeneratedFile ) : string {
140
- return file . writeByteOrderMark ? "\u00EF\u00BB\u00BF" : "" ;
141
- }
142
-
143
- function getErrorBaseline ( toBeCompiled : Harness . Compiler . TestFile [ ] , otherFiles : Harness . Compiler . TestFile [ ] , result : Harness . Compiler . CompilerResult ) {
144
- return Harness . Compiler . getErrorBaseline ( toBeCompiled . concat ( otherFiles ) , result . errors ) ;
145
- }
146
-
147
137
// check errors
148
138
it ( "Correct errors for " + fileName , ( ) => {
149
139
if ( this . errors ) {
150
- Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? $ / , ".errors.txt" ) , ( ) : string => {
151
- if ( result . errors . length === 0 ) return null ;
152
- return getErrorBaseline ( toBeCompiled , otherFiles , result ) ;
153
- } ) ;
140
+ Harness . Compiler . doErrorBaseline ( justName , toBeCompiled . concat ( otherFiles ) , result . errors ) ;
154
141
}
155
142
} ) ;
156
143
@@ -168,8 +155,10 @@ class CompilerBaselineRunner extends RunnerBase {
168
155
Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? $ / , ".sourcemap.txt" ) , ( ) => {
169
156
const record = result . getSourceMapRecord ( ) ;
170
157
if ( options . noEmitOnError && result . errors . length !== 0 && record === undefined ) {
171
- // Because of the noEmitOnError option no files are created. We need to return null because baselining isn"t required.
158
+ // Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
159
+ /* tslint:disable:no-null-keyword */
172
160
return null ;
161
+ /* tslint:enable:no-null-keyword */
173
162
}
174
163
return record ;
175
164
} ) ;
@@ -178,217 +167,20 @@ class CompilerBaselineRunner extends RunnerBase {
178
167
179
168
it ( "Correct JS output for " + fileName , ( ) => {
180
169
if ( hasNonDtsFiles && this . emit ) {
181
- if ( ! options . noEmit && result . files . length === 0 && result . errors . length === 0 ) {
182
- throw new Error ( "Expected at least one js file to be emitted or at least one error to be created." ) ;
183
- }
184
-
185
- // check js output
186
- Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? / , ".js" ) , ( ) => {
187
- let tsCode = "" ;
188
- const tsSources = otherFiles . concat ( toBeCompiled ) ;
189
- if ( tsSources . length > 1 ) {
190
- tsCode += "//// [" + fileName + "] ////\r\n\r\n" ;
191
- }
192
- for ( let i = 0 ; i < tsSources . length ; i ++ ) {
193
- tsCode += "//// [" + Harness . Path . getFileName ( tsSources [ i ] . unitName ) + "]\r\n" ;
194
- tsCode += tsSources [ i ] . content + ( i < ( tsSources . length - 1 ) ? "\r\n" : "" ) ;
195
- }
196
-
197
- let jsCode = "" ;
198
- for ( let i = 0 ; i < result . files . length ; i ++ ) {
199
- jsCode += "//// [" + Harness . Path . getFileName ( result . files [ i ] . fileName ) + "]\r\n" ;
200
- jsCode += getByteOrderMarkText ( result . files [ i ] ) ;
201
- jsCode += result . files [ i ] . code ;
202
- }
203
-
204
- if ( result . declFilesCode . length > 0 ) {
205
- jsCode += "\r\n\r\n" ;
206
- for ( let i = 0 ; i < result . declFilesCode . length ; i ++ ) {
207
- jsCode += "//// [" + Harness . Path . getFileName ( result . declFilesCode [ i ] . fileName ) + "]\r\n" ;
208
- jsCode += getByteOrderMarkText ( result . declFilesCode [ i ] ) ;
209
- jsCode += result . declFilesCode [ i ] . code ;
210
- }
211
- }
212
-
213
- const declFileCompilationResult =
214
- Harness . Compiler . compileDeclarationFiles (
215
- toBeCompiled , otherFiles , result , harnessSettings , options , /*currentDirectory*/ undefined ) ;
216
-
217
- if ( declFileCompilationResult && declFileCompilationResult . declResult . errors . length ) {
218
- jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n" ;
219
- jsCode += "\r\n\r\n" ;
220
- jsCode += getErrorBaseline ( declFileCompilationResult . declInputFiles , declFileCompilationResult . declOtherFiles , declFileCompilationResult . declResult ) ;
221
- }
222
-
223
- if ( jsCode . length > 0 ) {
224
- return tsCode + "\r\n\r\n" + jsCode ;
225
- }
226
- else {
227
- return null ;
228
- }
229
- } ) ;
170
+ Harness . Compiler . doJsEmitBaseline ( justName , fileName , options , result , toBeCompiled , otherFiles , harnessSettings ) ;
230
171
}
231
172
} ) ;
232
173
233
174
it ( "Correct Sourcemap output for " + fileName , ( ) => {
234
- if ( options . inlineSourceMap ) {
235
- if ( result . sourceMaps . length > 0 ) {
236
- throw new Error ( "No sourcemap files should be generated if inlineSourceMaps was set." ) ;
237
- }
238
- return null ;
239
- }
240
- else if ( options . sourceMap ) {
241
- if ( result . sourceMaps . length !== result . files . length ) {
242
- throw new Error ( "Number of sourcemap files should be same as js files." ) ;
243
- }
244
-
245
- Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? / , ".js.map" ) , ( ) => {
246
- if ( options . noEmitOnError && result . errors . length !== 0 && result . sourceMaps . length === 0 ) {
247
- // We need to return null here or the runBaseLine will actually create a empty file.
248
- // Baselining isn't required here because there is no output.
249
- return null ;
250
- }
251
-
252
- let sourceMapCode = "" ;
253
- for ( let i = 0 ; i < result . sourceMaps . length ; i ++ ) {
254
- sourceMapCode += "//// [" + Harness . Path . getFileName ( result . sourceMaps [ i ] . fileName ) + "]\r\n" ;
255
- sourceMapCode += getByteOrderMarkText ( result . sourceMaps [ i ] ) ;
256
- sourceMapCode += result . sourceMaps [ i ] . code ;
257
- }
258
-
259
- return sourceMapCode ;
260
- } ) ;
261
- }
175
+ Harness . Compiler . doSourcemapBaseline ( justName , options , result ) ;
262
176
} ) ;
263
177
264
178
it ( "Correct type/symbol baselines for " + fileName , ( ) => {
265
179
if ( fileName . indexOf ( "APISample" ) >= 0 ) {
266
180
return ;
267
181
}
268
182
269
- // NEWTODO: Type baselines
270
- if ( result . errors . length !== 0 ) {
271
- return ;
272
- }
273
-
274
- // The full walker simulates the types that you would get from doing a full
275
- // compile. The pull walker simulates the types you get when you just do
276
- // a type query for a random node (like how the LS would do it). Most of the
277
- // time, these will be the same. However, occasionally, they can be different.
278
- // Specifically, when the compiler internally depends on symbol IDs to order
279
- // things, then we may see different results because symbols can be created in a
280
- // different order with 'pull' operations, and thus can produce slightly differing
281
- // output.
282
- //
283
- // For example, with a full type check, we may see a type displayed as: number | string
284
- // But with a pull type check, we may see it as: string | number
285
- //
286
- // These types are equivalent, but depend on what order the compiler observed
287
- // certain parts of the program.
288
-
289
- const program = result . program ;
290
- const allFiles = toBeCompiled . concat ( otherFiles ) . filter ( file => ! ! program . getSourceFile ( file . unitName ) ) ;
291
-
292
- const fullWalker = new TypeWriterWalker ( program , /*fullTypeCheck*/ true ) ;
293
-
294
- const fullResults = ts . createMap < TypeWriterResult [ ] > ( ) ;
295
- const pullResults = ts . createMap < TypeWriterResult [ ] > ( ) ;
296
-
297
- for ( const sourceFile of allFiles ) {
298
- fullResults [ sourceFile . unitName ] = fullWalker . getTypeAndSymbols ( sourceFile . unitName ) ;
299
- pullResults [ sourceFile . unitName ] = fullWalker . getTypeAndSymbols ( sourceFile . unitName ) ;
300
- }
301
-
302
- // Produce baselines. The first gives the types for all expressions.
303
- // The second gives symbols for all identifiers.
304
- let e1 : Error , e2 : Error ;
305
- try {
306
- checkBaseLines ( /*isSymbolBaseLine*/ false ) ;
307
- }
308
- catch ( e ) {
309
- e1 = e ;
310
- }
311
-
312
- try {
313
- checkBaseLines ( /*isSymbolBaseLine*/ true ) ;
314
- }
315
- catch ( e ) {
316
- e2 = e ;
317
- }
318
-
319
- if ( e1 || e2 ) {
320
- throw e1 || e2 ;
321
- }
322
-
323
- return ;
324
-
325
- function checkBaseLines ( isSymbolBaseLine : boolean ) {
326
- const fullBaseLine = generateBaseLine ( fullResults , isSymbolBaseLine ) ;
327
- const pullBaseLine = generateBaseLine ( pullResults , isSymbolBaseLine ) ;
328
-
329
- const fullExtension = isSymbolBaseLine ? ".symbols" : ".types" ;
330
- const pullExtension = isSymbolBaseLine ? ".symbols.pull" : ".types.pull" ;
331
-
332
- if ( fullBaseLine !== pullBaseLine ) {
333
- Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? / , fullExtension ) , ( ) => fullBaseLine ) ;
334
- Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? / , pullExtension ) , ( ) => pullBaseLine ) ;
335
- }
336
- else {
337
- Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? / , fullExtension ) , ( ) => fullBaseLine ) ;
338
- }
339
- }
340
-
341
- function generateBaseLine ( typeWriterResults : ts . Map < TypeWriterResult [ ] > , isSymbolBaseline : boolean ) : string {
342
- const typeLines : string [ ] = [ ] ;
343
- const typeMap : { [ fileName : string ] : { [ lineNum : number ] : string [ ] ; } } = { } ;
344
-
345
- allFiles . forEach ( file => {
346
- const codeLines = file . content . split ( "\n" ) ;
347
- typeWriterResults [ file . unitName ] . forEach ( result => {
348
- if ( isSymbolBaseline && ! result . symbol ) {
349
- return ;
350
- }
351
-
352
- const typeOrSymbolString = isSymbolBaseline ? result . symbol : result . type ;
353
- const formattedLine = result . sourceText . replace ( / \r ? \n / g, "" ) + " : " + typeOrSymbolString ;
354
- if ( ! typeMap [ file . unitName ] ) {
355
- typeMap [ file . unitName ] = { } ;
356
- }
357
-
358
- let typeInfo = [ formattedLine ] ;
359
- const existingTypeInfo = typeMap [ file . unitName ] [ result . line ] ;
360
- if ( existingTypeInfo ) {
361
- typeInfo = existingTypeInfo . concat ( typeInfo ) ;
362
- }
363
- typeMap [ file . unitName ] [ result . line ] = typeInfo ;
364
- } ) ;
365
-
366
- typeLines . push ( "=== " + file . unitName + " ===\r\n" ) ;
367
- for ( let i = 0 ; i < codeLines . length ; i ++ ) {
368
- const currentCodeLine = codeLines [ i ] ;
369
- typeLines . push ( currentCodeLine + "\r\n" ) ;
370
- if ( typeMap [ file . unitName ] ) {
371
- const typeInfo = typeMap [ file . unitName ] [ i ] ;
372
- if ( typeInfo ) {
373
- typeInfo . forEach ( ty => {
374
- typeLines . push ( ">" + ty + "\r\n" ) ;
375
- } ) ;
376
- if ( i + 1 < codeLines . length && ( codeLines [ i + 1 ] . match ( / ^ \s * [ { | } ] \s * $ / ) || codeLines [ i + 1 ] . trim ( ) === "" ) ) {
377
- }
378
- else {
379
- typeLines . push ( "\r\n" ) ;
380
- }
381
- }
382
- }
383
- else {
384
- typeLines . push ( "No type information for this code." ) ;
385
- }
386
- }
387
- } ) ;
388
-
389
- return typeLines . join ( "" ) ;
390
- }
391
-
183
+ Harness . Compiler . doTypeAndSymbolBaseline ( justName , result , toBeCompiled . concat ( otherFiles ) . filter ( file => ! ! result . program . getSourceFile ( file . unitName ) ) ) ;
392
184
} ) ;
393
185
} ) ;
394
186
}
0 commit comments