diff --git a/lib/runnable.js b/lib/runnable.js index bba47d9542..4bc2be2448 100644 --- a/lib/runnable.js +++ b/lib/runnable.js @@ -298,6 +298,10 @@ Runnable.prototype.run = function(fn) { return callFnAsync(this.fn); } try { + // allows skip() to be used in an explicit async context + this.skip = function() { + done(new Pending()); + }; callFnAsync(this.fn); } catch (err) { done(utils.getError(err)); diff --git a/test/integration/fixtures/pending/skip.async.before.js b/test/integration/fixtures/pending/skip.async.before.js new file mode 100644 index 0000000000..114db36d88 --- /dev/null +++ b/test/integration/fixtures/pending/skip.async.before.js @@ -0,0 +1,16 @@ +describe('skip in before', function() { + before(function(done) { + var self = this; + setTimeout(function() { + self.skip(); + }, 50); + }); + + it('should never run this test', function() { + throw new Error('never thrown'); + }); + + it('should never run this test', function() { + throw new Error('never thrown'); + }); +}); diff --git a/test/integration/fixtures/pending/skip.async.beforeEach.js b/test/integration/fixtures/pending/skip.async.beforeEach.js new file mode 100644 index 0000000000..b8db22b94a --- /dev/null +++ b/test/integration/fixtures/pending/skip.async.beforeEach.js @@ -0,0 +1,16 @@ +describe('skip in beforeEach', function() { + beforeEach(function(done) { + var self = this; + setTimeout(function() { + self.skip(); + }, 50); + }); + + it('should never run this test', function() { + throw new Error('never thrown'); + }); + + it('should never run this test', function() { + throw new Error('never thrown'); + }); +}); diff --git a/test/integration/fixtures/pending/skip.async.spec.js b/test/integration/fixtures/pending/skip.async.spec.js new file mode 100644 index 0000000000..6096c59d2a --- /dev/null +++ b/test/integration/fixtures/pending/skip.async.spec.js @@ -0,0 +1,12 @@ +describe('skip in test', function() { + it('should skip async', function(done) { + var self = this; + setTimeout(function() { + self.skip(); + }, 50); + }); + + it('should run other tests in the suite', function() { + // Do nothing + }); +}); diff --git a/test/integration/pending.js b/test/integration/pending.js index 01ebbdf6eb..529ed80b43 100644 --- a/test/integration/pending.js +++ b/test/integration/pending.js @@ -60,4 +60,47 @@ describe('pending', function() { }); }); }); + + describe('asynchronous skip()', function() { + this.timeout(1000); + + describe('in spec', function() { + it('should immediately skip the spec and run all others', function(done) { + run('pending/skip.async.spec.js', args, function(err, res) { + assert(!err); + assert.equal(res.stats.pending, 1); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + describe('in before', function() { + it('should skip all suite specs', function(done) { + run('pending/skip.async.before.js', args, function(err, res) { + assert(!err); + assert.equal(res.stats.pending, 2); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + describe('in beforeEach', function() { + it('should skip all suite specs', function(done) { + run('pending/skip.sync.beforeEach.js', args, function(err, res) { + assert(!err); + assert.equal(res.stats.pending, 2); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + }); });