diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index a3542dc6..ae5fec59 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -4913,7 +4913,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { return; } - self.errored = result.errored; + self.errored = self.errored || result.errored; if (this.completeOnFirstError && result.errored) { this.skipToCleanup(iterativeIndex); @@ -6265,8 +6265,11 @@ getJasmineRequireObj().TreeProcessor = function() { queueRunnerFactory({ onComplete: function () { + var args = Array.prototype.slice.call(arguments, [0]); node.cleanupBeforeAfter(); - nodeComplete(node, node.getResult(), done); + nodeComplete(node, node.getResult(), function() { + done.apply(undefined, args); + }); }, queueableFns: [onStart].concat(wrapChildren(node, segmentNumber)), userContext: node.sharedUserContext(), diff --git a/spec/core/QueueRunnerSpec.js b/spec/core/QueueRunnerSpec.js index 0e57ae96..c1227eab 100644 --- a/spec/core/QueueRunnerSpec.js +++ b/spec/core/QueueRunnerSpec.js @@ -481,15 +481,18 @@ describe("QueueRunner", function() { var queueableFn = { fn: function() { throw new Error("error"); } }, nextQueueableFn = { fn: jasmine.createSpy("nextFunction") }, cleanupFn = { fn: jasmine.createSpy("cleanup") }, + onComplete = jasmine.createSpy("onComplete"), queueRunner = new jasmineUnderTest.QueueRunner({ queueableFns: [queueableFn, nextQueueableFn], cleanupFns: [cleanupFn], + onComplete: onComplete, completeOnFirstError: true }); queueRunner.execute(); expect(nextQueueableFn.fn).not.toHaveBeenCalled(); expect(cleanupFn.fn).toHaveBeenCalled(); + expect(onComplete).toHaveBeenCalledWith(jasmine.any(jasmineUnderTest.StopExecutionError)); }); it("does not skip when a cleanup function throws", function() { diff --git a/spec/core/TreeProcessorSpec.js b/spec/core/TreeProcessorSpec.js index 6ab3a15e..2e8a9ca8 100644 --- a/spec/core/TreeProcessorSpec.js +++ b/spec/core/TreeProcessorSpec.js @@ -297,7 +297,7 @@ describe("TreeProcessor", function() { node.getResult.and.returnValue({ my: 'result' }); queueRunner.calls.mostRecent().args[0].onComplete(); - expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' }, nodeDone); + expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' }, jasmine.any(Function)); }); it("runs a node with children", function() { @@ -328,6 +328,37 @@ describe("TreeProcessor", function() { expect(leaf2.execute).toHaveBeenCalledWith('bar', false); }); + it("cascades errors up the tree", function() { + var leaf = new Leaf(), + node = new Node({ children: [leaf] }), + root = new Node({ children: [node] }), + queueRunner = jasmine.createSpy('queueRunner'), + nodeComplete = jasmine.createSpy('nodeComplete'), + processor = new jasmineUnderTest.TreeProcessor({ + tree: root, + runnableIds: [node.id], + nodeComplete: nodeComplete, + queueRunnerFactory: queueRunner + }), + treeComplete = jasmine.createSpy('treeComplete'), + nodeDone = jasmine.createSpy('nodeDone'); + + processor.execute(treeComplete); + var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns; + queueableFns[0].fn(nodeDone); + + queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns; + expect(queueableFns.length).toBe(2); + + queueableFns[1].fn('foo'); + expect(leaf.execute).toHaveBeenCalledWith('foo', false); + + queueRunner.calls.mostRecent().args[0].onComplete('things'); + expect(nodeComplete).toHaveBeenCalled(); + nodeComplete.calls.mostRecent().args[2](); + expect(nodeDone).toHaveBeenCalledWith('things'); + }); + it("runs an excluded node with leaf", function() { var leaf1 = new Leaf(), node = new Node({ children: [leaf1] }), @@ -361,7 +392,7 @@ describe("TreeProcessor", function() { node.getResult.and.returnValue({ im: 'disabled' }); queueRunner.calls.mostRecent().args[0].onComplete(); - expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' }, nodeDone); + expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' }, jasmine.any(Function)); }); it("runs beforeAlls for a node with children", function() { diff --git a/spec/core/integration/SpecRunningSpec.js b/spec/core/integration/SpecRunningSpec.js index e0d8b2ed..b7289438 100644 --- a/spec/core/integration/SpecRunningSpec.js +++ b/spec/core/integration/SpecRunningSpec.js @@ -952,13 +952,17 @@ describe("spec running", function () { it("does not run further specs when one fails", function(done) { var actions = []; - env.it('fails', function() { - actions.push('fails'); - env.expect(1).toBe(2); + env.describe('wrapper', function() { + env.it('fails', function() { + actions.push('fails'); + env.expect(1).toBe(2); + }); }); - env.it('does not run', function() { - actions.push('does not run'); + env.describe('holder', function() { + env.it('does not run', function() { + actions.push('does not run'); + }); }); env.randomizeTests(false); diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js index 932c50ba..fd319365 100644 --- a/src/core/QueueRunner.js +++ b/src/core/QueueRunner.js @@ -159,7 +159,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { return; } - self.errored = result.errored; + self.errored = self.errored || result.errored; if (this.completeOnFirstError && result.errored) { this.skipToCleanup(iterativeIndex); diff --git a/src/core/TreeProcessor.js b/src/core/TreeProcessor.js index 43ca9c5b..d17b5d55 100644 --- a/src/core/TreeProcessor.js +++ b/src/core/TreeProcessor.js @@ -174,8 +174,11 @@ getJasmineRequireObj().TreeProcessor = function() { queueRunnerFactory({ onComplete: function () { + var args = Array.prototype.slice.call(arguments, [0]); node.cleanupBeforeAfter(); - nodeComplete(node, node.getResult(), done); + nodeComplete(node, node.getResult(), function() { + done.apply(undefined, args); + }); }, queueableFns: [onStart].concat(wrapChildren(node, segmentNumber)), userContext: node.sharedUserContext(),