/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-devtools-shared/src/__tests__/legacy/editing-test.js
686 строк
16 KB
Sebastian Markbåge
Rename SECRET INTERNALS to `__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE` (#28789)
09 апр 2024, 19:20
Не верифицирован
09 апр 2024, 19:20
f613165
Код
Авторство
О чём код?
/** * 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 type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type Store from 'react-devtools-shared/src/devtools/store'; describe('editing interface', () => { let PropTypes; let React; let ReactDOM; let bridge: FrontendBridge; let store: Store; const act = (callback: Function) => { callback(); jest.runAllTimers(); // Flush Bridge operations }; const flushPendingUpdates = () => { jest.runOnlyPendingTimers(); }; beforeEach(() => { bridge = global.bridge; store = global.store; store.collapseNodesByDefault = false; PropTypes = require('prop-types'); // Redirect all React/ReactDOM requires to the v15 UMD. // We use the UMD because Jest doesn't enable us to mock deep imports (e.g. "react/lib/Something"). jest.mock('react', () => jest.requireActual('react-15/dist/react.js')); jest.mock('react-dom', () => jest.requireActual('react-dom-15/dist/react-dom.js'), ); React = require('react'); ReactDOM = require('react-dom'); }); describe('props', () => { let committedProps; let id; function mountTestApp() { class ClassComponent extends React.Component { componentDidMount() { committedProps = this.props; } componentDidUpdate() { committedProps = this.props; } render() { return null; } } act(() => ReactDOM.render( React.createElement(ClassComponent, { array: [1, 2, 3], object: {nested: 'initial'}, shallow: 'initial', }), document.createElement('div'), ), ); id = ((store.getElementIDAtIndex(0): any): number); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', }); } // @reactVersion >= 16.0 it('should have editable values', () => { mountTestApp(); function overrideProps(path, value) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('overrideValueAtPath', { id, path, rendererID, type: 'props', value, }); flushPendingUpdates(); } overrideProps(['shallow'], 'updated'); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'updated', }); overrideProps(['object', 'nested'], 'updated'); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { nested: 'updated', }, shallow: 'updated', }); overrideProps(['array', 1], 'updated'); expect(committedProps).toStrictEqual({ array: [1, 'updated', 3], object: { nested: 'updated', }, shallow: 'updated', }); }); // @reactVersion >= 16.0 it('should have editable paths', () => { mountTestApp(); function renamePath(oldPath, newPath) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('renamePath', { id, oldPath, newPath, rendererID, type: 'props', }); flushPendingUpdates(); } renamePath(['shallow'], ['after']); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, after: 'initial', }); renamePath(['object', 'nested'], ['object', 'after']); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { after: 'initial', }, after: 'initial', }); }); // @reactVersion >= 16.0 it('should enable adding new object properties and array values', async () => { await mountTestApp(); function overrideProps(path, value) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('overrideValueAtPath', { id, path, rendererID, type: 'props', value, }); flushPendingUpdates(); } overrideProps(['new'], 'value'); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', new: 'value', }); overrideProps(['object', 'new'], 'value'); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', new: 'value', }, shallow: 'initial', new: 'value', }); overrideProps(['array', 3], 'new value'); expect(committedProps).toStrictEqual({ array: [1, 2, 3, 'new value'], object: { nested: 'initial', new: 'value', }, shallow: 'initial', new: 'value', }); }); // @reactVersion >= 16.0 it('should have deletable keys', () => { mountTestApp(); function deletePath(path) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('deletePath', { id, path, rendererID, type: 'props', }); flushPendingUpdates(); } deletePath(['shallow']); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, }); deletePath(['object', 'nested']); expect(committedProps).toStrictEqual({ array: [1, 2, 3], object: {}, }); deletePath(['array', 1]); expect(committedProps).toStrictEqual({ array: [1, 3], object: {}, }); }); }); describe('state', () => { let committedState; let id; function mountTestApp() { class ClassComponent extends React.Component { state = { array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', }; componentDidMount() { committedState = this.state; } componentDidUpdate() { committedState = this.state; } render() { return null; } } act(() => ReactDOM.render( React.createElement(ClassComponent, { object: {nested: 'initial'}, shallow: 'initial', }), document.createElement('div'), ), ); id = ((store.getElementIDAtIndex(0): any): number); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', }); } // @reactVersion >= 16.0 it('should have editable values', () => { mountTestApp(); function overrideState(path, value) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('overrideValueAtPath', { id, path, rendererID, type: 'state', value, }); flushPendingUpdates(); } overrideState(['shallow'], 'updated'); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: {nested: 'initial'}, shallow: 'updated', }); overrideState(['object', 'nested'], 'updated'); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: {nested: 'updated'}, shallow: 'updated', }); overrideState(['array', 1], 'updated'); expect(committedState).toStrictEqual({ array: [1, 'updated', 3], object: {nested: 'updated'}, shallow: 'updated', }); }); // @reactVersion >= 16.0 it('should have editable paths', () => { mountTestApp(); function renamePath(oldPath, newPath) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('renamePath', { id, oldPath, newPath, rendererID, type: 'state', }); flushPendingUpdates(); } renamePath(['shallow'], ['after']); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, after: 'initial', }); renamePath(['object', 'nested'], ['object', 'after']); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: { after: 'initial', }, after: 'initial', }); }); // @reactVersion >= 16.0 it('should enable adding new object properties and array values', async () => { await mountTestApp(); function overrideState(path, value) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('overrideValueAtPath', { id, path, rendererID, type: 'state', value, }); flushPendingUpdates(); } overrideState(['new'], 'value'); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', new: 'value', }); overrideState(['object', 'new'], 'value'); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', new: 'value', }, shallow: 'initial', new: 'value', }); overrideState(['array', 3], 'new value'); expect(committedState).toStrictEqual({ array: [1, 2, 3, 'new value'], object: { nested: 'initial', new: 'value', }, shallow: 'initial', new: 'value', }); }); // @reactVersion >= 16.0 it('should have deletable keys', () => { mountTestApp(); function deletePath(path) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('deletePath', { id, path, rendererID, type: 'state', }); flushPendingUpdates(); } deletePath(['shallow']); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, }); deletePath(['object', 'nested']); expect(committedState).toStrictEqual({ array: [1, 2, 3], object: {}, }); deletePath(['array', 1]); expect(committedState).toStrictEqual({ array: [1, 3], object: {}, }); }); }); describe('context', () => { let committedContext; let id; function mountTestApp() { class LegacyContextProvider extends React.Component<any> { static childContextTypes = { array: PropTypes.array, object: PropTypes.object, shallow: PropTypes.string, }; getChildContext() { return { array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', }; } render() { return this.props.children; } } class ClassComponent extends React.Component<any> { static contextTypes = { array: PropTypes.array, object: PropTypes.object, shallow: PropTypes.string, }; componentDidMount() { committedContext = this.context; } componentDidUpdate() { committedContext = this.context; } render() { return null; } } act(() => ReactDOM.render( React.createElement( LegacyContextProvider, null, React.createElement(ClassComponent), ), document.createElement('div'), ), ); // This test only covers Class components. // Function components using legacy context are not editable. id = ((store.getElementIDAtIndex(1): any): number); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', }); } // @reactVersion >= 16.0 it('should have editable values', () => { mountTestApp(); function overrideContext(path, value) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('overrideValueAtPath', { id, path, rendererID, type: 'context', value, }); flushPendingUpdates(); } overrideContext(['shallow'], 'updated'); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'updated', }); overrideContext(['object', 'nested'], 'updated'); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { nested: 'updated', }, shallow: 'updated', }); overrideContext(['array', 1], 'updated'); expect(committedContext).toStrictEqual({ array: [1, 'updated', 3], object: { nested: 'updated', }, shallow: 'updated', }); }); // @reactVersion >= 16.0 it('should have editable paths', () => { mountTestApp(); function renamePath(oldPath, newPath) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('renamePath', { id, oldPath, newPath, rendererID, type: 'context', }); flushPendingUpdates(); } renamePath(['shallow'], ['after']); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, after: 'initial', }); renamePath(['object', 'nested'], ['object', 'after']); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { after: 'initial', }, after: 'initial', }); }); // @reactVersion >= 16.0 it('should enable adding new object properties and array values', async () => { await mountTestApp(); function overrideContext(path, value) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('overrideValueAtPath', { id, path, rendererID, type: 'context', value, }); flushPendingUpdates(); } overrideContext(['new'], 'value'); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, shallow: 'initial', new: 'value', }); overrideContext(['object', 'new'], 'value'); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', new: 'value', }, shallow: 'initial', new: 'value', }); overrideContext(['array', 3], 'new value'); expect(committedContext).toStrictEqual({ array: [1, 2, 3, 'new value'], object: { nested: 'initial', new: 'value', }, shallow: 'initial', new: 'value', }); }); // @reactVersion >= 16.0 it('should have deletable keys', () => { mountTestApp(); function deletePath(path) { const rendererID = ((store.getRendererIDForElement(id): any): number); bridge.send('deletePath', { id, path, rendererID, type: 'context', }); flushPendingUpdates(); } deletePath(['shallow']); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: { nested: 'initial', }, }); deletePath(['object', 'nested']); expect(committedContext).toStrictEqual({ array: [1, 2, 3], object: {}, }); deletePath(['array', 1]); expect(committedContext).toStrictEqual({ array: [1, 3], object: {}, }); }); }); });