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. });