588
jest.restoreAllMocks();
589
});
590
591
+ // @gate !disableLegacyMode
592
it('does not swallow exceptions on mounting without boundaries', () => {
593
let container = document.createElement('div');
594
expect(() => {
606
}).toThrow('Hello');
607
});
608
609
+ // @gate !disableLegacyMode
610
it('does not swallow exceptions on updating without boundaries', () => {
611
let container = document.createElement('div');
612
ReactDOM.render(<BrokenComponentWillUpdate />, container);
627
}).toThrow('Hello');
628
});
629
630
+ // @gate !disableLegacyMode
631
it('does not swallow exceptions on unmounting without boundaries', () => {
632
const container = document.createElement('div');
633
ReactDOM.render(<BrokenComponentWillUnmount />, container);
636
}).toThrow('Hello');
637
});
638
639
+ // @gate !disableLegacyMode
640
it('prevents errors from leaking into other roots', () => {
641
const container1 = document.createElement('div');
642
const container2 = document.createElement('div');
674
expect(container3.firstChild).toBe(null);
675
});
676
677
+ // @gate !disableLegacyMode
678
it('logs a single error using both error boundaries', () => {
679
const container = document.createElement('div');
680
spyOnDev(console, 'error');
720
expect(log).toEqual(['BothErrorBoundaries componentWillUnmount']);
721
});
722
723
+ // @gate !disableLegacyMode
724
it('renders an error state if child throws in render', () => {
725
const container = document.createElement('div');
726
ReactDOM.render(
751
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
752
});
753
754
+ // @gate !disableLegacyMode
755
it('renders an error state if child throws in constructor', () => {
756
const container = document.createElement('div');
757
ReactDOM.render(
780
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
781
});
782
783
+ // @gate !disableLegacyMode
784
it('renders an error state if child throws in componentWillMount', () => {
785
const container = document.createElement('div');
786
ReactDOM.render(
809
});
810
811
// @gate !disableLegacyContext || !__DEV__
812
+ // @gate !disableLegacyMode
813
it('renders an error state if context provider throws in componentWillMount', () => {
814
class BrokenComponentWillMountWithContext extends React.Component {
815
static childContextTypes = {foo: PropTypes.number};
835
});
836
837
if (!require('shared/ReactFeatureFlags').disableModulePatternComponents) {
838
+ // @gate !disableLegacyMode
839
it('renders an error state if module-style context provider throws in componentWillMount', () => {
840
function BrokenComponentWillMountWithContext() {
841
return {
874
});
875
}
876
877
+ // @gate !disableLegacyMode
878
it('mounts the error message if mounting fails', () => {
879
function renderError(error) {
880
return <ErrorMessage message={error.message} />;
913
]);
914
});
915
916
+ // @gate !disableLegacyMode
917
it('propagates errors on retry on mounting', () => {
918
const container = document.createElement('div');
919
ReactDOM.render(
958
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
959
});
960
961
+ // @gate !disableLegacyMode
962
it('propagates errors inside boundary during componentWillMount', () => {
963
const container = document.createElement('div');
964
ReactDOM.render(
987
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
988
});
989
990
+ // @gate !disableLegacyMode
991
it('propagates errors inside boundary while rendering error state', () => {
992
const container = document.createElement('div');
993
ReactDOM.render(
1031
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1032
});
1033
1034
+ // @gate !disableLegacyMode
1035
it('does not call componentWillUnmount when aborting initial mount', () => {
1036
const container = document.createElement('div');
1037
ReactDOM.render(
1071
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1072
});
1073
1074
+ // @gate !disableLegacyMode
1075
it('resets callback refs if mounting aborts', () => {
1076
function childRef(x) {
1077
log.push('Child ref is set to ' + x);
1116
]);
1117
});
1118
1119
+ // @gate !disableLegacyMode
1120
it('resets object refs if mounting aborts', () => {
1121
const childRef = React.createRef();
1122
const errorMessageRef = React.createRef();
1157
expect(errorMessageRef.current).toEqual(null);
1158
});
1159
1160
+ // @gate !disableLegacyMode
1161
it('successfully mounts if no error occurs', () => {
1162
const container = document.createElement('div');
1163
ReactDOM.render(
1179
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1180
});
1181
1182
+ // @gate !disableLegacyMode
1183
it('catches if child throws in constructor during update', () => {
1184
const container = document.createElement('div');
1185
ReactDOM.render(
1228
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1229
});
1230
1231
+ // @gate !disableLegacyMode
1232
it('catches if child throws in componentWillMount during update', () => {
1233
const container = document.createElement('div');
1234
ReactDOM.render(
1278
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1279
});
1280
1281
+ // @gate !disableLegacyMode
1282
it('catches if child throws in componentWillReceiveProps during update', () => {
1283
const container = document.createElement('div');
1284
ReactDOM.render(
1323
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1324
});
1325
1326
+ // @gate !disableLegacyMode
1327
it('catches if child throws in componentWillUpdate during update', () => {
1328
const container = document.createElement('div');
1329
ReactDOM.render(
1369
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1370
});
1371
1372
+ // @gate !disableLegacyMode
1373
it('catches if child throws in render during update', () => {
1374
const container = document.createElement('div');
1375
ReactDOM.render(
1419
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1420
});
1421
1422
+ // @gate !disableLegacyMode
1423
it('keeps refs up-to-date during updates', () => {
1424
function child1Ref(x) {
1425
log.push('Child1 ref is set to ' + x);
1484
]);
1485
});
1486
1487
+ // @gate !disableLegacyMode
1488
it('recovers from componentWillUnmount errors on update', () => {
1489
const container = document.createElement('div');
1490
ReactDOM.render(
1541
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1542
});
1543
1544
+ // @gate !disableLegacyMode
1545
it('recovers from nested componentWillUnmount errors on update', () => {
1546
const container = document.createElement('div');
1547
ReactDOM.render(
1603
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1604
});
1605
1606
+ // @gate !disableLegacyMode
1607
it('picks the right boundary when handling unmounting errors', () => {
1608
function renderInnerError(error) {
1609
return <div>Caught an inner error: {error.message}.</div>;
1673
]);
1674
});
1675
1676
+ // @gate !disableLegacyMode
1677
it('can recover from error state', () => {
1678
const container = document.createElement('div');
1679
ReactDOM.render(
1722
]);
1723
});
1724
1725
+ // @gate !disableLegacyMode
1726
it('can update multiple times in error state', () => {
1727
const container = document.createElement('div');
1728
ReactDOM.render(
1747
ReactDOM.unmountComponentAtNode(container);
1748
});
1749
1750
+ // @gate !disableLegacyMode
1751
it("doesn't get into inconsistent state during removals", () => {
1752
const container = document.createElement('div');
1753
ReactDOM.render(
1767
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1768
});
1769
1770
+ // @gate !disableLegacyMode
1771
it("doesn't get into inconsistent state during additions", () => {
1772
const container = document.createElement('div');
1773
ReactDOM.render(<ErrorBoundary />, container);
1786
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1787
});
1788
1789
+ // @gate !disableLegacyMode
1790
it("doesn't get into inconsistent state during reorders", () => {
1791
function getAMixOfNormalAndBrokenRenderElements() {
1792
const elements = [];
1835
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1836
});
1837
1838
+ // @gate !disableLegacyMode
1839
it('catches errors originating downstream', () => {
1840
let fail = false;
1841
class Stateful extends React.Component {
1878
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1879
});
1880
1881
+ // @gate !disableLegacyMode
1882
it('catches errors in componentDidMount', () => {
1883
const container = document.createElement('div');
1884
ReactDOM.render(
1938
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1939
});
1940
1941
+ // @gate !disableLegacyMode
1942
it('catches errors in componentDidUpdate', () => {
1943
const container = document.createElement('div');
1944
ReactDOM.render(
1978
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
1979
});
1980
1981
+ // @gate !disableLegacyMode
1982
it('propagates errors inside boundary during componentDidMount', () => {
1983
const container = document.createElement('div');
1984
ReactDOM.render(
2016
expect(log).toEqual(['ErrorBoundary componentWillUnmount']);
2017
});
2018
2019
+ // @gate !disableLegacyMode
2020
it('calls componentDidCatch for each error that is captured', () => {
2021
function renderUnmountError(error) {
2022
return <div>Caught an unmounting error: {error.message}.</div>;
2118
]);
2119
});
2120
2121
+ // @gate !disableLegacyMode
2122
it('discards a bad root if the root component fails', () => {
2123
const X = null;
2124
const Y = undefined;
2150
expect(err2.message).toMatch(/got: undefined/);
2151
});
2152
2153
+ // @gate !disableLegacyMode
2154
it('renders empty output if error boundary does not handle the error', () => {
2155
const container = document.createElement('div');
2156
expect(() => {
2185
expect(log).toEqual(['NoopErrorBoundary componentWillUnmount']);
2186
});
2187
2188
+ // @gate !disableLegacyMode
2189
it('passes first error when two errors happen in commit', () => {
2190
const errors = [];
2191
let caughtError;
2225
expect(caughtError.message).toBe('child sad');
2226
});
2227
2228
+ // @gate !disableLegacyMode
2229
it('propagates uncaught error inside unbatched initial mount', () => {
2230
function Foo() {
2231
throw new Error('foo error');
2238
}).toThrow('foo error');
2239
});
2240
2241
+ // @gate !disableLegacyMode
2242
it('handles errors that occur in before-mutation commit hook', () => {
2243
const errors = [];
2244
let caughtError;