2.6 KB101 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import {gc} from 'shared/testUtils';
9import {Timer} from '../timer';
10
11describe('Timer', () => {
12 beforeEach(() => {
13 jest.useFakeTimers();
14 });
15 afterEach(() => {
16 jest.useRealTimers();
17 });
18
19 it('can enable and disable', () => {
20 const callback = jest.fn();
21 const timer = new Timer(callback, 100);
22
23 timer.enabled = true;
24 jest.advanceTimersByTime(250);
25 expect(callback).toHaveBeenCalledTimes(2);
26
27 timer.enabled = false;
28 jest.advanceTimersByTime(500);
29 expect(callback).toHaveBeenCalledTimes(2);
30
31 timer.enabled = true;
32 jest.advanceTimersByTime(200);
33 expect(callback).toHaveBeenCalledTimes(4);
34 });
35
36 it('error once cancels the timer', () => {
37 const callback = jest.fn(() => {
38 throw new Error('x');
39 });
40
41 // Initially enabled.
42 const timer = new Timer(callback, 100, true);
43 expect(timer.enabled).toBe(true);
44
45 // Try to call 3 times, but the first time it will throw.
46 try {
47 jest.advanceTimersByTime(350);
48 } catch (_e) {}
49
50 // After throw the timer is disabled.
51 expect(timer.enabled).toBe(false);
52 expect(callback).toHaveBeenCalledTimes(1);
53 });
54
55 it('returning false stops the timer', () => {
56 let count = 0;
57 const callback = jest.fn(() => {
58 count += 1;
59 return count < 3;
60 });
61 const timer = new Timer(callback, 100, true);
62 expect(timer.enabled).toBe(true);
63 jest.advanceTimersByTime(250);
64 expect(timer.enabled).toBe(true);
65 jest.advanceTimersByTime(500);
66 expect(timer.enabled).toBe(false);
67 expect(callback).toHaveBeenCalledTimes(3);
68 });
69
70 it('dispose cancels the timer forever', () => {
71 const callback = jest.fn();
72 const timer = new Timer(callback, 100);
73
74 timer.enabled = true;
75 jest.advanceTimersByTime(50);
76
77 timer.dispose();
78
79 // Cannot be re-enabled.
80 timer.enabled = true;
81 jest.advanceTimersByTime(500);
82 expect(timer.enabled).toBe(false);
83 expect(callback).toHaveBeenCalledTimes(0);
84 });
85
86 it('GC cancels the timer forever', async () => {
87 const callback = jest.fn();
88 let timer: Timer | null = new Timer(callback, 100, true);
89 expect(timer.enabled).toBe(true);
90
91 // GC the timer.
92 // eslint-disable-next-line @typescript-eslint/no-unused-vars
93 timer = null;
94 await gc();
95
96 // Callback should not be called after the time is gone.
97 jest.advanceTimersByTime(500);
98 expect(callback).toHaveBeenCalledTimes(0);
99 });
100});
101