diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 1d21364da7bb..27b4da48b2c7 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -504,8 +504,8 @@ angular.mock.$IntervalProvider = function() { } repeatFns.push({ - nextTime:(now + delay), - delay: delay, + nextTime: (now + (delay || 0)), + delay: delay || 1, fn: tick, id: nextRepeatId, deferred: deferred @@ -555,10 +555,16 @@ angular.mock.$IntervalProvider = function() { * @return {number} The amount of time moved forward. */ $interval.flush = function(millis) { + var before = now; now += millis; while (repeatFns.length && repeatFns[0].nextTime <= now) { var task = repeatFns[0]; task.fn(); + if (task.nextTime === before) { + // this can only happen the first time + // a zero-delay interval gets triggered + task.nextTime++; + } task.nextTime += task.delay; repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;}); } diff --git a/test/ngMock/angular-mocksSpec.js b/test/ngMock/angular-mocksSpec.js index 4bfad9d3bb10..7b827c25dffa 100644 --- a/test/ngMock/angular-mocksSpec.js +++ b/test/ngMock/angular-mocksSpec.js @@ -351,6 +351,75 @@ describe('ngMock', function() { })); + it('should allow you to NOT specify the delay time', inject(function($interval) { + var counterA = 0; + var counterB = 0; + + $interval(function() { counterA++; }); + $interval(function() { counterB++; }, 0); + + $interval.flush(1000); + expect(counterA).toBe(1000); + expect(counterB).toBe(1000); + $interval.flush(1000); + expect(counterA).toBe(2000); + expect(counterB).toBe(2000); + })); + + + it('should run tasks in correct relative order', inject(function($interval) { + var counterA = 0; + var counterB = 0; + $interval(function() { counterA++; }, 0); + $interval(function() { counterB++; }, 1000); + + $interval.flush(1000); + expect(counterA).toBe(1000); + expect(counterB).toBe(1); + $interval.flush(999); + expect(counterA).toBe(1999); + expect(counterB).toBe(1); + $interval.flush(1); + expect(counterA).toBe(2000); + expect(counterB).toBe(2); + })); + + + it('should NOT trigger zero-delay interval when flush has ran before', inject(function($interval) { + var counterA = 0; + var counterB = 0; + + $interval.flush(100); + + $interval(function() { counterA++; }); + $interval(function() { counterB++; }, 0); + + expect(counterA).toBe(0); + expect(counterB).toBe(0); + + $interval.flush(100); + + expect(counterA).toBe(100); + expect(counterB).toBe(100); + })); + + + it('should trigger zero-delay interval only once on flush zero', inject(function($interval) { + var counterA = 0; + var counterB = 0; + + $interval(function() { counterA++; }); + $interval(function() { counterB++; }, 0); + + $interval.flush(0); + expect(counterA).toBe(1); + expect(counterB).toBe(1); + $interval.flush(0); + expect(counterA).toBe(1); + expect(counterB).toBe(1); + })); + + it('should allow you to specify a number of iterations', inject(function($interval) { var counter = 0; $interval(function() {counter++;}, 1000, 2);