diff options
| author | Julie | 2013-09-13 12:47:05 -0700 | 
|---|---|---|
| committer | Vojta Jina | 2013-10-07 13:45:40 -0700 | 
| commit | 2b5ce84fca7b41fca24707e163ec6af84bc12e83 (patch) | |
| tree | d3fbcfd3c7e2e62fe60df6faa9823abda57b9bd7 /test/ngMock/angular-mocksSpec.js | |
| parent | a80e96cea184b392505f0a292785a5c66d45e165 (diff) | |
| download | angular.js-2b5ce84fca7b41fca24707e163ec6af84bc12e83.tar.bz2 | |
feat($interval): add a service wrapping setInterval
The $interval service simplifies creating and testing recurring tasks.
This service does not increment $browser's outstanding request count,
which means that scenario tests and Protractor tests will not timeout
when a site uses a polling function registered by $interval. Provides
a workaround for #2402.
For unit tests, repeated tasks can be controlled using ngMock$interval's
tick(), tickNext(), and tickAll() functions.
Diffstat (limited to 'test/ngMock/angular-mocksSpec.js')
| -rw-r--r-- | test/ngMock/angular-mocksSpec.js | 235 | 
1 files changed, 235 insertions, 0 deletions
| diff --git a/test/ngMock/angular-mocksSpec.js b/test/ngMock/angular-mocksSpec.js index 1a4290e0..851f7803 100644 --- a/test/ngMock/angular-mocksSpec.js +++ b/test/ngMock/angular-mocksSpec.js @@ -283,6 +283,241 @@ describe('ngMock', function() {    }); +  describe('$interval', function() { +    it('should run tasks repeatedly', inject(function($interval) { +      var counter = 0; +      $interval(function() { counter++; }, 1000); + +      expect(counter).toBe(0); + +      $interval.flush(1000); +      expect(counter).toBe(1); + +      $interval.flush(1000); + +      expect(counter).toBe(2); +    })); + + +    it('should call $apply after each task is executed', inject(function($interval, $rootScope) { +      var applySpy = spyOn($rootScope, '$apply').andCallThrough(); + +      $interval(noop, 1000); +      expect(applySpy).not.toHaveBeenCalled(); + +      $interval.flush(1000); +      expect(applySpy).toHaveBeenCalledOnce(); + +      applySpy.reset(); + +      $interval(noop, 1000); +      $interval(noop, 1000); +      $interval.flush(1000); +      expect(applySpy.callCount).toBe(3); +    })); + + +    it('should NOT call $apply if invokeApply is set to false', +        inject(function($interval, $rootScope) { +      var applySpy = spyOn($rootScope, '$apply').andCallThrough(); + +      $interval(noop, 1000, 0, false); +      expect(applySpy).not.toHaveBeenCalled(); + +      $interval.flush(2000); +      expect(applySpy).not.toHaveBeenCalled(); +    })); + + +    it('should allow you to specify the delay time', inject(function($interval) { +      var counter = 0; +      $interval(function() { counter++; }, 123); + +      expect(counter).toBe(0); + +      $interval.flush(122); +      expect(counter).toBe(0); + +      $interval.flush(1); +      expect(counter).toBe(1); +    })); + + +    it('should allow you to specify a number of iterations', inject(function($interval) { +      var counter = 0; +      $interval(function() {counter++}, 1000, 2); + +      $interval.flush(1000); +      expect(counter).toBe(1); +      $interval.flush(1000); +      expect(counter).toBe(2); +      $interval.flush(1000); +      expect(counter).toBe(2); +    })); + + +    describe('flush', function() { +      it('should move the clock forward by the specified time', inject(function($interval) { +        var counterA = 0; +        var counterB = 0; +        $interval(function() { counterA++; }, 100); +        $interval(function() { counterB++; }, 401); + +        $interval.flush(200); +        expect(counterA).toEqual(2); + +        $interval.flush(201); +        expect(counterA).toEqual(4); +        expect(counterB).toEqual(1); +      })); +    }); + + +    it('should return a promise which will be updated with the count on each iteration', +        inject(function($interval) { +      var log = [], +          promise = $interval(function() { log.push('tick'); }, 1000); + +      promise.then(function(value) { log.push('promise success: ' + value); }, +                   function(err) { log.push('promise error: ' + err); }, +                   function(note) { log.push('promise update: ' + note); }); +      expect(log).toEqual([]); + +      $interval.flush(1000); +      expect(log).toEqual(['tick', 'promise update: 0']); + +      $interval.flush(1000); +      expect(log).toEqual(['tick', 'promise update: 0', 'tick', 'promise update: 1']); +    })); + + +    it('should return a promise which will be resolved after the specified number of iterations', +        inject(function($interval) { +      var log = [], +          promise = $interval(function() { log.push('tick'); }, 1000, 2); + +      promise.then(function(value) { log.push('promise success: ' + value); }, +                   function(err) { log.push('promise error: ' + err); }, +                   function(note) { log.push('promise update: ' + note); }); +      expect(log).toEqual([]); + +      $interval.flush(1000); +      expect(log).toEqual(['tick', 'promise update: 0']); +      $interval.flush(1000); + +      expect(log).toEqual([ +          'tick', 'promise update: 0', 'tick', 'promise update: 1', 'promise success: 2']); + +    })); + + +    describe('exception handling', function() { +      beforeEach(module(function($exceptionHandlerProvider) { +        $exceptionHandlerProvider.mode('log'); +      })); + + +      it('should delegate exception to the $exceptionHandler service', inject( +          function($interval, $exceptionHandler) { +        $interval(function() { throw "Test Error"; }, 1000); +        expect($exceptionHandler.errors).toEqual([]); + +        $interval.flush(1000); +        expect($exceptionHandler.errors).toEqual(["Test Error"]); + +        $interval.flush(1000); +        expect($exceptionHandler.errors).toEqual(["Test Error", "Test Error"]); +      })); + + +      it('should call $apply even if an exception is thrown in callback', inject( +          function($interval, $rootScope) { +        var applySpy = spyOn($rootScope, '$apply').andCallThrough(); + +        $interval(function() { throw "Test Error"; }, 1000); +        expect(applySpy).not.toHaveBeenCalled(); + +        $interval.flush(1000); +        expect(applySpy).toHaveBeenCalled(); +      })); + + +      it('should still update the interval promise when an exception is thrown', +          inject(function($interval) { +        var log = [], +            promise = $interval(function() { throw "Some Error"; }, 1000); + +        promise.then(function(value) { log.push('promise success: ' + value); }, +                   function(err) { log.push('promise error: ' + err); }, +                   function(note) { log.push('promise update: ' + note); }); +        $interval.flush(1000); + +        expect(log).toEqual(['promise update: 0']); +      })); +    }); + + +    describe('cancel', function() { +      it('should cancel tasks', inject(function($interval) { +        var task1 = jasmine.createSpy('task1', 1000), +            task2 = jasmine.createSpy('task2', 1000), +            task3 = jasmine.createSpy('task3', 1000), +            promise1, promise3; + +        promise1 = $interval(task1, 200); +        $interval(task2, 1000); +        promise3 = $interval(task3, 333); + +        $interval.cancel(promise3); +        $interval.cancel(promise1); +        $interval.flush(1000); + +        expect(task1).not.toHaveBeenCalled(); +        expect(task2).toHaveBeenCalledOnce(); +        expect(task3).not.toHaveBeenCalled(); +      })); + + +      it('should cancel the promise', inject(function($interval, $rootScope) { +        var promise = $interval(noop, 1000), +            log = []; +        promise.then(function(value) { log.push('promise success: ' + value); }, +                   function(err) { log.push('promise error: ' + err); }, +                   function(note) { log.push('promise update: ' + note); }); +        expect(log).toEqual([]); + +        $interval.flush(1000); +        $interval.cancel(promise); +        $interval.flush(1000); +        $rootScope.$apply(); // For resolving the promise - +                             // necessary since q uses $rootScope.evalAsync. + +        expect(log).toEqual(['promise update: 0', 'promise error: canceled']); +      })); + + +      it('should return true if a task was successfully canceled', inject(function($interval) { +        var task1 = jasmine.createSpy('task1'), +            task2 = jasmine.createSpy('task2'), +            promise1, promise2; + +        promise1 = $interval(task1, 1000, 1); +        $interval.flush(1000); +        promise2 = $interval(task2, 1000, 1); + +        expect($interval.cancel(promise1)).toBe(false); +        expect($interval.cancel(promise2)).toBe(true); +      })); + + +      it('should not throw a runtime exception when given an undefined promise', +          inject(function($interval) { +        expect($interval.cancel()).toBe(false); +      })); +    }); +  }); + +    describe('defer', function() {      var browser, log;      beforeEach(inject(function($browser) { | 
