mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
223 lines
6.0 KiB
JavaScript
223 lines
6.0 KiB
JavaScript
/**
|
|
* 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
|
|
*/
|
|
|
|
import typeof ReactTestRenderer from 'react-test-renderer';
|
|
import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types';
|
|
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
|
|
import type Store from 'react-devtools-shared/src/devtools/store';
|
|
|
|
describe('OwnersListContext', () => {
|
|
let React;
|
|
let TestRenderer: ReactTestRenderer;
|
|
let bridge: FrontendBridge;
|
|
let legacyRender;
|
|
let store: Store;
|
|
let utils;
|
|
|
|
let BridgeContext;
|
|
let OwnersListContext;
|
|
let OwnersListContextController;
|
|
let StoreContext;
|
|
let TreeContextController;
|
|
|
|
beforeEach(() => {
|
|
utils = require('./utils');
|
|
utils.beforeEachProfiling();
|
|
|
|
legacyRender = utils.legacyRender;
|
|
|
|
bridge = global.bridge;
|
|
store = global.store;
|
|
store.collapseNodesByDefault = false;
|
|
|
|
React = require('react');
|
|
TestRenderer = utils.requireTestRenderer();
|
|
|
|
BridgeContext =
|
|
require('react-devtools-shared/src/devtools/views/context').BridgeContext;
|
|
OwnersListContext =
|
|
require('react-devtools-shared/src/devtools/views/Components/OwnersListContext').OwnersListContext;
|
|
OwnersListContextController =
|
|
require('react-devtools-shared/src/devtools/views/Components/OwnersListContext').OwnersListContextController;
|
|
StoreContext =
|
|
require('react-devtools-shared/src/devtools/views/context').StoreContext;
|
|
TreeContextController =
|
|
require('react-devtools-shared/src/devtools/views/Components/TreeContext').TreeContextController;
|
|
});
|
|
|
|
const Contexts = ({children, defaultOwnerID = null}) => (
|
|
<BridgeContext.Provider value={bridge}>
|
|
<StoreContext.Provider value={store}>
|
|
<TreeContextController defaultOwnerID={defaultOwnerID}>
|
|
<OwnersListContextController>{children}</OwnersListContextController>
|
|
</TreeContextController>
|
|
</StoreContext.Provider>
|
|
</BridgeContext.Provider>
|
|
);
|
|
|
|
async function getOwnersListForOwner(owner) {
|
|
let ownerDisplayNames = null;
|
|
|
|
function Suspender() {
|
|
const read = React.useContext(OwnersListContext);
|
|
const owners = read(owner.id);
|
|
ownerDisplayNames = owners.map(({displayName}) => displayName);
|
|
return null;
|
|
}
|
|
|
|
await utils.actAsync(() =>
|
|
TestRenderer.create(
|
|
<Contexts defaultOwnerID={owner.id}>
|
|
<React.Suspense fallback={null}>
|
|
<Suspender owner={owner} />
|
|
</React.Suspense>
|
|
</Contexts>,
|
|
),
|
|
);
|
|
|
|
expect(ownerDisplayNames).not.toBeNull();
|
|
|
|
return ownerDisplayNames;
|
|
}
|
|
|
|
it('should fetch the owners list for the selected element', async () => {
|
|
const Grandparent = () => <Parent />;
|
|
const Parent = () => {
|
|
return (
|
|
<React.Fragment>
|
|
<Child />
|
|
<Child />
|
|
</React.Fragment>
|
|
);
|
|
};
|
|
const Child = () => null;
|
|
|
|
utils.act(() =>
|
|
legacyRender(<Grandparent />, document.createElement('div')),
|
|
);
|
|
|
|
expect(store).toMatchInlineSnapshot(`
|
|
[root]
|
|
▾ <Grandparent>
|
|
▾ <Parent>
|
|
<Child>
|
|
<Child>
|
|
`);
|
|
|
|
const parent = ((store.getElementAtIndex(1): any): Element);
|
|
const firstChild = ((store.getElementAtIndex(2): any): Element);
|
|
|
|
expect(await getOwnersListForOwner(parent)).toMatchInlineSnapshot(`
|
|
[
|
|
"Grandparent",
|
|
"Parent",
|
|
]
|
|
`);
|
|
|
|
expect(await getOwnersListForOwner(firstChild)).toMatchInlineSnapshot(`
|
|
[
|
|
"Grandparent",
|
|
"Parent",
|
|
"Child",
|
|
]
|
|
`);
|
|
});
|
|
|
|
it('should fetch the owners list for the selected element that includes filtered components', async () => {
|
|
store.componentFilters = [utils.createDisplayNameFilter('^Parent$')];
|
|
|
|
const Grandparent = () => <Parent />;
|
|
const Parent = () => {
|
|
return (
|
|
<React.Fragment>
|
|
<Child />
|
|
<Child />
|
|
</React.Fragment>
|
|
);
|
|
};
|
|
const Child = () => null;
|
|
|
|
utils.act(() =>
|
|
legacyRender(<Grandparent />, document.createElement('div')),
|
|
);
|
|
|
|
expect(store).toMatchInlineSnapshot(`
|
|
[root]
|
|
▾ <Grandparent>
|
|
<Child>
|
|
<Child>
|
|
`);
|
|
|
|
const firstChild = ((store.getElementAtIndex(1): any): Element);
|
|
|
|
expect(await getOwnersListForOwner(firstChild)).toMatchInlineSnapshot(`
|
|
[
|
|
"Grandparent",
|
|
"Parent",
|
|
"Child",
|
|
]
|
|
`);
|
|
});
|
|
|
|
it('should include the current element even if there are no other owners', async () => {
|
|
store.componentFilters = [utils.createDisplayNameFilter('^Parent$')];
|
|
|
|
const Grandparent = () => <Parent />;
|
|
const Parent = () => null;
|
|
|
|
utils.act(() =>
|
|
legacyRender(<Grandparent />, document.createElement('div')),
|
|
);
|
|
|
|
expect(store).toMatchInlineSnapshot(`
|
|
[root]
|
|
<Grandparent>
|
|
`);
|
|
|
|
const grandparent = ((store.getElementAtIndex(0): any): Element);
|
|
|
|
expect(await getOwnersListForOwner(grandparent)).toMatchInlineSnapshot(`
|
|
[
|
|
"Grandparent",
|
|
]
|
|
`);
|
|
});
|
|
|
|
it('should include all owners for a component wrapped in react memo', async () => {
|
|
const InnerComponent = (props, ref) => <div ref={ref} />;
|
|
const ForwardRef = React.forwardRef(InnerComponent);
|
|
const Memo = React.memo(ForwardRef);
|
|
const Grandparent = () => {
|
|
const ref = React.createRef();
|
|
return <Memo ref={ref} />;
|
|
};
|
|
|
|
utils.act(() =>
|
|
legacyRender(<Grandparent />, document.createElement('div')),
|
|
);
|
|
|
|
expect(store).toMatchInlineSnapshot(`
|
|
[root]
|
|
▾ <Grandparent>
|
|
▾ <InnerComponent> [Memo]
|
|
<InnerComponent> [ForwardRef]
|
|
`);
|
|
|
|
const wrapped = ((store.getElementAtIndex(2): any): Element);
|
|
|
|
expect(await getOwnersListForOwner(wrapped)).toMatchInlineSnapshot(`
|
|
[
|
|
"Grandparent",
|
|
"InnerComponent",
|
|
"InnerComponent",
|
|
]
|
|
`);
|
|
});
|
|
});
|