Skip to content

Instantly share code, notes, and snippets.

@themouette
Created July 24, 2015 15:47
Show Gist options
  • Save themouette/fa79c2830365d09b6304 to your computer and use it in GitHub Desktop.
Save themouette/fa79c2830365d09b6304 to your computer and use it in GitHub Desktop.
mocha test launcher
#!/usr/bin/env iojs
var lookupDirs = ['app/shared/lib', 'app/shared'];
var resolveModuleSource = require('../babel-hooks');
require('babel/register')({
stage: 0,
resolveModuleSource: resolveModuleSource(lookupDirs)
});
var fs = require('fs');
var path = require('path');
var Mocha = require('mocha');
var glob = require('glob');
var minimatch = require('minimatch');
var options = require('minimist')(process.argv.slice(2));
var args = options._;
var ci = options.ci || false; // Run on CI server
var pattern = options.pattern || '*-test.js'; // The test files pattern
var ui = options.ui || 'bdd';
var cwd = options.cwd || 'app';
// prepare file argument
var args = args.length ? args : [cwd];
function extractFiles(args) {
var allFiles = [];
args.forEach(function (fileOrDir) {
fullpath = path.resolve(__dirname, '..', fileOrDir);
// If a directory is provided
if (fs.existsSync(fullpath) && fs.lstatSync(fullpath).isDirectory()) {
files = glob
.sync(pattern, {cwd: fullpath, matchBase: true, nodir: true})
.map(function (file) { return path.resolve(fileOrDir, file); });
}
// If a file is provided
else if (fs.existsSync(fullpath)) {
files = [fileOrDir];
}
// Assume anything else is a pattern
else {
files = glob.sync(fileOrDir, {nodir: true});
}
allFiles = allFiles
.concat(
files.filter(minimatch.filter(pattern, {matchBase: true}))
);
});
return allFiles.sort();
}
function init(files) {
var mochaOpts = {};
if (ci) {
mochaOpts = {
'reporter': 'mocha-jenkins-reporter',
'reporterOptions': {
'junit_report_name': 'Tests',
'junit_report_path': 'report.xml',
'junit_report_stack': 1
}
};
}
var mocha = new Mocha(mochaOpts);
mocha.useColors(!ci);
mocha.ui(ui);
mocha.growl(!ci);
files.forEach(function (file) {
// Use the m8thod 'addFile' to add the file to mocha
mocha.addFile(file);
});
return mocha;
}
var mocha = init(extractFiles(args));
if (options.ci) {
mocha.run(function(failures){
process.on('exit', function () {
process.exit(failures);
});
});
}
else {
var watch = require('watch');
var runner;
watch.watchTree(cwd, function runAgain(f) {
var files = extractFiles(args);
// abort current run
if (runner) {
runner.abort();
}
// purge files
files.forEach(function(file){
delete require.cache[path.resolve(file)];
});
if (typeof f !== 'object') {
// a file changed
delete require.cache[path.resolve(f)];
}
// recreate instance (taken from mocha original runner)
mocha.suite = mocha.suite.clone();
mocha.suite.ctx = new Mocha.Context;
mocha.ui(ui);
mocha.files = files;
runner = mocha.run(function(failures){
runner = null;
});
});
}
@themouette
Copy link
Author

Launch tests recursively.

./bin/test app/               # launch all tests in app/, matching *-test.js
./bin/test app/**/__tests__/**/* # launch all tests under a __tests__ folder, matching *-test.js
./bin/test app/foo/__tests__/foo-test.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment