| 
									
										
										
										
											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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('ProxySpec', () => { | 
					
						
							|  |  |  |   let ProxyZoneSpec: any; | 
					
						
							|  |  |  |   let delegate: ZoneSpec; | 
					
						
							|  |  |  |   let proxyZoneSpec: any; | 
					
						
							|  |  |  |   let proxyZone: Zone; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     ProxyZoneSpec = (Zone as any)['ProxyZoneSpec']; | 
					
						
							|  |  |  |     expect(typeof ProxyZoneSpec).toBe('function'); | 
					
						
							|  |  |  |     delegate = {name: 'delegate'}; | 
					
						
							|  |  |  |     proxyZoneSpec = new ProxyZoneSpec(delegate); | 
					
						
							|  |  |  |     proxyZone = Zone.current.fork(proxyZoneSpec); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('properties', () => { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     it('should expose ProxyZone in the properties', () => { | 
					
						
							|  |  |  |       expect(proxyZone.get('ProxyZoneSpec')).toBe(proxyZoneSpec); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should assert that it is in or out of ProxyZone', () => { | 
					
						
							|  |  |  |       let rootZone = Zone.current; | 
					
						
							|  |  |  |       while (rootZone.parent) { | 
					
						
							|  |  |  |         rootZone = rootZone.parent; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       rootZone.run(() => { | 
					
						
							|  |  |  |         expect(() => ProxyZoneSpec.assertPresent()).toThrow(); | 
					
						
							|  |  |  |         expect(ProxyZoneSpec.isLoaded()).toBe(false); | 
					
						
							|  |  |  |         expect(ProxyZoneSpec.get()).toBe(undefined); | 
					
						
							|  |  |  |         proxyZone.run(() => { | 
					
						
							|  |  |  |           expect(ProxyZoneSpec.isLoaded()).toBe(true); | 
					
						
							|  |  |  |           expect(() => ProxyZoneSpec.assertPresent()).not.toThrow(); | 
					
						
							|  |  |  |           expect(ProxyZoneSpec.get()).toBe(proxyZoneSpec); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should reset properties', () => { | 
					
						
							|  |  |  |       expect(proxyZone.get('myTestKey')).toBe(undefined); | 
					
						
							|  |  |  |       proxyZoneSpec.setDelegate({name: 'd1', properties: {'myTestKey': 'myTestValue'}}); | 
					
						
							|  |  |  |       expect(proxyZone.get('myTestKey')).toBe('myTestValue'); | 
					
						
							|  |  |  |       proxyZoneSpec.resetDelegate(); | 
					
						
							|  |  |  |       expect(proxyZone.get('myTestKey')).toBe(undefined); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('delegate', () => { | 
					
						
							|  |  |  |     it('should set/reset delegate', () => { | 
					
						
							|  |  |  |       const defaultDelegate: ZoneSpec = {name: 'defaultDelegate'}; | 
					
						
							|  |  |  |       const otherDelegate: ZoneSpec = {name: 'otherDelegate'}; | 
					
						
							|  |  |  |       const proxyZoneSpec = new ProxyZoneSpec(defaultDelegate); | 
					
						
							|  |  |  |       const proxyZone = Zone.current.fork(proxyZoneSpec); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(proxyZoneSpec.getDelegate()).toEqual(defaultDelegate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       proxyZoneSpec.setDelegate(otherDelegate); | 
					
						
							|  |  |  |       expect(proxyZoneSpec.getDelegate()).toEqual(otherDelegate); | 
					
						
							|  |  |  |       proxyZoneSpec.resetDelegate(); | 
					
						
							|  |  |  |       expect(proxyZoneSpec.getDelegate()).toEqual(defaultDelegate); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('forwarding', () => { | 
					
						
							|  |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       proxyZoneSpec = new ProxyZoneSpec(); | 
					
						
							|  |  |  |       proxyZone = Zone.current.fork(proxyZoneSpec); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should fork', () => { | 
					
						
							|  |  |  |       const forkedZone = proxyZone.fork({name: 'fork'}); | 
					
						
							|  |  |  |       expect(forkedZone).not.toBe(proxyZone); | 
					
						
							|  |  |  |       expect(forkedZone.name).toBe('fork'); | 
					
						
							|  |  |  |       let called = false; | 
					
						
							|  |  |  |       proxyZoneSpec.setDelegate({ | 
					
						
							|  |  |  |         name: '.', | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         onFork: | 
					
						
							|  |  |  |             (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, | 
					
						
							|  |  |  |              zoneSpec: ZoneSpec) => { | 
					
						
							|  |  |  |               expect(currentZone).toBe(proxyZone); | 
					
						
							|  |  |  |               expect(targetZone).toBe(proxyZone), expect(zoneSpec.name).toBe('fork2'); | 
					
						
							|  |  |  |               called = true; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  |       proxyZone.fork({name: 'fork2'}); | 
					
						
							|  |  |  |       expect(called).toBe(true); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should intercept', () => { | 
					
						
							|  |  |  |       const fn = (a: any) => a; | 
					
						
							|  |  |  |       expect(proxyZone.wrap(fn, 'test')('works')).toEqual('works'); | 
					
						
							|  |  |  |       proxyZoneSpec.setDelegate({ | 
					
						
							|  |  |  |         name: '.', | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         onIntercept: | 
					
						
							|  |  |  |             (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, | 
					
						
							|  |  |  |              delegate: Function, source: string): Function => { | 
					
						
							|  |  |  |               return () => '(works)'; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  |       expect(proxyZone.wrap(fn, 'test')('works')).toEqual('(works)'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should invoke', () => { | 
					
						
							|  |  |  |       const fn = () => 'works'; | 
					
						
							|  |  |  |       expect(proxyZone.run(fn)).toEqual('works'); | 
					
						
							|  |  |  |       proxyZoneSpec.setDelegate({ | 
					
						
							|  |  |  |         name: '.', | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         onInvoke: | 
					
						
							|  |  |  |             (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, | 
					
						
							|  |  |  |              delegate: Function, applyThis: any, applyArgs: any[], source: string) => { | 
					
						
							|  |  |  |               return `(${ | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |                   parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source)})`;
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  |       expect(proxyZone.run(fn)).toEqual('(works)'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should handleError', () => { | 
					
						
							|  |  |  |       const error = new Error('TestError'); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       const fn = () => { | 
					
						
							|  |  |  |         throw error; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       expect(() => proxyZone.run(fn)).toThrow(error); | 
					
						
							|  |  |  |       proxyZoneSpec.setDelegate({ | 
					
						
							|  |  |  |         name: '.', | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         onHandleError: | 
					
						
							|  |  |  |             (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any): | 
					
						
							|  |  |  |                 boolean => { | 
					
						
							|  |  |  |                   expect(error).toEqual(error); | 
					
						
							|  |  |  |                   return false; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       }); | 
					
						
							|  |  |  |       expect(() => proxyZone.runGuarded(fn)).not.toThrow(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should Task', () => { | 
					
						
							|  |  |  |       const fn = (): any => null; | 
					
						
							|  |  |  |       const task = proxyZone.scheduleMacroTask('test', fn, {}, () => null, () => null); | 
					
						
							|  |  |  |       expect(task.source).toEqual('test'); | 
					
						
							|  |  |  |       proxyZone.cancelTask(task); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('delegateSpec change', () => { | 
					
						
							|  |  |  |     let log: string[] = []; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       log = []; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     it('should trigger hasTask when invoke', (done: Function) => { | 
					
						
							|  |  |  |       const zoneSpec1 = { | 
					
						
							|  |  |  |         name: 'zone1', | 
					
						
							|  |  |  |         onHasTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, hasTask: HasTaskState) => { | 
					
						
							|  |  |  |           log.push(`zoneSpec1 hasTask: ${hasTask.microTask},${hasTask.macroTask}`); | 
					
						
							|  |  |  |           return delegate.hasTask(target, hasTask); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       const zoneSpec2 = { | 
					
						
							|  |  |  |         name: 'zone2', | 
					
						
							|  |  |  |         onHasTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, hasTask: HasTaskState) => { | 
					
						
							|  |  |  |           log.push(`zoneSpec2 hasTask: ${hasTask.microTask},${hasTask.macroTask}`); | 
					
						
							|  |  |  |           return delegate.hasTask(target, hasTask); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       proxyZoneSpec.setDelegate(zoneSpec1); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       proxyZone.run(() => { | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           log.push('timeout in zoneSpec1'); | 
					
						
							|  |  |  |         }, 50); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       proxyZoneSpec.setDelegate(zoneSpec2); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       proxyZone.run(() => { | 
					
						
							|  |  |  |         Promise.resolve(1).then(() => { | 
					
						
							|  |  |  |           log.push('then in zoneSpec2'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       proxyZoneSpec.setDelegate(null); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       proxyZone.run(() => { | 
					
						
							|  |  |  |         setTimeout(() => { | 
					
						
							|  |  |  |           log.push('timeout in null spec'); | 
					
						
							|  |  |  |         }, 50); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       proxyZoneSpec.setDelegate(zoneSpec2); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       proxyZone.run(() => { | 
					
						
							|  |  |  |         Promise.resolve(1).then(() => { | 
					
						
							|  |  |  |           log.push('then in zoneSpec2'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |       setTimeout(() => { | 
					
						
							|  |  |  |         expect(log).toEqual([ | 
					
						
							|  |  |  |           'zoneSpec1 hasTask: false,true', 'zoneSpec2 hasTask: false,true', | 
					
						
							|  |  |  |           'zoneSpec2 hasTask: true,true', 'zoneSpec2 hasTask: true,true', 'then in zoneSpec2', | 
					
						
							|  |  |  |           'then in zoneSpec2', 'zoneSpec2 hasTask: false,true', 'timeout in zoneSpec1', | 
					
						
							|  |  |  |           'timeout in null spec', 'zoneSpec2 hasTask: false,false' | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |         done(); | 
					
						
							|  |  |  |       }, 300); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); |