From 368f7deab3edde85f4ff6edb79156d14c4789c76 Mon Sep 17 00:00:00 2001 From: Pablo Date: Tue, 20 Feb 2024 13:41:23 -0300 Subject: [PATCH 1/4] fix(tests): Minor fix sandbox fake timers Sandbox was not cleaning up correctly and making fail the test that I added. --- spec/schedulers/AsapScheduler-spec.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/spec/schedulers/AsapScheduler-spec.ts b/spec/schedulers/AsapScheduler-spec.ts index 5ec0401753..56a2ff7609 100644 --- a/spec/schedulers/AsapScheduler-spec.ts +++ b/spec/schedulers/AsapScheduler-spec.ts @@ -66,7 +66,7 @@ describe('Scheduler.asap', () => { const sandbox = sinon.createSandbox(); const fakeTimer = sandbox.useFakeTimers(); // callThrough is missing from the declarations installed by the typings tool in stable - const stubSetInterval = ( sandbox.stub(global, 'setInterval')).callThrough(); + const stubSetInterval = ( sandbox.stub(fakeTimer, 'setInterval')).callThrough(); const period = 50; const state = { index: 0, period }; type State = typeof state; @@ -92,7 +92,7 @@ describe('Scheduler.asap', () => { const sandbox = sinon.createSandbox(); const fakeTimer = sandbox.useFakeTimers(); // callThrough is missing from the declarations installed by the typings tool in stable - const stubSetInterval = ( sandbox.stub(global, 'setInterval')).callThrough(); + const stubSetInterval = ( sandbox.stub(fakeTimer, 'setInterval')).callThrough(); const period = 50; const state = { index: 0, period }; type State = typeof state; @@ -148,6 +148,12 @@ describe('Scheduler.asap', () => { }, 0, 0); }); + it('should schedule asap actions from a delayed one', (done) => { + asap.schedule(() => { + asap.schedule(() => { done(); }); + }, 1); + }); + it('should cancel the setImmediate if all scheduled actions unsubscribe before it executes', (done) => { let asapExec1 = false; let asapExec2 = false; From f11d31defafcced629ce8e1d973f6760d3d866c2 Mon Sep 17 00:00:00 2001 From: Pablo Date: Tue, 20 Feb 2024 13:51:32 -0300 Subject: [PATCH 2/4] fix(animationFrameSchduler): Add failing tests --- .../AnimationFrameScheduler-spec.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/spec/schedulers/AnimationFrameScheduler-spec.ts b/spec/schedulers/AnimationFrameScheduler-spec.ts index eae794b1cb..1be5cf1e6b 100644 --- a/spec/schedulers/AnimationFrameScheduler-spec.ts +++ b/spec/schedulers/AnimationFrameScheduler-spec.ts @@ -141,6 +141,46 @@ describe('Scheduler.animationFrame', () => { } }); + it('should schedule next frame actions from a delayed one', (done) => { + animationFrame.schedule(() => { + animationFrame.schedule(() => { done(); }); + }, 1); + }); + + it('should schedule 2 actions for a subsequent frame', (done) => { + let runFirst = false; + animationFrame.schedule(() => { + animationFrame.schedule(() => { runFirst = true; }); + animationFrame.schedule(() => { + if (runFirst) { + done(); + } else { + done(new Error('First action did not run')); + } + }); + }); + }); + + it('should handle delayed action without affecting next frame actions', (done) => { + let runDelayed = false; + let runFirst = false; + animationFrame.schedule(() => { + animationFrame.schedule(() => { runFirst = true; }); + animationFrame.schedule(() => { + if (!runDelayed) { + done(new Error('Delayed action did not run')); + } else if (!runFirst) { + done(new Error('First action did not run')); + } else { + done(); + } + }); + + // This action will execute before the next frame because the delay is less than the one of the frame + animationFrame.schedule(() => { runDelayed = true; }, 1); + }); + }); + it('should not execute rescheduled actions when flushing', (done) => { let flushCount = 0; let scheduledIndices: number[] = []; From be643dbcac4c46fd72557918adb044db0aa09380 Mon Sep 17 00:00:00 2001 From: Pablo Date: Tue, 20 Feb 2024 13:55:42 -0300 Subject: [PATCH 3/4] fix(animationFrameScheduler): Fix the scenarios in added tests --- src/internal/scheduler/AnimationFrameAction.ts | 2 +- src/internal/scheduler/AnimationFrameScheduler.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/internal/scheduler/AnimationFrameAction.ts b/src/internal/scheduler/AnimationFrameAction.ts index f9c8f8e39d..502bbc7f16 100644 --- a/src/internal/scheduler/AnimationFrameAction.ts +++ b/src/internal/scheduler/AnimationFrameAction.ts @@ -33,7 +33,7 @@ export class AnimationFrameAction extends AsyncAction { // cancel the requested animation frame and set the scheduled flag to // undefined so the next AnimationFrameAction will request its own. const { actions } = scheduler; - if (id != null && actions[actions.length - 1]?.id !== id) { + if (id != null && id === scheduler._scheduled && actions[actions.length - 1]?.id !== id) { animationFrameProvider.cancelAnimationFrame(id as number); scheduler._scheduled = undefined; } diff --git a/src/internal/scheduler/AnimationFrameScheduler.ts b/src/internal/scheduler/AnimationFrameScheduler.ts index 640afa2488..3cf4d34d55 100644 --- a/src/internal/scheduler/AnimationFrameScheduler.ts +++ b/src/internal/scheduler/AnimationFrameScheduler.ts @@ -13,8 +13,13 @@ export class AnimationFrameScheduler extends AsyncScheduler { // are removed from the actions array and that can shift actions that are // scheduled to be executed in a subsequent flush into positions at which // they are executed within the current flush. - const flushId = this._scheduled; - this._scheduled = undefined; + let flushId; + if (action?.id) { + flushId = action?.id; + } else { + flushId = this._scheduled; + this._scheduled = undefined; + } const { actions } = this; let error: any; From 0ed6b9484fd2f158268801d322cae7029dab2620 Mon Sep 17 00:00:00 2001 From: Pablo Date: Thu, 22 Feb 2024 15:18:42 -0300 Subject: [PATCH 4/4] chore(animationFrameScheduler): minor code improvement --- src/internal/scheduler/AnimationFrameScheduler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal/scheduler/AnimationFrameScheduler.ts b/src/internal/scheduler/AnimationFrameScheduler.ts index 3cf4d34d55..1f21ffa164 100644 --- a/src/internal/scheduler/AnimationFrameScheduler.ts +++ b/src/internal/scheduler/AnimationFrameScheduler.ts @@ -14,8 +14,8 @@ export class AnimationFrameScheduler extends AsyncScheduler { // scheduled to be executed in a subsequent flush into positions at which // they are executed within the current flush. let flushId; - if (action?.id) { - flushId = action?.id; + if (action) { + flushId = action.id; } else { flushId = this._scheduled; this._scheduled = undefined;