From 8a6d7828c63f10e5c874a2ce9da8d406f0c9c577 Mon Sep 17 00:00:00 2001 From: Sheel Choksi Date: Thu, 14 Nov 2013 23:01:43 -0800 Subject: [PATCH] Make all async functions be subject to the timeout [finishes #60798058] --- lib/jasmine-core/jasmine.js | 17 ++++----- spec/core/SpecSpec.js | 69 +++++++++++++++++++++++++++++++++++-- src/core/Spec.js | 17 ++++----- 3 files changed, 84 insertions(+), 19 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 3b968686..2c325fb9 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -230,9 +230,8 @@ getJasmineRequireObj().Spec = function(j$) { this.id = attrs.id; this.description = attrs.description || ''; this.fn = attrs.fn; - this.beforeFns = attrs.beforeFns || function() {}; - this.afterFns = attrs.afterFns || function() {}; - this.catchingExceptions = attrs.catchingExceptions; + this.beforeFns = attrs.beforeFns || function() { return []; }; + this.afterFns = attrs.afterFns || function() { return []; }; this.onStart = attrs.onStart || function() {}; this.exceptionFormatter = attrs.exceptionFormatter || function() {}; this.getSpecName = attrs.getSpecName || function() { return ''; }; @@ -297,13 +296,15 @@ getJasmineRequireObj().Spec = function(j$) { timeout = void 0; } - var befores = this.beforeFns() || [], - afters = this.afterFns() || [], - thisOne = (this.fn.length) ? timeoutable(this.fn) : this.fn; - var allFns = befores.concat(thisOne).concat(afters); + var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns()), + allTimeoutableFns = []; + for (var i = 0; i < allFns.length; i++) { + var fn = allFns[i]; + allTimeoutableFns.push(fn.length > 0 ? timeoutable(fn) : fn); + } this.queueRunnerFactory({ - fns: allFns, + fns: allTimeoutableFns, onException: onException, onComplete: complete }); diff --git a/spec/core/SpecSpec.js b/spec/core/SpecSpec.js index c89a0cae..b0186dee 100644 --- a/spec/core/SpecSpec.js +++ b/spec/core/SpecSpec.js @@ -218,12 +218,37 @@ describe("Spec", function() { expect(specNameSpy.calls.mostRecent().args[0].id).toEqual(spec.id); }); - it("resets the timeout timer when an async spec throws an exception", function() { + it("sets a timeout for async functions to keep them from running forever", function() { + var queueRunnerSpy = jasmine.createSpy('queue runner'), + setTimeoutSpy = jasmine.createSpy('setTimeout'), + spec = new j$.Spec({ + beforeFns: function() { return [function(done) { }]; }, + fn: function(done) { }, + afterFns: function() { return [function(done) { }]; }, + timer: { + setTimeout: setTimeoutSpy, + clearTimeout: function() {} + }, + queueRunnerFactory: queueRunnerSpy + }); + + spec.execute(); + var fns = queueRunnerSpy.calls.mostRecent().args[0].fns; + + for (var i = 0; i < fns.length; i++) { + fns[i](); + } + + expect(setTimeoutSpy.calls.count()).toEqual(3); + expect(setTimeoutSpy).toHaveBeenCalledWith(jasmine.any(Function), j$.DEFAULT_TIMEOUT_INTERVAL); + }); + + it("resets the timeout timer when an async before throws an exception", function() { var queueRunnerSpy = jasmine.createSpy('queueRunner'), clearTimeoutSpy = jasmine.createSpy('clear timeout'), spec = new j$.Spec({ - fn: function(done) { }, - catchExceptions: function() { return true; }, + beforeFns: function() { return [function(done) {}]; }, + fn: function() { }, timer: { setTimeout: function () { return 920; }, clearTimeout: clearTimeoutSpy @@ -238,6 +263,44 @@ describe("Spec", function() { expect(clearTimeoutSpy).toHaveBeenCalledWith(920); }); + it("resets the timeout timer when an async spec throws an exception", function() { + var queueRunnerSpy = jasmine.createSpy('queueRunner'), + clearTimeoutSpy = jasmine.createSpy('clear timeout'), + spec = new j$.Spec({ + fn: function(done) { }, + timer: { + setTimeout: function () { return 920; }, + clearTimeout: clearTimeoutSpy + }, + queueRunnerFactory: queueRunnerSpy + }); + + spec.execute(); + queueRunnerSpy.calls.mostRecent().args[0].fns[0](); + queueRunnerSpy.calls.mostRecent().args[0].onException(new Error()); + + expect(clearTimeoutSpy).toHaveBeenCalledWith(920); + }); + + it("resets the timeout timer when an async after spec throws an exception", function() { + var queueRunnerSpy = jasmine.createSpy('queueRunner'), + clearTimeoutSpy = jasmine.createSpy('clear timeout'), + spec = new j$.Spec({ + fn: function() { }, + afterFns: function() { return [function(done) {}]; }, + timer: { + setTimeout: function () { return 920; }, + clearTimeout: clearTimeoutSpy + }, + queueRunnerFactory: queueRunnerSpy + }); + + spec.execute(); + queueRunnerSpy.calls.mostRecent().args[0].fns[1](); + queueRunnerSpy.calls.mostRecent().args[0].onException(new Error()); + + expect(clearTimeoutSpy).toHaveBeenCalledWith(920); + }); describe("when a spec is marked pending during execution", function() { it("should mark the spec as pending", function() { var fakeQueueRunner = function(opts) { diff --git a/src/core/Spec.js b/src/core/Spec.js index a75f0c1c..e8f48539 100644 --- a/src/core/Spec.js +++ b/src/core/Spec.js @@ -5,9 +5,8 @@ getJasmineRequireObj().Spec = function(j$) { this.id = attrs.id; this.description = attrs.description || ''; this.fn = attrs.fn; - this.beforeFns = attrs.beforeFns || function() {}; - this.afterFns = attrs.afterFns || function() {}; - this.catchingExceptions = attrs.catchingExceptions; + this.beforeFns = attrs.beforeFns || function() { return []; }; + this.afterFns = attrs.afterFns || function() { return []; }; this.onStart = attrs.onStart || function() {}; this.exceptionFormatter = attrs.exceptionFormatter || function() {}; this.getSpecName = attrs.getSpecName || function() { return ''; }; @@ -72,13 +71,15 @@ getJasmineRequireObj().Spec = function(j$) { timeout = void 0; } - var befores = this.beforeFns() || [], - afters = this.afterFns() || [], - thisOne = (this.fn.length) ? timeoutable(this.fn) : this.fn; - var allFns = befores.concat(thisOne).concat(afters); + var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns()), + allTimeoutableFns = []; + for (var i = 0; i < allFns.length; i++) { + var fn = allFns[i]; + allTimeoutableFns.push(fn.length > 0 ? timeoutable(fn) : fn); + } this.queueRunnerFactory({ - fns: allFns, + fns: allTimeoutableFns, onException: onException, onComplete: complete });