addons/isl/src/__tests__/timer.test.tsblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import {gc} from 'shared/testUtils';
b69ab319import {Timer} from '../timer';
b69ab3110
b69ab3111describe('Timer', () => {
b69ab3112 beforeEach(() => {
b69ab3113 jest.useFakeTimers();
b69ab3114 });
b69ab3115 afterEach(() => {
b69ab3116 jest.useRealTimers();
b69ab3117 });
b69ab3118
b69ab3119 it('can enable and disable', () => {
b69ab3120 const callback = jest.fn();
b69ab3121 const timer = new Timer(callback, 100);
b69ab3122
b69ab3123 timer.enabled = true;
b69ab3124 jest.advanceTimersByTime(250);
b69ab3125 expect(callback).toHaveBeenCalledTimes(2);
b69ab3126
b69ab3127 timer.enabled = false;
b69ab3128 jest.advanceTimersByTime(500);
b69ab3129 expect(callback).toHaveBeenCalledTimes(2);
b69ab3130
b69ab3131 timer.enabled = true;
b69ab3132 jest.advanceTimersByTime(200);
b69ab3133 expect(callback).toHaveBeenCalledTimes(4);
b69ab3134 });
b69ab3135
b69ab3136 it('error once cancels the timer', () => {
b69ab3137 const callback = jest.fn(() => {
b69ab3138 throw new Error('x');
b69ab3139 });
b69ab3140
b69ab3141 // Initially enabled.
b69ab3142 const timer = new Timer(callback, 100, true);
b69ab3143 expect(timer.enabled).toBe(true);
b69ab3144
b69ab3145 // Try to call 3 times, but the first time it will throw.
b69ab3146 try {
b69ab3147 jest.advanceTimersByTime(350);
b69ab3148 } catch (_e) {}
b69ab3149
b69ab3150 // After throw the timer is disabled.
b69ab3151 expect(timer.enabled).toBe(false);
b69ab3152 expect(callback).toHaveBeenCalledTimes(1);
b69ab3153 });
b69ab3154
b69ab3155 it('returning false stops the timer', () => {
b69ab3156 let count = 0;
b69ab3157 const callback = jest.fn(() => {
b69ab3158 count += 1;
b69ab3159 return count < 3;
b69ab3160 });
b69ab3161 const timer = new Timer(callback, 100, true);
b69ab3162 expect(timer.enabled).toBe(true);
b69ab3163 jest.advanceTimersByTime(250);
b69ab3164 expect(timer.enabled).toBe(true);
b69ab3165 jest.advanceTimersByTime(500);
b69ab3166 expect(timer.enabled).toBe(false);
b69ab3167 expect(callback).toHaveBeenCalledTimes(3);
b69ab3168 });
b69ab3169
b69ab3170 it('dispose cancels the timer forever', () => {
b69ab3171 const callback = jest.fn();
b69ab3172 const timer = new Timer(callback, 100);
b69ab3173
b69ab3174 timer.enabled = true;
b69ab3175 jest.advanceTimersByTime(50);
b69ab3176
b69ab3177 timer.dispose();
b69ab3178
b69ab3179 // Cannot be re-enabled.
b69ab3180 timer.enabled = true;
b69ab3181 jest.advanceTimersByTime(500);
b69ab3182 expect(timer.enabled).toBe(false);
b69ab3183 expect(callback).toHaveBeenCalledTimes(0);
b69ab3184 });
b69ab3185
b69ab3186 it('GC cancels the timer forever', async () => {
b69ab3187 const callback = jest.fn();
b69ab3188 let timer: Timer | null = new Timer(callback, 100, true);
b69ab3189 expect(timer.enabled).toBe(true);
b69ab3190
b69ab3191 // GC the timer.
b69ab3192 // eslint-disable-next-line @typescript-eslint/no-unused-vars
b69ab3193 timer = null;
b69ab3194 await gc();
b69ab3195
b69ab3196 // Callback should not be called after the time is gone.
b69ab3197 jest.advanceTimersByTime(500);
b69ab3198 expect(callback).toHaveBeenCalledTimes(0);
b69ab3199 });
b69ab31100});