1
+ oldConsole = require ' console'
1
2
fs = require ' fs'
2
3
os = require ' os'
3
4
path = require ' path'
@@ -30,6 +31,60 @@ header = """
30
31
majorVersion = parseInt CoffeeScript .VERSION .split (' .' )[0 ], 10
31
32
32
33
34
+ class CakeConsole extends oldConsole.Console
35
+ @LEVELS : [' debug' , ' info' , ' log' , ' warn' , ' error' , ' trace' ]
36
+ @levelNumsMap : do =>
37
+ ret = {}
38
+ ret[k] = i for k, i in @LEVELS
39
+ ret
40
+ @ validLevels: => " [#{ (@LEVELS .map (l) -> " '#{ l} '" ).join ' , ' } ]"
41
+
42
+ constructor : ({@level = ' log' , ... opts} = {}) ->
43
+ super opts
44
+ unless @level in @constructor .LEVELS
45
+ throw new TypeError " argument '#{ @level } ' was not a valid log level
46
+ (should be: #{ @constructor .validLevels ()} )"
47
+
48
+ @ getLevelNum: (l ) => @levelNumsMap [l] ? throw new TypeError " invalid level #{ l} "
49
+ curLevelNum : -> @constructor .getLevelNum @level
50
+ doesThisLevelApply : (l ) -> @ curLevelNum () <= @constructor .getLevelNum l
51
+
52
+ # TODO: for some reason this is done lazily in buildParser, so let's do the same here.
53
+ helpers .extend global , require ' util'
54
+ for l in @LEVELS
55
+ do (l ) => @ :: [l] = (... args ) ->
56
+ if @ doesThisLevelApply l
57
+ # NB: it's literally impossible to extend Console and propagate to the parent class because
58
+ # of some horrific unexplained initialization code used for the singleton console
59
+ # object, which employs a very complex prototype chain that makes it impossible to do
60
+ # the simple thing: https://github.com/nodejs/node/blob/17fae65c72321659390c4cbcd9ddaf248accb953/lib/internal/console/global.js#L29-L33.
61
+ # Undo the prototype chain nonsense and bind the method back to our subclass.
62
+ (oldConsole[l].bind @ ) ... args
63
+ else global .format ... args
64
+
65
+ @stdio : ({
66
+ stdout = process .stdout ,
67
+ stderr = process .stderr ,
68
+ ... opts,
69
+ } = {}) => new @ {
70
+ stdout,
71
+ stderr,
72
+ ... opts
73
+ }
74
+
75
+
76
+ option ' -l' , ' --level [LEVEL]' , ' log level [debug < info < log(default) < warn < error]'
77
+
78
+ setupConsole = ({level} = {}) ->
79
+ global .cakeConsole = CakeConsole .stdio {level}
80
+ global .console = global .cakeConsole
81
+ console .log " log level = #{ level} "
82
+
83
+ consoleTask = (name , description , action ) ->
84
+ global .task name, description, ({level = ' log' , ... opts} = {}) ->
85
+ setupConsole {level}
86
+ action {... opts}
87
+
33
88
# Log a message with a color.
34
89
log = (message , color , explanation ) ->
35
90
console .log color + message + reset + ' ' + (explanation or ' ' )
@@ -60,6 +115,7 @@ buildParser = ->
60
115
buildExceptParser = (callback ) ->
61
116
files = fs .readdirSync ' src'
62
117
files = (' src/' + file for file in files when file .match (/ \. (lit)? coffee$ / ))
118
+ console .info {files}
63
119
run [' -c' , ' -o' , ' lib/coffeescript' ].concat (files), callback
64
120
65
121
build = (callback ) ->
@@ -121,7 +177,7 @@ watchAndBuildAndTest = (harmony = no) ->
121
177
buildAndTest no , harmony
122
178
123
179
124
- task ' build' , ' build the CoffeeScript compiler from source' , build
180
+ consoleTask ' build' , ' build the CoffeeScript compiler from source' , build
125
181
126
182
task ' build:parser' , ' build the Jison parser only' , buildParser
127
183
@@ -190,7 +246,7 @@ task 'build:browser:full', 'merge the built scripts into a single file for use i
190
246
console .log " built ... running browser tests:"
191
247
invoke ' test:browser'
192
248
193
- task ' build:watch' , ' watch and continually rebuild the CoffeeScript compiler, running tests on each build' , ->
249
+ consoleTask ' build:watch' , ' watch and continually rebuild the CoffeeScript compiler, running tests on each build' , ->
194
250
watchAndBuildAndTest ()
195
251
196
252
task ' build:watch:harmony' , ' watch and continually rebuild the CoffeeScript compiler, running harmony tests on each build' , ->
@@ -400,16 +456,37 @@ task 'bench', 'quick benchmark of compilation time', ->
400
456
console .log " total #{ fmt total } "
401
457
402
458
459
+ class PatternSet
460
+ constructor : (patternStrings = []) ->
461
+ @matchers = (new RegExp p for p in patternStrings when p isnt ' ' )
462
+
463
+ isEmpty : -> @matchers .length is 0
464
+
465
+ iterMatchers : -> @matchers [Symbol .iterator ]()
466
+
467
+ matches : (arg ) -> if @ isEmpty () then yes else @ iterMatchers ().some (m) -> (m .exec arg)?
468
+
469
+ @ fromCommaDelimitedList: (commaListStr ) => new @ (commaListStr ? ' ' ).split / ,/
470
+ @ empty: => new @ []
471
+
472
+
403
473
# Run the CoffeeScript test suite.
404
- runTests = (CoffeeScript ) ->
474
+ runTests = (CoffeeScript , { filePatterns , descPatterns } = {} ) ->
405
475
CoffeeScript .register () unless global .testingBrowser
406
476
477
+ filePatterns ?= PatternSet .empty ()
478
+ descPatterns ?= PatternSet .empty ()
479
+ console .log {filePatterns, descPatterns}
480
+
407
481
# These are attached to `global` so that they’re accessible from within
408
482
# `test/async.coffee`, which has an async-capable version of
409
483
# `global.test`.
410
484
global .currentFile = null
411
485
global .passedTests = 0
412
486
global .failures = []
487
+ global .filteredOut =
488
+ files : []
489
+ tests : []
413
490
414
491
global [name] = func for name, func of require ' assert'
415
492
@@ -429,9 +506,22 @@ runTests = (CoffeeScript) ->
429
506
error : err
430
507
description : description
431
508
source : fn .toString () if fn .toString ?
509
+ onFilteredOut = (description , fn ) ->
510
+ console .info " test '#{ description} ' was filtered out by patterns"
511
+ filteredOut .tests .push
512
+ filename : global .currentFile
513
+ description : description
514
+ fn : fn
515
+ onFilteredFile = (file ) ->
516
+ console .info " file '#{ file} ' was filtered out by patterns"
517
+ filteredOut .files .push
518
+ filename : file
432
519
433
520
# Our test helper function for delimiting different test cases.
434
521
global .test = (description , fn ) ->
522
+ unless descPatterns .matches description
523
+ onFilteredOut description, fn
524
+ return
435
525
try
436
526
fn .test = {description, currentFile}
437
527
result = fn .call (fn)
@@ -445,6 +535,7 @@ runTests = (CoffeeScript) ->
445
535
passedTests++
446
536
catch err
447
537
onFail description, fn, err
538
+ console .info " passed: #{ description} in #{ currentFile} "
448
539
449
540
helpers .extend global , require ' ./test/support/helpers'
450
541
@@ -483,6 +574,9 @@ runTests = (CoffeeScript) ->
483
574
484
575
startTime = Date .now ()
485
576
for file in files when helpers .isCoffee file
577
+ unless filePatterns .matches file
578
+ onFilteredFile file
579
+ continue
486
580
literate = helpers .isLiterate file
487
581
currentFile = filename = path .join ' test' , file
488
582
code = fs .readFileSync filename
@@ -495,9 +589,14 @@ runTests = (CoffeeScript) ->
495
589
Promise .reject () if failures .length isnt 0
496
590
497
591
498
- task ' test ' , ' run the CoffeeScript language test suite ' , ->
499
- runTests (CoffeeScript). catch -> process . exit 1
592
+ option ' -f ' , ' --file [REGEXP*] ' , ' test file patterns to match '
593
+ option ' -d ' , ' --desc [REGEXP*] ' , ' test description patterns to match '
500
594
595
+ consoleTask ' test' , ' run the CoffeeScript language test suite' , ({file, desc} = {}) ->
596
+ testOptions =
597
+ filePatterns : new PatternSet file
598
+ descPatterns : new PatternSet desc
599
+ runTests (CoffeeScript, testOptions).catch -> process .exit 1
501
600
502
601
task ' test:browser' , ' run the test suite against the modern browser compiler in a headless browser' , ->
503
602
# Create very simple web server to serve the two files we need.
0 commit comments