From 718c411a2cae7975ec4cbb7ac3ff8bb13524d395 Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Tue, 6 Aug 2013 23:45:51 +0100 Subject: [PATCH] Allow skip from test context for #332 --- lib/context.js | 12 ++++++++++++ lib/pending.js | 16 ++++++++++++++++ lib/runnable.js | 11 +++++++++++ lib/runner.js | 27 +++++++++++++++++++++++---- test/acceptance/pending.js | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 lib/pending.js diff --git a/lib/context.js b/lib/context.js index c983b6eb6a..3885218db9 100644 --- a/lib/context.js +++ b/lib/context.js @@ -67,6 +67,18 @@ Context.prototype.slow = function(ms){ return this; }; +/** + * Mark a test as skipped. + * + * @return {Context} self + * @api private + */ + +Context.prototype.skip = function(){ + this.runnable().skip(); + return this; +}; + /** * Inspect the context void of `._runnable`. * diff --git a/lib/pending.js b/lib/pending.js new file mode 100644 index 0000000000..265ec73c18 --- /dev/null +++ b/lib/pending.js @@ -0,0 +1,16 @@ + +/** + * Expose `Pending`. + */ + +module.exports = Pending; + +/** + * Initialize a new `Pending` error with the given message. + * + * @param {String} message + */ + +function Pending(message) { + this.message = message; +} diff --git a/lib/runnable.js b/lib/runnable.js index 9b216abbde..7ce2f5cf90 100644 --- a/lib/runnable.js +++ b/lib/runnable.js @@ -4,6 +4,7 @@ var EventEmitter = require('events').EventEmitter , debug = require('debug')('mocha:runnable') + , Pending = require('./pending') , milliseconds = require('./ms') , utils = require('./utils'); @@ -104,6 +105,16 @@ Runnable.prototype.enableTimeouts = function(enabled){ return this; }; +/** + * Halt and mark as pending. + * + * @api private + */ + +Runnable.prototype.skip = function(){ + throw new Pending(); +}; + /** * Return the full title generated by recursively * concatenating the parent's full title. diff --git a/lib/runner.js b/lib/runner.js index 0c9cc551a7..1c006ca275 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -4,6 +4,7 @@ var EventEmitter = require('events').EventEmitter , debug = require('debug')('mocha:runner') + , Pending = require('./pending') , Test = require('./test') , utils = require('./utils') , filter = utils.filter @@ -261,10 +262,14 @@ Runner.prototype.hook = function(name, fn){ var testError = hook.error(); if (testError) self.fail(self.test, testError); if (err) { - self.failHook(hook, err); + if (err instanceof Pending) { + suite.pending = true; + } else { + self.failHook(hook, err); - // stop executing hooks, notify callee of hook err - return fn(err); + // stop executing hooks, notify callee of hook err + return fn(err); + } } self.emit('hook end', hook); delete hook.ctx.currentTest; @@ -446,6 +451,11 @@ Runner.prototype.runTests = function(suite, fn){ self.emit('test', self.test = test); self.hookDown('beforeEach', function(err, errSuite){ + if (suite.pending) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } if (err) return hookErr(err, errSuite, false); self.currentRunnable = self.test; @@ -453,8 +463,17 @@ Runner.prototype.runTests = function(suite, fn){ test = self.test; if (err) { - self.fail(test, err); + if (err instanceof Pending) { + self.emit('pending', test); + } else { + self.fail(test, err); + } self.emit('test end', test); + + if (err instanceof Pending) { + return next(); + } + return self.hookUp('afterEach', next); } diff --git a/test/acceptance/pending.js b/test/acceptance/pending.js index 4ef963709c..b40b3c03ed 100644 --- a/test/acceptance/pending.js +++ b/test/acceptance/pending.js @@ -1,3 +1,41 @@ describe('pending', function(){ it('should be allowed') }) + +describe('skip in test', function(){ + it('should skip immediately', function(){ + this.skip(); + throw new Error('never thrown'); + }) + + it('should run other tests in the suite', function(){ + }) +}) + +describe('skip in before', function(){ + before(function(){ + this.skip(); + }) + + it('should never run this test', function(){ + throw new Error('never thrown'); + }) + + it('should never run this test', function(){ + throw new Error('never thrown'); + }) +}) + +describe('skip in beforeEach', function(){ + beforeEach(function(){ + this.skip(); + }) + + it('should never run this test', function(){ + throw new Error('never thrown'); + }) + + it('should never run this test', function(){ + throw new Error('never thrown'); + }) +})