@samitouri / QOS-React / commits / 5bb4ad7376

Added ErrorBoundary tests for useEffect and useLayoutEffect (#14401)

Brian Vaughn committed Dec 6, 2018 at 13:55 UTC 5bb4ad7376b315b61865ea5424e9f76ba6a5c5a3
1 file changed +87
packages/react-dom/src/__tests__/ReactErrorBoundaries-test.internal.js
+87
@@ -28,6 +28,8 @@ describe('ReactErrorBoundaries', () => {
28 let BrokenComponentWillMountErrorBoundary;
29 let BrokenComponentDidMountErrorBoundary;
30 let BrokenRender;
31 + let BrokenUseEffect;
32 + let BrokenUseLayoutEffect;
33 let ErrorBoundary;
34 let ErrorMessage;
35 let NoopErrorBoundary;
@@ -35,9 +37,11 @@ describe('ReactErrorBoundaries', () => {
37 let Normal;
38
39 beforeEach(() => {
40 + jest.useFakeTimers();
41 jest.resetModules();
42 PropTypes = require('prop-types');
43 ReactFeatureFlags = require('shared/ReactFeatureFlags');
44 + ReactFeatureFlags.enableHooks = true;
45 ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
46 ReactDOM = require('react-dom');
47 React = require('react');
@@ -386,6 +390,28 @@ describe('ReactErrorBoundaries', () => {
390 }
391 };
392
393 + BrokenUseEffect = props => {
394 + log.push('BrokenUseEffect render');
395 +
396 + React.useEffect(() => {
397 + log.push('BrokenUseEffect useEffect [!]');
398 + throw new Error('Hello');
399 + });
400 +
401 + return props.children;
402 + };
403 +
404 + BrokenUseLayoutEffect = props => {
405 + log.push('BrokenUseLayoutEffect render');
406 +
407 + React.useLayoutEffect(() => {
408 + log.push('BrokenUseLayoutEffect useLayoutEffect [!]');
409 + throw new Error('Hello');
410 + });
411 +
412 + return props.children;
413 + };
414 +
415 NoopErrorBoundary = class extends React.Component {
416 constructor(props) {
417 super(props);
@@ -1795,6 +1821,67 @@ describe('ReactErrorBoundaries', () => {
1821 expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1822 });
1823
1824 + it('catches errors in useEffect', () => {
1825 + const container = document.createElement('div');
1826 + ReactDOM.render(
1827 + <ErrorBoundary>
1828 + <BrokenUseEffect>Initial value</BrokenUseEffect>
1829 + </ErrorBoundary>,
1830 + container,
1831 + );
1832 + expect(log).toEqual([
1833 + 'ErrorBoundary constructor',
1834 + 'ErrorBoundary componentWillMount',
1835 + 'ErrorBoundary render success',
1836 + 'BrokenUseEffect render',
1837 + 'ErrorBoundary componentDidMount',
1838 + ]);
1839 +
1840 + expect(container.firstChild.textContent).toBe('Initial value');
1841 + log.length = 0;
1842 +
1843 + jest.runAllTimers();
1844 +
1845 + // Flush passive effects and handle the error
1846 + expect(log).toEqual([
1847 + 'BrokenUseEffect useEffect [!]',
1848 + // Handle the error
1849 + 'ErrorBoundary static getDerivedStateFromError',
1850 + 'ErrorBoundary componentWillUpdate',
1851 + 'ErrorBoundary render error',
1852 + 'ErrorBoundary componentDidUpdate',
1853 + ]);
1854 +
1855 + expect(container.firstChild.textContent).toBe('Caught an error: Hello.');
1856 + });
1857 +
1858 + it('catches errors in useLayoutEffect', () => {
1859 + const container = document.createElement('div');
1860 + ReactDOM.render(
1861 + <ErrorBoundary>
1862 + <BrokenUseLayoutEffect>Initial value</BrokenUseLayoutEffect>
1863 + </ErrorBoundary>,
1864 + container,
1865 + );
1866 + expect(log).toEqual([
1867 + 'ErrorBoundary constructor',
1868 + 'ErrorBoundary componentWillMount',
1869 + 'ErrorBoundary render success',
1870 + 'BrokenUseLayoutEffect render',
1871 + 'BrokenUseLayoutEffect useLayoutEffect [!]',
1872 + // Fiber proceeds with the hooks
1873 + 'ErrorBoundary componentDidMount',
1874 + // The error propagates to the higher boundary
1875 + 'ErrorBoundary static getDerivedStateFromError',
1876 + // Fiber retries from the root
1877 + 'ErrorBoundary componentWillUpdate',
1878 + 'ErrorBoundary render error',
1879 + 'ErrorBoundary componentDidUpdate',
1880 + ]);
1881 +
1882 + expect(container.firstChild.textContent).toBe('Caught an error: Hello.');
1883 + });
1884 +
1885 it('propagates errors inside boundary during componentDidMount', () => {
1886 const container = document.createElement('div');
1887 ReactDOM.render(