| var defined = require('defined'); |
| var createDefaultStream = require('./lib/default_stream'); |
| var Test = require('./lib/test'); |
| var createResult = require('./lib/results'); |
| var through = require('through'); |
| |
| var canEmitExit = typeof process !== 'undefined' && process |
| && typeof process.on === 'function' && process.browser !== true |
| ; |
| var canExit = typeof process !== 'undefined' && process |
| && typeof process.exit === 'function' |
| ; |
| |
| var nextTick = typeof setImmediate !== 'undefined' |
| ? setImmediate |
| : process.nextTick |
| ; |
| |
| exports = module.exports = (function () { |
| var harness; |
| var lazyLoad = function () { |
| return getHarness().apply(this, arguments); |
| }; |
| |
| lazyLoad.only = function () { |
| return getHarness().only.apply(this, arguments); |
| }; |
| |
| lazyLoad.createStream = function (opts) { |
| if (!opts) opts = {}; |
| if (!harness) { |
| var output = through(); |
| getHarness({ stream: output, objectMode: opts.objectMode }); |
| return output; |
| } |
| return harness.createStream(opts); |
| }; |
| |
| lazyLoad.onFinish = function () { |
| return getHarness().onFinish.apply(this, arguments); |
| }; |
| |
| lazyLoad.onFailure = function() { |
| return getHarness().onFailure.apply(this, arguments); |
| }; |
| |
| lazyLoad.getHarness = getHarness |
| |
| return lazyLoad |
| |
| function getHarness (opts) { |
| if (!opts) opts = {}; |
| opts.autoclose = !canEmitExit; |
| if (!harness) harness = createExitHarness(opts); |
| return harness; |
| } |
| })(); |
| |
| function createExitHarness (conf) { |
| if (!conf) conf = {}; |
| var harness = createHarness({ |
| autoclose: defined(conf.autoclose, false) |
| }); |
| |
| var stream = harness.createStream({ objectMode: conf.objectMode }); |
| var es = stream.pipe(conf.stream || createDefaultStream()); |
| if (canEmitExit) { |
| es.on('error', function (err) { harness._exitCode = 1 }); |
| } |
| |
| var ended = false; |
| stream.on('end', function () { ended = true }); |
| |
| if (conf.exit === false) return harness; |
| if (!canEmitExit || !canExit) return harness; |
| |
| var inErrorState = false; |
| |
| process.on('exit', function (code) { |
| // let the process exit cleanly. |
| if (code !== 0) { |
| return |
| } |
| |
| if (!ended) { |
| var only = harness._results._only; |
| for (var i = 0; i < harness._tests.length; i++) { |
| var t = harness._tests[i]; |
| if (only && t !== only) continue; |
| t._exit(); |
| } |
| } |
| harness.close(); |
| process.exit(code || harness._exitCode); |
| }); |
| |
| return harness; |
| } |
| |
| exports.createHarness = createHarness; |
| exports.Test = Test; |
| exports.test = exports; // tap compat |
| exports.test.skip = Test.skip; |
| |
| var exitInterval; |
| |
| function createHarness (conf_) { |
| if (!conf_) conf_ = {}; |
| var results = createResult(); |
| if (conf_.autoclose !== false) { |
| results.once('done', function () { results.close() }); |
| } |
| |
| var test = function (name, conf, cb) { |
| var t = new Test(name, conf, cb); |
| test._tests.push(t); |
| |
| (function inspectCode (st) { |
| st.on('test', function sub (st_) { |
| inspectCode(st_); |
| }); |
| st.on('result', function (r) { |
| if (!r.ok && typeof r !== 'string') test._exitCode = 1 |
| }); |
| })(t); |
| |
| results.push(t); |
| return t; |
| }; |
| test._results = results; |
| |
| test._tests = []; |
| |
| test.createStream = function (opts) { |
| return results.createStream(opts); |
| }; |
| |
| test.onFinish = function (cb) { |
| results.on('done', cb); |
| }; |
| |
| test.onFailure = function (cb) { |
| results.on('fail', cb); |
| }; |
| |
| var only = false; |
| test.only = function () { |
| if (only) throw new Error('there can only be one only test'); |
| only = true; |
| var t = test.apply(null, arguments); |
| results.only(t); |
| return t; |
| }; |
| test._exitCode = 0; |
| |
| test.close = function () { results.close() }; |
| |
| return test; |
| } |