| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   AsyncTestCompleter, | 
					
						
							|  |  |  |   beforeEach, | 
					
						
							|  |  |  |   ddescribe, | 
					
						
							|  |  |  |   describe, | 
					
						
							|  |  |  |   expect, | 
					
						
							|  |  |  |   fakeAsync, | 
					
						
							|  |  |  |   flushMicrotasks, | 
					
						
							|  |  |  |   iit, | 
					
						
							|  |  |  |   inject, | 
					
						
							|  |  |  |   it, | 
					
						
							|  |  |  |   Log, | 
					
						
							|  |  |  |   tick, | 
					
						
							|  |  |  |   xit | 
					
						
							|  |  |  | } from 'angular2/testing_internal'; | 
					
						
							| 
									
										
										
										
											2015-11-06 17:34:07 -08:00
										 |  |  | import {TimerWrapper, PromiseWrapper} from 'angular2/src/facade/async'; | 
					
						
							|  |  |  | import {BaseException} from 'angular2/src/facade/exceptions'; | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | import {Parser} from 'angular2/src/compiler/expression_parser/parser'; | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							|  |  |  |   describe('fake async', () => { | 
					
						
							|  |  |  |     it('should run synchronous code', () => { | 
					
						
							|  |  |  |       var ran = false; | 
					
						
							|  |  |  |       fakeAsync(() => { ran = true; })(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(ran).toEqual(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should pass arguments to the wrapped function', () => { | 
					
						
							|  |  |  |       fakeAsync((foo, bar) => { | 
					
						
							|  |  |  |         expect(foo).toEqual('foo'); | 
					
						
							|  |  |  |         expect(bar).toEqual('bar'); | 
					
						
							|  |  |  |       })('foo', 'bar'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work with inject()', | 
					
						
							| 
									
										
										
										
											2016-04-18 16:04:35 -07:00
										 |  |  |        fakeAsync(inject([Parser], (parser) => { expect(parser).toBeAnInstanceOf(Parser); }))); | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-19 09:13:17 +02:00
										 |  |  |     it('should throw on nested calls', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(() => { fakeAsync(() => { fakeAsync(() => null)(); })(); }) | 
					
						
							|  |  |  |           .toThrowError('fakeAsync() calls can not be nested'); | 
					
						
							| 
									
										
										
										
											2015-05-19 09:13:17 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-02 19:55:03 +02:00
										 |  |  |     it('should flush microtasks before returning', () => { | 
					
						
							|  |  |  |       var thenRan = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       fakeAsync(() => { PromiseWrapper.resolve(null).then(_ => { thenRan = true; }); })(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(thenRan).toEqual(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should propagate the return value', | 
					
						
							|  |  |  |        () => { expect(fakeAsync(() => 'foo')()).toEqual('foo'); }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  |     describe('Promise', () => { | 
					
						
							|  |  |  |       it('should run asynchronous code', fakeAsync(() => { | 
					
						
							|  |  |  |            var thenRan = false; | 
					
						
							|  |  |  |            PromiseWrapper.resolve(null).then((_) => { thenRan = true; }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(thenRan).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            flushMicrotasks(); | 
					
						
							|  |  |  |            expect(thenRan).toEqual(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run chained thens', fakeAsync(() => { | 
					
						
							|  |  |  |            var log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            PromiseWrapper.resolve(null).then((_) => log.add(1)).then((_) => log.add(2)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(log.result()).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            flushMicrotasks(); | 
					
						
							|  |  |  |            expect(log.result()).toEqual('1; 2'); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run Promise created in Promise', fakeAsync(() => { | 
					
						
							|  |  |  |            var log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            PromiseWrapper.resolve(null).then((_) => { | 
					
						
							|  |  |  |              log.add(1); | 
					
						
							|  |  |  |              PromiseWrapper.resolve(null).then((_) => log.add(2)); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(log.result()).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            flushMicrotasks(); | 
					
						
							|  |  |  |            expect(log.result()).toEqual('1; 2'); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // TODO(vicb): check why this doesn't work in JS - linked to open issues on GH ?
 | 
					
						
							|  |  |  |       xit('should complain if the test throws an exception during async calls', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           fakeAsync(() => { | 
					
						
							|  |  |  |             PromiseWrapper.resolve(null).then((_) => { throw new BaseException('async'); }); | 
					
						
							|  |  |  |             flushMicrotasks(); | 
					
						
							|  |  |  |           })(); | 
					
						
							|  |  |  |         }).toThrowError('async'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should complain if a test throws an exception', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(() => { fakeAsync(() => { throw new BaseException('sync'); })(); }) | 
					
						
							|  |  |  |             .toThrowError('sync'); | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('timers', () => { | 
					
						
							|  |  |  |       it('should run queued zero duration timer on zero tick', fakeAsync(() => { | 
					
						
							|  |  |  |            var ran = false; | 
					
						
							|  |  |  |            TimerWrapper.setTimeout(() => {ran = true}, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(); | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run queued timer after sufficient clock ticks', fakeAsync(() => { | 
					
						
							|  |  |  |            var ran = false; | 
					
						
							|  |  |  |            TimerWrapper.setTimeout(() => { ran = true; }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(6); | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(6); | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run queued timer only once', fakeAsync(() => { | 
					
						
							|  |  |  |            var cycles = 0; | 
					
						
							|  |  |  |            TimerWrapper.setTimeout(() => { cycles++; }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not run cancelled timer', fakeAsync(() => { | 
					
						
							|  |  |  |            var ran = false; | 
					
						
							|  |  |  |            var id = TimerWrapper.setTimeout(() => { ran = true; }, 10); | 
					
						
							|  |  |  |            TimerWrapper.clearTimeout(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should throw an error on dangling timers', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(() => { fakeAsync(() => { TimerWrapper.setTimeout(() => {}, 10); })(); }) | 
					
						
							|  |  |  |             .toThrowError('1 timer(s) still in the queue.'); | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should throw an error on dangling periodic timers', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(() => { fakeAsync(() => { TimerWrapper.setInterval(() => {}, 10); })(); }) | 
					
						
							|  |  |  |             .toThrowError('1 periodic timer(s) still in the queue.'); | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run periodic timers', fakeAsync(() => { | 
					
						
							|  |  |  |            var cycles = 0; | 
					
						
							|  |  |  |            var id = TimerWrapper.setInterval(() => { cycles++; }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            TimerWrapper.clearInterval(id); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not run cancelled periodic timer', fakeAsync(() => { | 
					
						
							|  |  |  |            var ran = false; | 
					
						
							|  |  |  |            var id = TimerWrapper.setInterval(() => { ran = true; }, 10); | 
					
						
							|  |  |  |            TimerWrapper.clearInterval(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should be able to cancel periodic timers from a callback', fakeAsync(() => { | 
					
						
							|  |  |  |            var cycles = 0; | 
					
						
							|  |  |  |            var id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            id = TimerWrapper.setInterval(() => { | 
					
						
							|  |  |  |              cycles++; | 
					
						
							|  |  |  |              TimerWrapper.clearInterval(id); | 
					
						
							|  |  |  |            }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should process microtasks before timers', fakeAsync(() => { | 
					
						
							|  |  |  |            var log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            PromiseWrapper.resolve(null).then((_) => log.add('microtask')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            TimerWrapper.setTimeout(() => log.add('timer'), 9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            var id = TimerWrapper.setInterval(() => log.add('periodic timer'), 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(log.result()).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(log.result()).toEqual('microtask; timer; periodic timer'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            TimerWrapper.clearInterval(id); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should process micro-tasks created in timers before next timers', fakeAsync(() => { | 
					
						
							|  |  |  |            var log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            PromiseWrapper.resolve(null).then((_) => log.add('microtask')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            TimerWrapper.setTimeout(() => { | 
					
						
							|  |  |  |              log.add('timer'); | 
					
						
							|  |  |  |              PromiseWrapper.resolve(null).then((_) => log.add('t microtask')); | 
					
						
							|  |  |  |            }, 9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            var id = TimerWrapper.setInterval(() => { | 
					
						
							|  |  |  |              log.add('periodic timer'); | 
					
						
							|  |  |  |              PromiseWrapper.resolve(null).then((_) => log.add('pt microtask')); | 
					
						
							|  |  |  |            }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(log.result()) | 
					
						
							|  |  |  |                .toEqual('microtask; timer; t microtask; periodic timer; pt microtask'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(log.result()) | 
					
						
							|  |  |  |                .toEqual( | 
					
						
							|  |  |  |                    'microtask; timer; t microtask; periodic timer; pt microtask; periodic timer; pt microtask'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            TimerWrapper.clearInterval(id); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('outside of the fakeAsync zone', () => { | 
					
						
							|  |  |  |       it('calling flushMicrotasks should throw', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(() => { flushMicrotasks(); }) | 
					
						
							|  |  |  |             .toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('calling tick should throw', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(() => { tick(); }) | 
					
						
							|  |  |  |             .toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							| 
									
										
										
										
											2015-05-27 09:53:37 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } |