From 6fc71bab2efae31b574a327de23d491345f4f504 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Mon, 3 Dec 2012 21:30:11 -0800 Subject: [PATCH] feature-detect process.exit() and "exit" events, exit tests now passes --- index.js | 29 ++++++++++++++++++++++++++--- lib/test.js | 17 +++++++++++++++++ test/exit.js | 2 +- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 1914e8dd..5d9e64cc 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,17 @@ exports = module.exports = createHarness(); exports.createHarness = createHarness; exports.Test = Test; +var canEmitExit = false; +var canExit = false; +//* +var canEmitExit = typeof process !== 'undefined' && process + && typeof process.on === 'function' +; +var canExit = typeof process !== 'undefined' && process + && typeof process.exit === 'function' +; +//*/ + function createHarness () { var pending = []; var running = false; @@ -15,6 +26,15 @@ function createHarness () { var test = function (name, conf, cb) { var t = new Test(name, conf, cb); + if (!conf || typeof conf !== 'object') conf = {}; + + if (conf.exit !== false && canEmitExit) { + process.on('exit', function (code) { + t._exit(); + out.close(); + if (code === 0 && !t._ok) process.exit(1); + }); + } process.nextTick(function () { if (!out.piped) out.pipe(createDefaultStream()); @@ -40,7 +60,7 @@ function createHarness () { t.on('end', onend); - return t + return t; function onend () { running = false; @@ -56,8 +76,11 @@ function createHarness () { } process.nextTick(function () { - if (pending.length) pending.shift()() - else out.close() + if (pending.length) return pending.shift()(); + out.close(); + if (conf.exit !== false && canExit && !t._ok) { + process.exit(1); + } }); } }; diff --git a/lib/test.js b/lib/test.js index 6f16dba4..7d8c21c7 100644 --- a/lib/test.js +++ b/lib/test.js @@ -32,6 +32,7 @@ function Test (name_, opts_, cb_) { this._plan = undefined; this._cb = cb; this._progeny = []; + this._ok = true; } Test.prototype.run = function () { @@ -70,6 +71,21 @@ Test.prototype.end = function () { this.ended = true; }; +Test.prototype._exit = function () { + if (this._plan !== undefined && + !this._planError && this.assertCount !== this._plan) { + this._planError = true; + this.fail('plan != count', { + expected : this._plan, + actual : this.assertCount + }); + } + else if (!this.ended) { + this.fail('test exited without ending'); + } + +}; + Test.prototype._assert = function assert (ok, opts) { var self = this; var extra = opts.extra || {}; @@ -83,6 +99,7 @@ Test.prototype._assert = function assert (ok, opts) { actual : defined(extra.actual, opts.actual), expected : defined(extra.expected, opts.expected) }; + this._ok = Boolean(this._ok && ok); if (!ok) { res.error = defined(extra.error, opts.error, new Error(res.name)); diff --git a/test/exit.js b/test/exit.js index 59cf3fe5..275f3efe 100644 --- a/test/exit.js +++ b/test/exit.js @@ -93,7 +93,7 @@ tap.test('too few exit', function (t) { { id: 3, ok: true, name: 'should be equivalent' }, { id: 4, ok: true, name: 'should be equivalent' }, { id: 5, ok: true, name: 'should be equivalent' }, - { id: 6, ok: false, name: 'too few assertions' }, + { id: 6, ok: false, name: 'plan != count' }, 'tests 6', 'pass 5', 'fail 1'