let React;
let ReactNoop;
let Scheduler;
let act;
let Activity;
let useState;
let assertLog;
describe('Activity error handling', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactNoop = require('react-noop-renderer');
Scheduler = require('scheduler');
act = require('internal-test-utils').act;
Activity = React.Activity;
useState = React.useState;
const InternalTestUtils = require('internal-test-utils');
assertLog = InternalTestUtils.assertLog;
});
function Text({text}) {
Scheduler.log(text);
return text;
}
it(
'errors inside a hidden Activity do not escape in the visible part ' +
'of the UI',
async () => {
class ErrorBoundary extends React.Component {
state = {error: null};
static getDerivedStateFromError(error) {
return {error};
}
render() {
if (this.state.error) {
return (
<Text text={`Caught an error: ${this.state.error.message}`} />
);
}
return this.props.children;
}
}
function Throws() {
throw new Error('Oops!');
}
let setShowMore;
function App({content, more}) {
const [showMore, _setShowMore] = useState(false);
setShowMore = _setShowMore;
return (
<>
<div>{content}</div>
<div>
<ErrorBoundary>
<Activity mode={showMore ? 'visible' : 'hidden'}>
{more}
</Activity>
</ErrorBoundary>
</div>
</>
);
}
await act(() =>
ReactNoop.render(
<App content={<Text text="Visible" />} more={<Throws />} />,
),
);
assertLog(['Visible']);
expect(ReactNoop).toMatchRenderedOutput(
<>
<div>Visible</div>
<div />
</>,
);
await act(() => setShowMore(true));
assertLog(['Caught an error: Oops!', 'Caught an error: Oops!']);
expect(ReactNoop).toMatchRenderedOutput(
<>
<div>Visible</div>
<div>Caught an error: Oops!</div>
</>,
);
},
);
});