220 lines
4.8 KiB
JavaScript
220 lines
4.8 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
/* eslint no-unused-vars: off */
|
||
|
/* eslint-env commonjs */
|
||
|
|
||
|
/**
|
||
|
* Shim process.stdout.
|
||
|
*/
|
||
|
|
||
|
process.stdout = require('browser-stdout')({label: false});
|
||
|
|
||
|
var parseQuery = require('./lib/browser/parse-query');
|
||
|
var highlightTags = require('./lib/browser/highlight-tags');
|
||
|
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 listenerCount for 'uncaughtException'.
|
||
|
*/
|
||
|
|
||
|
process.listenerCount = function(name) {
|
||
|
if (name === 'uncaughtException') {
|
||
|
return uncaughtExceptionHandlers.length;
|
||
|
}
|
||
|
return 0;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* 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.options.allowUncaught;
|
||
|
};
|
||
|
uncaughtExceptionHandlers.push(fn);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
process.listeners = function(e) {
|
||
|
if (e === 'uncaughtException') {
|
||
|
return uncaughtExceptionHandlers;
|
||
|
}
|
||
|
return [];
|
||
|
};
|
||
|
|
||
|
// 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};
|
||
|
}
|
||
|
if (opts.delay === true) {
|
||
|
this.delay();
|
||
|
}
|
||
|
var self = this;
|
||
|
Object.keys(opts)
|
||
|
.filter(function(opt) {
|
||
|
return opt !== 'delay';
|
||
|
})
|
||
|
.forEach(function(opt) {
|
||
|
if (Object.prototype.hasOwnProperty.call(opts, opt)) {
|
||
|
self[opt](opts[opt]);
|
||
|
}
|
||
|
});
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Run mocha, returning the Runner.
|
||
|
*/
|
||
|
|
||
|
mocha.run = function(fn) {
|
||
|
var options = mocha.options;
|
||
|
mocha.globals('location');
|
||
|
|
||
|
var query = 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
|
||
|
) {
|
||
|
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 = Object.assign(mocha, global);
|