11fs = require ' fs'
22os = require ' os'
33path = require ' path'
4+ { performance } = require ' perf_hooks'
45_ = require ' underscore'
56{ spawn , exec , execSync } = require ' child_process'
67CoffeeScript = require ' ./lib/coffeescript'
78helpers = require ' ./lib/coffeescript/helpers'
9+ { setupConsole } = require ' ./build-support/console'
10+ { PatternSet } = require ' ./build-support/patterns'
811
912# ANSI Terminal Colors.
1013bold = red = green = yellow = reset = ' '
11- unless process .env .NODE_DISABLE_COLORS
14+ USE_COLORS = process .stdout .hasColors ? () and not process .env .NODE_DISABLE_COLORS
15+ if USE_COLORS
1216 bold = ' \x1B [0;1m'
1317 red = ' \x1B [0;31m'
1418 green = ' \x1B [0;32m'
@@ -29,6 +33,12 @@ header = """
2933# Used in folder names like `docs/v1`.
3034majorVersion = parseInt CoffeeScript .VERSION .split (' .' )[0 ], 10
3135
36+ option ' -l' , ' --level [LEVEL]' , ' log level [debug < info < log(default) < warn < error]'
37+
38+ task = (name , description , action ) ->
39+ global .task name, description, ({level = ' log' , ... opts} = {}) ->
40+ setupConsole {level, useColors : USE_COLORS}
41+ action {... opts}
3242
3343# Log a message with a color.
3444log = (message , color , explanation ) ->
@@ -53,13 +63,32 @@ run = (args, callback) ->
5363buildParser = ->
5464 helpers .extend global , require ' util'
5565 require ' jison'
66+
67+ startParserBuild = performance .now ()
68+
69+ # Gather summary statistics about the grammar.
70+ parser = require (' ./lib/coffeescript/grammar' ).parser
71+ {symbols_ , terminals_ , productions_ } = parser
72+ countKeys = (obj ) -> (Object .keys obj).length
73+ numSyms = countKeys symbols_
74+ numTerms = countKeys terminals_
75+ numProds = countKeys productions_
76+ console .info " parser created (#{ numSyms} symbols, #{ numTerms} terminals, #{ numProds} productions)"
77+
78+ loadGrammar = performance .now ()
79+ console .info " loading grammar: #{ loadGrammar - startParserBuild} ms"
80+
5681 # We don't need `moduleMain`, since the parser is unlikely to be run standalone.
57- parser = require (' ./lib/coffeescript/grammar' ).parser .generate (moduleMain : -> )
58- fs .writeFileSync ' lib/coffeescript/parser.js' , parser
82+ fs .writeFileSync ' lib/coffeescript/parser.js' , parser .generate (moduleMain : -> )
83+
84+ parserBuildComplete = performance .now ()
85+ console .info " parser generation: #{ parserBuildComplete - loadGrammar} ms"
86+ console .info " full parser build time: #{ parserBuildComplete - startParserBuild} ms"
5987
6088buildExceptParser = (callback ) ->
6189 files = fs .readdirSync ' src'
6290 files = (' src/' + file for file in files when file .match (/ \. (lit)? coffee$ / ))
91+ console .dir .debug {files}
6392 run [' -c' , ' -o' , ' lib/coffeescript' ].concat (files), callback
6493
6594build = (callback ) ->
@@ -401,15 +430,24 @@ task 'bench', 'quick benchmark of compilation time', ->
401430
402431
403432# Run the CoffeeScript test suite.
404- runTests = (CoffeeScript ) ->
433+ runTests = (CoffeeScript , { filePatterns , negFilePatterns , descPatterns , negDescPatterns } = {} ) ->
405434 CoffeeScript .register () unless global .testingBrowser
406435
436+ filePatterns ?= PatternSet .empty ()
437+ negFilePatterns ?= PatternSet .empty {negated : yes }
438+ descPatterns ?= PatternSet .empty ()
439+ negDescPatterns ?= PatternSet .empty {negated : yes }
440+ console .dir .debug {filePatterns, negFilePatterns, descPatterns, negDescPatterns}
441+
407442 # These are attached to `global` so that they’re accessible from within
408443 # `test/async.coffee`, which has an async-capable version of
409444 # `global.test`.
410445 global .currentFile = null
411446 global .passedTests = 0
412447 global .failures = []
448+ global .filteredOut =
449+ files : []
450+ tests : []
413451
414452 global [name] = func for name, func of require ' assert'
415453
@@ -429,9 +467,22 @@ runTests = (CoffeeScript) ->
429467 error : err
430468 description : description
431469 source : fn .toString () if fn .toString ?
470+ onFilteredOut = (description , fn ) ->
471+ console .warn " test '#{ description} ' was filtered out by patterns"
472+ filteredOut .tests .push
473+ filename : global .currentFile
474+ description : description
475+ fn : fn
476+ onFilteredFile = (file ) ->
477+ console .warn " file '#{ file} ' was filtered out by patterns"
478+ filteredOut .files .push
479+ filename : file
432480
433481 # Our test helper function for delimiting different test cases.
434482 global .test = (description , fn ) ->
483+ unless (descPatterns .allows description) and (negDescPatterns .allows description)
484+ onFilteredOut description, fn
485+ return
435486 try
436487 fn .test = {description, currentFile}
437488 result = fn .call (fn)
@@ -445,6 +496,7 @@ runTests = (CoffeeScript) ->
445496 passedTests++
446497 catch err
447498 onFail description, fn, err
499+ console .info " passed: #{ description} in #{ currentFile} "
448500
449501 helpers .extend global , require ' ./test/support/helpers'
450502
@@ -483,6 +535,9 @@ runTests = (CoffeeScript) ->
483535
484536 startTime = Date .now ()
485537 for file in files when helpers .isCoffee file
538+ unless (filePatterns .allows file) and (negFilePatterns .allows file)
539+ onFilteredFile file
540+ continue
486541 literate = helpers .isLiterate file
487542 currentFile = filename = path .join ' test' , file
488543 code = fs .readFileSync filename
@@ -495,9 +550,23 @@ runTests = (CoffeeScript) ->
495550 Promise .reject () if failures .length isnt 0
496551
497552
498- task ' test' , ' run the CoffeeScript language test suite' , ->
499- runTests (CoffeeScript).catch -> process .exit 1
500-
553+ option ' -f' , ' --file [REGEXP*]' , ' regexp patterns to positively match against test file paths'
554+ option null , ' --negFile [REGEXP*]' , ' regexp patterns to negatively match against test file paths'
555+ option ' -d' , ' --desc [REGEXP*]' , ' regexp patterns to positively match against test descriptions'
556+ option null , ' --negDesc [REGEXP*]' , ' regexp patterns to negatively match against test descriptions'
557+
558+ task ' test' , ' run the CoffeeScript language test suite' , ({
559+ file = [],
560+ negFile = [],
561+ desc = [],
562+ negDesc = [],
563+ } = {}) ->
564+ testOptions =
565+ filePatterns : new PatternSet file
566+ negFilePatterns : new PatternSet negFile, {negated : yes }
567+ descPatterns : new PatternSet desc
568+ negDescPatterns : new PatternSet negDesc, {negated : yes }
569+ runTests (CoffeeScript, testOptions).catch -> process .exit 1
501570
502571task ' test:browser' , ' run the test suite against the modern browser compiler in a headless browser' , ->
503572 # Create very simple web server to serve the two files we need.
0 commit comments