js-algorithms/node_modules/mocha/lib/mocha.js
2015-07-24 11:14:18 +04:30

447 lines
9.9 KiB
JavaScript

/*!
* mocha
* Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var path = require('path')
, escapeRe = require('escape-string-regexp')
, utils = require('./utils');
/**
* Expose `Mocha`.
*/
exports = module.exports = Mocha;
/**
* To require local UIs and reporters when running in node.
*/
if (typeof process !== 'undefined' && typeof process.cwd === 'function') {
var join = path.join
, cwd = process.cwd();
module.paths.push(cwd, join(cwd, 'node_modules'));
}
/**
* Expose internals.
*/
exports.utils = utils;
exports.interfaces = require('./interfaces');
exports.reporters = require('./reporters');
exports.Runnable = require('./runnable');
exports.Context = require('./context');
exports.Runner = require('./runner');
exports.Suite = require('./suite');
exports.Hook = require('./hook');
exports.Test = require('./test');
/**
* Return image `name` path.
*
* @param {String} name
* @return {String}
* @api private
*/
function image(name) {
return __dirname + '/../images/' + name + '.png';
}
/**
* Setup mocha with `options`.
*
* Options:
*
* - `ui` name "bdd", "tdd", "exports" etc
* - `reporter` reporter instance, defaults to `mocha.reporters.spec`
* - `globals` array of accepted globals
* - `timeout` timeout in milliseconds
* - `bail` bail on the first test failure
* - `slow` milliseconds to wait before considering a test slow
* - `ignoreLeaks` ignore global leaks
* - `fullTrace` display the full stack-trace on failing
* - `grep` string or regexp to filter tests with
*
* @param {Object} options
* @api public
*/
function Mocha(options) {
options = options || {};
this.files = [];
this.options = options;
if (options.grep) this.grep(new RegExp(options.grep));
if (options.fgrep) this.grep(options.fgrep);
this.suite = new exports.Suite('', new exports.Context);
this.ui(options.ui);
this.bail(options.bail);
this.reporter(options.reporter, options.reporterOptions);
if (null != options.timeout) this.timeout(options.timeout);
this.useColors(options.useColors);
if (options.enableTimeouts !== null) this.enableTimeouts(options.enableTimeouts);
if (options.slow) this.slow(options.slow);
this.suite.on('pre-require', function (context) {
exports.afterEach = context.afterEach || context.teardown;
exports.after = context.after || context.suiteTeardown;
exports.beforeEach = context.beforeEach || context.setup;
exports.before = context.before || context.suiteSetup;
exports.describe = context.describe || context.suite;
exports.it = context.it || context.test;
exports.setup = context.setup || context.beforeEach;
exports.suiteSetup = context.suiteSetup || context.before;
exports.suiteTeardown = context.suiteTeardown || context.after;
exports.suite = context.suite || context.describe;
exports.teardown = context.teardown || context.afterEach;
exports.test = context.test || context.it;
exports.run = context.run;
});
}
/**
* Enable or disable bailing on the first failure.
*
* @param {Boolean} [bail]
* @api public
*/
Mocha.prototype.bail = function(bail){
if (0 == arguments.length) bail = true;
this.suite.bail(bail);
return this;
};
/**
* Add test `file`.
*
* @param {String} file
* @api public
*/
Mocha.prototype.addFile = function(file){
this.files.push(file);
return this;
};
/**
* Set reporter to `reporter`, defaults to "spec".
*
* @param {String|Function} reporter name or constructor
* @param {Object} reporterOptions optional options
* @api public
*/
Mocha.prototype.reporter = function(reporter, reporterOptions){
if ('function' == typeof reporter) {
this._reporter = reporter;
} else {
reporter = reporter || 'spec';
var _reporter;
try { _reporter = require('./reporters/' + reporter); } catch (err) {}
if (!_reporter) try { _reporter = require(reporter); } catch (err) {
err.message.indexOf('Cannot find module') !== -1
? console.warn('"' + reporter + '" reporter not found')
: console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack);
}
if (!_reporter && reporter === 'teamcity')
console.warn('The Teamcity reporter was moved to a package named ' +
'mocha-teamcity-reporter ' +
'(https://npmjs.org/package/mocha-teamcity-reporter).');
if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
this._reporter = _reporter;
}
this.options.reporterOptions = reporterOptions;
return this;
};
/**
* Set test UI `name`, defaults to "bdd".
*
* @param {String} bdd
* @api public
*/
Mocha.prototype.ui = function(name){
name = name || 'bdd';
this._ui = exports.interfaces[name];
if (!this._ui) try { this._ui = require(name); } catch (err) {}
if (!this._ui) throw new Error('invalid interface "' + name + '"');
this._ui = this._ui(this.suite);
return this;
};
/**
* Load registered files.
*
* @api private
*/
Mocha.prototype.loadFiles = function(fn){
var self = this;
var suite = this.suite;
var pending = this.files.length;
this.files.forEach(function(file){
file = path.resolve(file);
suite.emit('pre-require', global, file, self);
suite.emit('require', require(file), file, self);
suite.emit('post-require', global, file, self);
--pending || (fn && fn());
});
};
/**
* Enable growl support.
*
* @api private
*/
Mocha.prototype._growl = function(runner, reporter) {
var notify = require('growl');
runner.on('end', function(){
var stats = reporter.stats;
if (stats.failures) {
var msg = stats.failures + ' of ' + runner.total + ' tests failed';
notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
} else {
notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
name: 'mocha'
, title: 'Passed'
, image: image('ok')
});
}
});
};
/**
* Add regexp to grep, if `re` is a string it is escaped.
*
* @param {RegExp|String} re
* @return {Mocha}
* @api public
*/
Mocha.prototype.grep = function(re){
this.options.grep = 'string' == typeof re
? new RegExp(escapeRe(re))
: re;
return this;
};
/**
* Invert `.grep()` matches.
*
* @return {Mocha}
* @api public
*/
Mocha.prototype.invert = function(){
this.options.invert = true;
return this;
};
/**
* Ignore global leaks.
*
* @param {Boolean} ignore
* @return {Mocha}
* @api public
*/
Mocha.prototype.ignoreLeaks = function(ignore){
this.options.ignoreLeaks = !!ignore;
return this;
};
/**
* Enable global leak checking.
*
* @return {Mocha}
* @api public
*/
Mocha.prototype.checkLeaks = function(){
this.options.ignoreLeaks = false;
return this;
};
/**
* Display long stack-trace on failing
*
* @return {Mocha}
* @api public
*/
Mocha.prototype.fullTrace = function() {
this.options.fullStackTrace = true;
return this;
};
/**
* Enable growl support.
*
* @return {Mocha}
* @api public
*/
Mocha.prototype.growl = function(){
this.options.growl = true;
return this;
};
/**
* Ignore `globals` array or string.
*
* @param {Array|String} globals
* @return {Mocha}
* @api public
*/
Mocha.prototype.globals = function(globals){
this.options.globals = (this.options.globals || []).concat(globals);
return this;
};
/**
* Emit color output.
*
* @param {Boolean} colors
* @return {Mocha}
* @api public
*/
Mocha.prototype.useColors = function(colors){
if (colors !== undefined) {
this.options.useColors = colors;
}
return this;
};
/**
* Use inline diffs rather than +/-.
*
* @param {Boolean} inlineDiffs
* @return {Mocha}
* @api public
*/
Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
? inlineDiffs
: false;
return this;
};
/**
* Set the timeout in milliseconds.
*
* @param {Number} timeout
* @return {Mocha}
* @api public
*/
Mocha.prototype.timeout = function(timeout){
this.suite.timeout(timeout);
return this;
};
/**
* Set slowness threshold in milliseconds.
*
* @param {Number} slow
* @return {Mocha}
* @api public
*/
Mocha.prototype.slow = function(slow){
this.suite.slow(slow);
return this;
};
/**
* Enable timeouts.
*
* @param {Boolean} enabled
* @return {Mocha}
* @api public
*/
Mocha.prototype.enableTimeouts = function(enabled) {
this.suite.enableTimeouts(arguments.length && enabled !== undefined
? enabled
: true);
return this
};
/**
* Makes all tests async (accepting a callback)
*
* @return {Mocha}
* @api public
*/
Mocha.prototype.asyncOnly = function(){
this.options.asyncOnly = true;
return this;
};
/**
* Disable syntax highlighting (in browser).
* @returns {Mocha}
* @api public
*/
Mocha.prototype.noHighlighting = function() {
this.options.noHighlighting = true;
return this;
};
/**
* Delay root suite execution.
* @returns {Mocha}
* @api public
*/
Mocha.prototype.delay = function delay() {
this.options.delay = true;
return this;
};
/**
* Run tests and invoke `fn()` when complete.
*
* @param {Function} fn
* @return {Runner}
* @api public
*/
Mocha.prototype.run = function(fn){
if (this.files.length) this.loadFiles();
var suite = this.suite;
var options = this.options;
options.files = this.files;
var runner = new exports.Runner(suite, options.delay);
var reporter = new this._reporter(runner, options);
runner.ignoreLeaks = false !== options.ignoreLeaks;
runner.fullStackTrace = options.fullStackTrace;
runner.asyncOnly = options.asyncOnly;
if (options.grep) runner.grep(options.grep, options.invert);
if (options.globals) runner.globals(options.globals);
if (options.growl) this._growl(runner, reporter);
if (options.useColors !== undefined) {
exports.reporters.Base.useColors = options.useColors;
}
exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
function done(failures) {
if (reporter.done) {
reporter.done(failures, fn);
} else fn && fn(failures);
}
return runner.run(done);
};