UNPKG

@testim/testim-cli

Version:

Command line interface for running Testing on you CI

155 lines (129 loc) 4.42 kB
var q = require('q'), co = require('co'), path = require('path'), isGeneratorFn = require('is-generator').fn, hasES6Support = require('../helpers/detectHarmony'), interfaces = { bdd: ['before', 'beforeEach', 'it', 'after', 'afterEach'], tdd: ['suiteSetup', 'setup', 'test', 'suiteTeardown', 'teardown'], qunit: ['before', 'beforeEach', 'test', 'after', 'afterEach'] }; /** * Mocha runner */ module.exports.run = function(config, specs, capabilities) { var Mocha = require('mocha'), defer = q.defer(), compilers = config.mochaOpts.compilers, requires = config.mochaOpts.require, runner; if(typeof config.mochaOpts.ui !== 'string') { config.mochaOpts.ui = 'bdd'; } var mocha = new Mocha(config.mochaOpts); mocha.loadFiles(); mocha.reporter(function(){}); compilers = Array.isArray(compilers) ? compilers : []; requires = Array.isArray(requires) ? requires : []; compilers.concat(requires).forEach(function(mod) { mod = mod.split(':'); mod = mod[mod.length - 1]; if (mod[0] === '.') { mod = path.join(process.cwd(), mod); } require(mod); }); specs.forEach(function(spec) { mocha.addFile(spec); }); /** * enable generators if supported */ if(hasES6Support && interfaces[config.mochaOpts.ui]) { mocha.suite.on('pre-require', function() { interfaces[config.mochaOpts.ui].forEach(runInGenerator.bind(null, config.mochaOpts.ui)); }); } var events = { 'suite': 'suite:start', 'suite end': 'suite:end', 'test': 'test:start', 'test end': 'test:end', 'hook': 'hook:start', 'hook end': 'hook:end', 'pass': 'test:pass', 'fail': 'test:fail', 'pending': 'test:pending' }; q(config.before()).then(function() { try { runner = mocha.run(defer.resolve.bind(defer)); } catch(e) { defer.reject({ message: e.message, stack: e.stack }); } Object.keys(events).forEach(function(e) { runner.on(e, function(payload, err) { var error = null; if(err) { error = { message: err.message, stack: err.stack, }; } var message = { event: events[e], pid: process.pid, title: payload.title, pending: payload.pending || false, parent: payload.parent ? payload.parent.title : null, type: payload.tests ? 'suite' : 'test', file: payload.file, err: error, duration: payload.duration, runner: {} }; message.runner[process.pid] = capabilities; process.send(message); }); }); }, defer.reject.bind(defer)); return defer.promise; }; var runInGenerator = function (ui, fnName) { var origFn = global[fnName], interfaceTestFnName = interfaces[ui][2]; var runSpec = function(specTitle, specFn) { return origFn.call(null, specTitle, co.wrap(specFn)); }; var runHook = function(hookFn) { return origFn.call(null, co.wrap(hookFn)); }; global[fnName] = function() { var args = Array.prototype.slice.call(arguments), specFn = typeof args[0] === 'function' ? args.shift() : args.pop(), specTitle = args[0]; /** * if specFn is undefined we are dealing with a pending function */ if(fnName === interfaceTestFnName && arguments.length === 1) { return origFn.call(null, arguments[0]); } /** * only run in a generator if * is set */ if(!isGeneratorFn(specFn)) { return origFn.call(null, specTitle || specFn, specFn); } if(fnName === interfaceTestFnName) { return runSpec(specTitle, specFn); } return runHook(specFn); }; if(fnName === interfaceTestFnName) { global[fnName].skip = origFn.skip; global[fnName].only = origFn.only; } };