@@ -34,9 +34,9 @@ export default function Test( settings ) {
34
34
this . assertions = [ ] ;
35
35
this . semaphore = 0 ;
36
36
this . module = config . currentModule ;
37
- this . stack = sourceFromStacktrace ( 3 ) ;
38
37
this . steps = [ ] ;
39
38
this . timeout = undefined ;
39
+ this . errorForStack = new Error ( ) ;
40
40
41
41
// If a module is skipped, all its tests and the tests of the child suites
42
42
// should be treated as skipped even if they are defined as `only` or `todo`.
@@ -112,6 +112,12 @@ function getNotStartedModules( startModule ) {
112
112
}
113
113
114
114
Test . prototype = {
115
+
116
+ // generating a stack trace can be expensive, so using a getter defers this until we need it
117
+ get stack ( ) {
118
+ return extractStacktrace ( this . errorForStack , 2 ) ;
119
+ } ,
120
+
115
121
before : function ( ) {
116
122
var module = this . module ,
117
123
notStartedModules = getNotStartedModules ( module ) ;
@@ -318,6 +324,7 @@ Test.prototype = {
318
324
// avoid leaking it. It is not used by the legacy testDone callbacks.
319
325
emit ( "testEnd" , this . testReport . end ( true ) ) ;
320
326
this . testReport . slimAssertions ( ) ;
327
+ const test = this ;
321
328
322
329
return runLoggingCallbacks ( "testDone" , {
323
330
name : testName ,
@@ -334,7 +341,8 @@ Test.prototype = {
334
341
testId : this . testId ,
335
342
336
343
// Source of Test
337
- source : this . stack
344
+ // generating stack trace is expensive, so using a getter will help defer this until we need it
345
+ get source ( ) { return test . stack ; }
338
346
} ) . then ( function ( ) {
339
347
if ( module . testsRun === numberOfTests ( module ) ) {
340
348
const completedModules = [ module ] ;
0 commit comments