| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import '../../lib/rxjs/rxjs-fake-async'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {Observable} from 'rxjs'; | 
					
						
							|  |  |  | import {delay} from 'rxjs/operators'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {isNode, patchMacroTask, zoneSymbol} from '../../lib/common/utils'; | 
					
						
							|  |  |  | import {ifEnvSupports} from '../test-util'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function supportNode() { | 
					
						
							|  |  |  |   return isNode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (supportNode as any).message = 'support node'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function supportClock() { | 
					
						
							|  |  |  |   const _global: any = typeof window === 'undefined' ? global : window; | 
					
						
							|  |  |  |   return typeof jasmine.clock === 'function' && | 
					
						
							|  |  |  |       _global[zoneSymbol('fakeAsyncAutoFakeAsyncWhenClockPatched')]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (supportClock as any).message = 'support patch clock'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('FakeAsyncTestZoneSpec', () => { | 
					
						
							|  |  |  |   let FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec']; | 
					
						
							|  |  |  |   let testZoneSpec: any; | 
					
						
							|  |  |  |   let fakeAsyncTestZone: Zone; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     testZoneSpec = new FakeAsyncTestZoneSpec('name'); | 
					
						
							|  |  |  |     fakeAsyncTestZone = Zone.current.fork(testZoneSpec); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('sets the FakeAsyncTestZoneSpec property', () => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |       expect(Zone.current.get('FakeAsyncTestZoneSpec')).toEqual(testZoneSpec); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('synchronous code', () => { | 
					
						
							|  |  |  |     it('should run', () => { | 
					
						
							|  |  |  |       let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         ran = true; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(ran).toEqual(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw the error in the code', () => { | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |           throw new Error('sync'); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }).toThrowError('sync'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw error on Rejected promise', () => { | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							|  |  |  |         fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |           Promise.reject('myError'); | 
					
						
							|  |  |  |           testZoneSpec.flushMicrotasks(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }).toThrowError('Uncaught (in promise): myError'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('asynchronous code', () => { | 
					
						
							|  |  |  |     it('should run', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let thenRan = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         Promise.resolve(null).then((_) => { | 
					
						
							|  |  |  |           thenRan = true; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(thenRan).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.flushMicrotasks(); | 
					
						
							|  |  |  |         expect(thenRan).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should rethrow the exception on flushMicroTasks for error thrown in Promise callback', | 
					
						
							|  |  |  |        () => { | 
					
						
							|  |  |  |          fakeAsyncTestZone.run(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            Promise.resolve(null).then((_) => { | 
					
						
							|  |  |  |              throw new Error('async'); | 
					
						
							|  |  |  |            }); | 
					
						
							| 
									
										
										
										
											2019-07-30 14:35:30 -07:00
										 |  |  |            expect(() => { | 
					
						
							|  |  |  |              testZoneSpec.flushMicrotasks(); | 
					
						
							|  |  |  |            }).toThrowError(/Uncaught \(in promise\): Error: async/); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |          }); | 
					
						
							|  |  |  |        }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run chained thens', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let log: number[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Promise.resolve(null).then((_) => log.push(1)).then((_) => log.push(2)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(log).toEqual([]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.flushMicrotasks(); | 
					
						
							|  |  |  |         expect(log).toEqual([1, 2]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run Promise created in Promise', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let log: number[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Promise.resolve(null).then((_) => { | 
					
						
							|  |  |  |           log.push(1); | 
					
						
							|  |  |  |           Promise.resolve(null).then((_) => log.push(2)); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(log).toEqual([]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.flushMicrotasks(); | 
					
						
							|  |  |  |         expect(log).toEqual([1, 2]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('timers', () => { | 
					
						
							|  |  |  |     it('should run queued zero duration timer on zero tick', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           ran = true; | 
					
						
							|  |  |  |         }, 0); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(); | 
					
						
							|  |  |  |         expect(ran).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run queued immediate timer on zero tick', ifEnvSupports('setImmediate', () => { | 
					
						
							|  |  |  |          fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            setImmediate(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            testZoneSpec.tick(); | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 11:00:21 +09:00
										 |  |  |     it('should default to processNewMacroTasksSynchronously if providing other flags', () => { | 
					
						
							|  |  |  |       function nestedTimer(callback: () => any): void { | 
					
						
							|  |  |  |         setTimeout(() => setTimeout(() => callback())); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         const callback = jasmine.createSpy('callback'); | 
					
						
							|  |  |  |         nestedTimer(callback); | 
					
						
							|  |  |  |         expect(callback).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |         testZoneSpec.tick(0, null, {}); | 
					
						
							|  |  |  |         expect(callback).toHaveBeenCalled(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-03 00:56:56 +09:00
										 |  |  |     it('should not queue new macro task on tick with processNewMacroTasksSynchronously=false', | 
					
						
							|  |  |  |        () => { | 
					
						
							|  |  |  |          function nestedTimer(callback: () => any): void { | 
					
						
							|  |  |  |            setTimeout(() => setTimeout(() => callback())); | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  |          fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |            const callback = jasmine.createSpy('callback'); | 
					
						
							|  |  |  |            nestedTimer(callback); | 
					
						
							|  |  |  |            expect(callback).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |            testZoneSpec.tick(0, null, {processNewMacroTasksSynchronously: false}); | 
					
						
							|  |  |  |            expect(callback).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |            testZoneSpec.flush(); | 
					
						
							|  |  |  |            expect(callback).toHaveBeenCalled(); | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  |        }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     it('should run queued timer after sufficient clock ticks', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           ran = true; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(6); | 
					
						
							|  |  |  |         expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(4); | 
					
						
							|  |  |  |         expect(ran).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run doTick callback even if no work ran', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let totalElapsed = 0; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         function doTick(elapsed: number) { | 
					
						
							|  |  |  |           totalElapsed += elapsed; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         setTimeout(() => {}, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(6, doTick); | 
					
						
							|  |  |  |         expect(totalElapsed).toEqual(6); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(6, doTick); | 
					
						
							|  |  |  |         expect(totalElapsed).toEqual(12); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(6, doTick); | 
					
						
							|  |  |  |         expect(totalElapsed).toEqual(18); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run queued timer created by timer callback', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let counter = 0; | 
					
						
							|  |  |  |         const startCounterLoop = () => { | 
					
						
							|  |  |  |           counter++; | 
					
						
							|  |  |  |           setTimeout(startCounterLoop, 10); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         startCounterLoop(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(counter).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(counter).toEqual(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(counter).toEqual(3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(30); | 
					
						
							|  |  |  |         expect(counter).toEqual(6); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run queued timer only once', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let cycles = 0; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           cycles++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       expect(testZoneSpec.pendingTimers.length).toBe(0); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not run cancelled timer', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         let id: any = setTimeout(() => { | 
					
						
							|  |  |  |           ran = true; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         clearTimeout(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(ran).toEqual(false); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should pass arguments to times', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let value = 'genuine value'; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         let id = setTimeout((arg1, arg2) => { | 
					
						
							|  |  |  |           value = arg1 + arg2; | 
					
						
							|  |  |  |         }, 0, 'expected', ' value'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(); | 
					
						
							|  |  |  |         expect(value).toEqual('expected value'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should pass arguments to setImmediate', ifEnvSupports('setImmediate', () => { | 
					
						
							|  |  |  |          fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |            let value = 'genuine value'; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            let id = setImmediate((arg1, arg2) => { | 
					
						
							|  |  |  |              value = arg1 + arg2; | 
					
						
							|  |  |  |            }, 'expected', ' value'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            testZoneSpec.tick(); | 
					
						
							|  |  |  |            expect(value).toEqual('expected value'); | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run periodic timers', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let cycles = 0; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         let id = setInterval(() => { | 
					
						
							|  |  |  |           cycles++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(id).toBeGreaterThan(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(30); | 
					
						
							|  |  |  |         expect(cycles).toEqual(6); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should pass arguments to periodic timers', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let value = 'genuine value'; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         let id = setInterval((arg1, arg2) => { | 
					
						
							|  |  |  |           value = arg1 + arg2; | 
					
						
							|  |  |  |         }, 10, 'expected', ' value'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(value).toEqual('expected value'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not run cancelled periodic timer', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         let id = setInterval(() => { | 
					
						
							|  |  |  |           ran = true; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(ran).toEqual(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ran = false; | 
					
						
							|  |  |  |         clearInterval(id); | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(ran).toEqual(false); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should be able to cancel periodic timers from a callback', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let cycles = 0; | 
					
						
							|  |  |  |         let id: number; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         id = setInterval(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                cycles++; | 
					
						
							|  |  |  |                clearInterval(id); | 
					
						
							|  |  |  |              }, 10) as any as number; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycles).toEqual(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should process microtasks before timers', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let log: string[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Promise.resolve(null).then((_) => log.push('microtask')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         setTimeout(() => log.push('timer'), 9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         setInterval(() => log.push('periodic timer'), 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(log).toEqual([]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(log).toEqual(['microtask', 'timer', 'periodic timer']); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should process micro-tasks created in timers before next timers', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let log: string[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Promise.resolve(null).then((_) => log.push('microtask')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           log.push('timer'); | 
					
						
							|  |  |  |           Promise.resolve(null).then((_) => log.push('t microtask')); | 
					
						
							|  |  |  |         }, 9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let id = setInterval(() => { | 
					
						
							|  |  |  |           log.push('periodic timer'); | 
					
						
							|  |  |  |           Promise.resolve(null).then((_) => log.push('pt microtask')); | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(log).toEqual( | 
					
						
							|  |  |  |             ['microtask', 'timer', 't microtask', 'periodic timer', 'pt microtask']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(log).toEqual([ | 
					
						
							|  |  |  |           'microtask', 'timer', 't microtask', 'periodic timer', 'pt microtask', 'periodic timer', | 
					
						
							|  |  |  |           'pt microtask' | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw the exception from tick for error thrown in timer callback', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           throw new Error('timer'); | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           testZoneSpec.tick(10); | 
					
						
							|  |  |  |         }).toThrowError('timer'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  |       // There should be no pending timers after the error in timer callback.
 | 
					
						
							|  |  |  |       expect(testZoneSpec.pendingTimers.length).toBe(0); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw the exception from tick for error thrown in periodic timer callback', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let count = 0; | 
					
						
							|  |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           count++; | 
					
						
							|  |  |  |           throw new Error(count.toString()); | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         expect(() => { | 
					
						
							|  |  |  |           testZoneSpec.tick(10); | 
					
						
							|  |  |  |         }).toThrowError('1'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Periodic timer is cancelled on first error.
 | 
					
						
							|  |  |  |         expect(count).toBe(1); | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(count).toBe(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       // Periodic timer is removed from pending queue on error.
 | 
					
						
							|  |  |  |       expect(testZoneSpec.pendingPeriodicTimers.length).toBe(0); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should be able to resume processing timer callbacks after handling an error', () => { | 
					
						
							|  |  |  |     fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |       let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       setTimeout(() => { | 
					
						
							|  |  |  |         throw new Error('timer'); | 
					
						
							|  |  |  |       }, 10); | 
					
						
							|  |  |  |       setTimeout(() => { | 
					
						
							|  |  |  |         ran = true; | 
					
						
							|  |  |  |       }, 10); | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |       }).toThrowError('timer'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       expect(ran).toBe(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Restart timer queue processing.
 | 
					
						
							|  |  |  |       testZoneSpec.tick(0); | 
					
						
							|  |  |  |       expect(ran).toBe(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     // There should be no pending timers after the error in timer callback.
 | 
					
						
							|  |  |  |     expect(testZoneSpec.pendingTimers.length).toBe(0); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('flushing all tasks', () => { | 
					
						
							|  |  |  |     it('should flush all pending timers', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let x = false; | 
					
						
							|  |  |  |         let y = false; | 
					
						
							|  |  |  |         let z = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           x = true; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           y = true; | 
					
						
							|  |  |  |         }, 100); | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           z = true; | 
					
						
							|  |  |  |         }, 70); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let elapsed = testZoneSpec.flush(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(elapsed).toEqual(100); | 
					
						
							|  |  |  |         expect(x).toBe(true); | 
					
						
							|  |  |  |         expect(y).toBe(true); | 
					
						
							|  |  |  |         expect(z).toBe(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should flush nested timers', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let x = true; | 
					
						
							|  |  |  |         let y = true; | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           x = true; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |           setTimeout(() => { | 
					
						
							|  |  |  |             y = true; | 
					
						
							|  |  |  |           }, 100); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         }, 200); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let elapsed = testZoneSpec.flush(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(elapsed).toEqual(300); | 
					
						
							|  |  |  |         expect(x).toBe(true); | 
					
						
							|  |  |  |         expect(y).toBe(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should advance intervals', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let x = false; | 
					
						
							|  |  |  |         let y = false; | 
					
						
							|  |  |  |         let z = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           x = true; | 
					
						
							|  |  |  |         }, 50); | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           y = true; | 
					
						
							|  |  |  |         }, 141); | 
					
						
							|  |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           z++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let elapsed = testZoneSpec.flush(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(elapsed).toEqual(141); | 
					
						
							|  |  |  |         expect(x).toBe(true); | 
					
						
							|  |  |  |         expect(y).toBe(true); | 
					
						
							|  |  |  |         expect(z).toEqual(14); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not wait for intervals', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let z = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           z++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let elapsed = testZoneSpec.flush(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(elapsed).toEqual(0); | 
					
						
							|  |  |  |         expect(z).toEqual(0); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should process micro-tasks created in timers before next timers', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let log: string[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Promise.resolve(null).then((_) => log.push('microtask')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           log.push('timer'); | 
					
						
							|  |  |  |           Promise.resolve(null).then((_) => log.push('t microtask')); | 
					
						
							|  |  |  |         }, 20); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let id = setInterval(() => { | 
					
						
							|  |  |  |           log.push('periodic timer'); | 
					
						
							|  |  |  |           Promise.resolve(null).then((_) => log.push('pt microtask')); | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.flush(); | 
					
						
							|  |  |  |         expect(log).toEqual( | 
					
						
							|  |  |  |             ['microtask', 'periodic timer', 'pt microtask', 'timer', 't microtask']); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw the exception from tick for error thrown in timer callback', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           throw new Error('timer'); | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           testZoneSpec.flush(); | 
					
						
							|  |  |  |         }).toThrowError('timer'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  |       // There should be no pending timers after the error in timer callback.
 | 
					
						
							|  |  |  |       expect(testZoneSpec.pendingTimers.length).toBe(0); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should do something reasonable with polling timeouts', () => { | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							|  |  |  |         fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |           let z = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           let poll = () => { | 
					
						
							|  |  |  |             setTimeout(() => { | 
					
						
							|  |  |  |               z++; | 
					
						
							|  |  |  |               poll(); | 
					
						
							|  |  |  |             }, 10); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           poll(); | 
					
						
							|  |  |  |           testZoneSpec.flush(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |           .toThrowError( | 
					
						
							|  |  |  |               'flush failed after reaching the limit of 20 tasks. Does your code use a polling timeout?'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('accepts a custom limit', () => { | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							|  |  |  |         fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |           let z = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           let poll = () => { | 
					
						
							|  |  |  |             setTimeout(() => { | 
					
						
							|  |  |  |               z++; | 
					
						
							|  |  |  |               poll(); | 
					
						
							|  |  |  |             }, 10); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           poll(); | 
					
						
							|  |  |  |           testZoneSpec.flush(10); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |           .toThrowError( | 
					
						
							|  |  |  |               'flush failed after reaching the limit of 10 tasks. Does your code use a polling timeout?'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('can flush periodic timers if flushPeriodic is true', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let x = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           x++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let elapsed = testZoneSpec.flush(20, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(elapsed).toEqual(10); | 
					
						
							|  |  |  |         expect(x).toEqual(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('can flush multiple periodic timers if flushPeriodic is true', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let x = 0; | 
					
						
							|  |  |  |         let y = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           x++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           y++; | 
					
						
							|  |  |  |         }, 100); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let elapsed = testZoneSpec.flush(20, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(elapsed).toEqual(100); | 
					
						
							|  |  |  |         expect(x).toEqual(10); | 
					
						
							|  |  |  |         expect(y).toEqual(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('can flush till the last periodic task is processed', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let x = 0; | 
					
						
							|  |  |  |         let y = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           x++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // This shouldn't cause the flush to throw an exception even though
 | 
					
						
							|  |  |  |         // it would require 100 iterations of the shorter timer.
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         setInterval(() => { | 
					
						
							|  |  |  |           y++; | 
					
						
							|  |  |  |         }, 1000); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let elapsed = testZoneSpec.flush(20, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Should stop right after the longer timer has been processed.
 | 
					
						
							|  |  |  |         expect(elapsed).toEqual(1000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(x).toEqual(100); | 
					
						
							|  |  |  |         expect(y).toEqual(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('outside of FakeAsync Zone', () => { | 
					
						
							|  |  |  |     it('calling flushMicrotasks should throw exception', () => { | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							|  |  |  |         testZoneSpec.flushMicrotasks(); | 
					
						
							|  |  |  |       }).toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     it('calling tick should throw exception', () => { | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							|  |  |  |         testZoneSpec.tick(); | 
					
						
							|  |  |  |       }).toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('requestAnimationFrame', () => { | 
					
						
							|  |  |  |     const functions = | 
					
						
							|  |  |  |         ['requestAnimationFrame', 'webkitRequestAnimationFrame', 'mozRequestAnimationFrame']; | 
					
						
							|  |  |  |     functions.forEach((fnName) => { | 
					
						
							|  |  |  |       describe(fnName, ifEnvSupports(fnName, () => { | 
					
						
							|  |  |  |                  it('should schedule a requestAnimationFrame with timeout of 16ms', () => { | 
					
						
							|  |  |  |                    fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |                      let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                      requestAnimationFrame(() => { | 
					
						
							|  |  |  |                        ran = true; | 
					
						
							|  |  |  |                      }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |                      testZoneSpec.tick(6); | 
					
						
							|  |  |  |                      expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                      testZoneSpec.tick(10); | 
					
						
							|  |  |  |                      expect(ran).toEqual(true); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  it('does not count as a pending timer', () => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                    fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |                      requestAnimationFrame(() => {}); | 
					
						
							|  |  |  |                    }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |                    expect(testZoneSpec.pendingTimers.length).toBe(0); | 
					
						
							|  |  |  |                    expect(testZoneSpec.pendingPeriodicTimers.length).toBe(0); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  it('should cancel a scheduled requestAnimatiomFrame', () => { | 
					
						
							|  |  |  |                    fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |                      let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                      const id = requestAnimationFrame(() => { | 
					
						
							|  |  |  |                        ran = true; | 
					
						
							|  |  |  |                      }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |                      testZoneSpec.tick(6); | 
					
						
							|  |  |  |                      expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                      cancelAnimationFrame(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                      testZoneSpec.tick(10); | 
					
						
							|  |  |  |                      expect(ran).toEqual(false); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  it('is not flushed when flushPeriodic is false', () => { | 
					
						
							|  |  |  |                    let ran = false; | 
					
						
							|  |  |  |                    fakeAsyncTestZone.run(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                      requestAnimationFrame(() => { | 
					
						
							|  |  |  |                        ran = true; | 
					
						
							|  |  |  |                      }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |                      testZoneSpec.flush(20); | 
					
						
							|  |  |  |                      expect(ran).toEqual(false); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  it('is flushed when flushPeriodic is true', () => { | 
					
						
							|  |  |  |                    let ran = false; | 
					
						
							|  |  |  |                    fakeAsyncTestZone.run(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                      requestAnimationFrame(() => { | 
					
						
							|  |  |  |                        ran = true; | 
					
						
							|  |  |  |                      }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |                      const elapsed = testZoneSpec.flush(20, true); | 
					
						
							|  |  |  |                      expect(elapsed).toEqual(16); | 
					
						
							|  |  |  |                      expect(ran).toEqual(true); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  it('should pass timestamp as parameter', () => { | 
					
						
							|  |  |  |                    let timestamp = 0; | 
					
						
							|  |  |  |                    let timestamp1 = 0; | 
					
						
							|  |  |  |                    fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |                      requestAnimationFrame((ts) => { | 
					
						
							|  |  |  |                        timestamp = ts; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                        requestAnimationFrame(ts1 => { | 
					
						
							|  |  |  |                          timestamp1 = ts1; | 
					
						
							|  |  |  |                        }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |                      }); | 
					
						
							|  |  |  |                      const elapsed = testZoneSpec.flush(20, true); | 
					
						
							|  |  |  |                      const elapsed1 = testZoneSpec.flush(20, true); | 
					
						
							|  |  |  |                      expect(elapsed).toEqual(16); | 
					
						
							|  |  |  |                      expect(elapsed1).toEqual(16); | 
					
						
							|  |  |  |                      expect(timestamp).toEqual(16); | 
					
						
							|  |  |  |                      expect(timestamp1).toEqual(32); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe( | 
					
						
							|  |  |  |       'XHRs', ifEnvSupports('XMLHttpRequest', () => { | 
					
						
							|  |  |  |         it('should throw an exception if an XHR is initiated in the zone', () => { | 
					
						
							|  |  |  |           expect(() => { | 
					
						
							|  |  |  |             fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |               let finished = false; | 
					
						
							|  |  |  |               let req = new XMLHttpRequest(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               req.onreadystatechange = () => { | 
					
						
							|  |  |  |                 if (req.readyState === XMLHttpRequest.DONE) { | 
					
						
							|  |  |  |                   finished = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               req.open('GET', '/test', true); | 
					
						
							|  |  |  |               req.send(); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }).toThrowError('Cannot make XHRs from within a fake async test. Request URL: /test'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('node process', ifEnvSupports(supportNode, () => { | 
					
						
							|  |  |  |              it('should be able to schedule microTask with additional arguments', () => { | 
					
						
							|  |  |  |                const process = global['process']; | 
					
						
							|  |  |  |                const nextTick = process && process['nextTick']; | 
					
						
							|  |  |  |                if (!nextTick) { | 
					
						
							|  |  |  |                  return; | 
					
						
							|  |  |  |                } | 
					
						
							|  |  |  |                fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |                  let tickRun = false; | 
					
						
							|  |  |  |                  let cbArgRun = false; | 
					
						
							|  |  |  |                  nextTick( | 
					
						
							|  |  |  |                      (strArg: string, cbArg: Function) => { | 
					
						
							|  |  |  |                        tickRun = true; | 
					
						
							|  |  |  |                        expect(strArg).toEqual('stringArg'); | 
					
						
							|  |  |  |                        cbArg(); | 
					
						
							|  |  |  |                      }, | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                      'stringArg', | 
					
						
							|  |  |  |                      () => { | 
					
						
							|  |  |  |                        cbArgRun = true; | 
					
						
							|  |  |  |                      }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |                  expect(tickRun).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  testZoneSpec.flushMicrotasks(); | 
					
						
							|  |  |  |                  expect(tickRun).toEqual(true); | 
					
						
							|  |  |  |                  expect(cbArgRun).toEqual(true); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('should allow user define which macroTask fakeAsyncTest', () => { | 
					
						
							|  |  |  |     let FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec']; | 
					
						
							|  |  |  |     let testZoneSpec: any; | 
					
						
							|  |  |  |     let fakeAsyncTestZone: Zone; | 
					
						
							|  |  |  |     it('should support custom non perodic macroTask', () => { | 
					
						
							|  |  |  |       testZoneSpec = new FakeAsyncTestZoneSpec( | 
					
						
							|  |  |  |           'name', false, [{source: 'TestClass.myTimeout', callbackArgs: ['test']}]); | 
					
						
							|  |  |  |       class TestClass { | 
					
						
							|  |  |  |         myTimeout(callback: Function) {} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       fakeAsyncTestZone = Zone.current.fork(testZoneSpec); | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let ran = false; | 
					
						
							|  |  |  |         patchMacroTask( | 
					
						
							|  |  |  |             TestClass.prototype, 'myTimeout', | 
					
						
							|  |  |  |             (self: any, args: any[]) => | 
					
						
							|  |  |  |                 ({name: 'TestClass.myTimeout', target: self, cbIdx: 0, args: args})); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const testClass = new TestClass(); | 
					
						
							|  |  |  |         testClass.myTimeout(function(callbackArgs: any) { | 
					
						
							|  |  |  |           ran = true; | 
					
						
							|  |  |  |           expect(callbackArgs).toEqual('test'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(); | 
					
						
							|  |  |  |         expect(ran).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should support custom non perodic macroTask by global flag', () => { | 
					
						
							|  |  |  |       testZoneSpec = new FakeAsyncTestZoneSpec('name'); | 
					
						
							|  |  |  |       class TestClass { | 
					
						
							|  |  |  |         myTimeout(callback: Function) {} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       fakeAsyncTestZone = Zone.current.fork(testZoneSpec); | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let ran = false; | 
					
						
							|  |  |  |         patchMacroTask( | 
					
						
							|  |  |  |             TestClass.prototype, 'myTimeout', | 
					
						
							|  |  |  |             (self: any, args: any[]) => | 
					
						
							|  |  |  |                 ({name: 'TestClass.myTimeout', target: self, cbIdx: 0, args: args})); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const testClass = new TestClass(); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         testClass.myTimeout(() => { | 
					
						
							|  |  |  |           ran = true; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(); | 
					
						
							|  |  |  |         expect(ran).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should support custom perodic macroTask', () => { | 
					
						
							|  |  |  |       testZoneSpec = new FakeAsyncTestZoneSpec( | 
					
						
							|  |  |  |           'name', false, [{source: 'TestClass.myInterval', isPeriodic: true}]); | 
					
						
							|  |  |  |       fakeAsyncTestZone = Zone.current.fork(testZoneSpec); | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         let cycle = 0; | 
					
						
							|  |  |  |         class TestClass { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |           myInterval(callback: Function, interval: number): any { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         } | 
					
						
							|  |  |  |         patchMacroTask( | 
					
						
							|  |  |  |             TestClass.prototype, 'myInterval', | 
					
						
							|  |  |  |             (self: any, args: any[]) => | 
					
						
							|  |  |  |                 ({name: 'TestClass.myInterval', target: self, cbIdx: 0, args: args})); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const testClass = new TestClass(); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         const id = testClass.myInterval(() => { | 
					
						
							|  |  |  |           cycle++; | 
					
						
							|  |  |  |         }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(cycle).toEqual(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycle).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         testZoneSpec.tick(10); | 
					
						
							|  |  |  |         expect(cycle).toEqual(2); | 
					
						
							|  |  |  |         clearInterval(id); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('return promise', () => { | 
					
						
							|  |  |  |     let log: string[]; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       log = []; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should wait for promise to resolve', () => { | 
					
						
							| 
									
										
										
										
											2020-11-04 19:58:29 -05:00
										 |  |  |       return new Promise<void>((res, _) => { | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           log.push('resolved'); | 
					
						
							|  |  |  |           res(); | 
					
						
							|  |  |  |         }, 100); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     afterEach(() => { | 
					
						
							|  |  |  |       expect(log).toEqual(['resolved']); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('fakeAsyncTest should patch Date', () => { | 
					
						
							|  |  |  |     let FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec']; | 
					
						
							|  |  |  |     let testZoneSpec: any; | 
					
						
							|  |  |  |     let fakeAsyncTestZone: Zone; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       testZoneSpec = new FakeAsyncTestZoneSpec('name', false); | 
					
						
							|  |  |  |       fakeAsyncTestZone = Zone.current.fork(testZoneSpec); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should get date diff correctly', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         const start = Date.now(); | 
					
						
							|  |  |  |         testZoneSpec.tick(100); | 
					
						
							|  |  |  |         const end = Date.now(); | 
					
						
							|  |  |  |         expect(end - start).toBe(100); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should check date type correctly', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         const d: any = new Date(); | 
					
						
							|  |  |  |         expect(d instanceof Date).toBe(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should new Date with parameter correctly', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         const d: Date = new Date(0); | 
					
						
							|  |  |  |         expect(d.getFullYear()).toBeLessThan(1971); | 
					
						
							|  |  |  |         const d1: Date = new Date('December 17, 1995 03:24:00'); | 
					
						
							|  |  |  |         expect(d1.getFullYear()).toEqual(1995); | 
					
						
							|  |  |  |         const d2: Date = new Date(1995, 11, 17, 3, 24, 0); | 
					
						
							|  |  |  |         expect(d2.getFullYear()).toEqual(1995); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d2.setFullYear(1985); | 
					
						
							|  |  |  |         expect(isNaN(d2.getTime())).toBeFalsy(); | 
					
						
							|  |  |  |         expect(d2.getFullYear()).toBe(1985); | 
					
						
							|  |  |  |         expect(d2.getMonth()).toBe(11); | 
					
						
							|  |  |  |         expect(d2.getDate()).toBe(17); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should get Date.UTC() correctly', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         const utcDate = new Date(Date.UTC(96, 11, 1, 0, 0, 0)); | 
					
						
							|  |  |  |         expect(utcDate.getFullYear()).toBe(1996); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should call Date.parse() correctly', () => { | 
					
						
							|  |  |  |       fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |         const unixTimeZero = Date.parse('01 Jan 1970 00:00:00 GMT'); | 
					
						
							|  |  |  |         expect(unixTimeZero).toBe(0); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe( | 
					
						
							|  |  |  |       'fakeAsyncTest should work without patch jasmine.clock', | 
					
						
							|  |  |  |       ifEnvSupports( | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |           () => { | 
					
						
							|  |  |  |             return !supportClock() && supportNode(); | 
					
						
							|  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |           () => { | 
					
						
							|  |  |  |             const fakeAsync = (Zone as any)[Zone.__symbol__('fakeAsyncTest')].fakeAsync; | 
					
						
							|  |  |  |             let spy: any; | 
					
						
							|  |  |  |             beforeEach(() => { | 
					
						
							|  |  |  |               spy = jasmine.createSpy('timer'); | 
					
						
							|  |  |  |               jasmine.clock().install(); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |             afterEach(() => { | 
					
						
							|  |  |  |               jasmine.clock().uninstall(); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |             it('should check date type correctly', fakeAsync(() => { | 
					
						
							|  |  |  |                  const d: any = new Date(); | 
					
						
							|  |  |  |                  expect(d instanceof Date).toBe(true); | 
					
						
							|  |  |  |                })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should check date type correctly without fakeAsync', () => { | 
					
						
							|  |  |  |               const d: any = new Date(); | 
					
						
							|  |  |  |               expect(d instanceof Date).toBe(true); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should tick correctly', fakeAsync(() => { | 
					
						
							|  |  |  |                  jasmine.clock().mockDate(); | 
					
						
							|  |  |  |                  const start = Date.now(); | 
					
						
							|  |  |  |                  jasmine.clock().tick(100); | 
					
						
							|  |  |  |                  const end = Date.now(); | 
					
						
							|  |  |  |                  expect(end - start).toBe(100); | 
					
						
							|  |  |  |                })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should tick correctly without fakeAsync', () => { | 
					
						
							|  |  |  |               jasmine.clock().mockDate(); | 
					
						
							|  |  |  |               const start = Date.now(); | 
					
						
							|  |  |  |               jasmine.clock().tick(100); | 
					
						
							|  |  |  |               const end = Date.now(); | 
					
						
							|  |  |  |               expect(end - start).toBe(100); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should mock date correctly', fakeAsync(() => { | 
					
						
							|  |  |  |                  const baseTime = new Date(2013, 9, 23); | 
					
						
							|  |  |  |                  jasmine.clock().mockDate(baseTime); | 
					
						
							|  |  |  |                  const start = Date.now(); | 
					
						
							|  |  |  |                  expect(start).toBe(baseTime.getTime()); | 
					
						
							|  |  |  |                  jasmine.clock().tick(100); | 
					
						
							|  |  |  |                  const end = Date.now(); | 
					
						
							|  |  |  |                  expect(end - start).toBe(100); | 
					
						
							|  |  |  |                  expect(end).toBe(baseTime.getTime() + 100); | 
					
						
							|  |  |  |                  expect(new Date().getFullYear()).toEqual(2013); | 
					
						
							|  |  |  |                })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should mock date correctly without fakeAsync', () => { | 
					
						
							|  |  |  |               const baseTime = new Date(2013, 9, 23); | 
					
						
							|  |  |  |               jasmine.clock().mockDate(baseTime); | 
					
						
							|  |  |  |               const start = Date.now(); | 
					
						
							|  |  |  |               expect(start).toBe(baseTime.getTime()); | 
					
						
							|  |  |  |               jasmine.clock().tick(100); | 
					
						
							|  |  |  |               const end = Date.now(); | 
					
						
							|  |  |  |               expect(end - start).toBe(100); | 
					
						
							|  |  |  |               expect(end).toBe(baseTime.getTime() + 100); | 
					
						
							|  |  |  |               expect(new Date().getFullYear()).toEqual(2013); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should handle new Date correctly', fakeAsync(() => { | 
					
						
							|  |  |  |                  const baseTime = new Date(2013, 9, 23); | 
					
						
							|  |  |  |                  jasmine.clock().mockDate(baseTime); | 
					
						
							|  |  |  |                  const start = new Date(); | 
					
						
							|  |  |  |                  expect(start.getTime()).toBe(baseTime.getTime()); | 
					
						
							|  |  |  |                  jasmine.clock().tick(100); | 
					
						
							|  |  |  |                  const end = new Date(); | 
					
						
							|  |  |  |                  expect(end.getTime() - start.getTime()).toBe(100); | 
					
						
							|  |  |  |                  expect(end.getTime()).toBe(baseTime.getTime() + 100); | 
					
						
							|  |  |  |                })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should handle new Date correctly without fakeAsync', () => { | 
					
						
							|  |  |  |               const baseTime = new Date(2013, 9, 23); | 
					
						
							|  |  |  |               jasmine.clock().mockDate(baseTime); | 
					
						
							|  |  |  |               const start = new Date(); | 
					
						
							|  |  |  |               expect(start.getTime()).toBe(baseTime.getTime()); | 
					
						
							|  |  |  |               jasmine.clock().tick(100); | 
					
						
							|  |  |  |               const end = new Date(); | 
					
						
							|  |  |  |               expect(end.getTime() - start.getTime()).toBe(100); | 
					
						
							|  |  |  |               expect(end.getTime()).toBe(baseTime.getTime() + 100); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should handle setTimeout correctly', fakeAsync(() => { | 
					
						
							|  |  |  |                  setTimeout(spy, 100); | 
					
						
							|  |  |  |                  expect(spy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |                  jasmine.clock().tick(100); | 
					
						
							|  |  |  |                  expect(spy).toHaveBeenCalled(); | 
					
						
							|  |  |  |                })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it('should handle setTimeout correctly without fakeAsync', () => { | 
					
						
							|  |  |  |               setTimeout(spy, 100); | 
					
						
							|  |  |  |               expect(spy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |               jasmine.clock().tick(100); | 
					
						
							|  |  |  |               expect(spy).toHaveBeenCalled(); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('fakeAsyncTest should patch jasmine.clock', ifEnvSupports(supportClock, () => { | 
					
						
							|  |  |  |              let spy: any; | 
					
						
							|  |  |  |              beforeEach(() => { | 
					
						
							|  |  |  |                spy = jasmine.createSpy('timer'); | 
					
						
							|  |  |  |                jasmine.clock().install(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |              afterEach(() => { | 
					
						
							|  |  |  |                jasmine.clock().uninstall(); | 
					
						
							|  |  |  |              }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |              it('should check date type correctly', () => { | 
					
						
							|  |  |  |                const d: any = new Date(); | 
					
						
							|  |  |  |                expect(d instanceof Date).toBe(true); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              it('should get date diff correctly', () => { | 
					
						
							|  |  |  |                const start = Date.now(); | 
					
						
							|  |  |  |                jasmine.clock().tick(100); | 
					
						
							|  |  |  |                const end = Date.now(); | 
					
						
							|  |  |  |                expect(end - start).toBe(100); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              it('should tick correctly', () => { | 
					
						
							|  |  |  |                const start = Date.now(); | 
					
						
							|  |  |  |                jasmine.clock().tick(100); | 
					
						
							|  |  |  |                const end = Date.now(); | 
					
						
							|  |  |  |                expect(end - start).toBe(100); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              it('should mock date correctly', () => { | 
					
						
							|  |  |  |                const baseTime = new Date(2013, 9, 23); | 
					
						
							|  |  |  |                jasmine.clock().mockDate(baseTime); | 
					
						
							|  |  |  |                const start = Date.now(); | 
					
						
							|  |  |  |                expect(start).toBe(baseTime.getTime()); | 
					
						
							|  |  |  |                jasmine.clock().tick(100); | 
					
						
							|  |  |  |                const end = Date.now(); | 
					
						
							|  |  |  |                expect(end - start).toBe(100); | 
					
						
							|  |  |  |                expect(end).toBe(baseTime.getTime() + 100); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              it('should handle new Date correctly', () => { | 
					
						
							|  |  |  |                const baseTime = new Date(2013, 9, 23); | 
					
						
							|  |  |  |                jasmine.clock().mockDate(baseTime); | 
					
						
							|  |  |  |                const start = new Date(); | 
					
						
							|  |  |  |                expect(start.getTime()).toBe(baseTime.getTime()); | 
					
						
							|  |  |  |                jasmine.clock().tick(100); | 
					
						
							|  |  |  |                const end = new Date(); | 
					
						
							|  |  |  |                expect(end.getTime() - start.getTime()).toBe(100); | 
					
						
							|  |  |  |                expect(end.getTime()).toBe(baseTime.getTime() + 100); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              it('should handle setTimeout correctly', () => { | 
					
						
							|  |  |  |                setTimeout(spy, 100); | 
					
						
							|  |  |  |                expect(spy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |                jasmine.clock().tick(100); | 
					
						
							|  |  |  |                expect(spy).toHaveBeenCalled(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('fakeAsyncTest should patch rxjs scheduler', ifEnvSupports(supportClock, () => { | 
					
						
							|  |  |  |              let FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec']; | 
					
						
							|  |  |  |              let testZoneSpec: any; | 
					
						
							|  |  |  |              let fakeAsyncTestZone: Zone; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              beforeEach(() => { | 
					
						
							|  |  |  |                testZoneSpec = new FakeAsyncTestZoneSpec('name', false); | 
					
						
							|  |  |  |                fakeAsyncTestZone = Zone.current.fork(testZoneSpec); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              it('should get date diff correctly', (done) => { | 
					
						
							|  |  |  |                fakeAsyncTestZone.run(() => { | 
					
						
							|  |  |  |                  let result: any = null; | 
					
						
							|  |  |  |                  const observable = new Observable((subscribe: any) => { | 
					
						
							|  |  |  |                    subscribe.next('hello'); | 
					
						
							|  |  |  |                    subscribe.complete(); | 
					
						
							|  |  |  |                  }); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |                  observable.pipe(delay(1000)).subscribe((v: any) => { | 
					
						
							|  |  |  |                    result = v; | 
					
						
							|  |  |  |                  }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |                  expect(result).toBe(null); | 
					
						
							|  |  |  |                  testZoneSpec.tick(1000); | 
					
						
							|  |  |  |                  expect(result).toBe('hello'); | 
					
						
							|  |  |  |                  done(); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Log { | 
					
						
							|  |  |  |   logItems: any[]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   constructor() { | 
					
						
							|  |  |  |     this.logItems = []; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   add(value: any /** TODO #9100 */): void { | 
					
						
							|  |  |  |     this.logItems.push(value); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |   fn(value: any /** TODO #9100 */) { | 
					
						
							|  |  |  |     return (a1: any = null, a2: any = null, a3: any = null, a4: any = null, a5: any = null) => { | 
					
						
							|  |  |  |       this.logItems.push(value); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   clear(): void { | 
					
						
							|  |  |  |     this.logItems = []; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   result(): string { | 
					
						
							|  |  |  |     return this.logItems.join('; '); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const resolvedPromise = Promise.resolve(null); | 
					
						
							|  |  |  | const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec']; | 
					
						
							|  |  |  | const fakeAsyncTestModule = (Zone as any)[Zone.__symbol__('fakeAsyncTest')]; | 
					
						
							|  |  |  | const {fakeAsync, tick, discardPeriodicTasks, flush, flushMicrotasks} = fakeAsyncTestModule; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   describe('fake async', () => { | 
					
						
							|  |  |  |     it('should run synchronous code', () => { | 
					
						
							|  |  |  |       let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       fakeAsync(() => { | 
					
						
							|  |  |  |         ran = true; | 
					
						
							|  |  |  |       })(); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(ran).toEqual(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should pass arguments to the wrapped function', () => { | 
					
						
							|  |  |  |       fakeAsync((foo: any /** TODO #9100 */, bar: any /** TODO #9100 */) => { | 
					
						
							|  |  |  |         expect(foo).toEqual('foo'); | 
					
						
							|  |  |  |         expect(bar).toEqual('bar'); | 
					
						
							|  |  |  |       })('foo', 'bar'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw on nested calls', () => { | 
					
						
							|  |  |  |       expect(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         fakeAsync(() => { | 
					
						
							|  |  |  |           fakeAsync((): any /** TODO #9100 */ => null)(); | 
					
						
							|  |  |  |         })(); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }).toThrowError('fakeAsync() calls can not be nested'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should flush microtasks before returning', () => { | 
					
						
							|  |  |  |       let thenRan = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       fakeAsync(() => { | 
					
						
							|  |  |  |         resolvedPromise.then(_ => { | 
					
						
							|  |  |  |           thenRan = true; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       })(); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(thenRan).toEqual(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     it('should propagate the return value', () => { | 
					
						
							|  |  |  |       expect(fakeAsync(() => 'foo')()).toEqual('foo'); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('Promise', () => { | 
					
						
							|  |  |  |       it('should run asynchronous code', fakeAsync(() => { | 
					
						
							|  |  |  |            let thenRan = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            resolvedPromise.then((_) => { | 
					
						
							|  |  |  |              thenRan = true; | 
					
						
							|  |  |  |            }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            expect(thenRan).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            flushMicrotasks(); | 
					
						
							|  |  |  |            expect(thenRan).toEqual(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run chained thens', fakeAsync(() => { | 
					
						
							|  |  |  |            const log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            resolvedPromise.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(() => { | 
					
						
							|  |  |  |            const log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            resolvedPromise.then((_) => { | 
					
						
							|  |  |  |              log.add(1); | 
					
						
							|  |  |  |              resolvedPromise.then((_) => log.add(2)); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(log.result()).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            flushMicrotasks(); | 
					
						
							|  |  |  |            expect(log.result()).toEqual('1; 2'); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should complain if the test throws an exception during async calls', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           fakeAsync(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |             resolvedPromise.then((_) => { | 
					
						
							|  |  |  |               throw new Error('async'); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |             flushMicrotasks(); | 
					
						
							|  |  |  |           })(); | 
					
						
							| 
									
										
										
										
											2019-07-30 14:35:30 -07:00
										 |  |  |         }).toThrowError(/Uncaught \(in promise\): Error: async/); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should complain if a test throws an exception', () => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         expect(() => { | 
					
						
							|  |  |  |           fakeAsync(() => { | 
					
						
							|  |  |  |             throw new Error('sync'); | 
					
						
							|  |  |  |           })(); | 
					
						
							|  |  |  |         }).toThrowError('sync'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('timers', () => { | 
					
						
							|  |  |  |       it('should run queued zero duration timer on zero tick', fakeAsync(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }, 0); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(); | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run queued timer after sufficient clock ticks', fakeAsync(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            tick(6); | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(6); | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run queued timer only once', fakeAsync(() => { | 
					
						
							|  |  |  |            let cycles = 0; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              cycles++; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            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(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            const id = setTimeout(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |            clearTimeout(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should throw an error on dangling timers', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |           fakeAsync(() => { | 
					
						
							|  |  |  |             setTimeout(() => {}, 10); | 
					
						
							|  |  |  |           })(); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         }).toThrowError('1 timer(s) still in the queue.'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should throw an error on dangling periodic timers', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |           fakeAsync(() => { | 
					
						
							|  |  |  |             setInterval(() => {}, 10); | 
					
						
							|  |  |  |           })(); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         }).toThrowError('1 periodic timer(s) still in the queue.'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should run periodic timers', fakeAsync(() => { | 
					
						
							|  |  |  |            let cycles = 0; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            const id = setInterval(() => { | 
					
						
							|  |  |  |              cycles++; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(3); | 
					
						
							|  |  |  |            clearInterval(id); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not run cancelled periodic timer', fakeAsync(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            const id = setInterval(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |            clearInterval(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(ran).toEqual(false); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should be able to cancel periodic timers from a callback', fakeAsync(() => { | 
					
						
							|  |  |  |            let cycles = 0; | 
					
						
							|  |  |  |            let id: any /** TODO #9100 */; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            id = setInterval(() => { | 
					
						
							|  |  |  |              cycles++; | 
					
						
							|  |  |  |              clearInterval(id); | 
					
						
							|  |  |  |            }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should clear periodic timers', fakeAsync(() => { | 
					
						
							|  |  |  |            let cycles = 0; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            const id = setInterval(() => { | 
					
						
							|  |  |  |              cycles++; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            discardPeriodicTasks(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            // Tick once to clear out the timer which already started.
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(cycles).toEqual(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            // Nothing should change
 | 
					
						
							|  |  |  |            expect(cycles).toEqual(2); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should process microtasks before timers', fakeAsync(() => { | 
					
						
							|  |  |  |            const log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            resolvedPromise.then((_) => log.add('microtask')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            setTimeout(() => log.add('timer'), 9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            const id = setInterval(() => log.add('periodic timer'), 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(log.result()).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            tick(10); | 
					
						
							|  |  |  |            expect(log.result()).toEqual('microtask; timer; periodic timer'); | 
					
						
							|  |  |  |            clearInterval(id); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should process micro-tasks created in timers before next timers', fakeAsync(() => { | 
					
						
							|  |  |  |            const log = new Log(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            resolvedPromise.then((_) => log.add('microtask')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              log.add('timer'); | 
					
						
							|  |  |  |              resolvedPromise.then((_) => log.add('t microtask')); | 
					
						
							|  |  |  |            }, 9); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            const id = setInterval(() => { | 
					
						
							|  |  |  |              log.add('periodic timer'); | 
					
						
							|  |  |  |              resolvedPromise.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'); | 
					
						
							|  |  |  |            clearInterval(id); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should flush tasks', fakeAsync(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            flush(); | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should flush multiple tasks', fakeAsync(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							|  |  |  |            let ran2 = false; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							|  |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              ran2 = true; | 
					
						
							|  |  |  |            }, 30); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            let elapsed = flush(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |            expect(ran2).toEqual(true); | 
					
						
							|  |  |  |            expect(elapsed).toEqual(30); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should move periodic tasks', fakeAsync(() => { | 
					
						
							|  |  |  |            let ran = false; | 
					
						
							|  |  |  |            let count = 0; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |            setInterval(() => { | 
					
						
							|  |  |  |              count++; | 
					
						
							|  |  |  |            }, 10); | 
					
						
							|  |  |  |            setTimeout(() => { | 
					
						
							|  |  |  |              ran = true; | 
					
						
							|  |  |  |            }, 35); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |            let elapsed = flush(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(count).toEqual(3); | 
					
						
							|  |  |  |            expect(ran).toEqual(true); | 
					
						
							|  |  |  |            expect(elapsed).toEqual(35); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            discardPeriodicTasks(); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('outside of the fakeAsync zone', () => { | 
					
						
							|  |  |  |       it('calling flushMicrotasks should throw', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           flushMicrotasks(); | 
					
						
							|  |  |  |         }).toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('calling tick should throw', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           tick(); | 
					
						
							|  |  |  |         }).toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('calling flush should throw', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           flush(); | 
					
						
							|  |  |  |         }).toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('calling discardPeriodicTasks should throw', () => { | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           discardPeriodicTasks(); | 
					
						
							|  |  |  |         }).toThrowError('The code should be running in the fakeAsync zone to call this function'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('only one `fakeAsync` zone per test', () => { | 
					
						
							|  |  |  |       let zoneInBeforeEach: Zone; | 
					
						
							|  |  |  |       let zoneInTest1: Zone; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       beforeEach(fakeAsync(() => { | 
					
						
							|  |  |  |         zoneInBeforeEach = Zone.current; | 
					
						
							|  |  |  |       })); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should use the same zone as in beforeEach', fakeAsync(() => { | 
					
						
							|  |  |  |            zoneInTest1 = Zone.current; | 
					
						
							|  |  |  |            expect(zoneInTest1).toBe(zoneInBeforeEach); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('fakeAsync should work with Date', () => { | 
					
						
							|  |  |  |       it('should get date diff correctly', fakeAsync(() => { | 
					
						
							|  |  |  |            const start = Date.now(); | 
					
						
							|  |  |  |            tick(100); | 
					
						
							|  |  |  |            const end = Date.now(); | 
					
						
							|  |  |  |            expect(end - start).toBe(100); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should check date type correctly', fakeAsync(() => { | 
					
						
							|  |  |  |            const d: any = new Date(); | 
					
						
							|  |  |  |            expect(d instanceof Date).toBe(true); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should new Date with parameter correctly', fakeAsync(() => { | 
					
						
							|  |  |  |            const d: Date = new Date(0); | 
					
						
							|  |  |  |            expect(d.getFullYear()).toBeLessThan(1971); | 
					
						
							|  |  |  |            const d1: Date = new Date('December 17, 1995 03:24:00'); | 
					
						
							|  |  |  |            expect(d1.getFullYear()).toEqual(1995); | 
					
						
							|  |  |  |            const d2: Date = new Date(1995, 11, 17, 3, 24, 0); | 
					
						
							|  |  |  |            expect(isNaN(d2.getTime())).toBeFalsy(); | 
					
						
							|  |  |  |            expect(d2.getFullYear()).toEqual(1995); | 
					
						
							|  |  |  |            d2.setFullYear(1985); | 
					
						
							|  |  |  |            expect(d2.getFullYear()).toBe(1985); | 
					
						
							|  |  |  |            expect(d2.getMonth()).toBe(11); | 
					
						
							|  |  |  |            expect(d2.getDate()).toBe(17); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should get Date.UTC() correctly', fakeAsync(() => { | 
					
						
							|  |  |  |            const utcDate = new Date(Date.UTC(96, 11, 1, 0, 0, 0)); | 
					
						
							|  |  |  |            expect(utcDate.getFullYear()).toBe(1996); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should call Date.parse() correctly', fakeAsync(() => { | 
					
						
							|  |  |  |            const unixTimeZero = Date.parse('01 Jan 1970 00:00:00 GMT'); | 
					
						
							|  |  |  |            expect(unixTimeZero).toBe(0); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('ProxyZone', () => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       ProxyZoneSpec.assertPresent(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     afterEach(() => { | 
					
						
							|  |  |  |       ProxyZoneSpec.assertPresent(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should allow fakeAsync zone to retroactively set a zoneSpec outside of fakeAsync', () => { | 
					
						
							|  |  |  |       ProxyZoneSpec.assertPresent(); | 
					
						
							|  |  |  |       let state: string = 'not run'; | 
					
						
							|  |  |  |       const testZone = Zone.current.fork({name: 'test-zone'}); | 
					
						
							|  |  |  |       (fakeAsync(() => { | 
					
						
							|  |  |  |         testZone.run(() => { | 
					
						
							|  |  |  |           Promise.resolve('works').then((v) => state = v); | 
					
						
							|  |  |  |           expect(state).toEqual('not run'); | 
					
						
							|  |  |  |           flushMicrotasks(); | 
					
						
							|  |  |  |           expect(state).toEqual('works'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }))(); | 
					
						
							|  |  |  |       expect(state).toEqual('works'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } |