Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Separate Rethrow and Noop scenarios in boundary tests
  • Loading branch information
gaearon committed Nov 30, 2016
commit 7bc10c0dd9442afbf2bc7b113bc0ec9ae7fe6358
1 change: 1 addition & 0 deletions scripts/fiber/tests-passing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,7 @@ src/renderers/shared/shared/__tests__/ReactErrorBoundaries-test.js
* propagates errors inside boundary during componentDidMount
* lets different boundaries catch their own first errors
* discards a bad root if the root component fails
* renders empty output if error boundary does not handle the error

src/renderers/shared/shared/__tests__/ReactIdentity-test.js
* should allow key property to express identity
Expand Down
102 changes: 86 additions & 16 deletions src/renderers/shared/shared/__tests__/ReactErrorBoundaries-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ describe('ReactErrorBoundaries', () => {
var ErrorBoundary;
var ErrorMessage;
var NoopErrorBoundary;
var RethrowErrorBoundary;
var Normal;

beforeEach(() => {
Expand Down Expand Up @@ -394,7 +395,12 @@ describe('ReactErrorBoundaries', () => {
log.push('NoopErrorBoundary componentWillUnmount');
}
unstable_handleError() {
log.push('NoopErrorBoundary unstable_handleError');
if (ReactDOMFeatureFlags.useFiber) {
log.push('NoopErrorBoundary unstable_handleError');
} else {
// In Stack, not calling setState() is treated as a rethrow.
log.push('NoopErrorBoundary unstable_handleError [*]');
}
}
};

Expand Down Expand Up @@ -478,6 +484,35 @@ describe('ReactErrorBoundaries', () => {
},
};

RethrowErrorBoundary = class extends React.Component {
constructor(props) {
super(props);
log.push('RethrowErrorBoundary constructor');
}
render() {
log.push('RethrowErrorBoundary render');
return <BrokenRender />;
}
componentWillMount() {
log.push('RethrowErrorBoundary componentWillMount');
}
componentDidMount() {
log.push('RethrowErrorBoundary componentDidMount');
}
componentWillUnmount() {
log.push('RethrowErrorBoundary componentWillUnmount');
}
unstable_handleError(error) {
if (!ReactDOMFeatureFlags.useFiber) {
log.push('RethrowErrorBoundary unstable_handleError [*]');
// In Stack, not calling setState() is treated as a rethrow.
return;
}
log.push('RethrowErrorBoundary unstable_handleError [!]');
throw error;
}
};

ErrorMessage = class extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -753,35 +788,41 @@ describe('ReactErrorBoundaries', () => {
var container = document.createElement('div');
ReactDOM.render(
<ErrorBoundary>
<NoopErrorBoundary>
<RethrowErrorBoundary>
<BrokenRender />
</NoopErrorBoundary>
</RethrowErrorBoundary>
</ErrorBoundary>,
container
);
expect(container.firstChild.textContent).toBe(
ReactDOMFeatureFlags.useFiber ? '' : 'Caught an error: Hello.'
);
expect(container.firstChild.textContent).toBe('Caught an error: Hello.');
expect(log).toEqual([
'ErrorBoundary constructor',
'ErrorBoundary componentWillMount',
'ErrorBoundary render success',
'NoopErrorBoundary constructor',
'NoopErrorBoundary componentWillMount',
'NoopErrorBoundary render',
'RethrowErrorBoundary constructor',
'RethrowErrorBoundary componentWillMount',
'RethrowErrorBoundary render',
'BrokenRender constructor',
'BrokenRender componentWillMount',
'BrokenRender render [!]',
...(ReactDOMFeatureFlags.useFiber ? [
// In Fiber, noop error boundaries render null
'NoopErrorBoundary componentDidMount',
'RethrowErrorBoundary componentDidMount',
'ErrorBoundary componentDidMount',
'NoopErrorBoundary unstable_handleError',
'RethrowErrorBoundary unstable_handleError [!]',
// The error got rethrown here.
// This time, the error propagates to the higher boundary
'RethrowErrorBoundary componentWillUnmount',
'ErrorBoundary unstable_handleError',
// Render the error
'ErrorBoundary componentWillUpdate',
'ErrorBoundary render error',
'ErrorBoundary componentDidUpdate',
] : [
// The first error boundary catches the error.
// However, it doesn't adjust its state so next render will also fail.
'NoopErrorBoundary unstable_handleError',
'NoopErrorBoundary render',
'RethrowErrorBoundary unstable_handleError [*]',
'RethrowErrorBoundary render',
'BrokenRender constructor',
'BrokenRender componentWillMount',
'BrokenRender render [!]',
Expand All @@ -797,9 +838,6 @@ describe('ReactErrorBoundaries', () => {
ReactDOM.unmountComponentAtNode(container);
expect(log).toEqual([
'ErrorBoundary componentWillUnmount',
...(ReactDOMFeatureFlags.useFiber ? [
'NoopErrorBoundary componentWillUnmount',
] : []),
]);
});

Expand Down Expand Up @@ -2051,6 +2089,38 @@ describe('ReactErrorBoundaries', () => {
expect(err1.message).toMatch(/got: null/);
expect(err2.message).toMatch(/got: undefined/);
});

it('renders empty output if error boundary does not handle the error', () => {
var container = document.createElement('div');
ReactDOM.render(
<div>
Sibling
<NoopErrorBoundary>
<BrokenRender />
</NoopErrorBoundary>
</div>,
container
);
expect(container.firstChild.textContent).toBe('Sibling');
expect(log).toEqual([
'NoopErrorBoundary constructor',
'NoopErrorBoundary componentWillMount',
'NoopErrorBoundary render',
'BrokenRender constructor',
'BrokenRender componentWillMount',
'BrokenRender render [!]',
// In Fiber, noop error boundaries render null
'NoopErrorBoundary componentDidMount',
'NoopErrorBoundary unstable_handleError',
// Nothing happens.
]);

log.length = 0;
ReactDOM.unmountComponentAtNode(container);
expect(log).toEqual([
'NoopErrorBoundary componentWillUnmount',
]);
});
}

});