fix(core): In Testability.whenStable update callback, pass more complete (#25010)
data about tasks. When building a list of pending tasks for callers of whenStable(), Testability will copy data about the task into a new object, in order to avoid leaking references to tasks. This change copies more properties from Tasks into the list of pending tasks, as well as a reference to Task.data to give callers more information about the tasks that are pending. Specifically, this also copies runCount and task ID, which are needed in order for callers to know when a given task is repeating. PR Close #25010
This commit is contained in:
parent
3355502f2f
commit
16c03c0f38
|
@ -25,10 +25,15 @@ export declare interface PublicTestability {
|
||||||
// Angular internal, not intended for public API.
|
// Angular internal, not intended for public API.
|
||||||
export interface PendingMacrotask {
|
export interface PendingMacrotask {
|
||||||
source: string;
|
source: string;
|
||||||
isPeriodic: boolean;
|
|
||||||
delay?: number;
|
|
||||||
creationLocation: Error;
|
creationLocation: Error;
|
||||||
xhr?: XMLHttpRequest;
|
runCount?: number;
|
||||||
|
data: TaskData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TaskData {
|
||||||
|
target?: XMLHttpRequest;
|
||||||
|
delay?: number;
|
||||||
|
isPeriodic?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Angular internal, not intended for public API.
|
// Angular internal, not intended for public API.
|
||||||
|
@ -152,17 +157,14 @@ export class Testability implements PublicTestability {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the tasks data so that we don't leak tasks.
|
||||||
return this.taskTrackingZone.macroTasks.map((t: Task) => {
|
return this.taskTrackingZone.macroTasks.map((t: Task) => {
|
||||||
return {
|
return {
|
||||||
source: t.source,
|
source: t.source,
|
||||||
isPeriodic: t.data.isPeriodic,
|
|
||||||
delay: t.data.delay,
|
|
||||||
// From TaskTrackingZone:
|
// From TaskTrackingZone:
|
||||||
// https://github.com/angular/zone.js/blob/master/lib/zone-spec/task-tracking.ts#L40
|
// https://github.com/angular/zone.js/blob/master/lib/zone-spec/task-tracking.ts#L40
|
||||||
creationLocation: (t as any).creationLocation as Error,
|
creationLocation: (t as any).creationLocation as Error,
|
||||||
// Added by Zones for XHRs
|
data: t.data
|
||||||
// https://github.com/angular/zone.js/blob/master/lib/browser/browser.ts#L133
|
|
||||||
xhr: (t.data as any).target
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,9 +143,9 @@ class MockNgZone extends NgZone {
|
||||||
const tasks = execute.calls.mostRecent().args[1] as PendingMacrotask[];
|
const tasks = execute.calls.mostRecent().args[1] as PendingMacrotask[];
|
||||||
|
|
||||||
expect(tasks.length).toEqual(1);
|
expect(tasks.length).toEqual(1);
|
||||||
expect(tasks[0].delay).toEqual(1000);
|
expect(tasks[0].data.delay).toEqual(1000);
|
||||||
expect(tasks[0].source).toEqual('setTimeout');
|
expect(tasks[0].source).toEqual('setTimeout');
|
||||||
expect(tasks[0].isPeriodic).toEqual(false);
|
expect(tasks[0].data.isPeriodic).toEqual(false);
|
||||||
|
|
||||||
clearTimeout(id);
|
clearTimeout(id);
|
||||||
}));
|
}));
|
||||||
|
@ -207,11 +207,11 @@ class MockNgZone extends NgZone {
|
||||||
expect(execute).toHaveBeenCalled();
|
expect(execute).toHaveBeenCalled();
|
||||||
|
|
||||||
const update1 = updateCallback.calls.all()[0].args[0] as PendingMacrotask[];
|
const update1 = updateCallback.calls.all()[0].args[0] as PendingMacrotask[];
|
||||||
expect(update1[0].delay).toEqual(500);
|
expect(update1[0].data.delay).toEqual(500);
|
||||||
|
|
||||||
const update2 = updateCallback.calls.all()[1].args[0] as PendingMacrotask[];
|
const update2 = updateCallback.calls.all()[1].args[0] as PendingMacrotask[];
|
||||||
expect(update2[0].delay).toEqual(500);
|
expect(update2[0].data.delay).toEqual(500);
|
||||||
expect(update2[1].delay).toEqual(300);
|
expect(update2[1].data.delay).toEqual(300);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('cancels the done callback if the update callback returns true', fakeAsync(() => {
|
it('cancels the done callback if the update callback returns true', fakeAsync(() => {
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe('testability example', () => {
|
||||||
|
|
||||||
browser.driver.executeAsyncScript(waitWithResultScript).then((result: any[]) => {
|
browser.driver.executeAsyncScript(waitWithResultScript).then((result: any[]) => {
|
||||||
let pendingTask = result[0];
|
let pendingTask = result[0];
|
||||||
expect(pendingTask.delay).toEqual(5000);
|
expect(pendingTask.data.delay).toEqual(5000);
|
||||||
expect(pendingTask.source).toEqual('setTimeout');
|
expect(pendingTask.source).toEqual('setTimeout');
|
||||||
expect(element(by.css('.status')).getText()).not.toContain('done');
|
expect(element(by.css('.status')).getText()).not.toContain('done');
|
||||||
done();
|
done();
|
||||||
|
|
Loading…
Reference in New Issue