@@ -18,8 +18,8 @@ var HOOK_TYPE_BEFORE_ALL = Suite.constants.HOOK_TYPE_BEFORE_ALL;
18
18
var EVENT_ROOT_SUITE_RUN = Suite . constants . EVENT_ROOT_SUITE_RUN ;
19
19
var STATE_FAILED = Runnable . constants . STATE_FAILED ;
20
20
var STATE_PASSED = Runnable . constants . STATE_PASSED ;
21
+ var STATE_SKIPPED = Runnable . constants . STATE_SKIPPED ;
21
22
var dQuote = utils . dQuote ;
22
- var ngettext = utils . ngettext ;
23
23
var sQuote = utils . sQuote ;
24
24
var stackFilter = utils . stackTraceFilter ( ) ;
25
25
var stringify = utils . stringify ;
@@ -106,6 +106,10 @@ var constants = utils.defineConstants(
106
106
* Emitted when {@link Test} becomes pending
107
107
*/
108
108
EVENT_TEST_PENDING : 'pending' ,
109
+ /**
110
+ * Emitted when {@link Test} becomes skipped
111
+ */
112
+ EVENT_TEST_SKIPPED : 'skipped' ,
109
113
/**
110
114
* Emitted when {@link Test} execution has failed, but will retry
111
115
*/
@@ -122,8 +126,7 @@ module.exports = Runner;
122
126
* @public
123
127
* @class
124
128
* @param {Suite } suite Root suite
125
- * @param {boolean } [delay] Whether or not to delay execution of root suite
126
- * until ready.
129
+ * @param {boolean } [delay] Whether to delay execution of root suite until ready.
127
130
*/
128
131
function Runner ( suite , delay ) {
129
132
var self = this ;
@@ -271,12 +274,8 @@ Runner.prototype.checkGlobals = function(test) {
271
274
this . _globals = this . _globals . concat ( leaks ) ;
272
275
273
276
if ( leaks . length ) {
274
- var format = ngettext (
275
- leaks . length ,
276
- 'global leak detected: %s' ,
277
- 'global leaks detected: %s'
278
- ) ;
279
- var error = new Error ( util . format ( format , leaks . map ( sQuote ) . join ( ', ' ) ) ) ;
277
+ var msg = 'global leak(s) detected: %s' ;
278
+ var error = new Error ( util . format ( msg , leaks . map ( sQuote ) . join ( ', ' ) ) ) ;
280
279
this . fail ( test , error ) ;
281
280
}
282
281
} ;
@@ -287,9 +286,11 @@ Runner.prototype.checkGlobals = function(test) {
287
286
* @private
288
287
* @param {Test } test
289
288
* @param {Error } err
289
+ * @param {boolean } [force=false] - Whether to fail a pending test.
290
290
*/
291
- Runner . prototype . fail = function ( test , err ) {
292
- if ( test . isPending ( ) ) {
291
+ Runner . prototype . fail = function ( test , err , force ) {
292
+ force = force === true ;
293
+ if ( test . isPending ( ) && ! force ) {
293
294
return ;
294
295
}
295
296
@@ -361,7 +362,7 @@ Runner.prototype.hook = function(name, fn) {
361
362
var hooks = suite . getHooks ( name ) ;
362
363
var self = this ;
363
364
364
- function next ( i ) {
365
+ function nextHook ( i ) {
365
366
var hook = hooks [ i ] ;
366
367
if ( ! hook ) {
367
368
return fn ( ) ;
@@ -419,18 +420,29 @@ Runner.prototype.hook = function(name, fn) {
419
420
return fn ( errForbid ) ;
420
421
}
421
422
} else if ( err ) {
422
- self . failHook ( hook , err ) ;
423
- // stop executing hooks, notify callee of hook err
424
- return fn ( err ) ;
423
+ if ( name === HOOK_TYPE_BEFORE_ALL ) {
424
+ self . failHook ( hook , err ) ;
425
+ suite . tests . forEach ( function ( test ) {
426
+ test . skipped = true ;
427
+ } ) ;
428
+ suite . suites . forEach ( function ( suite ) {
429
+ suite . skipped = true ;
430
+ } ) ;
431
+ hooks = [ ] ;
432
+ } else {
433
+ self . failHook ( hook , err ) ;
434
+ // stop executing hooks, notify callee of hook err
435
+ return fn ( err ) ;
436
+ }
425
437
}
426
438
self . emit ( constants . EVENT_HOOK_END , hook ) ;
427
439
delete hook . ctx . currentTest ;
428
- next ( ++ i ) ;
440
+ nextHook ( ++ i ) ;
429
441
} ) ;
430
442
}
431
443
432
444
Runner . immediately ( function ( ) {
433
- next ( 0 ) ;
445
+ nextHook ( 0 ) ;
434
446
} ) ;
435
447
} ;
436
448
@@ -587,7 +599,7 @@ Runner.prototype.runTests = function(suite, fn) {
587
599
}
588
600
}
589
601
590
- function next ( err , errSuite ) {
602
+ function nextTest ( err , errSuite ) {
591
603
// if we bail after first err
592
604
if ( self . failures && suite . _bail ) {
593
605
tests = [ ] ;
@@ -624,24 +636,29 @@ Runner.prototype.runTests = function(suite, fn) {
624
636
// test suite don't do any immediate recursive loops. Thus,
625
637
// allowing a JS runtime to breathe.
626
638
if ( self . _grep !== self . _defaultGrep ) {
627
- Runner . immediately ( next ) ;
639
+ Runner . immediately ( nextTest ) ;
628
640
} else {
629
- next ( ) ;
641
+ nextTest ( ) ;
630
642
}
631
643
return ;
632
644
}
633
645
646
+ // skipped by failing hook
647
+ if ( test . isSkipped ( ) ) {
648
+ test . state = STATE_SKIPPED ;
649
+ self . emit ( constants . EVENT_TEST_SKIPPED , test ) ;
650
+ return nextTest ( ) ;
651
+ }
652
+
634
653
// static skip, no hooks are executed
635
654
if ( test . isPending ( ) ) {
636
655
if ( self . forbidPending ) {
637
- test . isPending = alwaysFalse ;
638
- self . fail ( test , new Error ( 'Pending test forbidden' ) ) ;
639
- delete test . isPending ;
656
+ self . fail ( test , new Error ( 'Pending test forbidden' ) , true ) ;
640
657
} else {
641
658
self . emit ( constants . EVENT_TEST_PENDING , test ) ;
642
659
}
643
660
self . emit ( constants . EVENT_TEST_END , test ) ;
644
- return next ( ) ;
661
+ return nextTest ( ) ;
645
662
}
646
663
647
664
// execute test and hook(s)
@@ -650,9 +667,7 @@ Runner.prototype.runTests = function(suite, fn) {
650
667
// conditional skip within beforeEach
651
668
if ( test . isPending ( ) ) {
652
669
if ( self . forbidPending ) {
653
- test . isPending = alwaysFalse ;
654
- self . fail ( test , new Error ( 'Pending test forbidden' ) ) ;
655
- delete test . isPending ;
670
+ self . fail ( test , new Error ( 'Pending test forbidden' ) , true ) ;
656
671
} else {
657
672
self . emit ( constants . EVENT_TEST_PENDING , test ) ;
658
673
}
@@ -662,7 +677,7 @@ Runner.prototype.runTests = function(suite, fn) {
662
677
self . suite = errSuite || self . suite ;
663
678
return self . hookUp ( HOOK_TYPE_AFTER_EACH , function ( e , eSuite ) {
664
679
self . suite = origSuite ;
665
- next ( e , eSuite ) ;
680
+ nextTest ( e , eSuite ) ;
666
681
} ) ;
667
682
}
668
683
if ( err ) {
@@ -674,14 +689,12 @@ Runner.prototype.runTests = function(suite, fn) {
674
689
// conditional skip within it
675
690
if ( test . pending ) {
676
691
if ( self . forbidPending ) {
677
- test . isPending = alwaysFalse ;
678
- self . fail ( test , new Error ( 'Pending test forbidden' ) ) ;
679
- delete test . isPending ;
692
+ self . fail ( test , new Error ( 'Pending test forbidden' ) , true ) ;
680
693
} else {
681
694
self . emit ( constants . EVENT_TEST_PENDING , test ) ;
682
695
}
683
696
self . emit ( constants . EVENT_TEST_END , test ) ;
684
- return self . hookUp ( HOOK_TYPE_AFTER_EACH , next ) ;
697
+ return self . hookUp ( HOOK_TYPE_AFTER_EACH , nextTest ) ;
685
698
} else if ( err ) {
686
699
var retry = test . currentRetry ( ) ;
687
700
if ( retry < test . retries ( ) ) {
@@ -693,31 +706,27 @@ Runner.prototype.runTests = function(suite, fn) {
693
706
694
707
// Early return + hook trigger so that it doesn't
695
708
// increment the count wrong
696
- return self . hookUp ( HOOK_TYPE_AFTER_EACH , next ) ;
709
+ return self . hookUp ( HOOK_TYPE_AFTER_EACH , nextTest ) ;
697
710
} else {
698
711
self . fail ( test , err ) ;
699
712
}
700
713
self . emit ( constants . EVENT_TEST_END , test ) ;
701
- return self . hookUp ( HOOK_TYPE_AFTER_EACH , next ) ;
714
+ return self . hookUp ( HOOK_TYPE_AFTER_EACH , nextTest ) ;
702
715
}
703
716
704
717
test . state = STATE_PASSED ;
705
718
self . emit ( constants . EVENT_TEST_PASS , test ) ;
706
719
self . emit ( constants . EVENT_TEST_END , test ) ;
707
- self . hookUp ( HOOK_TYPE_AFTER_EACH , next ) ;
720
+ self . hookUp ( HOOK_TYPE_AFTER_EACH , nextTest ) ;
708
721
} ) ;
709
722
} ) ;
710
723
}
711
724
712
- this . next = next ;
725
+ this . next = nextTest ;
713
726
this . hookErr = hookErr ;
714
- next ( ) ;
727
+ nextTest ( ) ;
715
728
} ;
716
729
717
- function alwaysFalse ( ) {
718
- return false ;
719
- }
720
-
721
730
/**
722
731
* Run the given `suite` and invoke the callback `fn()` when complete.
723
732
*
@@ -738,7 +747,7 @@ Runner.prototype.runSuite = function(suite, fn) {
738
747
739
748
this . emit ( constants . EVENT_SUITE_BEGIN , ( this . suite = suite ) ) ;
740
749
741
- function next ( errSuite ) {
750
+ function nextSuite ( errSuite ) {
742
751
if ( errSuite ) {
743
752
// current suite failed on a hook from errSuite
744
753
if ( errSuite === suite ) {
@@ -765,33 +774,33 @@ Runner.prototype.runSuite = function(suite, fn) {
765
774
// See comment in `this.runTests()` for more information.
766
775
if ( self . _grep !== self . _defaultGrep ) {
767
776
Runner . immediately ( function ( ) {
768
- self . runSuite ( curr , next ) ;
777
+ self . runSuite ( curr , nextSuite ) ;
769
778
} ) ;
770
779
} else {
771
- self . runSuite ( curr , next ) ;
780
+ self . runSuite ( curr , nextSuite ) ;
772
781
}
773
782
}
774
783
775
784
function done ( errSuite ) {
776
785
self . suite = suite ;
777
- self . nextSuite = next ;
786
+ self . nextSuite = nextSuite ;
778
787
779
788
// remove reference to test
780
789
delete self . test ;
781
790
782
- self . hook ( HOOK_TYPE_AFTER_ALL , function ( ) {
791
+ self . hook ( HOOK_TYPE_AFTER_ALL , function cbHook ( ) {
783
792
self . emit ( constants . EVENT_SUITE_END , suite ) ;
784
793
fn ( errSuite ) ;
785
794
} ) ;
786
795
}
787
796
788
- this . nextSuite = next ;
797
+ this . nextSuite = nextSuite ;
789
798
790
- this . hook ( HOOK_TYPE_BEFORE_ALL , function ( err ) {
791
- if ( err ) {
792
- return done ( ) ;
793
- }
794
- self . runTests ( suite , next ) ;
799
+ this . hook ( HOOK_TYPE_BEFORE_ALL , function cbHook ( /* err */ ) {
800
+ // if (err) {
801
+ // return done();
802
+ // }
803
+ self . runTests ( suite , nextSuite ) ;
795
804
} ) ;
796
805
} ;
797
806
@@ -850,9 +859,7 @@ Runner.prototype.uncaught = function(err) {
850
859
return ;
851
860
} else if ( runnable . isPending ( ) ) {
852
861
// report 'pending test' retrospectively as failed
853
- runnable . isPending = alwaysFalse ;
854
- this . fail ( runnable , err ) ;
855
- delete runnable . isPending ;
862
+ this . fail ( runnable , err , true ) ;
856
863
return ;
857
864
}
858
865
0 commit comments