2019-05-31 11:56:07 -04:00
|
|
|
/**
|
|
|
|
* @license
|
2020-05-19 15:08:49 -04:00
|
|
|
* Copyright Google LLC All Rights Reserved.
|
2019-05-31 11:56:07 -04: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 19:40:21 -04:00
|
|
|
it('should expose ProxyZone in the properties', () => {
|
|
|
|
expect(proxyZone.get('ProxyZoneSpec')).toBe(proxyZoneSpec);
|
|
|
|
});
|
2019-05-31 11:56:07 -04: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 19:40:21 -04: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-05-31 11:56:07 -04: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 19:40:21 -04:00
|
|
|
onIntercept:
|
|
|
|
(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
|
|
|
|
delegate: Function, source: string): Function => {
|
|
|
|
return () => '(works)';
|
|
|
|
}
|
2019-05-31 11:56:07 -04: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 19:40:21 -04:00
|
|
|
onInvoke:
|
|
|
|
(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
|
|
|
|
delegate: Function, applyThis: any, applyArgs: any[], source: string) => {
|
|
|
|
return `(${
|
2019-05-31 11:56:07 -04:00
|
|
|
parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source)})`;
|
2020-04-13 19:40:21 -04:00
|
|
|
}
|
2019-05-31 11:56:07 -04:00
|
|
|
});
|
|
|
|
expect(proxyZone.run(fn)).toEqual('(works)');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handleError', () => {
|
|
|
|
const error = new Error('TestError');
|
2020-04-13 19:40:21 -04:00
|
|
|
const fn = () => {
|
|
|
|
throw error;
|
|
|
|
};
|
2019-05-31 11:56:07 -04:00
|
|
|
expect(() => proxyZone.run(fn)).toThrow(error);
|
|
|
|
proxyZoneSpec.setDelegate({
|
|
|
|
name: '.',
|
2020-04-13 19:40:21 -04:00
|
|
|
onHandleError:
|
|
|
|
(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any):
|
|
|
|
boolean => {
|
|
|
|
expect(error).toEqual(error);
|
|
|
|
return false;
|
|
|
|
}
|
2019-05-31 11:56:07 -04: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 19:40:21 -04:00
|
|
|
beforeEach(() => {
|
|
|
|
log = [];
|
|
|
|
});
|
2019-05-31 11:56:07 -04: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 19:40:21 -04:00
|
|
|
proxyZone.run(() => {
|
|
|
|
setTimeout(() => {
|
|
|
|
log.push('timeout in zoneSpec1');
|
|
|
|
}, 50);
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
proxyZoneSpec.setDelegate(zoneSpec2);
|
2020-04-13 19:40:21 -04:00
|
|
|
proxyZone.run(() => {
|
|
|
|
Promise.resolve(1).then(() => {
|
|
|
|
log.push('then in zoneSpec2');
|
|
|
|
});
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
proxyZoneSpec.setDelegate(null);
|
2020-04-13 19:40:21 -04:00
|
|
|
proxyZone.run(() => {
|
|
|
|
setTimeout(() => {
|
|
|
|
log.push('timeout in null spec');
|
|
|
|
}, 50);
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
proxyZoneSpec.setDelegate(zoneSpec2);
|
2020-04-13 19:40:21 -04:00
|
|
|
proxyZone.run(() => {
|
|
|
|
Promise.resolve(1).then(() => {
|
|
|
|
log.push('then in zoneSpec2');
|
|
|
|
});
|
|
|
|
});
|
2019-05-31 11:56:07 -04: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);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|