blob: 48528eb9115e5f541bb98f665c3815548260a3ae [file] [log] [blame]
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;
}