@@ -4,7 +4,9 @@ var util = require('util');
4
4
var Promise = require ( 'bluebird' ) ;
5
5
var hasFlag = require ( 'has-flag' ) ;
6
6
var Test = require ( './test' ) ;
7
+ var Hook = require ( './hook' ) ;
7
8
var send = require ( './send' ) ;
9
+ var objectAssign = require ( 'object-assign' ) ;
8
10
9
11
function noop ( ) { }
10
12
@@ -13,7 +15,7 @@ function each(items, fn, context) {
13
15
}
14
16
15
17
function eachSeries ( items , fn , context ) {
16
- return Promise . resolve ( items ) . each ( fn . bind ( context ) ) ;
18
+ return Promise . each ( items , fn . bind ( context ) ) ;
17
19
}
18
20
19
21
function Runner ( opts ) {
@@ -25,112 +27,77 @@ function Runner(opts) {
25
27
26
28
this . results = [ ] ;
27
29
28
- this . stats = {
29
- failCount : 0 ,
30
- passCount : 0 ,
31
- testCount : 0
32
- } ;
30
+ this . tests = [ ] ;
33
31
34
- this . tests = {
35
- concurrent : [ ] ,
36
- serial : [ ] ,
37
- only : [ ] ,
38
- before : [ ] ,
39
- after : [ ] ,
40
- beforeEach : [ ] ,
41
- afterEach : [ ]
42
- } ;
32
+ this . test = makeChain ( {
33
+ type : 'test' ,
34
+ serial : false ,
35
+ exclusive : false ,
36
+ skipped : false
37
+ } , this . _addFn . bind ( this ) ) ;
43
38
}
44
39
45
40
util . inherits ( Runner , EventEmitter ) ;
46
41
module . exports = Runner ;
47
42
48
- Runner . prototype . addTest = function ( title , cb ) {
49
- this . stats . testCount ++ ;
50
- this . tests . concurrent . push ( new Test ( title , cb ) ) ;
51
- } ;
52
-
53
- Runner . prototype . addSerialTest = function ( title , cb ) {
54
- this . stats . testCount ++ ;
55
- this . tests . serial . push ( new Test ( title , cb ) ) ;
56
- } ;
57
-
58
- Runner . prototype . addBeforeHook = function ( title , cb ) {
59
- var test = new Test ( title , cb ) ;
60
- test . type = 'hook' ;
61
-
62
- this . tests . before . push ( test ) ;
63
- } ;
64
-
65
- Runner . prototype . addAfterHook = function ( title , cb ) {
66
- var test = new Test ( title , cb ) ;
67
- test . type = 'hook' ;
68
-
69
- this . tests . after . push ( test ) ;
43
+ var chainableFunctions = {
44
+ serial : { serial : true } ,
45
+ before : { type : 'before' } ,
46
+ after : { type : 'after' } ,
47
+ skip : { skipped : true } ,
48
+ only : { exclusive : true } ,
49
+ beforeEach : { type : 'beforeEach' } ,
50
+ afterEach : { type : 'afterEach' }
70
51
} ;
71
52
72
- Runner . prototype . addBeforeEachHook = function ( title , cb ) {
73
- if ( ! cb ) {
74
- cb = title ;
75
- title = undefined ;
53
+ function makeChain ( defaults , parentAdd ) {
54
+ function fn ( title , fn ) {
55
+ parentAdd ( defaults , title , fn ) ;
76
56
}
77
57
78
- this . tests . beforeEach . push ( {
79
- title : title ,
80
- fn : cb
81
- } ) ;
82
- } ;
83
-
84
- Runner . prototype . addAfterEachHook = function ( title , cb ) {
85
- if ( ! cb ) {
86
- cb = title ;
87
- title = undefined ;
58
+ function add ( opts , title , fn ) {
59
+ opts = objectAssign ( { } , defaults , opts ) ;
60
+ parentAdd ( objectAssign ( { } , defaults , opts ) , title , fn ) ;
88
61
}
89
62
90
- this . tests . afterEach . push ( {
91
- title : title ,
92
- fn : cb
63
+ Object . keys ( chainableFunctions ) . forEach ( function ( key ) {
64
+ Object . defineProperty ( fn , key , {
65
+ get : function ( ) {
66
+ return makeChain ( objectAssign ( { } , defaults , chainableFunctions [ key ] ) , add ) ;
67
+ }
68
+ } ) ;
93
69
} ) ;
94
- } ;
95
70
96
- Runner . prototype . addSkippedTest = function ( title , cb ) {
97
- var test = new Test ( title , cb ) ;
98
- test . skip = true ;
71
+ return fn ;
72
+ }
99
73
100
- this . tests . concurrent . push ( test ) ;
101
- } ;
74
+ Object . keys ( chainableFunctions ) . forEach ( function ( key ) {
75
+ Object . defineProperty ( Runner . prototype , key , {
76
+ get : function ( ) {
77
+ return this . test [ key ] ;
78
+ }
79
+ } ) ;
80
+ } ) ;
102
81
103
- Runner . prototype . addOnlyTest = function ( title , cb ) {
104
- this . stats . testCount ++ ;
105
- this . tests . only . push ( new Test ( title , cb ) ) ;
82
+ Runner . prototype . _addFn = function ( opts , title , fn ) {
83
+ var Constructor = ( opts && / E a c h / . test ( opts . type ) ) ? Hook : Test ;
84
+ var test = new Constructor ( title , fn ) ;
85
+ test . metadata = objectAssign ( { } , opts ) ;
86
+ this . tests . push ( test ) ;
106
87
} ;
107
88
108
89
Runner . prototype . _runTestWithHooks = function ( test ) {
109
90
if ( test . skip ) {
110
91
return this . _addTestResult ( test ) ;
111
92
}
112
93
113
- var beforeHooks = this . tests . beforeEach . map ( function ( hook ) {
114
- var title = hook . title || 'beforeEach for "' + test . title + '"' ;
115
- hook = new Test ( title , hook . fn ) ;
116
- hook . type = 'eachHook' ;
117
-
118
- return hook ;
119
- } ) ;
120
-
121
- var afterHooks = this . tests . afterEach . map ( function ( hook ) {
122
- var title = hook . title || 'afterEach for "' + test . title + '"' ;
123
- hook = new Test ( title , hook . fn ) ;
124
- hook . type = 'eachHook' ;
125
-
126
- return hook ;
127
- } ) ;
128
-
129
- var tests = [ ] ;
94
+ function hookToTest ( hook ) {
95
+ return hook . test ( test . title ) ;
96
+ }
130
97
131
- tests . push . apply ( tests , beforeHooks ) ;
98
+ var tests = this . select ( { type : 'beforeEach' , skipped : false } ) . map ( hookToTest ) ;
132
99
tests . push ( test ) ;
133
- tests . push . apply ( tests , afterHooks ) ;
100
+ tests . push . apply ( tests , this . select ( { type : 'afterEach' , skipped : false } ) . map ( hookToTest ) ) ;
134
101
135
102
var context = { } ;
136
103
@@ -158,15 +125,15 @@ Runner.prototype._runTest = function (test) {
158
125
} ) ;
159
126
} ;
160
127
161
- Runner . prototype . concurrent = function ( tests ) {
128
+ Runner . prototype . _runConcurrent = function ( tests ) {
162
129
if ( hasFlag ( 'serial' ) ) {
163
- return this . serial ( tests ) ;
130
+ return this . _runSerial ( tests ) ;
164
131
}
165
132
166
133
return each ( tests , this . _runTestWithHooks , this ) ;
167
134
} ;
168
135
169
- Runner . prototype . serial = function ( tests ) {
136
+ Runner . prototype . _runSerial = function ( tests ) {
170
137
return eachSeries ( tests , this . _runTestWithHooks , this ) ;
171
138
} ;
172
139
@@ -179,7 +146,7 @@ Runner.prototype._addTestResult = function (test) {
179
146
duration : test . duration ,
180
147
title : test . title ,
181
148
error : test . assertError ,
182
- type : test . type ,
149
+ type : test . metadata . type ,
183
150
skip : test . skip
184
151
} ;
185
152
@@ -188,43 +155,48 @@ Runner.prototype._addTestResult = function (test) {
188
155
} ;
189
156
190
157
Runner . prototype . run = function ( ) {
191
- var tests = this . tests ;
192
- var stats = this . stats ;
193
158
var self = this ;
159
+ var hasExclusive = Boolean ( this . select ( { exclusive : true , skipped : false , type : 'test' } ) . length ) ;
160
+ var serial = this . select ( { exclusive : hasExclusive , skipped : false , serial : true , type : 'test' } ) ;
161
+ var concurrent = this . select ( { exclusive : hasExclusive , skipped : false , serial : false , type : 'test' } ) ;
194
162
195
- var hasOnlyTests = tests . only . length > 0 ;
163
+ var stats = this . stats = {
164
+ failCount : 0 ,
165
+ passCount : 0 ,
166
+ testCount : serial . length + concurrent . length
167
+ } ;
196
168
197
169
// Runner is executed directly in tests, in that case process.send() == undefined
198
170
if ( process . send ) {
199
171
send ( 'stats' , stats ) ;
200
172
}
201
173
202
- return eachSeries ( tests . before , this . _runTest , this )
174
+ return eachSeries ( this . select ( { type : ' before' , skipped : false } ) , this . _runTest , this )
203
175
. catch ( noop )
204
176
. then ( function ( ) {
205
177
if ( stats . failCount > 0 ) {
206
178
return Promise . reject ( ) ;
207
179
}
208
180
} )
209
181
. then ( function ( ) {
210
- return self . concurrent ( tests . only ) ;
211
- } )
212
- . then ( function ( ) {
213
- if ( ! hasOnlyTests ) {
214
- return self . serial ( tests . serial ) ;
215
- }
182
+ return self . _runSerial ( serial ) ;
216
183
} )
217
184
. then ( function ( ) {
218
- if ( ! hasOnlyTests ) {
219
- return self . concurrent ( tests . concurrent ) ;
220
- }
185
+ return self . _runConcurrent ( concurrent ) ;
221
186
} )
222
187
. then ( function ( ) {
223
- return eachSeries ( tests . after , self . _runTest , self ) ;
188
+ return eachSeries ( self . select ( { type : ' after' , skipped : false } ) , self . _runTest , self ) ;
224
189
} )
225
190
. catch ( noop )
226
191
. then ( function ( ) {
227
- stats . testCount = tests . only . length || stats . testCount ;
228
192
stats . passCount = stats . testCount - stats . failCount ;
229
193
} ) ;
230
194
} ;
195
+
196
+ Runner . prototype . select = function ( filter ) {
197
+ return this . tests . filter ( function ( test ) {
198
+ return Object . keys ( filter ) . every ( function ( key ) {
199
+ return filter [ key ] === test . metadata [ key ] ;
200
+ } ) ;
201
+ } ) ;
202
+ } ;
0 commit comments