'use strict';
let React;
let ReactDOMClient;
let ReactFeatureFlags;
let act;
let container;
function loadModules({
enableProfilerTimer = true,
enableProfilerCommitHooks = true,
enableProfilerNestedUpdatePhase = true,
} = {}) {
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.enableProfilerTimer = enableProfilerTimer;
ReactFeatureFlags.enableProfilerCommitHooks = enableProfilerCommitHooks;
ReactFeatureFlags.enableProfilerNestedUpdatePhase =
enableProfilerNestedUpdatePhase;
React = require('react');
ReactDOMClient = require('react-dom/client');
const InternalTestUtils = require('internal-test-utils');
act = InternalTestUtils.act;
}
describe('Profiler', () => {
beforeEach(() => {
container = document.createElement('div');
});
describe('works in profiling and non-profiling bundles', () => {
[true, false].forEach(enableProfilerTimer => {
describe(`enableProfilerTimer:${
enableProfilerTimer ? 'enabled' : 'disabled'
}`, () => {
beforeEach(() => {
jest.resetModules();
loadModules({enableProfilerTimer});
});
if (__DEV__ && enableProfilerTimer) {
it('should warn if required params are missing', async () => {
const root = ReactDOMClient.createRoot(container);
await expect(async () => {
await act(() => {
root.render(<React.Profiler />);
});
}).toErrorDev(
'Profiler must specify an "id" of type `string` as a prop. Received the type `undefined` instead.',
{
withoutStack: true,
},
);
});
}
it('should support an empty Profiler (with no children)', async () => {
const root = ReactDOMClient.createRoot(container);
await act(() => {
root.render(<React.Profiler id="label" onRender={jest.fn()} />);
});
expect(container.innerHTML).toMatchSnapshot();
await act(() => {
root.render(
<div>
<React.Profiler id="label" onRender={jest.fn()} />
</div>,
);
});
expect(container.innerHTML).toMatchSnapshot();
});
it('should render children', async () => {
const FunctionComponent = ({label}) => <span>{label}</span>;
const root = ReactDOMClient.createRoot(container);
await act(() => {
root.render(
<div>
<span>outside span</span>
<React.Profiler id="label" onRender={jest.fn()}>
<span>inside span</span>
<FunctionComponent label="function component" />
</React.Profiler>
</div>,
);
});
expect(container.innerHTML).toMatchSnapshot();
});
it('should support nested Profilers', async () => {
const FunctionComponent = ({label}) => <div>{label}</div>;
class ClassComponent extends React.Component {
render() {
return <span>{this.props.label}</span>;
}
}
const root = ReactDOMClient.createRoot(container);
await act(() => {
root.render(
<React.Profiler id="outer" onRender={jest.fn()}>
<FunctionComponent label="outer function component" />
<React.Profiler id="inner" onRender={jest.fn()}>
<ClassComponent label="inner class component" />
<span>inner span</span>
</React.Profiler>
</React.Profiler>,
);
});
expect(container.innerHTML).toMatchSnapshot();
});
});
});
});
});