UNPKG

3.97 kBJavaScriptView Raw
1var defined = require('defined');
2var createDefaultStream = require('./lib/default_stream');
3var Test = require('./lib/test');
4var createResult = require('./lib/results');
5var through = require('through');
6
7var canEmitExit = typeof process !== 'undefined' && process
8 && typeof process.on === 'function' && process.browser !== true
9;
10var canExit = typeof process !== 'undefined' && process
11 && typeof process.exit === 'function'
12;
13
14var nextTick = typeof setImmediate !== 'undefined'
15 ? setImmediate
16 : process.nextTick
17;
18
19exports = module.exports = (function () {
20 var harness;
21 var lazyLoad = function () {
22 return getHarness().apply(this, arguments);
23 };
24
25 lazyLoad.only = function () {
26 return getHarness().only.apply(this, arguments);
27 };
28
29 lazyLoad.createStream = function (opts) {
30 if (!opts) opts = {};
31 if (!harness) {
32 var output = through();
33 getHarness({ stream: output, objectMode: opts.objectMode });
34 return output;
35 }
36 return harness.createStream(opts);
37 };
38
39 lazyLoad.onFinish = function () {
40 return getHarness().onFinish.apply(this, arguments);
41 };
42
43 lazyLoad.getHarness = getHarness
44
45 return lazyLoad
46
47 function getHarness (opts) {
48 if (!opts) opts = {};
49 opts.autoclose = !canEmitExit;
50 if (!harness) harness = createExitHarness(opts);
51 return harness;
52 }
53})();
54
55function createExitHarness (conf) {
56 if (!conf) conf = {};
57 var harness = createHarness({
58 autoclose: defined(conf.autoclose, false)
59 });
60
61 var stream = harness.createStream({ objectMode: conf.objectMode });
62 var es = stream.pipe(conf.stream || createDefaultStream());
63 if (canEmitExit) {
64 es.on('error', function (err) { harness._exitCode = 1 });
65 }
66
67 var ended = false;
68 stream.on('end', function () { ended = true });
69
70 if (conf.exit === false) return harness;
71 if (!canEmitExit || !canExit) return harness;
72
73 var inErrorState = false;
74
75 process.on('exit', function (code) {
76 // let the process exit cleanly.
77 if (code !== 0) {
78 return
79 }
80
81 if (!ended) {
82 var only = harness._results._only;
83 for (var i = 0; i < harness._tests.length; i++) {
84 var t = harness._tests[i];
85 if (only && t !== only) continue;
86 t._exit();
87 }
88 }
89 harness.close();
90 process.exit(code || harness._exitCode);
91 });
92
93 return harness;
94}
95
96exports.createHarness = createHarness;
97exports.Test = Test;
98exports.test = exports; // tap compat
99exports.test.skip = Test.skip;
100
101var exitInterval;
102
103function createHarness (conf_) {
104 if (!conf_) conf_ = {};
105 var results = createResult();
106 if (conf_.autoclose !== false) {
107 results.once('done', function () { results.close() });
108 }
109
110 var test = function (name, conf, cb) {
111 var t = new Test(name, conf, cb);
112 test._tests.push(t);
113
114 (function inspectCode (st) {
115 st.on('test', function sub (st_) {
116 inspectCode(st_);
117 });
118 st.on('result', function (r) {
119 if (!r.ok && typeof r !== 'string') test._exitCode = 1
120 });
121 })(t);
122
123 results.push(t);
124 return t;
125 };
126 test._results = results;
127
128 test._tests = [];
129
130 test.createStream = function (opts) {
131 return results.createStream(opts);
132 };
133
134 test.onFinish = function (cb) {
135 results.on('done', cb);
136 };
137
138 var only = false;
139 test.only = function () {
140 if (only) throw new Error('there can only be one only test');
141 only = true;
142 var t = test.apply(null, arguments);
143 results.only(t);
144 return t;
145 };
146 test._exitCode = 0;
147
148 test.close = function () { results.close() };
149
150 return test;
151}