From 2d3788678bc80dd08c5fbd1f07c6f118bd259f0d Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Sat, 15 Jun 2024 17:41:43 -0700 Subject: [PATCH 01/13] RN: Migrate `LogBoxInspectorContainer-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58641095 --- .../LogBoxInspectorContainer-test.js | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js b/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js index 853954e6ebdf..8368411158f7 100644 --- a/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js +++ b/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js @@ -18,9 +18,16 @@ const { } = require('../LogBoxNotificationContainer'); const React = require('react'); +// Mock `LogBoxLogNotification` because we are interested in snapshotting the +// behavior of `LogBoxNotificationContainer`, not `LogBoxLogNotification`. +jest.mock('../UI/LogBoxNotification', () => ({ + __esModule: true, + default: 'LogBoxLogNotification', +})); + describe('LogBoxNotificationContainer', () => { it('should render null with no logs', () => { - const output = render.shallowRender( + const output = render.create( , ); @@ -28,7 +35,7 @@ describe('LogBoxNotificationContainer', () => { }); it('should render null with no selected log and disabled', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render the latest warning notification', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render the latest error notification', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render both an error and warning notification', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render selected fatal error even when disabled', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render selected syntax error even when disabled', () => { - const output = render.shallowRender( + const output = render.create( Date: Sat, 15 Jun 2024 17:41:43 -0700 Subject: [PATCH 02/13] RN: Migrate `LogBoxInspectorMessageHeader-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58641096 --- .../LogBoxInspectorMessageHeader-test.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorMessageHeader-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorMessageHeader-test.js index 078f582015e2..287b185dae5f 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorMessageHeader-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorMessageHeader-test.js @@ -16,9 +16,16 @@ const LogBoxInspectorMessageHeader = require('../LogBoxInspectorMessageHeader').default; const React = require('react'); +// Mock `LogBoxMessage` because we are interested in snapshotting the +// behavior of `LogBoxInspectorMessageHeader`, not `LogBoxMessage`. +jest.mock('../LogBoxMessage', () => ({ + __esModule: true, + default: 'LogBoxMessage', +})); + describe('LogBoxInspectorMessageHeader', () => { it('should render error', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render fatal', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render syntax error', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should not render See More button for short content', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should not render "See More" if expanded', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render "See More" if collapsed', () => { - const output = render.shallowRender( + const output = render.create( Date: Sat, 15 Jun 2024 17:41:43 -0700 Subject: [PATCH 03/13] RN: Migrate `LogBoxButton-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58641097 --- .../LogBox/UI/__tests__/LogBoxButton-test.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxButton-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxButton-test.js index f5f6c972d3c4..797ccde3f230 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxButton-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxButton-test.js @@ -15,9 +15,16 @@ const render = require('../../../../jest/renderer'); const LogBoxButton = require('../LogBoxButton').default; const React = require('react'); +// Mock `TouchableWithoutFeedback` because we are interested in snapshotting the +// behavior of `LogBoxButton`, not `TouchableWithoutFeedback`. +jest.mock('../../../Components/Touchable/TouchableWithoutFeedback', () => ({ + __esModule: true, + default: 'TouchableWithoutFeedback', +})); + describe('LogBoxButton', () => { it('should render only a view without an onPress', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render TouchableWithoutFeedback and pass through props', () => { - const output = render.shallowRender( + const output = render.create( Date: Sat, 15 Jun 2024 18:53:36 -0700 Subject: [PATCH 04/13] RN: Migrate `LogBoxInspector-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58641098 --- .../Libraries/LogBox/UI/LogBoxInspector.js | 78 ++--------------- .../LogBox/UI/LogBoxInspectorBody.js | 87 +++++++++++++++++++ .../UI/__tests__/LogBoxInspector-test.js | 21 ++++- .../LogBoxInspector-test.js.snap | 2 +- .../__snapshots__/public-api-test.js.snap | 15 +++- 5 files changed, 125 insertions(+), 78 deletions(-) create mode 100644 packages/react-native/Libraries/LogBox/UI/LogBoxInspectorBody.js diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspector.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspector.js index 110e411b62a6..ae6ddbc551ff 100644 --- a/packages/react-native/Libraries/LogBox/UI/LogBoxInspector.js +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspector.js @@ -9,40 +9,37 @@ */ import Keyboard from '../../Components/Keyboard/Keyboard'; -import ScrollView from '../../Components/ScrollView/ScrollView'; import View from '../../Components/View/View'; import StyleSheet from '../../StyleSheet/StyleSheet'; import * as LogBoxData from '../Data/LogBoxData'; import LogBoxLog, {type LogLevel} from '../Data/LogBoxLog'; -import LogBoxInspectorCodeFrame from './LogBoxInspectorCodeFrame'; +import LogBoxInspectorBody from './LogBoxInspectorBody'; import LogBoxInspectorFooter from './LogBoxInspectorFooter'; import LogBoxInspectorHeader from './LogBoxInspectorHeader'; -import LogBoxInspectorMessageHeader from './LogBoxInspectorMessageHeader'; -import LogBoxInspectorReactFrames from './LogBoxInspectorReactFrames'; -import LogBoxInspectorStackFrames from './LogBoxInspectorStackFrames'; import * as LogBoxStyle from './LogBoxStyle'; import * as React from 'react'; +import {useEffect} from 'react'; -type Props = $ReadOnly<{| +type Props = $ReadOnly<{ onDismiss: () => void, onChangeSelectedIndex: (index: number) => void, onMinimize: () => void, logs: $ReadOnlyArray, selectedIndex: number, fatalType?: ?LogLevel, -|}>; +}>; -function LogBoxInspector(props: Props): React.Node { +export default function LogBoxInspector(props: Props): React.Node { const {logs, selectedIndex} = props; let log = logs[selectedIndex]; - React.useEffect(() => { + useEffect(() => { if (log) { LogBoxData.symbolicateLogNow(log); } }, [log]); - React.useEffect(() => { + useEffect(() => { // Optimistically symbolicate the last and next logs. if (logs.length > 1) { const selected = selectedIndex; @@ -54,7 +51,7 @@ function LogBoxInspector(props: Props): React.Node { } }, [logs, selectedIndex]); - React.useEffect(() => { + useEffect(() => { Keyboard.dismiss(); }, []); @@ -84,68 +81,9 @@ function LogBoxInspector(props: Props): React.Node { ); } -const headerTitleMap = { - warn: 'Console Warning', - error: 'Console Error', - fatal: 'Uncaught Error', - syntax: 'Syntax Error', - component: 'Render Error', -}; - -function LogBoxInspectorBody(props: {log: LogBoxLog, onRetry: () => void}) { - const [collapsed, setCollapsed] = React.useState(true); - - React.useEffect(() => { - setCollapsed(true); - }, [props.log]); - - const headerTitle = - props.log.type ?? - headerTitleMap[props.log.isComponentError ? 'component' : props.log.level]; - - if (collapsed) { - return ( - <> - setCollapsed(!collapsed)} - message={props.log.message} - level={props.log.level} - title={headerTitle} - /> - - - - - - - ); - } - return ( - - setCollapsed(!collapsed)} - message={props.log.message} - level={props.log.level} - title={headerTitle} - /> - - - - - ); -} - const styles = StyleSheet.create({ root: { flex: 1, backgroundColor: LogBoxStyle.getTextColor(), }, - scrollBody: { - backgroundColor: LogBoxStyle.getBackgroundColor(0.9), - flex: 1, - }, }); - -export default LogBoxInspector; diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorBody.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorBody.js new file mode 100644 index 000000000000..65af7fb2cdde --- /dev/null +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorBody.js @@ -0,0 +1,87 @@ +/** + * 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 strict-local + * @format + */ + +import ScrollView from '../../Components/ScrollView/ScrollView'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import LogBoxLog from '../Data/LogBoxLog'; +import LogBoxInspectorCodeFrame from './LogBoxInspectorCodeFrame'; +import LogBoxInspectorMessageHeader from './LogBoxInspectorMessageHeader'; +import LogBoxInspectorReactFrames from './LogBoxInspectorReactFrames'; +import LogBoxInspectorStackFrames from './LogBoxInspectorStackFrames'; +import * as LogBoxStyle from './LogBoxStyle'; +import * as React from 'react'; +import {useEffect, useState} from 'react'; + +const headerTitleMap = { + warn: 'Console Warning', + error: 'Console Error', + fatal: 'Uncaught Error', + syntax: 'Syntax Error', + component: 'Render Error', +}; + +export default function LogBoxInspectorBody(props: { + log: LogBoxLog, + onRetry: () => void, +}): React.Node { + const [collapsed, setCollapsed] = useState(true); + + useEffect(() => { + setCollapsed(true); + }, [props.log]); + + const headerTitle = + props.log.type ?? + headerTitleMap[props.log.isComponentError ? 'component' : props.log.level]; + + if (collapsed) { + return ( + <> + setCollapsed(!collapsed)} + message={props.log.message} + level={props.log.level} + title={headerTitle} + /> + + + + + + + ); + } + return ( + + setCollapsed(!collapsed)} + message={props.log.message} + level={props.log.level} + title={headerTitle} + /> + + + + + ); +} + +const styles = StyleSheet.create({ + root: { + flex: 1, + backgroundColor: LogBoxStyle.getTextColor(), + }, + scrollBody: { + backgroundColor: LogBoxStyle.getBackgroundColor(0.9), + flex: 1, + }, +}); diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspector-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspector-test.js index af725eb2143e..49fb2a1c8a36 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspector-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspector-test.js @@ -16,6 +16,21 @@ const LogBoxLog = require('../../Data/LogBoxLog').default; const LogBoxInspector = require('../LogBoxInspector').default; const React = require('react'); +// Mock child components because we are interested in snapshotting the behavior +// of `LogBoxInspector`, not its children. +jest.mock('../LogBoxInspectorBody', () => ({ + __esModule: true, + default: 'LogBoxInspectorBody', +})); +jest.mock('../LogBoxInspectorFooter', () => ({ + __esModule: true, + default: 'LogBoxInspectorFooter', +})); +jest.mock('../LogBoxInspectorHeader', () => ({ + __esModule: true, + default: 'LogBoxInspectorHeader', +})); + const logs = [ new LogBoxLog({ level: 'warn', @@ -54,7 +69,7 @@ const logs = [ describe('LogBoxContainer', () => { it('should render null with no logs', () => { - const output = render.shallowRender( + const output = render.create( {}} onMinimize={() => {}} @@ -68,7 +83,7 @@ describe('LogBoxContainer', () => { }); it('should render warning with selectedIndex 0', () => { - const output = render.shallowRender( + const output = render.create( {}} onMinimize={() => {}} @@ -82,7 +97,7 @@ describe('LogBoxContainer', () => { }); it('should render fatal with selectedIndex 2', () => { - const output = render.shallowRender( + const output = render.create( {}} onMinimize={() => {}} diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap index 34f1094a3487..f55f910b19ee 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap @@ -35,7 +35,7 @@ exports[`LogBoxContainer should render fatal with selectedIndex 2 1`] = ` "symbolicated": Object { "error": null, "stack": null, - "status": "NONE", + "status": "PENDING", }, "symbolicatedComponentStack": Object { "componentStack": null, diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 2629df495faa..1472314996b3 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -5523,16 +5523,23 @@ declare export default typeof LogBoxButton; `; exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxInspector.js 1`] = ` -"type Props = $ReadOnly<{| +"type Props = $ReadOnly<{ onDismiss: () => void, onChangeSelectedIndex: (index: number) => void, onMinimize: () => void, logs: $ReadOnlyArray, selectedIndex: number, fatalType?: ?LogLevel, -|}>; -declare function LogBoxInspector(props: Props): React.Node; -declare export default typeof LogBoxInspector; +}>; +declare export default function LogBoxInspector(props: Props): React.Node; +" +`; + +exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxInspectorBody.js 1`] = ` +"declare export default function LogBoxInspectorBody(props: { + log: LogBoxLog, + onRetry: () => void, +}): React.Node; " `; From f3082985c66f47f19bf06b01158d5ec91a7a6257 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 05/13] RN: Migrate `LogBoxInspectorCodeFrame-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643061 --- .../LogBoxInspectorCodeFrame-test.js | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorCodeFrame-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorCodeFrame-test.js index 0d27cc4f5e31..7fd6c0872fb5 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorCodeFrame-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorCodeFrame-test.js @@ -15,17 +15,34 @@ const render = require('../../../../jest/renderer'); const LogBoxInspectorCodeFrame = require('../LogBoxInspectorCodeFrame').default; const React = require('react'); +// Mock child components because we are interested in snapshotting the behavior +// of `LogBoxInspectorCodeFrame`, not its children. +jest.mock('../../../Components/ScrollView/ScrollView', () => ({ + __esModule: true, + default: 'ScrollView', +})); +jest.mock('../AnsiHighlight', () => ({ + __esModule: true, + default: 'Ansi', +})); +jest.mock('../LogBoxButton', () => ({ + __esModule: true, + default: 'LogBoxButton', +})); +jest.mock('../LogBoxInspectorSection', () => ({ + __esModule: true, + default: 'LogBoxInspectorSection', +})); + describe('LogBoxInspectorCodeFrame', () => { it('should render null for no code frame', () => { - const output = render.shallowRender( - , - ); + const output = render.create(); expect(output).toMatchSnapshot(); }); it('should render a code frame', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render a code frame without a location', () => { - const output = render.shallowRender( + const output = render.create( Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 06/13] RN: Migrate `LogBoxInspectorFooter-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643066 --- .../LogBox/UI/LogBoxInspectorFooter.js | 48 ++------------- .../LogBox/UI/LogBoxInspectorFooterButton.js | 58 +++++++++++++++++++ .../__tests__/LogBoxInspectorFooter-test.js | 15 +++-- .../LogBoxInspectorFooter-test.js.snap | 12 ++-- .../__snapshots__/public-api-test.js.snap | 18 ++++-- 5 files changed, 95 insertions(+), 56 deletions(-) create mode 100644 packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooter.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooter.js index 44d344f0334a..4100fb4a4149 100644 --- a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooter.js +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooter.js @@ -10,21 +10,20 @@ import type {LogLevel} from '../Data/LogBoxLog'; -import SafeAreaView from '../../Components/SafeAreaView/SafeAreaView'; import View from '../../Components/View/View'; import StyleSheet from '../../StyleSheet/StyleSheet'; import Text from '../../Text/Text'; -import LogBoxButton from './LogBoxButton'; +import LogBoxInspectorFooterButton from './LogBoxInspectorFooterButton'; import * as LogBoxStyle from './LogBoxStyle'; import * as React from 'react'; -type Props = $ReadOnly<{| +type Props = $ReadOnly<{ onDismiss: () => void, onMinimize: () => void, level?: ?LogLevel, -|}>; +}>; -function LogBoxInspectorFooter(props: Props): React.Node { +export default function LogBoxInspectorFooter(props: Props): React.Node { if (props.level === 'syntax') { return ( @@ -39,34 +38,12 @@ function LogBoxInspectorFooter(props: Props): React.Node { return ( - - + + ); } -type ButtonProps = $ReadOnly<{| - onPress: () => void, - text: string, -|}>; - -function FooterButton(props: ButtonProps): React.Node { - return ( - - - - {props.text} - - - - ); -} - const styles = StyleSheet.create({ root: { backgroundColor: LogBoxStyle.getBackgroundColor(1), @@ -79,17 +56,6 @@ const styles = StyleSheet.create({ button: { flex: 1, }, - buttonContent: { - alignItems: 'center', - height: 48, - justifyContent: 'center', - }, - buttonLabel: { - color: LogBoxStyle.getTextColor(1), - fontSize: 14, - includeFontPadding: false, - lineHeight: 20, - }, syntaxErrorText: { textAlign: 'center', width: '100%', @@ -102,5 +68,3 @@ const styles = StyleSheet.create({ color: LogBoxStyle.getTextColor(0.6), }, }); - -export default LogBoxInspectorFooter; diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js new file mode 100644 index 000000000000..d2208c773e2a --- /dev/null +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorFooterButton.js @@ -0,0 +1,58 @@ +/** + * 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 strict-local + * @format + */ + +import SafeAreaView from '../../Components/SafeAreaView/SafeAreaView'; +import View from '../../Components/View/View'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import Text from '../../Text/Text'; +import LogBoxButton from './LogBoxButton'; +import * as LogBoxStyle from './LogBoxStyle'; +import * as React from 'react'; + +type ButtonProps = $ReadOnly<{ + onPress: () => void, + text: string, +}>; + +export default function LogBoxInspectorFooterButton( + props: ButtonProps, +): React.Node { + return ( + + + + {props.text} + + + + ); +} + +const styles = StyleSheet.create({ + button: { + flex: 1, + }, + buttonContent: { + alignItems: 'center', + height: 48, + justifyContent: 'center', + }, + buttonLabel: { + color: LogBoxStyle.getTextColor(1), + fontSize: 14, + includeFontPadding: false, + lineHeight: 20, + }, +}); diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorFooter-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorFooter-test.js index 500ad24f8106..4465a0b21c65 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorFooter-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorFooter-test.js @@ -15,9 +15,16 @@ const render = require('../../../../jest/renderer'); const LogBoxInspectorFooter = require('../LogBoxInspectorFooter').default; const React = require('react'); +// Mock `LogBoxInspectorFooterButton` because we are interested in snapshotting +// the behavior of `LogBoxInspectorFooter`, not `LogBoxInspectorFooterButton`. +jest.mock('../LogBoxInspectorFooterButton', () => ({ + __esModule: true, + default: 'LogBoxInspectorFooterButton', +})); + describe('LogBoxInspectorFooter', () => { it('should render two buttons for warning', () => { - const output = render.shallowRender( + const output = render.create( {}} onDismiss={() => {}} @@ -29,7 +36,7 @@ describe('LogBoxInspectorFooter', () => { }); it('should render two buttons for error', () => { - const output = render.shallowRender( + const output = render.create( {}} onDismiss={() => {}} @@ -41,7 +48,7 @@ describe('LogBoxInspectorFooter', () => { }); it('should render two buttons for fatal', () => { - const output = render.shallowRender( + const output = render.create( {}} onDismiss={() => {}} @@ -53,7 +60,7 @@ describe('LogBoxInspectorFooter', () => { }); it('should render no buttons and a message for syntax error', () => { - const output = render.shallowRender( + const output = render.create( {}} onDismiss={() => {}} diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorFooter-test.js.snap b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorFooter-test.js.snap index 958f456d53f5..dc84cb131f00 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorFooter-test.js.snap +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorFooter-test.js.snap @@ -60,11 +60,11 @@ exports[`LogBoxInspectorFooter should render two buttons for error 1`] = ` } } > - - @@ -87,11 +87,11 @@ exports[`LogBoxInspectorFooter should render two buttons for fatal 1`] = ` } } > - - @@ -114,11 +114,11 @@ exports[`LogBoxInspectorFooter should render two buttons for warning 1`] = ` } } > - - diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 1472314996b3..83f5ceeef230 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -5553,13 +5553,23 @@ declare export default typeof LogBoxInspectorCodeFrame; `; exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxInspectorFooter.js 1`] = ` -"type Props = $ReadOnly<{| +"type Props = $ReadOnly<{ onDismiss: () => void, onMinimize: () => void, level?: ?LogLevel, -|}>; -declare function LogBoxInspectorFooter(props: Props): React.Node; -declare export default typeof LogBoxInspectorFooter; +}>; +declare export default function LogBoxInspectorFooter(props: Props): React.Node; +" +`; + +exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxInspectorFooterButton.js 1`] = ` +"type ButtonProps = $ReadOnly<{ + onPress: () => void, + text: string, +}>; +declare export default function LogBoxInspectorFooterButton( + props: ButtonProps +): React.Node; " `; From aaf34d079f53c86ba96029b50349af1b6a5eefcb Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 07/13] RN: Migrate `LogBoxInspectorHeader-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643059 --- .../LogBox/UI/LogBoxInspectorHeader.js | 71 ++--------------- .../LogBox/UI/LogBoxInspectorHeaderButton.js | 76 +++++++++++++++++++ .../__tests__/LogBoxInspectorHeader-test.js | 15 +++- .../__snapshots__/public-api-test.js.snap | 19 ++++- 4 files changed, 107 insertions(+), 74 deletions(-) create mode 100644 packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js index 1f578db82f0f..0f5d270aa3f8 100644 --- a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js @@ -8,26 +8,25 @@ * @format */ -import type {ImageSource} from '../../Image/ImageSource'; import type {LogLevel} from '../Data/LogBoxLog'; import StatusBar from '../../Components/StatusBar/StatusBar'; import View from '../../Components/View/View'; -import Image from '../../Image/Image'; import StyleSheet from '../../StyleSheet/StyleSheet'; import Text from '../../Text/Text'; import Platform from '../../Utilities/Platform'; -import LogBoxButton from './LogBoxButton'; +import LogBoxInspectorHeaderButton from './LogBoxInspectorHeaderButton'; import * as LogBoxStyle from './LogBoxStyle'; import * as React from 'react'; -type Props = $ReadOnly<{| + +type Props = $ReadOnly<{ onSelectIndex: (selectedIndex: number) => void, selectedIndex: number, total: number, level: LogLevel, -|}>; +}>; -function LogBoxInspectorHeader(props: Props): React.Node { +export default function LogBoxInspectorHeader(props: Props): React.Node { if (props.level === 'syntax') { return ( @@ -70,64 +69,6 @@ function LogBoxInspectorHeader(props: Props): React.Node { ); } -const backgroundForLevel = (level: LogLevel) => - ({ - warn: { - default: 'transparent', - pressed: LogBoxStyle.getWarningDarkColor(), - }, - error: { - default: 'transparent', - pressed: LogBoxStyle.getErrorDarkColor(), - }, - fatal: { - default: 'transparent', - pressed: LogBoxStyle.getFatalDarkColor(), - }, - syntax: { - default: 'transparent', - pressed: LogBoxStyle.getFatalDarkColor(), - }, - })[level]; - -function LogBoxInspectorHeaderButton( - props: $ReadOnly<{| - disabled: boolean, - image: ImageSource, - level: LogLevel, - onPress?: ?() => void, - |}>, -): React.Node { - return ( - - {props.disabled ? null : ( - - )} - - ); -} - -const headerStyles = StyleSheet.create({ - button: { - alignItems: 'center', - aspectRatio: 1, - justifyContent: 'center', - marginTop: 5, - marginRight: 6, - marginLeft: 6, - marginBottom: -8, - borderRadius: 3, - }, - buttonImage: { - height: 14, - width: 8, - tintColor: LogBoxStyle.getTextColor(), - }, -}); - const styles = StyleSheet.create({ syntax: { backgroundColor: LogBoxStyle.getFatalColor(), @@ -164,5 +105,3 @@ const styles = StyleSheet.create({ paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 40, }, }); - -export default LogBoxInspectorHeader; diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js new file mode 100644 index 000000000000..73270c0319a9 --- /dev/null +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js @@ -0,0 +1,76 @@ +/** + * 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 strict-local + * @format + */ + +import type {ImageSource} from '../../Image/ImageSource'; +import type {LogLevel} from '../Data/LogBoxLog'; + +import Image from '../../Image/Image'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import LogBoxButton from './LogBoxButton'; +import * as LogBoxStyle from './LogBoxStyle'; +import * as React from 'react'; + +const backgroundForLevel = (level: LogLevel) => + ({ + warn: { + default: 'transparent', + pressed: LogBoxStyle.getWarningDarkColor(), + }, + error: { + default: 'transparent', + pressed: LogBoxStyle.getErrorDarkColor(), + }, + fatal: { + default: 'transparent', + pressed: LogBoxStyle.getFatalDarkColor(), + }, + syntax: { + default: 'transparent', + pressed: LogBoxStyle.getFatalDarkColor(), + }, + })[level]; + +export default function LogBoxInspectorHeaderButton( + props: $ReadOnly<{ + disabled: boolean, + image: ImageSource, + level: LogLevel, + onPress?: ?() => void, + }>, +): React.Node { + return ( + + {props.disabled ? null : ( + + )} + + ); +} + +const styles = StyleSheet.create({ + button: { + alignItems: 'center', + aspectRatio: 1, + justifyContent: 'center', + marginTop: 5, + marginRight: 6, + marginLeft: 6, + marginBottom: -8, + borderRadius: 3, + }, + buttonImage: { + height: 14, + width: 8, + tintColor: LogBoxStyle.getTextColor(), + }, +}); diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorHeader-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorHeader-test.js index 3ea9f2392c59..a16f1474b56c 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorHeader-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorHeader-test.js @@ -15,9 +15,16 @@ const render = require('../../../../jest/renderer'); const LogBoxInspectorHeader = require('../LogBoxInspectorHeader').default; const React = require('react'); +// Mock `LogBoxInspectorHeaderButton` because we are interested in snapshotting +// the behavior of `LogBoxInspectorHeader`, not `LogBoxInspectorHeaderButton`. +jest.mock('../LogBoxInspectorHeaderButton', () => ({ + __esModule: true, + default: 'LogBoxInspectorHeaderButton', +})); + describe('LogBoxInspectorHeader', () => { it('should render no buttons for one total', () => { - const output = render.shallowRender( + const output = render.create( {}} selectedIndex={0} @@ -30,7 +37,7 @@ describe('LogBoxInspectorHeader', () => { }); it('should render both buttons for two total', () => { - const output = render.shallowRender( + const output = render.create( {}} selectedIndex={1} @@ -43,7 +50,7 @@ describe('LogBoxInspectorHeader', () => { }); it('should render two buttons for three or more total', () => { - const output = render.shallowRender( + const output = render.create( {}} selectedIndex={0} @@ -56,7 +63,7 @@ describe('LogBoxInspectorHeader', () => { }); it('should render syntax error header', () => { - const output = render.shallowRender( + const output = render.create( {}} selectedIndex={0} diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 83f5ceeef230..94215f233a0a 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -5574,14 +5574,25 @@ declare export default function LogBoxInspectorFooterButton( `; exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxInspectorHeader.js 1`] = ` -"type Props = $ReadOnly<{| +"type Props = $ReadOnly<{ onSelectIndex: (selectedIndex: number) => void, selectedIndex: number, total: number, level: LogLevel, -|}>; -declare function LogBoxInspectorHeader(props: Props): React.Node; -declare export default typeof LogBoxInspectorHeader; +}>; +declare export default function LogBoxInspectorHeader(props: Props): React.Node; +" +`; + +exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxInspectorHeaderButton.js 1`] = ` +"declare export default function LogBoxInspectorHeaderButton( + props: $ReadOnly<{ + disabled: boolean, + image: ImageSource, + level: LogLevel, + onPress?: ?() => void, + }> +): React.Node; " `; From 53b0b27d86dbb29ded48ae0b8fc5e40f3bf5788d Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 08/13] RN: Migrate `LogBoxInspectorReactFrames-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643055 --- .../LogBoxInspectorReactFrames-test.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorReactFrames-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorReactFrames-test.js index 04737ad3a318..2320e2404be0 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorReactFrames-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorReactFrames-test.js @@ -17,9 +17,20 @@ const LogBoxInspectorReactFrames = require('../LogBoxInspectorReactFrames').default; const React = require('react'); +// Mock child components because we are interested in snapshotting the behavior +// of `LogBoxInspectorReactFrames`, not its children. +jest.mock('../LogBoxButton', () => ({ + __esModule: true, + default: 'LogBoxButton', +})); +jest.mock('../LogBoxInspectorSection', () => ({ + __esModule: true, + default: 'LogBoxInspectorSection', +})); + describe('LogBoxInspectorReactFrames', () => { it('should render null for no componentStack frames', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render componentStack frames without full path pressable', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render componentStack frames with full path pressable', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render componentStack frames with parent folder of index.js', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render componentStack frames with more than 3 stacks', () => { - const output = render.shallowRender( + const output = render.create( Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 09/13] RN: Migrate `LogBoxInspectorSection-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643056 --- .../LogBox/UI/__tests__/LogBoxInspectorSection-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSection-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSection-test.js index 0302f35acfc0..0f7a8361870f 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSection-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSection-test.js @@ -17,7 +17,7 @@ const React = require('react'); describe('LogBoxInspectorSection', () => { it('should render with only heading', () => { - const output = render.shallowRender( + const output = render.create( Child , @@ -27,7 +27,7 @@ describe('LogBoxInspectorSection', () => { }); it('should render with action on the right', () => { - const output = render.shallowRender( + const output = render.create( Right}> From c5eb763f8dc236fc2655bea8a9cdb9d1ed2694ad Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 10/13] RN: Migrate `LogBoxInspectorSourceMapStatus-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643069 --- .../LogBoxInspectorSourceMapStatus-test.js | 13 ++++-- ...ogBoxInspectorSourceMapStatus-test.js.snap | 42 +++++++------------ 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSourceMapStatus-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSourceMapStatus-test.js index 940efb2580f0..f9ca446de360 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSourceMapStatus-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorSourceMapStatus-test.js @@ -16,9 +16,16 @@ const LogBoxInspectorSourceMapStatus = require('../LogBoxInspectorSourceMapStatus').default; const React = require('react'); +// Mock `LogBoxButton` because we are interested in snapshotting the behavior +// of `LogBoxInspectorSourceMapStatus`, not `LogBoxButton`. +jest.mock('../LogBoxButton', () => ({ + __esModule: true, + default: 'LogBoxButton', +})); + describe('LogBoxInspectorSourceMapStatus', () => { it('should render for failed', () => { - const output = render.shallowRender( + const output = render.create( {}} status="FAILED" />, ); @@ -26,7 +33,7 @@ describe('LogBoxInspectorSourceMapStatus', () => { }); it('should render for pending', () => { - const output = render.shallowRender( + const output = render.create( {}} status="PENDING" />, ); @@ -34,7 +41,7 @@ describe('LogBoxInspectorSourceMapStatus', () => { }); it('should render null for complete', () => { - const output = render.shallowRender( + const output = render.create( {}} status="COMPLETE" />, ); diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorSourceMapStatus-test.js.snap b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorSourceMapStatus-test.js.snap index 612a75000e45..df2fcc921281 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorSourceMapStatus-test.js.snap +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorSourceMapStatus-test.js.snap @@ -27,25 +27,20 @@ exports[`LogBoxInspectorSourceMapStatus should render for failed 1`] = ` } } > - - Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 11/13] RN: Migrate `LogBoxInspectorStackFrame-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643057 --- .../UI/__tests__/LogBoxInspectorStackFrame-test.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrame-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrame-test.js index 6b738788f82f..b853ee231706 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrame-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrame-test.js @@ -16,9 +16,16 @@ const LogBoxInspectorStackFrame = require('../LogBoxInspectorStackFrame').default; const React = require('react'); +// Mock `LogBoxButton` because we are interested in snapshotting the behavior +// of `LogBoxInspectorStackFrame`, not `LogBoxButton`. +jest.mock('../LogBoxButton', () => ({ + __esModule: true, + default: 'LogBoxButton', +})); + describe('LogBoxInspectorStackFrame', () => { it('should render stack frame', () => { - const output = render.shallowRender( + const output = render.create( {}} frame={{ @@ -35,7 +42,7 @@ describe('LogBoxInspectorStackFrame', () => { }); it('should render stack frame without press feedback', () => { - const output = render.shallowRender( + const output = render.create( { }); it('should render collapsed stack frame with dimmed text', () => { - const output = render.shallowRender( + const output = render.create( {}} frame={{ From 83c90a884ba73d924953bfcfd3a53772745b7fcc Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Sat, 15 Jun 2024 18:57:06 -0700 Subject: [PATCH 12/13] RN: Migrate `LogBoxInspectorStackFrames-test.js` from Shallow Renderer Summary: Migrates this Jest unit test away from using `react-shallow-renderer` because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643067 --- .../LogBoxInspectorStackFrames-test.js | 14 +- .../LogBoxInspectorStackFrames-test.js.snap | 207 ++++++++++++++---- 2 files changed, 178 insertions(+), 43 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrames-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrames-test.js index f7381ed1206e..a8d648692c98 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrames-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxInspectorStackFrames-test.js @@ -17,9 +17,15 @@ import LogBoxInspectorStackFrames, { const render = require('../../../../jest/renderer'); const LogBoxLog = require('../../Data/LogBoxLog').default; -const {} = require('../LogBoxInspectorStackFrames'); const React = require('react'); +// Mock `LogBoxInspectorSection` because we are interested in snapshotting the +// behavior of `LogBoxInspectorStackFrames`, not `LogBoxInspectorSection`. +jest.mock('../LogBoxInspectorSection', () => ({ + __esModule: true, + default: 'LogBoxInspectorSection', +})); + const createLogWithFrames = (collapsedOptions: Array) => { return new LogBoxLog({ level: 'warn', @@ -44,9 +50,9 @@ const createCollapsedFrames = (collapsedOptions: Array) => { })); }; -describe('LogBoxInspectorStackFrame', () => { +describe('LogBoxInspectorStackFrames', () => { it('should render stack frames with 1 frame collapsed', () => { - const output = render.shallowRender( + const output = render.create( {}} log={createLogWithFrames([false, true])} @@ -57,7 +63,7 @@ describe('LogBoxInspectorStackFrame', () => { }); it('should render null for empty stack frames', () => { - const output = render.shallowRender( + const output = render.create( {}} log={createLogWithFrames([])} diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorStackFrames-test.js.snap b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorStackFrames-test.js.snap index 8d2882cebb09..803ef114aeb9 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorStackFrames-test.js.snap +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorStackFrames-test.js.snap @@ -1,61 +1,190 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`LogBoxInspectorStackFrame should render null for empty stack frames 1`] = `null`; +exports[`LogBoxInspectorStackFrames should render null for empty stack frames 1`] = `null`; -exports[`LogBoxInspectorStackFrame should render stack frames with 1 frame collapsed 1`] = ` - +exports[`LogBoxInspectorStackFrames should render stack frames with 1 frame collapsed 1`] = ` + - This call stack is not symbolicated. Some features are unavailable such as viewing the function name or tapping to open files. + Call Stack - - - + > + + + This call stack is not symbolicated. Some features are unavailable such as viewing the function name or tapping to open files. + + + + + + foo + + + dependency.js:1:2 + + + + + + + See 1 more frame + + + + + `; From cd3634bbf3b44bed8cdbf3ac1456a574a6b36539 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Sat, 15 Jun 2024 19:12:36 -0700 Subject: [PATCH 13/13] '[skip ci] RN: Migrate from Shallow Renderer Summary: Migrates this Jest unit test away from using because it is no longer recommended. Changelog: [Internal] Differential Revision: D58643068 --- .../Libraries/LogBox/UI/LogBoxNotification.js | 162 ++---------------- .../LogBox/UI/LogBoxNotificationCountBadge.js | 63 +++++++ .../UI/LogBoxNotificationDismissButton.js | 67 ++++++++ .../LogBox/UI/LogBoxNotificationMessage.js | 57 ++++++ .../UI/__tests__/LogBoxNotification-test.js | 21 ++- .../LogBoxNotification-test.js.snap | 6 +- .../__snapshots__/public-api-test.js.snap | 25 ++- 7 files changed, 246 insertions(+), 155 deletions(-) create mode 100644 packages/react-native/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js create mode 100644 packages/react-native/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js create mode 100644 packages/react-native/Libraries/LogBox/UI/LogBoxNotificationMessage.js diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxNotification.js b/packages/react-native/Libraries/LogBox/UI/LogBoxNotification.js index 5e8aaf07f736..b1529ed57447 100644 --- a/packages/react-native/Libraries/LogBox/UI/LogBoxNotification.js +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxNotification.js @@ -8,18 +8,17 @@ * @format */ -import type {Message as MessageType} from '../Data/parseLogBoxLog'; - import View from '../../Components/View/View'; -import Image from '../../Image/Image'; import StyleSheet from '../../StyleSheet/StyleSheet'; -import Text from '../../Text/Text'; import * as LogBoxData from '../Data/LogBoxData'; import LogBoxLog from '../Data/LogBoxLog'; import LogBoxButton from './LogBoxButton'; -import LogBoxMessage from './LogBoxMessage'; +import LogBoxNotificationCountBadge from './LogBoxNotificationCountBadge'; +import LogBoxNotificationDismissButton from './LogBoxNotificationDismissButton'; +import LogBoxNotificationMessage from './LogBoxNotificationMessage'; import * as LogBoxStyle from './LogBoxStyle'; import * as React from 'react'; +import {useEffect} from 'react'; type Props = $ReadOnly<{ log: LogBoxLog, @@ -29,167 +28,34 @@ type Props = $ReadOnly<{ onPressDismiss: () => void, }>; -function LogBoxLogNotification(props: Props): React.Node { +export default function LogBoxNotification(props: Props): React.Node { const {totalLogCount, level, log} = props; // Eagerly symbolicate so the stack is available when pressing to inspect. - React.useEffect(() => { + useEffect(() => { LogBoxData.symbolicateLogLazy(log); }, [log]); return ( - + - - - - + + + + ); } -function CountBadge(props: {count: number, level: 'error' | 'warn'}) { - return ( - - {/* $FlowFixMe[incompatible-type] (>=0.114.0) This suppression was added - * when fixing the type of `StyleSheet.create`. Remove this comment to - * see the error. */} - - - {props.count <= 1 ? '!' : props.count} - - - - ); -} - -function Message(props: {message: MessageType}) { - return ( - - - {props.message && ( - - )} - - - ); -} - -function DismissButton(props: {onPress: () => void}) { - return ( - - - - - - ); -} - -const countStyles = StyleSheet.create({ - warn: { - backgroundColor: LogBoxStyle.getWarningColor(1), - }, - error: { - backgroundColor: LogBoxStyle.getErrorColor(1), - }, - outside: { - padding: 2, - borderRadius: 25, - backgroundColor: '#fff', - marginRight: 8, - }, - inside: { - minWidth: 18, - paddingLeft: 4, - paddingRight: 4, - borderRadius: 25, - fontWeight: '600', - }, - text: { - color: LogBoxStyle.getTextColor(1), - fontSize: 14, - lineHeight: 18, - textAlign: 'center', - fontWeight: '600', - textShadowColor: LogBoxStyle.getBackgroundColor(0.4), - textShadowOffset: {width: 0, height: 0}, - textShadowRadius: 3, - }, -}); - -const messageStyles = StyleSheet.create({ - container: { - alignSelf: 'stretch', - flexGrow: 1, - flexShrink: 1, - flexBasis: 'auto', - borderLeftColor: LogBoxStyle.getTextColor(0.2), - borderLeftWidth: 1, - paddingLeft: 8, - }, - text: { - color: LogBoxStyle.getTextColor(1), - flex: 1, - fontSize: 14, - lineHeight: 22, - }, - substitutionText: { - color: LogBoxStyle.getTextColor(0.6), - }, -}); - -const dismissStyles = StyleSheet.create({ - container: { - alignSelf: 'center', - flexDirection: 'row', - flexGrow: 0, - flexShrink: 0, - flexBasis: 'auto', - marginLeft: 5, - }, - press: { - height: 20, - width: 20, - borderRadius: 25, - alignSelf: 'flex-end', - alignItems: 'center', - justifyContent: 'center', - }, - image: { - height: 8, - width: 8, - tintColor: LogBoxStyle.getBackgroundColor(1), - }, -}); - -const toastStyles = StyleSheet.create({ +const styles = StyleSheet.create({ container: { height: 48, position: 'relative', @@ -215,5 +81,3 @@ const toastStyles = StyleSheet.create({ flexBasis: 'auto', }, }); - -export default LogBoxLogNotification; diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js b/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js new file mode 100644 index 000000000000..42c91fdc4b52 --- /dev/null +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationCountBadge.js @@ -0,0 +1,63 @@ +/** + * 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 strict-local + * @format + */ + +import View from '../../Components/View/View'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import Text from '../../Text/Text'; +import * as LogBoxStyle from './LogBoxStyle'; +import * as React from 'react'; + +export default function LogBoxNotificationCountBadge(props: { + count: number, + level: 'error' | 'warn', +}): React.Node { + return ( + + {/* $FlowFixMe[incompatible-type] (>=0.114.0) This suppression was added + * when fixing the type of `StyleSheet.create`. Remove this comment to + * see the error. */} + + {props.count <= 1 ? '!' : props.count} + + + ); +} + +const styles = StyleSheet.create({ + warn: { + backgroundColor: LogBoxStyle.getWarningColor(1), + }, + error: { + backgroundColor: LogBoxStyle.getErrorColor(1), + }, + outside: { + padding: 2, + borderRadius: 25, + backgroundColor: '#fff', + marginRight: 8, + }, + inside: { + minWidth: 18, + paddingLeft: 4, + paddingRight: 4, + borderRadius: 25, + fontWeight: '600', + }, + text: { + color: LogBoxStyle.getTextColor(1), + fontSize: 14, + lineHeight: 18, + textAlign: 'center', + fontWeight: '600', + textShadowColor: LogBoxStyle.getBackgroundColor(0.4), + textShadowOffset: {width: 0, height: 0}, + textShadowRadius: 3, + }, +}); diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js b/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js new file mode 100644 index 000000000000..01ff23832884 --- /dev/null +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationDismissButton.js @@ -0,0 +1,67 @@ +/** + * 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 strict-local + * @format + */ + +import View from '../../Components/View/View'; +import Image from '../../Image/Image'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import LogBoxButton from './LogBoxButton'; +import * as LogBoxStyle from './LogBoxStyle'; +import * as React from 'react'; + +export default function LogBoxNotificationDismissButton(props: { + onPress: () => void, +}): React.Node { + return ( + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + alignSelf: 'center', + flexDirection: 'row', + flexGrow: 0, + flexShrink: 0, + flexBasis: 'auto', + marginLeft: 5, + }, + press: { + height: 20, + width: 20, + borderRadius: 25, + alignSelf: 'flex-end', + alignItems: 'center', + justifyContent: 'center', + }, + image: { + height: 8, + width: 8, + tintColor: LogBoxStyle.getBackgroundColor(1), + }, +}); diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationMessage.js b/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationMessage.js new file mode 100644 index 000000000000..6ce473129cfe --- /dev/null +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxNotificationMessage.js @@ -0,0 +1,57 @@ +/** + * 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 strict-local + * @format + */ + +import type {Message as MessageType} from '../Data/parseLogBoxLog'; + +import View from '../../Components/View/View'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import Text from '../../Text/Text'; +import LogBoxMessage from './LogBoxMessage'; +import * as LogBoxStyle from './LogBoxStyle'; +import * as React from 'react'; + +export default function LogBoxNotificationMessage(props: { + message: MessageType, +}): React.Node { + return ( + + + {props.message && ( + + )} + + + ); +} + +const styles = StyleSheet.create({ + container: { + alignSelf: 'stretch', + flexGrow: 1, + flexShrink: 1, + flexBasis: 'auto', + borderLeftColor: LogBoxStyle.getTextColor(0.2), + borderLeftWidth: 1, + paddingLeft: 8, + }, + text: { + color: LogBoxStyle.getTextColor(1), + flex: 1, + fontSize: 14, + lineHeight: 22, + }, + substitutionText: { + color: LogBoxStyle.getTextColor(0.6), + }, +}); diff --git a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxNotification-test.js b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxNotification-test.js index 99353fae11f5..78c87ec39608 100644 --- a/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxNotification-test.js +++ b/packages/react-native/Libraries/LogBox/UI/__tests__/LogBoxNotification-test.js @@ -16,6 +16,25 @@ const LogBoxLog = require('../../Data/LogBoxLog').default; const LogBoxNotification = require('../LogBoxNotification').default; const React = require('react'); +// Mock child components because we are interested in snapshotting the behavior +// of `LogBoxNotification`, not its children. +jest.mock('../LogBoxButton', () => ({ + __esModule: true, + default: 'LogBoxButton', +})); +jest.mock('../LogBoxNotificationCountBadge', () => ({ + __esModule: true, + default: 'LogBoxNotificationCountBadge', +})); +jest.mock('../LogBoxNotificationDismissButton', () => ({ + __esModule: true, + default: 'LogBoxNotificationDismissButton', +})); +jest.mock('../LogBoxNotificationMessage', () => ({ + __esModule: true, + default: 'LogBoxNotificationMessage', +})); + const log = new LogBoxLog({ level: 'warn', isComponentError: false, @@ -30,7 +49,7 @@ const log = new LogBoxLog({ describe('LogBoxNotification', () => { it('should render log', () => { - const output = render.shallowRender( + const output = render.create( - - - diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 94215f233a0a..0aa73605507f 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -5684,8 +5684,29 @@ exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBox onPressOpen: () => void, onPressDismiss: () => void, }>; -declare function LogBoxLogNotification(props: Props): React.Node; -declare export default typeof LogBoxLogNotification; +declare export default function LogBoxNotification(props: Props): React.Node; +" +`; + +exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxNotificationCountBadge.js 1`] = ` +"declare export default function LogBoxNotificationCountBadge(props: { + count: number, + level: \\"error\\" | \\"warn\\", +}): React.Node; +" +`; + +exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxNotificationDismissButton.js 1`] = ` +"declare export default function LogBoxNotificationDismissButton(props: { + onPress: () => void, +}): React.Node; +" +`; + +exports[`public API should not change unintentionally Libraries/LogBox/UI/LogBoxNotificationMessage.js 1`] = ` +"declare export default function LogBoxNotificationMessage(props: { + message: MessageType, +}): React.Node; " `;