fix(fake_async): share zone between beforeEach
and it
This is needed for the case if a `beforeEach` instantiates `NgZone`and the `it` uses `TestComponentBuilder.createFakeAsync`. Otherwise the `NgZone` will use the root zone as parent, and `TestComponentBuilder.createFakeAsync` will always return undefined as `tick` does not forward promises created under the zone of `NgZone`.
This commit is contained in:
parent
3ce11ed58c
commit
16cc9b46aa
@ -285,5 +285,21 @@ export function main() {
|
|||||||
}).toThrowError('The code should be running in the fakeAsync zone to call this function');
|
}).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;
|
||||||
|
beforeEach(fakeAsync(() => { zoneInBeforeEach = Zone.current; }));
|
||||||
|
|
||||||
|
it('should use the same zone as in beforeEach', fakeAsync(() => {
|
||||||
|
zoneInTest1 = Zone.current;
|
||||||
|
expect(zoneInTest1).toBe(zoneInBeforeEach);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should use a different zone between tests', fakeAsync(() => {
|
||||||
|
expect(Zone.current).toBe(zoneInBeforeEach);
|
||||||
|
expect(Zone.current).not.toBe(zoneInTest1);
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,22 @@ import {BaseException} from '../index';
|
|||||||
|
|
||||||
let _FakeAsyncTestZoneSpecType = (Zone as any /** TODO #9100 */)['FakeAsyncTestZoneSpec'];
|
let _FakeAsyncTestZoneSpecType = (Zone as any /** TODO #9100 */)['FakeAsyncTestZoneSpec'];
|
||||||
|
|
||||||
|
let _fakeAsyncZone: Zone = null;
|
||||||
|
let _fakeAsyncTestZoneSpec: any = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears out the shared fake async zone for a test.
|
||||||
|
* To be called in a global `beforeEach`.
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export function resetFakeAsyncZone() {
|
||||||
|
_fakeAsyncZone = null;
|
||||||
|
_fakeAsyncTestZoneSpec = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _inFakeAsyncCall = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps a function to be executed in the fakeAsync zone:
|
* Wraps a function to be executed in the fakeAsync zone:
|
||||||
* - microtasks are manually executed by calling `flushMicrotasks()`,
|
* - microtasks are manually executed by calling `flushMicrotasks()`,
|
||||||
@ -29,40 +45,49 @@ let _FakeAsyncTestZoneSpecType = (Zone as any /** TODO #9100 */)['FakeAsyncTestZ
|
|||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export function fakeAsync(fn: Function): (...args: any[]) => any {
|
export function fakeAsync(fn: Function): (...args: any[]) => any {
|
||||||
if (Zone.current.get('FakeAsyncTestZoneSpec') != null) {
|
|
||||||
throw new BaseException('fakeAsync() calls can not be nested');
|
|
||||||
}
|
|
||||||
|
|
||||||
let fakeAsyncTestZoneSpec = new _FakeAsyncTestZoneSpecType();
|
|
||||||
let fakeAsyncZone = Zone.current.fork(fakeAsyncTestZoneSpec);
|
|
||||||
|
|
||||||
return function(...args: any[] /** TODO #9100 */) {
|
return function(...args: any[] /** TODO #9100 */) {
|
||||||
let res = fakeAsyncZone.run(() => {
|
if (_inFakeAsyncCall) {
|
||||||
let res = fn(...args);
|
throw new BaseException('fakeAsync() calls can not be nested');
|
||||||
flushMicrotasks();
|
}
|
||||||
|
_inFakeAsyncCall = true;
|
||||||
|
try {
|
||||||
|
if (!_fakeAsyncZone) {
|
||||||
|
if (Zone.current.get('FakeAsyncTestZoneSpec') != null) {
|
||||||
|
throw new BaseException('fakeAsync() calls can not be nested');
|
||||||
|
}
|
||||||
|
|
||||||
|
_fakeAsyncTestZoneSpec = new _FakeAsyncTestZoneSpecType();
|
||||||
|
_fakeAsyncZone = Zone.current.fork(_fakeAsyncTestZoneSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = _fakeAsyncZone.run(() => {
|
||||||
|
let res = fn(...args);
|
||||||
|
flushMicrotasks();
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) {
|
||||||
|
throw new BaseException(
|
||||||
|
`${_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length} ` +
|
||||||
|
`periodic timer(s) still in the queue.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_fakeAsyncTestZoneSpec.pendingTimers.length > 0) {
|
||||||
|
throw new BaseException(
|
||||||
|
`${_fakeAsyncTestZoneSpec.pendingTimers.length} timer(s) still in the queue.`);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
});
|
} finally {
|
||||||
|
_inFakeAsyncCall = false;
|
||||||
if (fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) {
|
|
||||||
throw new BaseException(
|
|
||||||
`${fakeAsyncTestZoneSpec.pendingPeriodicTimers.length} ` +
|
|
||||||
`periodic timer(s) still in the queue.`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fakeAsyncTestZoneSpec.pendingTimers.length > 0) {
|
|
||||||
throw new BaseException(
|
|
||||||
`${fakeAsyncTestZoneSpec.pendingTimers.length} timer(s) still in the queue.`);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getFakeAsyncZoneSpec(): any {
|
function _getFakeAsyncZoneSpec(): any {
|
||||||
let zoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
|
if (_fakeAsyncTestZoneSpec == null) {
|
||||||
if (zoneSpec == null) {
|
|
||||||
throw new Error('The code should be running in the fakeAsync zone to call this function');
|
throw new Error('The code should be running in the fakeAsync zone to call this function');
|
||||||
}
|
}
|
||||||
return zoneSpec;
|
return _fakeAsyncTestZoneSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,15 +14,19 @@
|
|||||||
|
|
||||||
import {SchemaMetadata} from '../index';
|
import {SchemaMetadata} from '../index';
|
||||||
|
|
||||||
|
import {resetFakeAsyncZone} from './fake_async';
|
||||||
import {TestBed, TestModuleMetadata, getTestBed} from './test_bed';
|
import {TestBed, TestModuleMetadata, getTestBed} from './test_bed';
|
||||||
|
|
||||||
declare var global: any;
|
declare var global: any;
|
||||||
|
|
||||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||||
|
|
||||||
// Reset the test providers before each test.
|
// Reset the test providers and the fake async zone before each test.
|
||||||
if (_global.beforeEach) {
|
if (_global.beforeEach) {
|
||||||
_global.beforeEach(() => { TestBed.resetTestingModule(); });
|
_global.beforeEach(() => {
|
||||||
|
TestBed.resetTestingModule();
|
||||||
|
resetFakeAsyncZone();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user