main
js 84 lines 2.47 KB
Raw
1 describe('ErrorBoundaryReconciliation', () => {
2 let BrokenRender;
3 let DidCatchErrorBoundary;
4 let GetDerivedErrorBoundary;
5 let React;
6 let ReactTestRenderer;
7 let span;
8 let act;
9
10 beforeEach(() => {
11 jest.resetModules();
12
13 ReactTestRenderer = require('react-test-renderer');
14 React = require('react');
15 act = require('internal-test-utils').act;
16 DidCatchErrorBoundary = class extends React.Component {
17 state = {error: null};
18 componentDidCatch(error) {
19 this.setState({error});
20 }
21 render() {
22 return this.state.error
23 ? React.createElement(this.props.fallbackTagName, {
24 prop: 'ErrorBoundary',
25 })
26 : this.props.children;
27 }
28 };
29
30 GetDerivedErrorBoundary = class extends React.Component {
31 state = {error: null};
32 static getDerivedStateFromError(error) {
33 return {error};
34 }
35 render() {
36 return this.state.error
37 ? React.createElement(this.props.fallbackTagName, {
38 prop: 'ErrorBoundary',
39 })
40 : this.props.children;
41 }
42 };
43
44 const InvalidType = undefined;
45 BrokenRender = ({fail}) =>
46 fail ? <InvalidType /> : <span prop="BrokenRender" />;
47 });
48
49 async function sharedTest(ErrorBoundary, fallbackTagName) {
50 let renderer;
51
52 await act(() => {
53 renderer = ReactTestRenderer.create(
54 <ErrorBoundary fallbackTagName={fallbackTagName}>
55 <BrokenRender fail={false} />
56 </ErrorBoundary>,
57 {unstable_isConcurrent: true},
58 );
59 });
60 expect(renderer).toMatchRenderedOutput(<span prop="BrokenRender" />);
61 await act(() => {
62 renderer.update(
63 <ErrorBoundary fallbackTagName={fallbackTagName}>
64 <BrokenRender fail={true} />
65 </ErrorBoundary>,
66 );
67 });
68
69 const Fallback = fallbackTagName;
70 expect(renderer).toMatchRenderedOutput(<Fallback prop="ErrorBoundary" />);
71 }
72
73 it('componentDidCatch can recover by rendering an element of the same type', () =>
74 sharedTest(DidCatchErrorBoundary, 'span'));
75
76 it('componentDidCatch can recover by rendering an element of a different type', () =>
77 sharedTest(DidCatchErrorBoundary, 'div'));
78
79 it('getDerivedStateFromError can recover by rendering an element of the same type', () =>
80 sharedTest(GetDerivedErrorBoundary, 'span'));
81
82 it('getDerivedStateFromError can recover by rendering an element of a different type', () =>
83 sharedTest(GetDerivedErrorBoundary, 'div'));
84 });