1+ 'use strict' ;
2+
3+ ( ( context : any ) => {
4+ var Mocha = context . Mocha ;
5+
6+ if ( typeof Mocha === 'undefined' ) {
7+ throw new Error ( 'Missing Mocha.js' ) ;
8+ }
9+
10+ if ( typeof Zone === 'undefined' ) {
11+ throw new Error ( 'Missing Zone.js' ) ;
12+ }
13+
14+ const ProxyZoneSpec = Zone [ 'ProxyZoneSpec' ] ;
15+ const SyncTestZoneSpec = Zone [ 'SyncTestZoneSpec' ] ;
16+
17+ if ( ! ProxyZoneSpec ) {
18+ throw new Error ( 'Missing ProxyZoneSpec' ) ;
19+ }
20+
21+ if ( Mocha [ '__zone_patch__' ] ) {
22+ throw new Error ( '"Mocha" has already been patched with "Zone".' ) ;
23+ }
24+
25+ Mocha [ '__zone_patch__' ] = true ;
26+
27+ const rootZone = Zone . current ;
28+ const syncZone = rootZone . fork ( new SyncTestZoneSpec ( 'Mocha.describe' ) ) ;
29+ let testZone = null ;
30+ const suiteZone = rootZone . fork ( new ProxyZoneSpec ( ) ) ;
31+
32+ const mochaOriginal = {
33+ after : Mocha . after ,
34+ afterEach : Mocha . afterEach ,
35+ before : Mocha . before ,
36+ beforeEach : Mocha . beforeEach ,
37+ describe : Mocha . describe ,
38+ it : Mocha . it
39+ } ;
40+
41+ function modifyArguments ( args : IArguments , syncTest : Function , asyncTest ?: Function ) : any [ ] {
42+ for ( let i = 0 ; i < args . length ; i ++ ) {
43+ let arg = args [ i ] ;
44+ if ( typeof arg === 'function' ) {
45+ // The `done` callback is only passed through if the function expects at
46+ // least one argument.
47+ // Note we have to make a function with correct number of arguments,
48+ // otherwise mocha will
49+ // think that all functions are sync or async.
50+ args [ i ] = ( arg . length === 0 ) ? syncTest ( arg ) : asyncTest ( arg ) ;
51+ // Mocha uses toString to view the test body in the result list, make sure we return the correct function body
52+ args [ i ] . toString = function ( ) {
53+ return arg . toString ( ) ;
54+ } ;
55+ }
56+ }
57+
58+ return args as any ;
59+ }
60+
61+ function wrapDescribeInZone ( args : IArguments ) : any [ ] {
62+ const syncTest : any = function ( fn ) {
63+ return function ( ) {
64+ return syncZone . run ( fn , this , arguments as any as any [ ] ) ;
65+ } ;
66+ } ;
67+
68+ return modifyArguments ( args , syncTest ) ;
69+ }
70+
71+ function wrapTestInZone ( args : IArguments ) : any [ ] {
72+ const asyncTest = function ( fn ) {
73+ return function ( done ) {
74+ return testZone . run ( fn , this , [ done ] ) ;
75+ } ;
76+ } ;
77+
78+ const syncTest : any = function ( fn ) {
79+ return function ( ) {
80+ return testZone . run ( fn , this ) ;
81+ } ;
82+ } ;
83+
84+ return modifyArguments ( args , syncTest , asyncTest ) ;
85+ }
86+
87+ function wrapSuiteInZone ( args : IArguments ) : any [ ] {
88+ const asyncTest = function ( fn ) {
89+ return function ( done ) {
90+ return suiteZone . run ( fn , this , [ done ] ) ;
91+ } ;
92+ } ;
93+
94+ const syncTest : any = function ( fn ) {
95+ return function ( ) {
96+ return suiteZone . run ( fn , this ) ;
97+ } ;
98+ } ;
99+
100+ return modifyArguments ( args , syncTest , asyncTest ) ;
101+ } ;
102+
103+ context . describe = context . suite = Mocha . describe = function ( ) {
104+ return mochaOriginal . describe . apply ( this , wrapDescribeInZone ( arguments ) ) ;
105+ } ;
106+
107+ context . xdescribe = context . suite . skip = Mocha . describe . skip = function ( ) {
108+ return mochaOriginal . describe . skip . apply ( this , wrapDescribeInZone ( arguments ) ) ;
109+ } ;
110+
111+ context . describe . only = context . suite . only = Mocha . describe . only = function ( ) {
112+ return mochaOriginal . describe . only . apply ( this , wrapDescribeInZone ( arguments ) ) ;
113+ } ;
114+
115+ context . it = context . specify = context . test = Mocha . it = function ( ) {
116+ return mochaOriginal . it . apply ( this , wrapTestInZone ( arguments ) ) ;
117+ } ;
118+
119+ context . xit = context . xspecify = Mocha . it . skip = function ( ) {
120+ return mochaOriginal . it . skip . apply ( this , wrapTestInZone ( arguments ) ) ;
121+ } ;
122+
123+ context . it . only = context . test . only = Mocha . it . only = function ( ) {
124+ return mochaOriginal . it . only . apply ( this , wrapTestInZone ( arguments ) ) ;
125+ } ;
126+
127+ context . after = context . suiteTeardown = Mocha . after = function ( ) {
128+ return mochaOriginal . after . apply ( this , wrapSuiteInZone ( arguments ) ) ;
129+ } ;
130+
131+ context . afterEach = context . teardown = Mocha . afterEach = function ( ) {
132+ return mochaOriginal . afterEach . apply ( this , wrapTestInZone ( arguments ) ) ;
133+ } ;
134+
135+ context . before = context . suiteSetup = Mocha . before = function ( ) {
136+ return mochaOriginal . before . apply ( this , wrapSuiteInZone ( arguments ) ) ;
137+ } ;
138+
139+ context . beforeEach = context . setup = Mocha . beforeEach = function ( ) {
140+ return mochaOriginal . beforeEach . apply ( this , wrapTestInZone ( arguments ) ) ;
141+ } ;
142+
143+ ( ( originalRunTest , originalRun ) => {
144+ Mocha . Runner . prototype . runTest = function ( fn ) {
145+ Zone . current . scheduleMicroTask ( 'mocha.forceTask' , ( ) => {
146+ originalRunTest . call ( this , fn ) ;
147+ } ) ;
148+ } ;
149+
150+ Mocha . Runner . prototype . run = function ( fn ) {
151+ this . on ( 'test' , ( e ) => {
152+ if ( Zone . current !== rootZone ) {
153+ throw new Error ( 'Unexpected zone: ' + Zone . current . name ) ;
154+ }
155+ testZone = rootZone . fork ( new ProxyZoneSpec ( ) ) ;
156+ } ) ;
157+
158+ return originalRun . call ( this , fn ) ;
159+ } ;
160+
161+
162+ } ) ( Mocha . Runner . prototype . runTest , Mocha . Runner . prototype . run ) ;
163+
164+ } ) ( window ) ;
0 commit comments