react-error-boundary 1.2.4 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/ErrorBoundary.js +116 -0
- package/dist/commonjs/ErrorBoundaryFallbackComponent.js +57 -0
- package/dist/commonjs/__tests__/ErrorBoundary.test.js +244 -0
- package/dist/commonjs/__tests__/ErrorBoundaryFallbackComponent.test.js +27 -0
- package/dist/commonjs/__tests__/__snapshots__/ErrorBoundaryFallbackComponent.test.js.snap +213 -0
- package/dist/commonjs/index.js +21 -0
- package/dist/commonjs/setupTests.js +13 -0
- package/dist/es/ErrorBoundary.js +101 -0
- package/dist/es/ErrorBoundaryFallbackComponent.js +47 -0
- package/dist/es/__tests__/ErrorBoundary.test.js +232 -0
- package/dist/es/__tests__/ErrorBoundaryFallbackComponent.test.js +18 -0
- package/dist/es/__tests__/__snapshots__/ErrorBoundaryFallbackComponent.test.js.snap +213 -0
- package/dist/es/index.js +6 -0
- package/dist/es/setupTests.js +4 -0
- package/dist/umd/react-error-boundary.js +1231 -0
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _enzyme = require('enzyme');
|
|
4
|
+
|
|
5
|
+
var _enzyme2 = _interopRequireDefault(_enzyme);
|
|
6
|
+
|
|
7
|
+
var _enzymeAdapterReact = require('enzyme-adapter-react-16');
|
|
8
|
+
|
|
9
|
+
var _enzymeAdapterReact2 = _interopRequireDefault(_enzymeAdapterReact);
|
|
10
|
+
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
|
|
13
|
+
_enzyme2.default.configure({ adapter: new _enzymeAdapterReact2.default() });
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
|
|
2
|
+
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
|
3
|
+
import _createClass from 'babel-runtime/helpers/createClass';
|
|
4
|
+
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
|
5
|
+
import _inherits from 'babel-runtime/helpers/inherits';
|
|
6
|
+
import React, { Component } from 'react';
|
|
7
|
+
import ErrorBoundaryFallbackComponent from './ErrorBoundaryFallbackComponent';
|
|
8
|
+
|
|
9
|
+
var babelPluginFlowReactPropTypes_proptype_ComponentType = require('react').babelPluginFlowReactPropTypes_proptype_ComponentType || require('prop-types').any;
|
|
10
|
+
|
|
11
|
+
var ErrorBoundary = function (_Component) {
|
|
12
|
+
_inherits(ErrorBoundary, _Component);
|
|
13
|
+
|
|
14
|
+
function ErrorBoundary() {
|
|
15
|
+
var _ref;
|
|
16
|
+
|
|
17
|
+
var _temp, _this, _ret;
|
|
18
|
+
|
|
19
|
+
_classCallCheck(this, ErrorBoundary);
|
|
20
|
+
|
|
21
|
+
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
|
22
|
+
args[_key] = arguments[_key];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ErrorBoundary.__proto__ || _Object$getPrototypeOf(ErrorBoundary)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
|
|
26
|
+
error: null,
|
|
27
|
+
info: null
|
|
28
|
+
}, _temp), _possibleConstructorReturn(_this, _ret);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
_createClass(ErrorBoundary, [{
|
|
32
|
+
key: 'componentDidCatch',
|
|
33
|
+
value: function componentDidCatch(error, info) {
|
|
34
|
+
var onError = this.props.onError;
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if (typeof onError === 'function') {
|
|
38
|
+
try {
|
|
39
|
+
/* istanbul ignore next: Ignoring ternary; can’t reproduce missing info in test environment. */
|
|
40
|
+
onError.call(this, error, info ? info.componentStack : '');
|
|
41
|
+
} catch (ignoredError) {}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.setState({ error: error, info: info });
|
|
45
|
+
}
|
|
46
|
+
}, {
|
|
47
|
+
key: 'render',
|
|
48
|
+
value: function render() {
|
|
49
|
+
var _props = this.props,
|
|
50
|
+
children = _props.children,
|
|
51
|
+
FallbackComponent = _props.FallbackComponent;
|
|
52
|
+
var _state = this.state,
|
|
53
|
+
error = _state.error,
|
|
54
|
+
info = _state.info;
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if (error !== null) {
|
|
58
|
+
return React.createElement(FallbackComponent, {
|
|
59
|
+
componentStack:
|
|
60
|
+
// istanbul ignore next: Ignoring ternary; can’t reproduce missing info in test environment.
|
|
61
|
+
info ? info.componentStack : '',
|
|
62
|
+
error: error
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return children || null;
|
|
67
|
+
}
|
|
68
|
+
}]);
|
|
69
|
+
|
|
70
|
+
return ErrorBoundary;
|
|
71
|
+
}(Component);
|
|
72
|
+
|
|
73
|
+
ErrorBoundary.defaultProps = {
|
|
74
|
+
FallbackComponent: ErrorBoundaryFallbackComponent
|
|
75
|
+
};
|
|
76
|
+
ErrorBoundary.propTypes = {
|
|
77
|
+
error: typeof Error === 'function' ? require('prop-types').instanceOf(Error) : require('prop-types').any,
|
|
78
|
+
info: require('prop-types').shape({
|
|
79
|
+
componentStack: require('prop-types').string.isRequired
|
|
80
|
+
})
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
export var withErrorBoundary = function withErrorBoundary(Component, FallbackComponent, onError) {
|
|
85
|
+
var Wrapped = function Wrapped(props) {
|
|
86
|
+
return React.createElement(
|
|
87
|
+
ErrorBoundary,
|
|
88
|
+
{ FallbackComponent: FallbackComponent, onError: onError },
|
|
89
|
+
React.createElement(Component, props)
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// Format for display in DevTools
|
|
94
|
+
var name = Component.displayName || Component.name;
|
|
95
|
+
Wrapped.displayName = name ? 'WithErrorBoundary(' + name + ')' : 'WithErrorBoundary';
|
|
96
|
+
|
|
97
|
+
return Wrapped;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
withErrorBoundary.propTypes = babelPluginFlowReactPropTypes_proptype_ComponentType === require('prop-types').any ? {} : babelPluginFlowReactPropTypes_proptype_ComponentType;
|
|
101
|
+
export default ErrorBoundary;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
var toTitle = function toTitle(error, componentStack) {
|
|
4
|
+
return error.toString() + "\n\nThis is located at:" + componentStack;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
var ErrorBoundaryFallbackComponent = function ErrorBoundaryFallbackComponent(_ref) {
|
|
8
|
+
var componentStack = _ref.componentStack,
|
|
9
|
+
error = _ref.error;
|
|
10
|
+
return React.createElement(
|
|
11
|
+
"div",
|
|
12
|
+
{ style: style, title: toTitle(error, componentStack) },
|
|
13
|
+
React.createElement(
|
|
14
|
+
"svg",
|
|
15
|
+
{ style: svgStyle, viewBox: "0 0 24 24", preserveAspectRatio: "xMidYMid" },
|
|
16
|
+
React.createElement("path", {
|
|
17
|
+
d: "M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,\n 12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,\n 12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,\n 9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,\n 8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,\n 15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,\n 17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z"
|
|
18
|
+
})
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
ErrorBoundaryFallbackComponent.propTypes = {
|
|
24
|
+
componentStack: require("prop-types").string.isRequired,
|
|
25
|
+
error: typeof Error === "function" ? require("prop-types").instanceOf(Error).isRequired : require("prop-types").any.isRequired
|
|
26
|
+
};
|
|
27
|
+
var style = {
|
|
28
|
+
height: '100%',
|
|
29
|
+
maxHeight: '100vh',
|
|
30
|
+
width: '100%',
|
|
31
|
+
maxWidth: '100vw',
|
|
32
|
+
display: 'flex',
|
|
33
|
+
flexDirection: 'column',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
textAlign: 'center',
|
|
36
|
+
backgroundColor: '#C00',
|
|
37
|
+
color: '#FFF',
|
|
38
|
+
boxSizing: 'border-box',
|
|
39
|
+
cursor: 'help'
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
var svgStyle = {
|
|
43
|
+
fill: 'currentColor',
|
|
44
|
+
flex: '1 1 auto'
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default ErrorBoundaryFallbackComponent;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { mount } from 'enzyme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import ErrorBoundary, { withErrorBoundary } from '../ErrorBoundary';
|
|
5
|
+
import ErrorBoundaryFallbackComponent from '../ErrorBoundaryFallbackComponent';
|
|
6
|
+
|
|
7
|
+
describe('ErrorBoundary', function () {
|
|
8
|
+
var consoleErrorSpy = void 0;
|
|
9
|
+
var mockError = void 0;
|
|
10
|
+
|
|
11
|
+
var Spell = void 0;
|
|
12
|
+
var Wand = void 0;
|
|
13
|
+
|
|
14
|
+
beforeAll(function () {
|
|
15
|
+
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(function () {
|
|
16
|
+
// React error boundaries print the error to `console.error` stream even when it’s caught by our
|
|
17
|
+
// `ErrorBoundary` component. We suppress `console.error` to keep our test console output clean.
|
|
18
|
+
// @see #11098 Allow suppressing error boundary logs from intentionally thrown/caught errors
|
|
19
|
+
// https://github.com/facebook/react/issues/11098
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
mockError = new Error('You cast an unforgivable curse! You’ve earned a one-way ticket to Azkaban.');
|
|
23
|
+
Spell = function Spell(_ref) {
|
|
24
|
+
var incantation = _ref.incantation;
|
|
25
|
+
|
|
26
|
+
switch (incantation) {
|
|
27
|
+
case 'Avada Kedavra':
|
|
28
|
+
case 'Crucio':
|
|
29
|
+
case 'Imperio':
|
|
30
|
+
throw mockError;
|
|
31
|
+
|
|
32
|
+
default:
|
|
33
|
+
return React.createElement(
|
|
34
|
+
'p',
|
|
35
|
+
null,
|
|
36
|
+
'You cast the ' + incantation + ' spell!'
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
Wand = function Wand(_ref2) {
|
|
42
|
+
var name = _ref2.name,
|
|
43
|
+
incantation = _ref2.incantation;
|
|
44
|
+
return React.createElement(
|
|
45
|
+
'div',
|
|
46
|
+
null,
|
|
47
|
+
React.createElement(
|
|
48
|
+
'p',
|
|
49
|
+
null,
|
|
50
|
+
'Casting spell with the ' + name + ' wand'
|
|
51
|
+
),
|
|
52
|
+
React.createElement(Spell, { incantation: incantation })
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
afterAll(function () {
|
|
58
|
+
consoleErrorSpy.mockRestore();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('Renders the child component if there is no error', function () {
|
|
62
|
+
var wrapper = mount(React.createElement(
|
|
63
|
+
ErrorBoundary,
|
|
64
|
+
null,
|
|
65
|
+
React.createElement(Wand, { name: 'Harry\u2019s', incantation: 'Expelliarmus' })
|
|
66
|
+
));
|
|
67
|
+
|
|
68
|
+
var WandWithErrorBoundary = withErrorBoundary(Wand);
|
|
69
|
+
var wrapperWithErrorBoundary = mount(React.createElement(WandWithErrorBoundary, { name: 'Harry\u2019s', incantation: 'Expelliarmus' }));
|
|
70
|
+
|
|
71
|
+
expect(wrapper.state().error).toBe(null);
|
|
72
|
+
expect(wrapper.state().info).toBe(null);
|
|
73
|
+
expect(wrapper.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, null))).toBe(false);
|
|
74
|
+
expect(wrapper.contains(React.createElement(Wand, { name: 'Harry\u2019s', incantation: 'Expelliarmus' }))).toBe(true);
|
|
75
|
+
|
|
76
|
+
// Note: We use `….instance().state …` instead of `….state() …` here because…
|
|
77
|
+
// > ReactWrapper::state() can only be called on the root
|
|
78
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.error).toBe(null);
|
|
79
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.info).toBe(null);
|
|
80
|
+
expect(wrapperWithErrorBoundary.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, null))).toBe(false);
|
|
81
|
+
expect(wrapperWithErrorBoundary.contains(React.createElement(Wand, { name: 'Harry\u2019s', incantation: 'Expelliarmus' }))).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('Sets its state to an error state and renders the default fallback component', function () {
|
|
85
|
+
var wrapper = mount(React.createElement(
|
|
86
|
+
ErrorBoundary,
|
|
87
|
+
null,
|
|
88
|
+
React.createElement(Wand, { name: 'Voldemort\u2019s', incantation: 'Avada Kedavra' })
|
|
89
|
+
));
|
|
90
|
+
|
|
91
|
+
var WandWithErrorBoundary = withErrorBoundary(Wand);
|
|
92
|
+
var wrapperWithErrorBoundary = mount(React.createElement(WandWithErrorBoundary, { name: 'Voldemort\u2019s', incantation: 'Avada Kedavra' }));
|
|
93
|
+
|
|
94
|
+
expect(wrapper.state().error).toEqual(expect.objectContaining(mockError));
|
|
95
|
+
expect(wrapper.state().info).toEqual(expect.objectContaining({
|
|
96
|
+
componentStack: expect.any(String)
|
|
97
|
+
}));
|
|
98
|
+
expect(wrapper.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, null))).toBe(true);
|
|
99
|
+
|
|
100
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.error).toEqual(expect.objectContaining(mockError));
|
|
101
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.info).toEqual(expect.objectContaining({
|
|
102
|
+
componentStack: expect.any(String)
|
|
103
|
+
}));
|
|
104
|
+
expect(wrapperWithErrorBoundary.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, null))).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('Sets its state to an error state and renders a custom fallback component', function () {
|
|
108
|
+
var MockFallbackComponent = function MockFallbackComponent(_ref3) {
|
|
109
|
+
var error = _ref3.error,
|
|
110
|
+
componentStack = _ref3.componentStack;
|
|
111
|
+
return React.createElement(
|
|
112
|
+
'div',
|
|
113
|
+
null,
|
|
114
|
+
React.createElement(
|
|
115
|
+
'p',
|
|
116
|
+
null,
|
|
117
|
+
React.createElement(
|
|
118
|
+
'strong',
|
|
119
|
+
null,
|
|
120
|
+
'Wand unable to perform magic!'
|
|
121
|
+
),
|
|
122
|
+
'Please contact Ollivanders in Diagon Alley for repairs.'
|
|
123
|
+
),
|
|
124
|
+
React.createElement(
|
|
125
|
+
'p',
|
|
126
|
+
null,
|
|
127
|
+
React.createElement(
|
|
128
|
+
'strong',
|
|
129
|
+
null,
|
|
130
|
+
'Error:'
|
|
131
|
+
),
|
|
132
|
+
' ',
|
|
133
|
+
error.toString()
|
|
134
|
+
),
|
|
135
|
+
React.createElement(
|
|
136
|
+
'p',
|
|
137
|
+
null,
|
|
138
|
+
React.createElement(
|
|
139
|
+
'strong',
|
|
140
|
+
null,
|
|
141
|
+
'Stacktrace:'
|
|
142
|
+
),
|
|
143
|
+
React.createElement(
|
|
144
|
+
'pre',
|
|
145
|
+
null,
|
|
146
|
+
componentStack
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
var wrapper = mount(React.createElement(
|
|
153
|
+
ErrorBoundary,
|
|
154
|
+
{ FallbackComponent: MockFallbackComponent },
|
|
155
|
+
React.createElement(Wand, { name: 'Voldemort\u2019s', incantation: 'Crucio' })
|
|
156
|
+
));
|
|
157
|
+
|
|
158
|
+
var WandWithErrorBoundary = withErrorBoundary(Wand, MockFallbackComponent);
|
|
159
|
+
var wrapperWithErrorBoundary = mount(React.createElement(WandWithErrorBoundary, { name: 'Voldemort\u2019s', incantation: 'Crucio' }));
|
|
160
|
+
|
|
161
|
+
expect(wrapper.state().error).toEqual(expect.objectContaining(mockError));
|
|
162
|
+
expect(wrapper.state().info).toEqual(expect.objectContaining({
|
|
163
|
+
componentStack: expect.any(String)
|
|
164
|
+
}));
|
|
165
|
+
expect(wrapper.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, null))).toBe(false);
|
|
166
|
+
expect(wrapper.containsMatchingElement(React.createElement(MockFallbackComponent, {
|
|
167
|
+
error: mockError /* componentStack="ignored" */
|
|
168
|
+
}))).toBe(true);
|
|
169
|
+
|
|
170
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.error).toEqual(expect.objectContaining(mockError));
|
|
171
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.info).toEqual(expect.objectContaining({
|
|
172
|
+
componentStack: expect.any(String)
|
|
173
|
+
}));
|
|
174
|
+
expect(wrapperWithErrorBoundary.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, null))).toBe(false);
|
|
175
|
+
expect(wrapperWithErrorBoundary.containsMatchingElement(React.createElement(MockFallbackComponent, {
|
|
176
|
+
error: mockError /* componentStack="ignored" */
|
|
177
|
+
}))).toBe(true);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('Sets its state to an error state and invokes the onError callback prop', function () {
|
|
181
|
+
var mockOnError = jest.fn().mockImplementation(function (error, // eslint-disable-line no-unused-vars
|
|
182
|
+
info) // eslint-disable-line no-unused-vars
|
|
183
|
+
{});
|
|
184
|
+
|
|
185
|
+
var mockOnErrorWithErrorBoundary = jest.fn().mockImplementation(function (error, // eslint-disable-line no-unused-vars
|
|
186
|
+
info) // eslint-disable-line no-unused-vars
|
|
187
|
+
{});
|
|
188
|
+
|
|
189
|
+
var wrapper = mount(React.createElement(
|
|
190
|
+
ErrorBoundary,
|
|
191
|
+
{ onError: mockOnError },
|
|
192
|
+
React.createElement(Wand, { name: 'Voldemort\u2019s', incantation: 'Imperio' })
|
|
193
|
+
));
|
|
194
|
+
var WandWithErrorBoundary = withErrorBoundary(Wand, ErrorBoundaryFallbackComponent, mockOnErrorWithErrorBoundary);
|
|
195
|
+
var wrapperWithErrorBoundary = mount(React.createElement(WandWithErrorBoundary, { name: 'Voldemort\u2019s', incantation: 'Imperio' }));
|
|
196
|
+
|
|
197
|
+
expect(wrapper.state().error).toEqual(expect.objectContaining(mockError));
|
|
198
|
+
expect(wrapper.state().info).toEqual(expect.objectContaining({
|
|
199
|
+
componentStack: expect.any(String)
|
|
200
|
+
}));
|
|
201
|
+
expect(mockOnError).toHaveBeenCalledWith(mockError, expect.any(String));
|
|
202
|
+
expect(wrapper.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, {
|
|
203
|
+
error: mockError /* componentStack="ignored" */
|
|
204
|
+
}))).toBe(true);
|
|
205
|
+
|
|
206
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.error).toEqual(expect.objectContaining(mockError));
|
|
207
|
+
expect(wrapperWithErrorBoundary.find(ErrorBoundary).instance().state.info).toEqual(expect.objectContaining({
|
|
208
|
+
componentStack: expect.any(String)
|
|
209
|
+
}));
|
|
210
|
+
expect(mockOnErrorWithErrorBoundary).toHaveBeenCalledWith(mockError, expect.any(String));
|
|
211
|
+
expect(wrapperWithErrorBoundary.containsMatchingElement(React.createElement(ErrorBoundaryFallbackComponent, {
|
|
212
|
+
error: mockError /* componentStack="ignored" */
|
|
213
|
+
}))).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('sets the correct displayName for wrapped components', function () {
|
|
217
|
+
function NormalComponent() {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
expect(withErrorBoundary(NormalComponent).displayName).toBe('WithErrorBoundary(NormalComponent)');
|
|
221
|
+
|
|
222
|
+
function ComponentWithDisplayNameOverride() {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
ComponentWithDisplayNameOverride.displayName = 'Override';
|
|
226
|
+
|
|
227
|
+
expect(withErrorBoundary(ComponentWithDisplayNameOverride).displayName).toBe('WithErrorBoundary(Override)');
|
|
228
|
+
expect(withErrorBoundary(function () {
|
|
229
|
+
return null;
|
|
230
|
+
}).displayName).toBe('WithErrorBoundary');
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
|
|
4
|
+
import ErrorBoundaryFallbackComponent from '../ErrorBoundaryFallbackComponent';
|
|
5
|
+
|
|
6
|
+
describe('ErrorBoundaryFallbackComponent', function () {
|
|
7
|
+
var mockError = void 0;
|
|
8
|
+
|
|
9
|
+
beforeAll(function () {
|
|
10
|
+
mockError = new Error('You cast an unforgivable curse! You’ve earned a one-way ticket to Azkaban.');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('Passes a snapshot test', function () {
|
|
14
|
+
var wrapper = shallow(React.createElement(ErrorBoundaryFallbackComponent, { error: mockError, componentStack: '' }));
|
|
15
|
+
|
|
16
|
+
expect(wrapper).toMatchSnapshot();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`ErrorBoundaryFallbackComponent Passes a snapshot test 1`] = `
|
|
4
|
+
ShallowWrapper {
|
|
5
|
+
Symbol(enzyme.__root__): [Circular],
|
|
6
|
+
Symbol(enzyme.__unrendered__): <ErrorBoundaryFallbackComponent
|
|
7
|
+
componentStack=""
|
|
8
|
+
error={[Error: You cast an unforgivable curse! You’ve earned a one-way ticket to Azkaban.]}
|
|
9
|
+
/>,
|
|
10
|
+
Symbol(enzyme.__renderer__): Object {
|
|
11
|
+
"batchedUpdates": [Function],
|
|
12
|
+
"getNode": [Function],
|
|
13
|
+
"render": [Function],
|
|
14
|
+
"simulateEvent": [Function],
|
|
15
|
+
"unmount": [Function],
|
|
16
|
+
},
|
|
17
|
+
Symbol(enzyme.__node__): Object {
|
|
18
|
+
"instance": null,
|
|
19
|
+
"key": undefined,
|
|
20
|
+
"nodeType": "host",
|
|
21
|
+
"props": Object {
|
|
22
|
+
"children": <svg
|
|
23
|
+
preserveAspectRatio="xMidYMid"
|
|
24
|
+
style={
|
|
25
|
+
Object {
|
|
26
|
+
"fill": "currentColor",
|
|
27
|
+
"flex": "1 1 auto",
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
viewBox="0 0 24 24"
|
|
31
|
+
>
|
|
32
|
+
<path
|
|
33
|
+
d="M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,
|
|
34
|
+
12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,
|
|
35
|
+
12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,
|
|
36
|
+
9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,
|
|
37
|
+
8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,
|
|
38
|
+
15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,
|
|
39
|
+
17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z"
|
|
40
|
+
/>
|
|
41
|
+
</svg>,
|
|
42
|
+
"style": Object {
|
|
43
|
+
"alignItems": "center",
|
|
44
|
+
"backgroundColor": "#C00",
|
|
45
|
+
"boxSizing": "border-box",
|
|
46
|
+
"color": "#FFF",
|
|
47
|
+
"cursor": "help",
|
|
48
|
+
"display": "flex",
|
|
49
|
+
"flexDirection": "column",
|
|
50
|
+
"height": "100%",
|
|
51
|
+
"maxHeight": "100vh",
|
|
52
|
+
"maxWidth": "100vw",
|
|
53
|
+
"textAlign": "center",
|
|
54
|
+
"width": "100%",
|
|
55
|
+
},
|
|
56
|
+
"title": "Error: You cast an unforgivable curse! You’ve earned a one-way ticket to Azkaban.
|
|
57
|
+
|
|
58
|
+
This is located at:",
|
|
59
|
+
},
|
|
60
|
+
"ref": null,
|
|
61
|
+
"rendered": Object {
|
|
62
|
+
"instance": null,
|
|
63
|
+
"key": undefined,
|
|
64
|
+
"nodeType": "host",
|
|
65
|
+
"props": Object {
|
|
66
|
+
"children": <path
|
|
67
|
+
d="M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,
|
|
68
|
+
12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,
|
|
69
|
+
12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,
|
|
70
|
+
9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,
|
|
71
|
+
8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,
|
|
72
|
+
15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,
|
|
73
|
+
17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z"
|
|
74
|
+
/>,
|
|
75
|
+
"preserveAspectRatio": "xMidYMid",
|
|
76
|
+
"style": Object {
|
|
77
|
+
"fill": "currentColor",
|
|
78
|
+
"flex": "1 1 auto",
|
|
79
|
+
},
|
|
80
|
+
"viewBox": "0 0 24 24",
|
|
81
|
+
},
|
|
82
|
+
"ref": null,
|
|
83
|
+
"rendered": Object {
|
|
84
|
+
"instance": null,
|
|
85
|
+
"key": undefined,
|
|
86
|
+
"nodeType": "host",
|
|
87
|
+
"props": Object {
|
|
88
|
+
"d": "M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,
|
|
89
|
+
12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,
|
|
90
|
+
12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,
|
|
91
|
+
9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,
|
|
92
|
+
8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,
|
|
93
|
+
15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,
|
|
94
|
+
17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z",
|
|
95
|
+
},
|
|
96
|
+
"ref": null,
|
|
97
|
+
"rendered": null,
|
|
98
|
+
"type": "path",
|
|
99
|
+
},
|
|
100
|
+
"type": "svg",
|
|
101
|
+
},
|
|
102
|
+
"type": "div",
|
|
103
|
+
},
|
|
104
|
+
Symbol(enzyme.__nodes__): Array [
|
|
105
|
+
Object {
|
|
106
|
+
"instance": null,
|
|
107
|
+
"key": undefined,
|
|
108
|
+
"nodeType": "host",
|
|
109
|
+
"props": Object {
|
|
110
|
+
"children": <svg
|
|
111
|
+
preserveAspectRatio="xMidYMid"
|
|
112
|
+
style={
|
|
113
|
+
Object {
|
|
114
|
+
"fill": "currentColor",
|
|
115
|
+
"flex": "1 1 auto",
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
viewBox="0 0 24 24"
|
|
119
|
+
>
|
|
120
|
+
<path
|
|
121
|
+
d="M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,
|
|
122
|
+
12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,
|
|
123
|
+
12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,
|
|
124
|
+
9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,
|
|
125
|
+
8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,
|
|
126
|
+
15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,
|
|
127
|
+
17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z"
|
|
128
|
+
/>
|
|
129
|
+
</svg>,
|
|
130
|
+
"style": Object {
|
|
131
|
+
"alignItems": "center",
|
|
132
|
+
"backgroundColor": "#C00",
|
|
133
|
+
"boxSizing": "border-box",
|
|
134
|
+
"color": "#FFF",
|
|
135
|
+
"cursor": "help",
|
|
136
|
+
"display": "flex",
|
|
137
|
+
"flexDirection": "column",
|
|
138
|
+
"height": "100%",
|
|
139
|
+
"maxHeight": "100vh",
|
|
140
|
+
"maxWidth": "100vw",
|
|
141
|
+
"textAlign": "center",
|
|
142
|
+
"width": "100%",
|
|
143
|
+
},
|
|
144
|
+
"title": "Error: You cast an unforgivable curse! You’ve earned a one-way ticket to Azkaban.
|
|
145
|
+
|
|
146
|
+
This is located at:",
|
|
147
|
+
},
|
|
148
|
+
"ref": null,
|
|
149
|
+
"rendered": Object {
|
|
150
|
+
"instance": null,
|
|
151
|
+
"key": undefined,
|
|
152
|
+
"nodeType": "host",
|
|
153
|
+
"props": Object {
|
|
154
|
+
"children": <path
|
|
155
|
+
d="M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,
|
|
156
|
+
12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,
|
|
157
|
+
12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,
|
|
158
|
+
9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,
|
|
159
|
+
8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,
|
|
160
|
+
15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,
|
|
161
|
+
17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z"
|
|
162
|
+
/>,
|
|
163
|
+
"preserveAspectRatio": "xMidYMid",
|
|
164
|
+
"style": Object {
|
|
165
|
+
"fill": "currentColor",
|
|
166
|
+
"flex": "1 1 auto",
|
|
167
|
+
},
|
|
168
|
+
"viewBox": "0 0 24 24",
|
|
169
|
+
},
|
|
170
|
+
"ref": null,
|
|
171
|
+
"rendered": Object {
|
|
172
|
+
"instance": null,
|
|
173
|
+
"key": undefined,
|
|
174
|
+
"nodeType": "host",
|
|
175
|
+
"props": Object {
|
|
176
|
+
"d": "M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,
|
|
177
|
+
12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,
|
|
178
|
+
12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,
|
|
179
|
+
9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,
|
|
180
|
+
8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,
|
|
181
|
+
15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,
|
|
182
|
+
17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z",
|
|
183
|
+
},
|
|
184
|
+
"ref": null,
|
|
185
|
+
"rendered": null,
|
|
186
|
+
"type": "path",
|
|
187
|
+
},
|
|
188
|
+
"type": "svg",
|
|
189
|
+
},
|
|
190
|
+
"type": "div",
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
Symbol(enzyme.__options__): Object {
|
|
194
|
+
"adapter": ReactSixteenAdapter {
|
|
195
|
+
"options": Object {
|
|
196
|
+
"enableComponentDidUpdateOnSetState": true,
|
|
197
|
+
"lifecycles": Object {
|
|
198
|
+
"componentDidUpdate": Object {
|
|
199
|
+
"onSetState": true,
|
|
200
|
+
},
|
|
201
|
+
"getDerivedStateFromProps": true,
|
|
202
|
+
"getSnapshotBeforeUpdate": true,
|
|
203
|
+
"setState": Object {
|
|
204
|
+
"skipsComponentDidUpdateOnNullish": true,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
"attachTo": undefined,
|
|
210
|
+
"hydrateIn": undefined,
|
|
211
|
+
},
|
|
212
|
+
}
|
|
213
|
+
`;
|
package/dist/es/index.js
ADDED