1
1
'use strict' ;
2
2
const EventEmitter = require ( 'events' ) ;
3
+ const cloneDeep = require ( 'lodash.clonedeep' ) ;
3
4
const Concurrent = require ( './concurrent' ) ;
4
5
const Sequence = require ( './sequence' ) ;
5
6
const Test = require ( './test' ) ;
6
7
8
+ class ContextBind {
9
+ constructor ( ref ) {
10
+ this . ref = ref ;
11
+ this . bound = false ;
12
+ this . boundContext = { } ;
13
+ }
14
+
15
+ get context ( ) {
16
+ if ( ! this . bound ) {
17
+ this . context = cloneDeep ( this . ref . context ) ;
18
+ }
19
+
20
+ return this . boundContext ;
21
+ }
22
+
23
+ set context ( context ) {
24
+ this . bound = true ;
25
+ this . boundContext = context ;
26
+ }
27
+ }
28
+
29
+ class Context {
30
+ constructor ( ) {
31
+ this . context = { } ;
32
+ }
33
+
34
+ clone ( ) {
35
+ return new ContextBind ( this ) ;
36
+ }
37
+ }
38
+
7
39
class TestCollection extends EventEmitter {
8
40
constructor ( options ) {
9
41
super ( ) ;
@@ -110,9 +142,9 @@ class TestCollection extends EventEmitter {
110
142
this . emit ( 'test' , result ) ;
111
143
}
112
144
113
- _buildHooks ( hooks , testTitle , context ) {
145
+ _buildHooks ( hooks , testTitle , contextRef ) {
114
146
return hooks . map ( hook => {
115
- const test = this . _buildHook ( hook , testTitle , context ) ;
147
+ const test = this . _buildHook ( hook , testTitle , contextRef ) ;
116
148
117
149
if ( hook . metadata . skipped || hook . metadata . todo ) {
118
150
return this . _skippedTest ( test ) ;
@@ -129,10 +161,6 @@ class TestCollection extends EventEmitter {
129
161
title += ` for ${ testTitle } ` ;
130
162
}
131
163
132
- if ( ! contextRef ) {
133
- contextRef = null ;
134
- }
135
-
136
164
const test = new Test ( {
137
165
contextRef,
138
166
failWithoutAssertions : false ,
@@ -147,10 +175,6 @@ class TestCollection extends EventEmitter {
147
175
}
148
176
149
177
_buildTest ( test , contextRef ) {
150
- if ( ! contextRef ) {
151
- contextRef = null ;
152
- }
153
-
154
178
test = new Test ( {
155
179
contextRef,
156
180
failWithoutAssertions : this . failWithoutAssertions ,
@@ -164,26 +188,26 @@ class TestCollection extends EventEmitter {
164
188
return test ;
165
189
}
166
190
167
- _buildTestWithHooks ( test , context ) {
191
+ _buildTestWithHooks ( test , contextRef ) {
168
192
if ( test . metadata . skipped || test . metadata . todo ) {
169
193
return new Sequence ( [ this . _skippedTest ( this . _buildTest ( test ) ) ] , true ) ;
170
194
}
171
195
172
- const contextRef = context ? Object . create ( context ) : { context : { } } ;
196
+ const context = contextRef . clone ( ) ;
173
197
174
- const beforeHooks = this . _buildHooks ( this . hooks . beforeEach , test . title , contextRef ) ;
175
- const afterHooks = this . _buildHooks ( this . hooks . afterEach , test . title , contextRef ) ;
198
+ const beforeHooks = this . _buildHooks ( this . hooks . beforeEach , test . title , context ) ;
199
+ const afterHooks = this . _buildHooks ( this . hooks . afterEach , test . title , context ) ;
176
200
177
- let sequence = new Sequence ( [ ] . concat ( beforeHooks , this . _buildTest ( test , contextRef ) , afterHooks ) , true ) ;
201
+ let sequence = new Sequence ( [ ] . concat ( beforeHooks , this . _buildTest ( test , context ) , afterHooks ) , true ) ;
178
202
if ( this . hooks . afterEachAlways . length > 0 ) {
179
- const afterAlwaysHooks = new Sequence ( this . _buildHooks ( this . hooks . afterEachAlways , test . title , contextRef ) ) ;
203
+ const afterAlwaysHooks = new Sequence ( this . _buildHooks ( this . hooks . afterEachAlways , test . title , context ) ) ;
180
204
sequence = new Sequence ( [ sequence , afterAlwaysHooks ] , false ) ;
181
205
}
182
206
return sequence ;
183
207
}
184
208
185
- _buildTests ( tests , context ) {
186
- return tests . map ( test => this . _buildTestWithHooks ( test , context ) ) ;
209
+ _buildTests ( tests , contextRef ) {
210
+ return tests . map ( test => this . _buildTestWithHooks ( test , contextRef ) ) ;
187
211
}
188
212
189
213
_hasUnskippedTests ( ) {
@@ -194,26 +218,24 @@ class TestCollection extends EventEmitter {
194
218
}
195
219
196
220
build ( ) {
197
- const sequenceTests = context => {
198
- const serialTests = new Sequence ( this . _buildTests ( this . tests . serial , context ) , this . bail ) ;
199
- const concurrentTests = new Concurrent ( this . _buildTests ( this . tests . concurrent , context ) , this . bail ) ;
200
- return new Sequence ( [ serialTests , concurrentTests ] ) ;
201
- } ;
221
+ const context = new Context ( ) ;
222
+
223
+ const serialTests = new Sequence ( this . _buildTests ( this . tests . serial , context ) , this . bail ) ;
224
+ const concurrentTests = new Concurrent ( this . _buildTests ( this . tests . concurrent , context ) , this . bail ) ;
225
+ const allTests = new Sequence ( [ serialTests , concurrentTests ] ) ;
202
226
203
227
let finalTests ;
204
228
// Only run before and after hooks when there are unskipped tests
205
229
if ( this . _hasUnskippedTests ( ) ) {
206
- const context = { context : { } } ;
207
-
208
230
const beforeHooks = new Sequence ( this . _buildHooks ( this . hooks . before , null , context ) ) ;
209
- const afterHooks = new Sequence ( this . _buildHooks ( this . hooks . after ) ) ;
210
- finalTests = new Sequence ( [ beforeHooks , sequenceTests ( context ) , afterHooks ] , true ) ;
231
+ const afterHooks = new Sequence ( this . _buildHooks ( this . hooks . after , null , context ) ) ;
232
+ finalTests = new Sequence ( [ beforeHooks , allTests , afterHooks ] , true ) ;
211
233
} else {
212
- finalTests = new Sequence ( [ sequenceTests ( ) ] , true ) ;
234
+ finalTests = new Sequence ( [ allTests ] , true ) ;
213
235
}
214
236
215
237
if ( this . hooks . afterAlways . length > 0 ) {
216
- const afterAlwaysHooks = new Sequence ( this . _buildHooks ( this . hooks . afterAlways ) ) ;
238
+ const afterAlwaysHooks = new Sequence ( this . _buildHooks ( this . hooks . afterAlways , null , context ) ) ;
217
239
finalTests = new Sequence ( [ finalTests , afterAlwaysHooks ] , false ) ;
218
240
}
219
241
0 commit comments