From f4e5573ee3268c61d53c9efb80554e995170181b Mon Sep 17 00:00:00 2001 From: slackersoft Date: Thu, 2 Oct 2014 08:10:29 -0700 Subject: [PATCH] Add explicit fail and move on for async functions - `done` now has a `fail` property which will call the global `fail` then continue to the next function in the queue [finish #73744618] Fix #567 Fix #568 --- spec/core/QueueRunnerSpec.js | 22 ++++++++++++++++++++++ spec/core/integration/EnvSpec.js | 12 ++++++++++++ src/core/Env.js | 1 + src/core/QueueRunner.js | 6 ++++++ 4 files changed, 41 insertions(+) diff --git a/spec/core/QueueRunnerSpec.js b/spec/core/QueueRunnerSpec.js index 8c4eb9a5..5e96be6e 100644 --- a/spec/core/QueueRunnerSpec.js +++ b/spec/core/QueueRunnerSpec.js @@ -93,6 +93,28 @@ describe("QueueRunner", function() { expect(onComplete).toHaveBeenCalled(); }); + it("explicitly fails an async function with a provided fail function and moves to the next function", function() { + var queueableFn1 = { fn: function(done) { + setTimeout(function() { done.fail('foo'); }, 100); + } }, + queueableFn2 = { fn: jasmine.createSpy('fn2') }, + failFn = jasmine.createSpy('fail'), + queueRunner = new j$.QueueRunner({ + queueableFns: [queueableFn1, queueableFn2], + fail: failFn + }); + + queueRunner.execute(); + + expect(failFn).not.toHaveBeenCalled(); + expect(queueableFn2.fn).not.toHaveBeenCalled(); + + jasmine.clock().tick(100); + + expect(failFn).toHaveBeenCalledWith('foo'); + expect(queueableFn2.fn).toHaveBeenCalled(); + }); + it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() { var timeout = 3, beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } }, diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index df9ef778..d0bde65c 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -972,6 +972,12 @@ describe("Env integration", function() { message: 'Failed: messy message' })] })); + expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({ + description: 'fails via the done callback', + failedExpectations: [jasmine.objectContaining({ + message: 'Failed: done failed' + })] + })); expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({ description: 'has a message from an Error', failedExpectations: [jasmine.objectContaining({ @@ -997,6 +1003,12 @@ describe("Env integration", function() { }, 1); }); + env.it('fails via the done callback', function(innerDone) { + setTimeout(function() { + innerDone.fail('done failed'); + }, 1); + }); + env.it('has a message from an Error', function(innerDone) { setTimeout(function() { env.fail(new Error('error message')); diff --git a/src/core/Env.js b/src/core/Env.js index 1b3170c5..b8a2cc74 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -170,6 +170,7 @@ getJasmineRequireObj().Env = function(j$) { options.catchException = catchException; options.clearStack = options.clearStack || clearStack; options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}; + options.fail = self.fail; new j$.QueueRunner(options).execute(); }; diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js index 516c9e84..839fa62b 100644 --- a/src/core/QueueRunner.js +++ b/src/core/QueueRunner.js @@ -18,6 +18,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { this.catchException = attrs.catchException || function() { return true; }; this.userContext = attrs.userContext || {}; this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout}; + this.fail = attrs.fail || function() {}; } QueueRunner.prototype.execute = function() { @@ -63,6 +64,11 @@ getJasmineRequireObj().QueueRunner = function(j$) { }), timeoutId; + next.fail = function() { + self.fail.apply(null, arguments); + next(); + }; + if (queueableFn.timeout) { timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() { var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');