@@ -5,6 +5,7 @@ var os = require("os");
55var path = require ( "path" ) ;
66var child_process = require ( "child_process" ) ;
77var Linter = require ( "tslint" ) ;
8+ var runTestsInParallel = require ( "./scripts/mocha-parallel" ) . runTestsInParallel ;
89
910// Variables
1011var compilerDirectory = "src/compiler/" ;
@@ -120,6 +121,7 @@ var languageServiceLibrarySources = [
120121
121122var harnessCoreSources = [
122123 "harness.ts" ,
124+ "virtualFileSystem.ts" ,
123125 "sourceMapRecorder.ts" ,
124126 "harnessLanguageService.ts" ,
125127 "fourslash.ts" ,
@@ -153,7 +155,9 @@ var harnessSources = harnessCoreSources.concat([
153155 "tsconfigParsing.ts" ,
154156 "commandLineParsing.ts" ,
155157 "convertCompilerOptionsFromJson.ts" ,
156- "convertTypingOptionsFromJson.ts"
158+ "convertTypingOptionsFromJson.ts" ,
159+ "tsserverProjectSystem.ts" ,
160+ "matchFiles.ts"
157161] . map ( function ( f ) {
158162 return path . join ( unittestsDirectory , f ) ;
159163} ) ) . concat ( [
@@ -187,7 +191,10 @@ var es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
187191 return { target : "lib." + source , sources : [ "header.d.ts" , source ] } ;
188192} ) ;
189193
190- var es2017LibrarySource = [ "es2017.object.d.ts" ] ;
194+ var es2017LibrarySource = [
195+ "es2017.object.d.ts" ,
196+ "es2017.sharedmemory.d.ts"
197+ ] ;
191198
192199var es2017LibrarySourceMap = es2017LibrarySource . map ( function ( source ) {
193200 return { target : "lib." + source , sources : [ "header.d.ts" , source ] } ;
@@ -207,7 +214,7 @@ var librarySourceMap = [
207214 { target : "lib.es2015.d.ts" , sources : [ "header.d.ts" , "es2015.d.ts" ] } ,
208215 { target : "lib.es2016.d.ts" , sources : [ "header.d.ts" , "es2016.d.ts" ] } ,
209216 { target : "lib.es2017.d.ts" , sources : [ "header.d.ts" , "es2017.d.ts" ] } ,
210-
217+
211218 // JavaScript + all host library
212219 { target : "lib.d.ts" , sources : [ "header.d.ts" , "es5.d.ts" ] . concat ( hostsLibrarySources ) } ,
213220 { target : "lib.es6.d.ts" , sources : [ "header.d.ts" , "es5.d.ts" ] . concat ( es2015LibrarySources , hostsLibrarySources , "dom.iterable.d.ts" ) }
@@ -271,6 +278,7 @@ var builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename);
271278 * @param {boolean } opts.noResolve: true if compiler should not include non-rooted files in compilation
272279 * @param {boolean } opts.stripInternal: true if compiler should remove declarations marked as @internal
273280 * @param {boolean } opts.noMapRoot: true if compiler omit mapRoot option
281+ * @param {boolean } opts.inlineSourceMap: true if compiler should inline sourceMap
274282 * @param callback: a function to execute after the compilation process ends
275283 */
276284function compileFile ( outFile , sources , prereqs , prefixes , useBuiltCompiler , opts , callback ) {
@@ -308,10 +316,16 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
308316 }
309317
310318 if ( useDebugMode ) {
311- options += " -sourcemap" ;
312- if ( ! opts . noMapRoot ) {
313- options += " -mapRoot file:///" + path . resolve ( path . dirname ( outFile ) ) ;
319+ if ( opts . inlineSourceMap ) {
320+ options += " --inlineSourceMap --inlineSources" ;
321+ } else {
322+ options += " -sourcemap" ;
323+ if ( ! opts . noMapRoot ) {
324+ options += " -mapRoot file:///" + path . resolve ( path . dirname ( outFile ) ) ;
325+ }
314326 }
327+ } else {
328+ options += " --newLine LF" ;
315329 }
316330
317331 if ( opts . stripInternal ) {
@@ -488,7 +502,13 @@ var nodeStandaloneDefinitionsFile = path.join(builtLocalDirectory, "typescript_s
488502compileFile ( servicesFile , servicesSources , [ builtLocalDirectory , copyright ] . concat ( servicesSources ) ,
489503 /*prefixes*/ [ copyright ] ,
490504 /*useBuiltCompiler*/ true ,
491- { noOutFile : false , generateDeclarations : true , preserveConstEnums : true , keepComments : true , noResolve : false , stripInternal : true } ,
505+ /*opts*/ { noOutFile : false ,
506+ generateDeclarations : true ,
507+ preserveConstEnums : true ,
508+ keepComments : true ,
509+ noResolve : false ,
510+ stripInternal : true
511+ } ,
492512 /*callback*/ function ( ) {
493513 jake . cpR ( servicesFile , nodePackageFile , { silent : true } ) ;
494514
@@ -511,16 +531,21 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca
511531 fs . writeFileSync ( nodeStandaloneDefinitionsFile , nodeStandaloneDefinitionsFileContents ) ;
512532 } ) ;
513533
514- compileFile ( servicesFileInBrowserTest , servicesSources , [ builtLocalDirectory , copyright ] . concat ( servicesSources ) ,
515- /*prefixes*/ [ copyright ] ,
516- /*useBuiltCompiler*/ true ,
517- { noOutFile : false , generateDeclarations : true , preserveConstEnums : true , keepComments : true , noResolve : false , stripInternal : true , noMapRoot : true } ,
518- /*callback*/ function ( ) {
519- var content = fs . readFileSync ( servicesFileInBrowserTest ) . toString ( ) ;
520- var i = content . lastIndexOf ( "\n" ) ;
521- fs . writeFileSync ( servicesFileInBrowserTest , content . substring ( 0 , i ) + "\r\n//# sourceURL=../built/local/typeScriptServices.js" + content . substring ( i ) ) ;
522- } ) ;
523-
534+ compileFile (
535+ servicesFileInBrowserTest ,
536+ servicesSources ,
537+ [ builtLocalDirectory , copyright ] . concat ( servicesSources ) ,
538+ /*prefixes*/ [ copyright ] ,
539+ /*useBuiltCompiler*/ true ,
540+ { noOutFile : false ,
541+ generateDeclarations : true ,
542+ preserveConstEnums : true ,
543+ keepComments : true ,
544+ noResolve : false ,
545+ stripInternal : true ,
546+ noMapRoot : true ,
547+ inlineSourceMap : true
548+ } ) ;
524549
525550var serverFile = path . join ( builtLocalDirectory , "tsserver.js" ) ;
526551compileFile ( serverFile , serverSources , [ builtLocalDirectory , copyright ] . concat ( serverSources ) , /*prefixes*/ [ copyright ] , /*useBuiltCompiler*/ true ) ;
@@ -621,7 +646,13 @@ directory(builtLocalDirectory);
621646
622647// Task to build the tests infrastructure using the built compiler
623648var run = path . join ( builtLocalDirectory , "run.js" ) ;
624- compileFile ( run , harnessSources , [ builtLocalDirectory , tscFile ] . concat ( libraryTargets ) . concat ( harnessSources ) , [ ] , /*useBuiltCompiler:*/ true ) ;
649+ compileFile (
650+ /*outFile*/ run ,
651+ /*source*/ harnessSources ,
652+ /*prereqs*/ [ builtLocalDirectory , tscFile ] . concat ( libraryTargets ) . concat ( harnessSources ) ,
653+ /*prefixes*/ [ ] ,
654+ /*useBuiltCompiler:*/ true ,
655+ /*opts*/ { inlineSourceMap : true } ) ;
625656
626657var internalTests = "internal/" ;
627658
@@ -680,9 +711,8 @@ function cleanTestDirs() {
680711}
681712
682713// used to pass data from jake command line directly to run.js
683- function writeTestConfigFile ( tests , light , testConfigFile ) {
684- console . log ( 'Running test(s): ' + tests ) ;
685- var testConfigContents = JSON . stringify ( { test : [ tests ] , light : light } ) ;
714+ function writeTestConfigFile ( tests , light , taskConfigsFolder , workerCount ) {
715+ var testConfigContents = JSON . stringify ( { test : tests ? [ tests ] : undefined , light : light , workerCount : workerCount , taskConfigsFolder : taskConfigsFolder } ) ;
686716 fs . writeFileSync ( 'test.config' , testConfigContents ) ;
687717}
688718
@@ -692,7 +722,7 @@ function deleteTemporaryProjectOutput() {
692722 }
693723}
694724
695- function runConsoleTests ( defaultReporter , defaultSubsets ) {
725+ function runConsoleTests ( defaultReporter , runInParallel ) {
696726 cleanTestDirs ( ) ;
697727 var debug = process . env . debug || process . env . d ;
698728 tests = process . env . test || process . env . tests || process . env . t ;
@@ -701,9 +731,22 @@ function runConsoleTests(defaultReporter, defaultSubsets) {
701731 if ( fs . existsSync ( testConfigFile ) ) {
702732 fs . unlinkSync ( testConfigFile ) ;
703733 }
734+ var workerCount , taskConfigsFolder ;
735+ if ( runInParallel ) {
736+ // generate name to store task configuration files
737+ var prefix = os . tmpdir ( ) + "/ts-tests" ;
738+ var i = 1 ;
739+ do {
740+ taskConfigsFolder = prefix + i ;
741+ i ++ ;
742+ } while ( fs . existsSync ( taskConfigsFolder ) ) ;
743+ fs . mkdirSync ( taskConfigsFolder ) ;
744+
745+ workerCount = process . env . workerCount || os . cpus ( ) . length ;
746+ }
704747
705- if ( tests || light ) {
706- writeTestConfigFile ( tests , light , testConfigFile ) ;
748+ if ( tests || light || taskConfigsFolder ) {
749+ writeTestConfigFile ( tests , light , taskConfigsFolder , workerCount ) ;
707750 }
708751
709752 if ( tests && tests . toLocaleLowerCase ( ) === "rwc" ) {
@@ -713,49 +756,81 @@ function runConsoleTests(defaultReporter, defaultSubsets) {
713756 colors = process . env . colors || process . env . color ;
714757 colors = colors ? ' --no-colors ' : ' --colors ' ;
715758 reporter = process . env . reporter || process . env . r || defaultReporter ;
759+ var bail = ( process . env . bail || process . env . b ) ? "--bail" : "" ;
716760 var lintFlag = process . env . lint !== 'false' ;
717761
718762 // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
719763 // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
720- var subsetRegexes ;
721- if ( defaultSubsets . length === 0 ) {
722- subsetRegexes = [ tests ] ;
764+ if ( ! runInParallel ) {
765+ tests = tests ? ' -g "' + tests + '"' : '' ;
766+ var cmd = "mocha" + ( debug ? " --debug-brk" : "" ) + " -R " + reporter + tests + colors + bail + ' -t ' + testTimeout + ' ' + run ;
767+ console . log ( cmd ) ;
768+
769+ var savedNodeEnv = process . env . NODE_ENV ;
770+ process . env . NODE_ENV = "development" ;
771+ exec ( cmd , function ( ) {
772+ process . env . NODE_ENV = savedNodeEnv ;
773+ runLinter ( ) ;
774+ finish ( ) ;
775+ } , function ( e , status ) {
776+ process . env . NODE_ENV = savedNodeEnv ;
777+ finish ( status ) ;
778+ } ) ;
779+
723780 }
724781 else {
725- var subsets = tests ? tests . split ( "|" ) : defaultSubsets ;
726- subsetRegexes = subsets . map ( function ( sub ) { return "^" + sub + ".*$" ; } ) ;
727- subsetRegexes . push ( "^(?!" + subsets . join ( "|" ) + ").*$" ) ;
728- }
729- subsetRegexes . forEach ( function ( subsetRegex , i ) {
730- tests = subsetRegex ? ' -g "' + subsetRegex + '"' : '' ;
731- var cmd = "mocha" + ( debug ? " --debug-brk" : "" ) + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run ;
732- console . log ( cmd ) ;
733- function finish ( ) {
782+ var savedNodeEnv = process . env . NODE_ENV ;
783+ process . env . NODE_ENV = "development" ;
784+ runTestsInParallel ( taskConfigsFolder , run , { testTimeout : testTimeout , noColors : colors === " --no-colors " } , function ( err ) {
785+ process . env . NODE_ENV = savedNodeEnv ;
786+
787+ // last worker clean everything and runs linter in case if there were no errors
734788 deleteTemporaryProjectOutput ( ) ;
789+ jake . rmRf ( taskConfigsFolder ) ;
790+ if ( err ) {
791+ fail ( err ) ;
792+ }
793+ else {
794+ runLinter ( ) ;
795+ complete ( ) ;
796+ }
797+ } ) ;
798+ }
799+
800+ function failWithStatus ( status ) {
801+ fail ( "Process exited with code " + status ) ;
802+ }
803+
804+ function finish ( errorStatus ) {
805+ deleteTemporaryProjectOutput ( ) ;
806+ if ( errorStatus !== undefined ) {
807+ failWithStatus ( errorStatus ) ;
808+ }
809+ else {
735810 complete ( ) ;
736811 }
737- exec ( cmd , function ( ) {
738- if ( lintFlag && i === 0 ) {
739- var lint = jake . Task [ 'lint' ] ;
740- lint . addListener ( 'complete' , function ( ) {
741- complete ( ) ;
742- } ) ;
743- lint . invoke ( ) ;
744- }
745- finish ( ) ;
746- } , finish ) ;
747- } ) ;
812+ }
813+ function runLinter ( ) {
814+ if ( ! lintFlag ) {
815+ return ;
816+ }
817+ var lint = jake . Task [ 'lint' ] ;
818+ lint . addListener ( 'complete' , function ( ) {
819+ complete ( ) ;
820+ } ) ;
821+ lint . invoke ( ) ;
822+ }
748823}
749824
750825var testTimeout = 20000 ;
751826desc ( "Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true." ) ;
752827task ( "runtests-parallel" , [ "build-rules" , "tests" , builtLocalDirectory ] , function ( ) {
753- runConsoleTests ( 'min' , [ 'compiler' , 'conformance' , 'Projects' , 'fourslash' ] ) ;
828+ runConsoleTests ( 'min' , /*runInParallel*/ true ) ;
754829} , { async : true } ) ;
755830
756- desc ( "Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|<more>] d[ebug]=true color[s]=false lint=true." ) ;
831+ desc ( "Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|<more>] d[ebug]=true color[s]=false lint=true bail=false ." ) ;
757832task ( "runtests" , [ "build-rules" , "tests" , builtLocalDirectory ] , function ( ) {
758- runConsoleTests ( 'mocha-fivemat-progress-reporter' , [ ] ) ;
833+ runConsoleTests ( 'mocha-fivemat-progress-reporter' , /*runInParallel*/ false ) ;
759834} , { async : true } ) ;
760835
761836desc ( "Generates code coverage data via instanbul" ) ;
@@ -772,7 +847,7 @@ compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile
772847
773848desc ( "Runs browserify on run.js to produce a file suitable for running tests in the browser" ) ;
774849task ( "browserify" , [ "tests" , builtLocalDirectory , nodeServerOutFile ] , function ( ) {
775- var cmd = 'browserify built/local/run.js -o built/local/bundle.js' ;
850+ var cmd = 'browserify built/local/run.js -d - o built/local/bundle.js' ;
776851 exec ( cmd ) ;
777852} , { async : true } ) ;
778853
@@ -789,11 +864,11 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi
789864 fs . unlinkSync ( testConfigFile ) ;
790865 }
791866 if ( tests || light ) {
792- writeTestConfigFile ( tests , light , testConfigFile ) ;
867+ writeTestConfigFile ( tests , light ) ;
793868 }
794869
795870 tests = tests ? tests : '' ;
796- var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + tests ;
871+ var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + JSON . stringify ( tests ) ;
797872 console . log ( cmd ) ;
798873 exec ( cmd ) ;
799874} , { async : true } ) ;
@@ -962,39 +1037,30 @@ function lintFileAsync(options, path, cb) {
9621037 } ) ;
9631038}
9641039
965- var servicesLintTargets = [
966- "navigateTo.ts" ,
967- "navigationBar.ts" ,
968- "outliningElementsCollector.ts" ,
969- "patternMatcher.ts" ,
970- "services.ts" ,
971- "shims.ts" ,
972- "jsTyping.ts"
973- ] . map ( function ( s ) {
974- return path . join ( servicesDirectory , s ) ;
975- } ) ;
9761040var lintTargets = compilerSources
977- . concat ( harnessCoreSources )
1041+ . concat ( harnessSources )
9781042 // Other harness sources
9791043 . concat ( [ "instrumenter.ts" ] . map ( function ( f ) { return path . join ( harnessDirectory , f ) } ) )
9801044 . concat ( serverCoreSources )
981- . concat ( [ "client.ts" ] . map ( function ( f ) { return path . join ( serverDirectory , f ) ; } ) )
9821045 . concat ( tslintRulesFiles )
983- . concat ( servicesLintTargets ) ;
1046+ . concat ( servicesSources ) ;
1047+
9841048
9851049desc ( "Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex" ) ;
9861050task ( "lint" , [ "build-rules" ] , function ( ) {
9871051 var lintOptions = getLinterOptions ( ) ;
9881052 var failed = 0 ;
9891053 var fileMatcher = RegExp ( process . env . f || process . env . file || process . env . files || "" ) ;
1054+ var done = { } ;
9901055 for ( var i in lintTargets ) {
9911056 var target = lintTargets [ i ] ;
992- if ( fileMatcher . test ( target ) ) {
1057+ if ( ! done [ target ] && fileMatcher . test ( target ) ) {
9931058 var result = lintFile ( lintOptions , target ) ;
9941059 if ( result . failureCount > 0 ) {
9951060 console . log ( result . output ) ;
9961061 failed += result . failureCount ;
9971062 }
1063+ done [ target ] = true ;
9981064 }
9991065 }
10001066 if ( failed > 0 ) {
0 commit comments