Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 3

/**

* Copyright (c) Meta Platforms, Inc. and affiliates.


*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

describe('profiling HostRoot', () => {


let React;
let ReactDOMClient;
let Scheduler;
let legacyRender;
let store;
let utils;
let getEffectDurations;
let effectDurations;
let passiveEffectDurations;

beforeEach(() => {
utils = require('./utils');
utils.beforeEachProfiling();

legacyRender = utils.legacyRender;

getEffectDurations = require('../backend/utils').getEffectDurations;

store = global.store;

React = require('react');
ReactDOMClient = require('react-dom/client');
Scheduler = require('scheduler');

effectDurations = [];
passiveEffectDurations = [];

// This is the DevTools hook installed by the env.beforEach()


// The hook is installed as a read-only property on the window,
// so for our test purposes we can just override the commit hook.
const hook = global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
hook.onPostCommitFiberRoot = function onPostCommitFiberRoot(
rendererID,
root,
) {
const {effectDuration, passiveEffectDuration} = getEffectDurations(root);
effectDurations.push(effectDuration);
passiveEffectDurations.push(passiveEffectDuration);
};
});

// @reactVersion >=18.0
it('should expose passive and layout effect durations for render()', () => {
function App() {
React.useEffect(() => {
Scheduler.unstable_advanceTime(10);
});
React.useLayoutEffect(() => {
Scheduler.unstable_advanceTime(100);
});
return null;
}

utils.act(() => store.profilerStore.startProfiling());


utils.act(() => {
const container = document.createElement('div');
legacyRender(<App />, container);
});
utils.act(() => store.profilerStore.stopProfiling());

expect(effectDurations).toHaveLength(1);
const effectDuration = effectDurations[0];
expect(effectDuration === null || effectDuration === 100).toBe(true);
expect(passiveEffectDurations).toHaveLength(1);
const passiveEffectDuration = passiveEffectDurations[0];
expect(passiveEffectDuration === null || passiveEffectDuration === 10).toBe(
true,
);
});

// @reactVersion >=18.0
it('should expose passive and layout effect durations for createRoot()', () => {
function App() {
React.useEffect(() => {
Scheduler.unstable_advanceTime(10);
});
React.useLayoutEffect(() => {
Scheduler.unstable_advanceTime(100);
});
return null;
}

utils.act(() => store.profilerStore.startProfiling());


utils.act(() => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);
root.render(<App />);
});
utils.act(() => store.profilerStore.stopProfiling());

expect(effectDurations).toHaveLength(1);
const effectDuration = effectDurations[0];
expect(effectDuration === null || effectDuration === 100).toBe(true);
expect(passiveEffectDurations).toHaveLength(1);
const passiveEffectDuration = passiveEffectDurations[0];
expect(passiveEffectDuration === null || passiveEffectDuration === 10).toBe(
true,
);
});

// @reactVersion >=18.0
it('should properly reset passive and layout effect durations between commits',
() => {
function App({shouldCascade}) {
const [, setState] = React.useState(false);
React.useEffect(() => {
Scheduler.unstable_advanceTime(10);
});
React.useLayoutEffect(() => {
Scheduler.unstable_advanceTime(100);
});
React.useLayoutEffect(() => {
if (shouldCascade) {
setState(true);
}
}, [shouldCascade]);
return null;
}

const container = document.createElement('div');


const root = ReactDOMClient.createRoot(container);

utils.act(() => store.profilerStore.startProfiling());


utils.act(() => root.render(<App />));
utils.act(() => root.render(<App shouldCascade={true} />));
utils.act(() => store.profilerStore.stopProfiling());

expect(effectDurations).toHaveLength(3);
expect(passiveEffectDurations).toHaveLength(3);

for (let i = 0; i < effectDurations.length; i++) {


const effectDuration = effectDurations[i];
expect(effectDuration === null || effectDuration === 100).toBe(true);
const passiveEffectDuration = passiveEffectDurations[i];
expect(
passiveEffectDuration === null || passiveEffectDuration === 10,
).toBe(true);
}
});
});

You might also like