@@ -5,6 +5,25 @@ var path = require('path');
5
5
var inherits = require ( 'util' ) . inherits ;
6
6
var EventEmitter = require ( 'events' ) . EventEmitter ;
7
7
8
+ /**
9
+ * Transitions:
10
+ *
11
+ * From -> To : Triggered by
12
+ *
13
+ * PENDING -> RUNNING : Results object calls .run
14
+ * RUNNING -> FINISHED : .end no remaining subtest
15
+ * RUNNING -> SUBTESTS : .end with subtests
16
+ * SUBTESTS -> FINISHED : .end after all subtests end
17
+ *
18
+ * .end is called when:
19
+ *
20
+ * - it's called by the test itself
21
+ * - there is a plan and:
22
+ * - The assertion count + number of children == plan
23
+ *
24
+ */
25
+
26
+
8
27
module . exports = Test ;
9
28
10
29
var nextTick = typeof setImmediate !== 'undefined'
@@ -36,6 +55,7 @@ function Test (name_, opts_, cb_) {
36
55
this . readable = true ;
37
56
this . name = name || '(anonymous)' ;
38
57
this . assertCount = 0 ;
58
+ this . pendingCount = 0 ;
39
59
this . _skip = opts . skip || false ;
40
60
this . _plan = undefined ;
41
61
this . _cb = cb ;
@@ -60,9 +80,19 @@ Test.prototype.run = function () {
60
80
} ;
61
81
62
82
Test . prototype . test = function ( name , opts , cb ) {
83
+ var self = this ;
63
84
var t = new Test ( name , opts , cb ) ;
64
85
this . _progeny . push ( t ) ;
86
+ this . pendingCount ++ ;
65
87
this . emit ( 'test' , t ) ;
88
+ t . on ( 'prerun' , function ( ) {
89
+ self . assertCount ++ ;
90
+ } )
91
+ if ( ! self . _pendingAsserts ( ) ) {
92
+ nextTick ( function ( ) {
93
+ self . end ( ) ;
94
+ } ) ;
95
+ }
66
96
} ;
67
97
68
98
Test . prototype . comment = function ( msg ) {
@@ -76,16 +106,19 @@ Test.prototype.plan = function (n) {
76
106
77
107
Test . prototype . end = function ( ) {
78
108
var self = this ;
109
+
79
110
if ( this . _progeny . length ) {
80
111
var t = this . _progeny . shift ( ) ;
81
- t . on ( 'end' , function ( ) { self . end ( ) } ) ;
112
+ t . on ( 'end' , function ( ) {
113
+ self . end ( ) ;
114
+ } ) ;
82
115
this . emit ( 'next' , t ) ;
83
116
return ;
84
117
}
85
118
86
119
if ( ! this . ended ) this . emit ( 'end' ) ;
87
- if ( this . _plan !== undefined &&
88
- ! this . _planError && this . assertCount !== this . _plan ) {
120
+ var pendingAsserts = this . _pendingAsserts ( ) ;
121
+ if ( ! this . _planError && this . _plan !== undefined && pendingAsserts ) {
89
122
this . _planError = true ;
90
123
this . fail ( 'plan != count' , {
91
124
expected : this . _plan ,
@@ -112,6 +145,15 @@ Test.prototype._exit = function () {
112
145
}
113
146
} ;
114
147
148
+ Test . prototype . _pendingAsserts = function ( ) {
149
+ if ( this . _plan === undefined ) {
150
+ return 1 ;
151
+ } else {
152
+ return this . _plan -
153
+ ( this . _progeny . length + this . assertCount ) ;
154
+ }
155
+ }
156
+
115
157
Test . prototype . _assert = function assert ( ok , opts ) {
116
158
var self = this ;
117
159
var extra = opts . extra || { } ;
@@ -160,20 +202,22 @@ Test.prototype._assert = function assert (ok, opts) {
160
202
161
203
self . emit ( 'result' , res ) ;
162
204
163
- if ( self . _plan === self . assertCount && extra . exiting ) {
164
- if ( ! self . ended ) self . end ( ) ;
165
- }
166
- else if ( self . _plan === self . assertCount ) {
167
- nextTick ( function ( ) {
168
- if ( ! self . ended ) self . end ( ) ;
169
- } ) ;
205
+ var pendingAsserts = self . _pendingAsserts ( ) ;
206
+ if ( ! pendingAsserts ) {
207
+ if ( extra . exiting ) {
208
+ self . end ( ) ;
209
+ } else {
210
+ nextTick ( function ( ) {
211
+ self . end ( ) ;
212
+ } ) ;
213
+ }
170
214
}
171
215
172
- if ( ! self . _planError && self . assertCount > self . _plan ) {
216
+ if ( ! self . _planError && pendingAsserts < 0 ) {
173
217
self . _planError = true ;
174
218
self . fail ( 'plan != count' , {
175
219
expected : self . _plan ,
176
- actual : self . assertCount
220
+ actual : self . _plan - pendingAsserts
177
221
} ) ;
178
222
}
179
223
} ;
0 commit comments