11/// <reference path="harness.ts" />
22/// <reference path="runnerbase.ts" />
33/// <reference path="typeWriter.ts" />
4- // In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`.
5- /* tslint:disable:no-null-keyword */
64
75const enum CompilerTestType {
86 Conformance ,
@@ -136,21 +134,10 @@ class CompilerBaselineRunner extends RunnerBase {
136134 otherFiles = undefined ;
137135 } ) ;
138136
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-
147137 // check errors
148138 it ( "Correct errors for " + fileName , ( ) => {
149139 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 ) ;
154141 }
155142 } ) ;
156143
@@ -168,8 +155,10 @@ class CompilerBaselineRunner extends RunnerBase {
168155 Harness . Baseline . runBaseline ( justName . replace ( / \. t s x ? $ / , ".sourcemap.txt" ) , ( ) => {
169156 const record = result . getSourceMapRecord ( ) ;
170157 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 */
172160 return null ;
161+ /* tslint:enable:no-null-keyword */
173162 }
174163 return record ;
175164 } ) ;
@@ -178,217 +167,20 @@ class CompilerBaselineRunner extends RunnerBase {
178167
179168 it ( "Correct JS output for " + fileName , ( ) => {
180169 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 ) ;
230171 }
231172 } ) ;
232173
233174 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 ) ;
262176 } ) ;
263177
264178 it ( "Correct type/symbol baselines for " + fileName , ( ) => {
265179 if ( fileName . indexOf ( "APISample" ) >= 0 ) {
266180 return ;
267181 }
268182
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 ) ) ) ;
392184 } ) ;
393185 } ) ;
394186 }
0 commit comments