haste-server/node_modules/mocha/bin/_mocha

321 lines
6.7 KiB
Plaintext
Raw Normal View History

2012-02-06 20:09:01 +01:00
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander')
, exec = require('child_process').exec
, path = require('path')
, resolve = path.resolve
, mocha = require('../')
, utils = mocha.utils
, reporters = mocha.reporters
, interfaces = mocha.interfaces
, Runner = mocha.Runner
, Suite = mocha.Suite
, vm = require('vm')
, fs = require('fs')
, join = path.join
, cwd = process.cwd();
/**
* Files.
*/
var files = [];
/**
* Images.
*/
var images = {
fail: __dirname + '/../images/error.png'
, pass: __dirname + '/../images/ok.png'
};
// options
program
.version(mocha.version)
.usage('[options] [files]')
.option('-r, --require <name>', 'require the given module')
.option('-R, --reporter <name>', 'specify the reporter to use', 'dot')
.option('-u, --ui <name>', 'specify user-interface (bdd|tdd|exports)', 'bdd')
.option('-g, --grep <pattern>', 'only run tests matching <pattern>')
.option('-t, --timeout <ms>', 'set test-case timeout in milliseconds [2000]')
.option('-s, --slow <ms>', '"slow" test threshold in milliseconds [75]', parseInt)
.option('-w, --watch', 'watch files for changes')
.option('-c, --colors', 'force enabling of colors')
.option('-C, --no-colors', 'force disabling of colors')
.option('-G, --growl', 'enable growl notification support')
.option('-d, --debug', "enable node's debugger")
.option('-b, --bail', "bail after first test failure")
.option('--globals <names>', 'allow the given comma-delimited global [names]', list, [])
.option('--ignore-leaks', 'ignore global variable leaks')
.option('--interfaces', 'display available interfaces')
.option('--reporters', 'display available reporters')
program.name = 'mocha';
// --reporters
program.on('reporters', function(){
console.log();
console.log(' dot - dot matrix');
console.log(' doc - html documentation');
console.log(' spec - hierarchical spec list');
console.log(' json - single json object');
console.log(' progress - progress bar');
console.log(' list - spec-style listing');
console.log(' tap - test-anything-protocol');
console.log(' landing - unicode landing strip');
console.log(' xunit - xunit reportert');
console.log(' teamcity - teamcity ci support');
console.log(' json-stream - newline delimited json events');
console.log();
process.exit();
});
// --interfaces
program.on('interfaces', function(){
console.log('');
console.log(' bdd');
console.log(' tdd');
console.log(' qunit');
console.log(' exports');
console.log('');
process.exit();
});
// -r, --require
module.paths.push(cwd, join(cwd, 'node_modules'));
program.on('require', function(mod){
var abs = path.existsSync(mod)
|| path.existsSync(mod + '.js');
if (abs) mod = join(cwd, mod);
require(mod);
});
// mocha.opts support
try {
var opts = fs.readFileSync('test/mocha.opts', 'utf8')
.trim()
.split(/\s+/);
process.argv = process.argv
.slice(0, 2)
.concat(opts.concat(process.argv.slice(2)));
} catch (err) {
// ignore
}
// parse args
program.parse(process.argv);
// infinite stack traces
Error.stackTraceLimit = Infinity; // TODO: config
// reporter
var suite = new Suite('')
, Base = require('../lib/reporters/base')
, Reporter = require('../lib/reporters/' + program.reporter)
, ui = interfaces[program.ui](suite);
// --no-colors
if (!program.colors) Base.useColors = false;
// --colors
if (~process.argv.indexOf('--colors') ||
~process.argv.indexOf('-c')) {
Base.useColors = true;
}
// --slow <ms>
if (program.slow) Base.slow = program.slow;
// --timeout
if (program.timeout) suite.timeout(program.timeout);
// --bail
suite.bail(program.bail);
// files
var files = program.args
, re = /\.js$/;
// coffee-script support
try {
require('coffee-script');
re = /\.(js|coffee)$/;
} catch (err) {
// ignore
}
// default files to test/*.{js,coffee}
if (!files.length) {
files = fs.readdirSync('test').filter(function(path){
return path.match(re);
}).map(function(path){
return join('test', path);
});
}
// resolve
files = files.map(function(path){
return resolve(path);
});
// --watch
if (program.watch) {
console.log();
hideCursor();
process.on('SIGINT', function(){
showCursor();
console.log('\n');
process.exit();
});
var frames = [
' \033[96m◜ \033[90mwatching\033[0m'
, ' \033[96m◠ \033[90mwatching\033[0m'
, ' \033[96m◝ \033[90mwatching\033[0m'
, ' \033[96m◞ \033[90mwatching\033[0m'
, ' \033[96m◡ \033[90mwatching\033[0m'
, ' \033[96m◟ \033[90mwatching\033[0m'
];
play(frames);
utils.watch(utils.files(cwd), function(){
stop()
suite = suite.clone();
ui = interfaces[program.ui](suite);
load(files, function(){
run(suite, function(){
play(frames);
});
});
});
return;
}
// load
load(files, function(){
run(suite, process.exit);
});
// require test files before
// running the root suite
function load(files, fn) {
var pending = files.length;
files.forEach(function(file){
delete require.cache[file];
suite.emit('pre-require', global, file);
suite.emit('require', require(file), file);
suite.emit('post-require', global, file);
--pending || fn();
});
}
// run the given suite
function run(suite, fn) {
suite.emit('run');
var runner = new Runner(suite);
var reporter = new Reporter(runner);
runner.globals(program.globals);
if (program.ignoreLeaks) runner.ignoreLeaks = true;
if (program.grep) runner.grep(new RegExp(program.grep));
if (program.growl) growl(runner, reporter);
runner.run(fn);
}
// enable growl notifications
function growl(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, { title: 'Failed', image: images.fail });
} else {
notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
title: 'Passed'
, image: images.pass
});
}
});
}
/**
* Parse list.
*/
function list(str) {
return str.split(/ *, */);
}
/**
* Hide the cursor.
*/
function hideCursor(){
process.stdout.write('\033[?25l');
};
/**
* Show the cursor.
*/
function showCursor(){
process.stdout.write('\033[?25h');
};
/**
* Stop play()ing.
*/
function stop() {
process.stdout.write('\033[2K');
clearInterval(play.timer);
}
/**
* Play the given array of strings.
*/
function play(arr, interval) {
var len = arr.length
, interval = interval || 100
, i = 0;
play.timer = setInterval(function(){
var str = arr[i++ % len];
process.stdout.write('\r' + str);
}, interval);
}