1 | 'use strict'; |
||
2 | |||
3 | /* eslint no-unused-vars: off */ |
||
4 | /* eslint-env commonjs */ |
||
5 | |||
6 | /** |
||
7 | * Shim process.stdout. |
||
8 | */ |
||
9 | |||
10 | process.stdout = require('browser-stdout')({level: false}); |
||
11 | |||
12 | var Mocha = require('./lib/mocha'); |
||
13 | |||
14 | /** |
||
15 | * Create a Mocha instance. |
||
16 | * |
||
17 | * @return {undefined} |
||
18 | */ |
||
19 | |||
20 | var mocha = new Mocha({ reporter: 'html' }); |
||
21 | |||
22 | /** |
||
23 | * Save timer references to avoid Sinon interfering (see GH-237). |
||
24 | */ |
||
25 | |||
26 | var Date = global.Date; |
||
0 ignored issues
–
show
Comprehensibility
introduced
by
![]() |
|||
27 | var setTimeout = global.setTimeout; |
||
28 | var setInterval = global.setInterval; |
||
29 | var clearTimeout = global.clearTimeout; |
||
30 | var clearInterval = global.clearInterval; |
||
31 | |||
32 | var uncaughtExceptionHandlers = []; |
||
33 | |||
34 | var originalOnerrorHandler = global.onerror; |
||
35 | |||
36 | /** |
||
37 | * Remove uncaughtException listener. |
||
38 | * Revert to original onerror handler if previously defined. |
||
39 | */ |
||
40 | |||
41 | process.removeListener = function (e, fn) { |
||
42 | if (e === 'uncaughtException') { |
||
43 | if (originalOnerrorHandler) { |
||
44 | global.onerror = originalOnerrorHandler; |
||
45 | } else { |
||
46 | global.onerror = function () {}; |
||
47 | } |
||
48 | var i = uncaughtExceptionHandlers.indexOf(fn); |
||
49 | if (i !== -1) { |
||
50 | uncaughtExceptionHandlers.splice(i, 1); |
||
51 | } |
||
52 | } |
||
53 | }; |
||
54 | |||
55 | /** |
||
56 | * Implements uncaughtException listener. |
||
57 | */ |
||
58 | |||
59 | process.on = function (e, fn) { |
||
60 | if (e === 'uncaughtException') { |
||
61 | global.onerror = function (err, url, line) { |
||
62 | fn(new Error(err + ' (' + url + ':' + line + ')')); |
||
63 | return !mocha.allowUncaught; |
||
64 | }; |
||
65 | uncaughtExceptionHandlers.push(fn); |
||
66 | } |
||
67 | }; |
||
68 | |||
69 | // The BDD UI is registered by default, but no UI will be functional in the |
||
70 | // browser without an explicit call to the overridden `mocha.ui` (see below). |
||
71 | // Ensure that this default UI does not expose its methods to the global scope. |
||
72 | mocha.suite.removeAllListeners('pre-require'); |
||
73 | |||
74 | var immediateQueue = []; |
||
75 | var immediateTimeout; |
||
76 | |||
77 | function timeslice () { |
||
78 | var immediateStart = new Date().getTime(); |
||
79 | while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) { |
||
80 | immediateQueue.shift()(); |
||
81 | } |
||
82 | if (immediateQueue.length) { |
||
83 | immediateTimeout = setTimeout(timeslice, 0); |
||
84 | } else { |
||
85 | immediateTimeout = null; |
||
86 | } |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * High-performance override of Runner.immediately. |
||
91 | */ |
||
92 | |||
93 | Mocha.Runner.immediately = function (callback) { |
||
94 | immediateQueue.push(callback); |
||
95 | if (!immediateTimeout) { |
||
96 | immediateTimeout = setTimeout(timeslice, 0); |
||
97 | } |
||
98 | }; |
||
99 | |||
100 | /** |
||
101 | * Function to allow assertion libraries to throw errors directly into mocha. |
||
102 | * This is useful when running tests in a browser because window.onerror will |
||
103 | * only receive the 'message' attribute of the Error. |
||
104 | */ |
||
105 | mocha.throwError = function (err) { |
||
106 | uncaughtExceptionHandlers.forEach(function (fn) { |
||
107 | fn(err); |
||
108 | }); |
||
109 | throw err; |
||
110 | }; |
||
111 | |||
112 | /** |
||
113 | * Override ui to ensure that the ui functions are initialized. |
||
114 | * Normally this would happen in Mocha.prototype.loadFiles. |
||
115 | */ |
||
116 | |||
117 | mocha.ui = function (ui) { |
||
118 | Mocha.prototype.ui.call(this, ui); |
||
119 | this.suite.emit('pre-require', global, null, this); |
||
120 | return this; |
||
121 | }; |
||
122 | |||
123 | /** |
||
124 | * Setup mocha with the given setting options. |
||
125 | */ |
||
126 | |||
127 | mocha.setup = function (opts) { |
||
128 | if (typeof opts === 'string') { |
||
129 | opts = { ui: opts }; |
||
130 | } |
||
131 | for (var opt in opts) { |
||
132 | if (opts.hasOwnProperty(opt)) { |
||
133 | this[opt](opts[opt]); |
||
134 | } |
||
135 | } |
||
136 | return this; |
||
137 | }; |
||
138 | |||
139 | /** |
||
140 | * Run mocha, returning the Runner. |
||
141 | */ |
||
142 | |||
143 | mocha.run = function (fn) { |
||
144 | var options = mocha.options; |
||
145 | mocha.globals('location'); |
||
146 | |||
147 | var query = Mocha.utils.parseQuery(global.location.search || ''); |
||
148 | if (query.grep) { |
||
149 | mocha.grep(query.grep); |
||
150 | } |
||
151 | if (query.fgrep) { |
||
152 | mocha.fgrep(query.fgrep); |
||
153 | } |
||
154 | if (query.invert) { |
||
155 | mocha.invert(); |
||
156 | } |
||
157 | |||
158 | return Mocha.prototype.run.call(mocha, function (err) { |
||
159 | // The DOM Document is not available in Web Workers. |
||
160 | var document = global.document; |
||
161 | if (document && document.getElementById('mocha') && options.noHighlighting !== true) { |
||
162 | Mocha.utils.highlightTags('code'); |
||
163 | } |
||
164 | if (fn) { |
||
165 | fn(err); |
||
166 | } |
||
167 | }); |
||
168 | }; |
||
169 | |||
170 | /** |
||
171 | * Expose the process shim. |
||
172 | * https://github.com/mochajs/mocha/pull/916 |
||
173 | */ |
||
174 | |||
175 | Mocha.process = process; |
||
176 | |||
177 | /** |
||
178 | * Expose mocha. |
||
179 | */ |
||
180 | |||
181 | global.Mocha = Mocha; |
||
182 | global.mocha = mocha; |
||
183 | |||
184 | // this allows test/acceptance/required-tokens.js to pass; thus, |
||
185 | // you can now do `const describe = require('mocha').describe` in a |
||
186 | // browser context (assuming browserification). should fix #880 |
||
187 | module.exports = global; |
||
188 |