mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
Before this change, the macrotask for `setInterval(callback, ms)` was no
longer tracked by `TaskTrackingZoneSpec` after the `callback` was
invoked for the first time. Now the periodic macrotask is tracked until
it is cancelled, e.g. `clearInterval(id)`.
BREAKING CHANGE: in TaskTrackingZoneSpec track a periodic task until it is cancelled
The breaking change is scoped only to the plugin
`zone.js/plugins/task-tracking`. If you used `TaskTrackingZoneSpec` and
checked the pending macroTasks e.g. using `(this.ngZone as any)._inner
._parent._properties.TaskTrackingZone.getTasksFor('macroTask')`, then
its behavior slightly changed for periodic macrotasks. For example,
previously the `setInterval` macrotask was no longer tracked after its
callback was executed for the first time. Now it's tracked until
the task is explicitly cancelled, e.g with `clearInterval(id)`.
fixes 45350
PR Close #45391
99 lines
3.6 KiB
TypeScript
99 lines
3.6 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
import {supportPatchXHROnProperty} from '../test-util';
|
|
|
|
declare const global: any;
|
|
|
|
describe('TaskTrackingZone', function() {
|
|
let _TaskTrackingZoneSpec: typeof TaskTrackingZoneSpec = (Zone as any)['TaskTrackingZoneSpec'];
|
|
let taskTrackingZoneSpec: TaskTrackingZoneSpec|null = null;
|
|
let taskTrackingZone: Zone;
|
|
|
|
beforeEach(() => {
|
|
taskTrackingZoneSpec = new _TaskTrackingZoneSpec();
|
|
taskTrackingZone = Zone.current.fork(taskTrackingZoneSpec);
|
|
});
|
|
|
|
it('should track tasks', (done: Function) => {
|
|
taskTrackingZone.run(() => {
|
|
taskTrackingZone.scheduleMicroTask('test1', () => {});
|
|
expect(taskTrackingZoneSpec!.microTasks.length).toBe(1);
|
|
expect(taskTrackingZoneSpec!.microTasks[0].source).toBe('test1');
|
|
|
|
setTimeout(() => {});
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(1);
|
|
expect(taskTrackingZoneSpec!.macroTasks[0].source).toBe('setTimeout');
|
|
taskTrackingZone.cancelTask(taskTrackingZoneSpec!.macroTasks[0]);
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(0);
|
|
|
|
setTimeout(() => {
|
|
// assert on execution it is null
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(0);
|
|
expect(taskTrackingZoneSpec!.microTasks.length).toBe(0);
|
|
|
|
// If a browser does not have XMLHttpRequest, then end test here.
|
|
if (typeof global['XMLHttpRequest'] == 'undefined') return done();
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.open('get', '/', true);
|
|
xhr.onreadystatechange = () => {
|
|
if (xhr.readyState == 4) {
|
|
// clear current event tasks using setTimeout
|
|
setTimeout(() => {
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(0);
|
|
expect(taskTrackingZoneSpec!.microTasks.length).toBe(0);
|
|
if (supportPatchXHROnProperty()) {
|
|
expect(taskTrackingZoneSpec!.eventTasks.length).not.toBe(0);
|
|
}
|
|
taskTrackingZoneSpec!.clearEvents();
|
|
expect(taskTrackingZoneSpec!.eventTasks.length).toBe(0);
|
|
done();
|
|
});
|
|
}
|
|
};
|
|
xhr.send();
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(1);
|
|
expect(taskTrackingZoneSpec!.macroTasks[0].source).toBe('XMLHttpRequest.send');
|
|
if (supportPatchXHROnProperty()) {
|
|
expect(taskTrackingZoneSpec!.eventTasks[0].source)
|
|
.toMatch(/\.addEventListener:readystatechange/);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should capture task creation stacktrace', (done) => {
|
|
taskTrackingZone.run(() => {
|
|
setTimeout(() => {
|
|
done();
|
|
});
|
|
expect((taskTrackingZoneSpec!.macroTasks[0] as any)['creationLocation']).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
it('should track periodic task until it is canceled', (done) => {
|
|
taskTrackingZone.run(() => {
|
|
const intervalCallback = jasmine.createSpy('intervalCallback');
|
|
const interval = setInterval(intervalCallback, 1);
|
|
|
|
expect(intervalCallback).not.toHaveBeenCalled();
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(1);
|
|
expect(taskTrackingZoneSpec!.macroTasks[0].source).toBe('setInterval');
|
|
|
|
setTimeout(() => {
|
|
expect(intervalCallback).toHaveBeenCalled();
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(1);
|
|
expect(taskTrackingZoneSpec!.macroTasks[0].source).toBe('setInterval');
|
|
|
|
clearInterval(interval);
|
|
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(0);
|
|
done();
|
|
}, 2);
|
|
});
|
|
});
|
|
});
|