UNPKG

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