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. /* eslint-disable no-func-assign */
    
  12. 
    
  13. 'use strict';
    
  14. 
    
  15. let React;
    
  16. let ReactNoop;
    
  17. let Scheduler;
    
  18. let act;
    
  19. let useEffect;
    
  20. let useLayoutEffect;
    
  21. let assertLog;
    
  22. 
    
  23. describe('ReactEffectOrdering', () => {
    
  24.   beforeEach(() => {
    
  25.     jest.resetModules();
    
  26.     jest.useFakeTimers();
    
  27. 
    
  28.     React = require('react');
    
  29.     ReactNoop = require('react-noop-renderer');
    
  30.     Scheduler = require('scheduler');
    
  31.     act = require('internal-test-utils').act;
    
  32.     useEffect = React.useEffect;
    
  33.     useLayoutEffect = React.useLayoutEffect;
    
  34. 
    
  35.     const InternalTestUtils = require('internal-test-utils');
    
  36.     assertLog = InternalTestUtils.assertLog;
    
  37.   });
    
  38. 
    
  39.   test('layout unmounts on deletion are fired in parent -> child order', async () => {
    
  40.     const root = ReactNoop.createRoot();
    
  41. 
    
  42.     function Parent() {
    
  43.       useLayoutEffect(() => {
    
  44.         return () => Scheduler.log('Unmount parent');
    
  45.       });
    
  46.       return <Child />;
    
  47.     }
    
  48. 
    
  49.     function Child() {
    
  50.       useLayoutEffect(() => {
    
  51.         return () => Scheduler.log('Unmount child');
    
  52.       });
    
  53.       return 'Child';
    
  54.     }
    
  55. 
    
  56.     await act(() => {
    
  57.       root.render(<Parent />);
    
  58.     });
    
  59.     expect(root).toMatchRenderedOutput('Child');
    
  60.     await act(() => {
    
  61.       root.render(null);
    
  62.     });
    
  63.     assertLog(['Unmount parent', 'Unmount child']);
    
  64.   });
    
  65. 
    
  66.   test('passive unmounts on deletion are fired in parent -> child order', async () => {
    
  67.     const root = ReactNoop.createRoot();
    
  68. 
    
  69.     function Parent() {
    
  70.       useEffect(() => {
    
  71.         return () => Scheduler.log('Unmount parent');
    
  72.       });
    
  73.       return <Child />;
    
  74.     }
    
  75. 
    
  76.     function Child() {
    
  77.       useEffect(() => {
    
  78.         return () => Scheduler.log('Unmount child');
    
  79.       });
    
  80.       return 'Child';
    
  81.     }
    
  82. 
    
  83.     await act(() => {
    
  84.       root.render(<Parent />);
    
  85.     });
    
  86.     expect(root).toMatchRenderedOutput('Child');
    
  87.     await act(() => {
    
  88.       root.render(null);
    
  89.     });
    
  90.     assertLog(['Unmount parent', 'Unmount child']);
    
  91.   });
    
  92. });