@@ -25,14 +25,14 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
2525
2626interface CompileProjectFilesResult {
2727 moduleKind : ts . ModuleKind ;
28- program : ts . Program ;
28+ program ?: ts . Program ;
29+ compilerOptions ?: ts . CompilerOptions ,
2930 errors : ts . Diagnostic [ ] ;
30- sourceMapData : ts . SourceMapData [ ] ;
31+ sourceMapData ? : ts . SourceMapData [ ] ;
3132}
3233
3334interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
34- outputFiles : BatchCompileProjectTestCaseEmittedFile [ ] ;
35- nonSubfolderDiskFiles : number ;
35+ outputFiles ?: BatchCompileProjectTestCaseEmittedFile [ ] ;
3636}
3737
3838class ProjectRunner extends RunnerBase {
@@ -119,9 +119,10 @@ class ProjectRunner extends RunnerBase {
119119
120120 function compileProjectFiles ( moduleKind : ts . ModuleKind , getInputFiles : ( ) => string [ ] ,
121121 getSourceFileText : ( fileName : string ) => string ,
122- writeFile : ( fileName : string , data : string , writeByteOrderMark : boolean ) => void ) : CompileProjectFilesResult {
122+ writeFile : ( fileName : string , data : string , writeByteOrderMark : boolean ) => void ,
123+ compilerOptions : ts . CompilerOptions ) : CompileProjectFilesResult {
123124
124- let program = ts . createProgram ( getInputFiles ( ) , createCompilerOptions ( ) , createCompilerHost ( ) ) ;
125+ let program = ts . createProgram ( getInputFiles ( ) , compilerOptions , createCompilerHost ( ) ) ;
125126 let errors = ts . getPreEmitDiagnostics ( program ) ;
126127
127128 let emitResult = program . emit ( ) ;
@@ -146,38 +147,6 @@ class ProjectRunner extends RunnerBase {
146147 sourceMapData
147148 } ;
148149
149- function createCompilerOptions ( ) : ts . CompilerOptions {
150- // Set the special options that depend on other testcase options
151- let compilerOptions : ts . CompilerOptions = {
152- mapRoot : testCase . resolveMapRoot && testCase . mapRoot ? Harness . IO . resolvePath ( testCase . mapRoot ) : testCase . mapRoot ,
153- sourceRoot : testCase . resolveSourceRoot && testCase . sourceRoot ? Harness . IO . resolvePath ( testCase . sourceRoot ) : testCase . sourceRoot ,
154- module : moduleKind ,
155- moduleResolution : ts . ModuleResolutionKind . Classic , // currently all tests use classic module resolution kind, this will change in the future
156- } ;
157-
158- // Set the values specified using json
159- let optionNameMap : ts . Map < ts . CommandLineOption > = { } ;
160- ts . forEach ( ts . optionDeclarations , option => {
161- optionNameMap [ option . name ] = option ;
162- } ) ;
163- for ( let name in testCase ) {
164- if ( name !== "mapRoot" && name !== "sourceRoot" && ts . hasProperty ( optionNameMap , name ) ) {
165- let option = optionNameMap [ name ] ;
166- let optType = option . type ;
167- let value = < any > testCase [ name ] ;
168- if ( typeof optType !== "string" ) {
169- let key = value . toLowerCase ( ) ;
170- if ( ts . hasProperty ( optType , key ) ) {
171- value = optType [ key ] ;
172- }
173- }
174- compilerOptions [ option . name ] = value ;
175- }
176- }
177-
178- return compilerOptions ;
179- }
180-
181150 function getSourceFile ( fileName : string , languageVersion : ts . ScriptTarget ) : ts . SourceFile {
182151 let sourceFile : ts . SourceFile = undefined ;
183152 if ( fileName === Harness . Compiler . defaultLibFileName ) {
@@ -212,23 +181,99 @@ class ProjectRunner extends RunnerBase {
212181 let nonSubfolderDiskFiles = 0 ;
213182
214183 let outputFiles : BatchCompileProjectTestCaseEmittedFile [ ] = [ ] ;
184+ let compilerOptions = createCompilerOptions ( ) ;
185+ let inputFiles = testCase . inputFiles ;
186+ let configFileName : string ;
187+ if ( compilerOptions . project ) {
188+ // Parse project
189+ configFileName = ts . normalizePath ( ts . combinePaths ( compilerOptions . project , "tsconfig.json" ) ) ;
190+ assert ( ! inputFiles || inputFiles . length === 0 , "cannot specify input files and project option together" ) ;
191+ }
192+ else if ( ! inputFiles || inputFiles . length === 0 ) {
193+ configFileName = ts . findConfigFile ( "" , { fileExists, readFile : getSourceFileText } ) ;
194+ }
195+
196+ if ( configFileName ) {
197+ let result = ts . readConfigFile ( configFileName , getSourceFileText ) ;
198+ if ( result . error ) {
199+ return {
200+ moduleKind,
201+ errors : [ result . error ]
202+ } ;
203+ }
215204
216- let projectCompilerResult = compileProjectFiles ( moduleKind , ( ) => testCase . inputFiles , getSourceFileText , writeFile ) ;
205+ let configObject = result . config ;
206+ let configParseResult = ts . parseConfigFile ( configObject , { fileExists, readFile : getSourceFileText , readDirectory } , ts . getDirectoryPath ( configFileName ) ) ;
207+ if ( configParseResult . errors . length > 0 ) {
208+ return {
209+ moduleKind,
210+ errors : configParseResult . errors
211+ } ;
212+ }
213+ inputFiles = configParseResult . fileNames ;
214+ compilerOptions = ts . extend ( compilerOptions , configParseResult . options ) ;
215+ }
216+
217+ let projectCompilerResult = compileProjectFiles ( moduleKind , ( ) => inputFiles , getSourceFileText , writeFile , compilerOptions ) ;
217218 return {
218219 moduleKind,
219220 program : projectCompilerResult . program ,
221+ compilerOptions,
220222 sourceMapData : projectCompilerResult . sourceMapData ,
221223 outputFiles,
222224 errors : projectCompilerResult . errors ,
223- nonSubfolderDiskFiles,
224225 } ;
225226
227+ function createCompilerOptions ( ) : ts . CompilerOptions {
228+ // Set the special options that depend on other testcase options
229+ let compilerOptions : ts . CompilerOptions = {
230+ mapRoot : testCase . resolveMapRoot && testCase . mapRoot ? Harness . IO . resolvePath ( testCase . mapRoot ) : testCase . mapRoot ,
231+ sourceRoot : testCase . resolveSourceRoot && testCase . sourceRoot ? Harness . IO . resolvePath ( testCase . sourceRoot ) : testCase . sourceRoot ,
232+ module : moduleKind ,
233+ moduleResolution : ts . ModuleResolutionKind . Classic , // currently all tests use classic module resolution kind, this will change in the future
234+ } ;
235+
236+ // Set the values specified using json
237+ let optionNameMap : ts . Map < ts . CommandLineOption > = { } ;
238+ ts . forEach ( ts . optionDeclarations , option => {
239+ optionNameMap [ option . name ] = option ;
240+ } ) ;
241+ for ( let name in testCase ) {
242+ if ( name !== "mapRoot" && name !== "sourceRoot" && ts . hasProperty ( optionNameMap , name ) ) {
243+ let option = optionNameMap [ name ] ;
244+ let optType = option . type ;
245+ let value = < any > testCase [ name ] ;
246+ if ( typeof optType !== "string" ) {
247+ let key = value . toLowerCase ( ) ;
248+ if ( ts . hasProperty ( optType , key ) ) {
249+ value = optType [ key ] ;
250+ }
251+ }
252+ compilerOptions [ option . name ] = value ;
253+ }
254+ }
255+
256+ return compilerOptions ;
257+ }
258+
259+ function getFileNameInTheProjectTest ( fileName : string ) : string {
260+ return ts . isRootedDiskPath ( fileName )
261+ ? fileName
262+ : ts . normalizeSlashes ( testCase . projectRoot ) + "/" + ts . normalizeSlashes ( fileName ) ;
263+ }
264+
265+ function readDirectory ( rootDir : string , extension : string , exclude : string [ ] ) : string [ ] {
266+ return Harness . IO . readDirectory ( getFileNameInTheProjectTest ( rootDir ) , extension , exclude ) ;
267+ }
268+
269+ function fileExists ( fileName : string ) : boolean {
270+ return Harness . IO . fileExists ( getFileNameInTheProjectTest ( fileName ) ) ;
271+ }
272+
226273 function getSourceFileText ( fileName : string ) : string {
227274 let text : string = undefined ;
228275 try {
229- text = Harness . IO . readFile ( ts . isRootedDiskPath ( fileName )
230- ? fileName
231- : ts . normalizeSlashes ( testCase . projectRoot ) + "/" + ts . normalizeSlashes ( fileName ) ) ;
276+ text = Harness . IO . readFile ( getFileNameInTheProjectTest ( fileName ) ) ;
232277 }
233278 catch ( e ) {
234279 // text doesn't get defined.
@@ -288,6 +333,9 @@ class ProjectRunner extends RunnerBase {
288333
289334 function compileCompileDTsFiles ( compilerResult : BatchCompileProjectTestCaseResult ) {
290335 let allInputFiles : { emittedFileName : string ; code : string ; } [ ] = [ ] ;
336+ if ( ! compilerResult . program ) {
337+ return ;
338+ }
291339 let compilerOptions = compilerResult . program . getCompilerOptions ( ) ;
292340
293341 ts . forEach ( compilerResult . program . getSourceFiles ( ) , sourceFile => {
@@ -317,7 +365,8 @@ class ProjectRunner extends RunnerBase {
317365 }
318366 } ) ;
319367
320- return compileProjectFiles ( compilerResult . moduleKind , getInputFiles , getSourceFileText , writeFile ) ;
368+ // Dont allow config files since we are compiling existing source options
369+ return compileProjectFiles ( compilerResult . moduleKind , getInputFiles , getSourceFileText , writeFile , compilerResult . compilerOptions ) ;
321370
322371 function findOutpuDtsFile ( fileName : string ) {
323372 return ts . forEach ( compilerResult . outputFiles , outputFile => outputFile . emittedFileName === fileName ? outputFile : undefined ) ;
@@ -352,7 +401,7 @@ class ProjectRunner extends RunnerBase {
352401
353402 function getCompilerResolutionInfo ( ) {
354403 let resolutionInfo : ProjectRunnerTestCaseResolutionInfo & ts . CompilerOptions = JSON . parse ( JSON . stringify ( testCase ) ) ;
355- resolutionInfo . resolvedInputFiles = ts . map ( compilerResult . program . getSourceFiles ( ) , inputFile => inputFile . fileName ) ;
404+ resolutionInfo . resolvedInputFiles = ts . map ( compilerResult . program ? compilerResult . program . getSourceFiles ( ) : undefined , inputFile => inputFile . fileName ) ;
356405 resolutionInfo . emittedFiles = ts . map ( compilerResult . outputFiles , outputFile => outputFile . emittedFileName ) ;
357406 return resolutionInfo ;
358407 }
@@ -409,7 +458,7 @@ class ProjectRunner extends RunnerBase {
409458 it ( "Errors in generated Dts files for (" + moduleNameToString ( moduleKind ) + "): " + testCaseFileName , ( ) => {
410459 if ( ! compilerResult . errors . length && testCase . declaration ) {
411460 let dTsCompileResult = compileCompileDTsFiles ( compilerResult ) ;
412- if ( dTsCompileResult . errors . length ) {
461+ if ( dTsCompileResult && dTsCompileResult . errors . length ) {
413462 Harness . Baseline . runBaseline ( "Errors in generated Dts files for (" + moduleNameToString ( compilerResult . moduleKind ) + "): " + testCaseFileName , getBaselineFolder ( compilerResult . moduleKind ) + testCaseJustName + ".dts.errors.txt" , ( ) => {
414463 return getErrorsBaseline ( dTsCompileResult ) ;
415464 } ) ;
0 commit comments