blob: fd891177556fff654796aa27f53b5b12f02e2632 [file] [log] [blame]
'use strict';
/* eslint no-unused-vars: off */
/* eslint-env commonjs */
/**
* Shim process.stdout.
*/
process.stdout = require('browser-stdout')({label: false});
var Mocha = require('./lib/mocha');
/**
* Create a Mocha instance.
*
* @return {undefined}
*/
var mocha = new Mocha({reporter: 'html'});
/**
* Save timer references to avoid Sinon interfering (see GH-237).
*/
var Date = global.Date;
var setTimeout = global.setTimeout;
var setInterval = global.setInterval;
var clearTimeout = global.clearTimeout;
var clearInterval = global.clearInterval;
var uncaughtExceptionHandlers = [];
var originalOnerrorHandler = global.onerror;
/**
* Remove uncaughtException listener.
* Revert to original onerror handler if previously defined.
*/
process.removeListener = function(e, fn) {
if (e === 'uncaughtException') {
if (originalOnerrorHandler) {
global.onerror = originalOnerrorHandler;
} else {
global.onerror = function() {};
}
var i = uncaughtExceptionHandlers.indexOf(fn);
if (i !== -1) {
uncaughtExceptionHandlers.splice(i, 1);
}
}
};
/**
* Implements uncaughtException listener.
*/
process.on = function(e, fn) {
if (e === 'uncaughtException') {
global.onerror = function(err, url, line) {
fn(new Error(err + ' (' + url + ':' + line + ')'));
return !mocha.allowUncaught;
};
uncaughtExceptionHandlers.push(fn);
}
};
// The BDD UI is registered by default, but no UI will be functional in the
// browser without an explicit call to the overridden `mocha.ui` (see below).
// Ensure that this default UI does not expose its methods to the global scope.
mocha.suite.removeAllListeners('pre-require');
var immediateQueue = [];
var immediateTimeout;
function timeslice() {
var immediateStart = new Date().getTime();
while (immediateQueue.length && new Date().getTime() - immediateStart < 100) {
immediateQueue.shift()();
}
if (immediateQueue.length) {
immediateTimeout = setTimeout(timeslice, 0);
} else {
immediateTimeout = null;
}
}
/**
* High-performance override of Runner.immediately.
*/
Mocha.Runner.immediately = function(callback) {
immediateQueue.push(callback);
if (!immediateTimeout) {
immediateTimeout = setTimeout(timeslice, 0);
}
};
/**
* Function to allow assertion libraries to throw errors directly into mocha.
* This is useful when running tests in a browser because window.onerror will
* only receive the 'message' attribute of the Error.
*/
mocha.throwError = function(err) {
uncaughtExceptionHandlers.forEach(function(fn) {
fn(err);
});
throw err;
};
/**
* Override ui to ensure that the ui functions are initialized.
* Normally this would happen in Mocha.prototype.loadFiles.
*/
mocha.ui = function(ui) {
Mocha.prototype.ui.call(this, ui);
this.suite.emit('pre-require', global, null, this);
return this;
};
/**
* Setup mocha with the given setting options.
*/
mocha.setup = function(opts) {
if (typeof opts === 'string') {
opts = {ui: opts};
}
for (var opt in opts) {
if (opts.hasOwnProperty(opt)) {
this[opt](opts[opt]);
}
}
return this;
};
/**
* Run mocha, returning the Runner.
*/
mocha.run = function(fn) {
var options = mocha.options;
mocha.globals('location');
var query = Mocha.utils.parseQuery(global.location.search || '');
if (query.grep) {
mocha.grep(query.grep);
}
if (query.fgrep) {
mocha.fgrep(query.fgrep);
}
if (query.invert) {
mocha.invert();
}
return Mocha.prototype.run.call(mocha, function(err) {
// The DOM Document is not available in Web Workers.
var document = global.document;
if (
document &&
document.getElementById('mocha') &&
options.noHighlighting !== true
) {
Mocha.utils.highlightTags('code');
}
if (fn) {
fn(err);
}
});
};
/**
* Expose the process shim.
* https://github.com/mochajs/mocha/pull/916
*/
Mocha.process = process;
/**
* Expose mocha.
*/
global.Mocha = Mocha;
global.mocha = mocha;
// this allows test/acceptance/required-tokens.js to pass; thus,
// you can now do `const describe = require('mocha').describe` in a
// browser context (assuming browserification). should fix #880
module.exports = global;