main
js 129 lines 3.25 KB
Raw
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 * @emails react-core
8 * @jest-environment node
9 */
10
11 'use strict';
12
13 let Scheduler;
14 let scheduleCallback;
15 let ImmediatePriority;
16 let UserBlockingPriority;
17 let NormalPriority;
18
19 describe('SchedulerNoDOM', () => {
20 // Scheduler falls back to a naive implementation using setTimeout.
21 // This is only meant to be used for testing purposes, like with jest's fake timer API.
22 beforeEach(() => {
23 jest.resetModules();
24 jest.useFakeTimers();
25 delete global.setImmediate;
26 delete global.MessageChannel;
27 jest.unmock('scheduler');
28
29 Scheduler = require('scheduler');
30 scheduleCallback = Scheduler.unstable_scheduleCallback;
31 UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
32 NormalPriority = Scheduler.unstable_NormalPriority;
33 });
34
35 it('runAllTimers flushes all scheduled callbacks', () => {
36 const log = [];
37 scheduleCallback(NormalPriority, () => {
38 log.push('A');
39 });
40 scheduleCallback(NormalPriority, () => {
41 log.push('B');
42 });
43 scheduleCallback(NormalPriority, () => {
44 log.push('C');
45 });
46 expect(log).toEqual([]);
47 jest.runAllTimers();
48 expect(log).toEqual(['A', 'B', 'C']);
49 });
50
51 it('executes callbacks in order of priority', () => {
52 const log = [];
53
54 scheduleCallback(NormalPriority, () => {
55 log.push('A');
56 });
57 scheduleCallback(NormalPriority, () => {
58 log.push('B');
59 });
60 scheduleCallback(UserBlockingPriority, () => {
61 log.push('C');
62 });
63 scheduleCallback(UserBlockingPriority, () => {
64 log.push('D');
65 });
66
67 expect(log).toEqual([]);
68 jest.runAllTimers();
69 expect(log).toEqual(['C', 'D', 'A', 'B']);
70 });
71
72 it('handles errors', () => {
73 let log = [];
74
75 scheduleCallback(ImmediatePriority, () => {
76 log.push('A');
77 throw new Error('Oops A');
78 });
79 scheduleCallback(ImmediatePriority, () => {
80 log.push('B');
81 });
82 scheduleCallback(ImmediatePriority, () => {
83 log.push('C');
84 throw new Error('Oops C');
85 });
86
87 expect(() => jest.runAllTimers()).toThrow('Oops A');
88
89 expect(log).toEqual(['A']);
90
91 log = [];
92
93 // B and C flush in a subsequent event. That way, the second error is not
94 // swallowed.
95 expect(() => jest.runAllTimers()).toThrow('Oops C');
96 expect(log).toEqual(['B', 'C']);
97 });
98 });
99
100 // See: https://github.com/facebook/react/pull/13088
101 describe('does not crash non-node SSR environments', () => {
102 it('if setTimeout is undefined', () => {
103 jest.resetModules();
104 const originalSetTimeout = global.setTimeout;
105 try {
106 delete global.setTimeout;
107 jest.unmock('scheduler');
108 expect(() => {
109 require('scheduler');
110 }).not.toThrow();
111 } finally {
112 global.setTimeout = originalSetTimeout;
113 }
114 });
115
116 it('if clearTimeout is undefined', () => {
117 jest.resetModules();
118 const originalClearTimeout = global.clearTimeout;
119 try {
120 delete global.clearTimeout;
121 jest.unmock('scheduler');
122 expect(() => {
123 require('scheduler');
124 }).not.toThrow();
125 } finally {
126 global.clearTimeout = originalClearTimeout;
127 }
128 });
129 });