fix(core): fix chained http call (#20924)
Fixes an issue where chained http calls would prematurely call testability whenStable callbacks after the first http call. Fixes #20921 PR Close #20924
This commit is contained in:
parent
fb4d84d5b8
commit
7e3f9a482a
|
@ -98,13 +98,22 @@ export class Testability implements PublicTestability {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_runCallbacksIfReady(): void {
|
_runCallbacksIfReady(): void {
|
||||||
if (this.isStable()) {
|
if (this.isStable()) {
|
||||||
// Schedules the call backs in a new frame so that it is always async.
|
if (this._callbacks.length !== 0) {
|
||||||
scheduleMicroTask(() => {
|
// Schedules the call backs after a macro task run outside of the angular zone to make sure
|
||||||
while (this._callbacks.length !== 0) {
|
// no new task are added
|
||||||
(this._callbacks.pop() !)(this._didWork);
|
this._ngZone.runOutsideAngular(() => {
|
||||||
}
|
setTimeout(() => {
|
||||||
|
if (this.isStable()) {
|
||||||
|
while (this._callbacks.length !== 0) {
|
||||||
|
(this._callbacks.pop() !)(this._didWork);
|
||||||
|
}
|
||||||
|
this._didWork = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
this._didWork = false;
|
this._didWork = false;
|
||||||
});
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not Ready
|
// Not Ready
|
||||||
this._didWork = true;
|
this._didWork = true;
|
||||||
|
|
|
@ -16,13 +16,11 @@ import {scheduleMicroTask} from '../../src/util';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Schedules a microtasks (using a resolved promise .then())
|
// Schedules a task to be run after Testability checks for oustanding tasks. Since Testability
|
||||||
function microTask(fn: Function): void {
|
// uses a 0 second timeout to check for outstanding tasks we add our 0 second timeout after a
|
||||||
scheduleMicroTask(() => {
|
// micro task (which ensures Testability's timeout is run first).
|
||||||
// We do double dispatch so that we can wait for scheduleMicrotask in the Testability when
|
function afterTestabilityCheck(fn: Function): void {
|
||||||
// NgZone becomes stable.
|
scheduleMicroTask(() => setTimeout(fn));
|
||||||
scheduleMicroTask(fn);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -65,7 +63,7 @@ class MockNgZone extends NgZone {
|
||||||
it('should fire whenstable callbacks if pending count is 0',
|
it('should fire whenstable callbacks if pending count is 0',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalled();
|
expect(execute).toHaveBeenCalled();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -82,11 +80,11 @@ class MockNgZone extends NgZone {
|
||||||
testability.increasePendingRequestCount();
|
testability.increasePendingRequestCount();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
testability.decreasePendingRequestCount();
|
testability.decreasePendingRequestCount();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -98,11 +96,11 @@ class MockNgZone extends NgZone {
|
||||||
testability.increasePendingRequestCount();
|
testability.increasePendingRequestCount();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
testability.decreasePendingRequestCount();
|
testability.decreasePendingRequestCount();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalled();
|
expect(execute).toHaveBeenCalled();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -120,7 +118,7 @@ class MockNgZone extends NgZone {
|
||||||
it('should fire whenstable callbacks with didWork if pending count is 0',
|
it('should fire whenstable callbacks with didWork if pending count is 0',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalledWith(false);
|
expect(execute).toHaveBeenCalledWith(false);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -131,14 +129,14 @@ class MockNgZone extends NgZone {
|
||||||
testability.increasePendingRequestCount();
|
testability.increasePendingRequestCount();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
testability.decreasePendingRequestCount();
|
testability.decreasePendingRequestCount();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalledWith(true);
|
expect(execute).toHaveBeenCalledWith(true);
|
||||||
testability.whenStable(execute2);
|
testability.whenStable(execute2);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute2).toHaveBeenCalledWith(false);
|
expect(execute2).toHaveBeenCalledWith(false);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -154,7 +152,7 @@ class MockNgZone extends NgZone {
|
||||||
ngZone.stable();
|
ngZone.stable();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalled();
|
expect(execute).toHaveBeenCalled();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -173,11 +171,11 @@ class MockNgZone extends NgZone {
|
||||||
ngZone.unstable();
|
ngZone.unstable();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
ngZone.stable();
|
ngZone.stable();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalled();
|
expect(execute).toHaveBeenCalled();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -198,15 +196,15 @@ class MockNgZone extends NgZone {
|
||||||
testability.increasePendingRequestCount();
|
testability.increasePendingRequestCount();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
testability.decreasePendingRequestCount();
|
testability.decreasePendingRequestCount();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
ngZone.stable();
|
ngZone.stable();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalled();
|
expect(execute).toHaveBeenCalled();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -221,19 +219,19 @@ class MockNgZone extends NgZone {
|
||||||
testability.increasePendingRequestCount();
|
testability.increasePendingRequestCount();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
ngZone.stable();
|
ngZone.stable();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
testability.decreasePendingRequestCount();
|
testability.decreasePendingRequestCount();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).not.toHaveBeenCalled();
|
expect(execute).not.toHaveBeenCalled();
|
||||||
testability.decreasePendingRequestCount();
|
testability.decreasePendingRequestCount();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalled();
|
expect(execute).toHaveBeenCalled();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -248,11 +246,11 @@ class MockNgZone extends NgZone {
|
||||||
ngZone.stable();
|
ngZone.stable();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalledWith(true);
|
expect(execute).toHaveBeenCalledWith(true);
|
||||||
testability.whenStable(execute2);
|
testability.whenStable(execute2);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute2).toHaveBeenCalledWith(false);
|
expect(execute2).toHaveBeenCalledWith(false);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -264,14 +262,14 @@ class MockNgZone extends NgZone {
|
||||||
ngZone.unstable();
|
ngZone.unstable();
|
||||||
testability.whenStable(execute);
|
testability.whenStable(execute);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
ngZone.stable();
|
ngZone.stable();
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute).toHaveBeenCalledWith(true);
|
expect(execute).toHaveBeenCalledWith(true);
|
||||||
testability.whenStable(execute2);
|
testability.whenStable(execute2);
|
||||||
|
|
||||||
microTask(() => {
|
afterTestabilityCheck(() => {
|
||||||
expect(execute2).toHaveBeenCalledWith(false);
|
expect(execute2).toHaveBeenCalledWith(false);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue