From cfd3bbc61f3f37334831a215c5dd87b68e765edd Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Thu, 19 Dec 2024 17:27:55 -0500 Subject: [PATCH 1/2] [assert helpers] not dom or reconciler --- .../__tests__/ReactCacheOld-test.internal.js | 35 +++++--- .../ReactHooksInspectionIntegration-test.js | 13 +-- .../__tests__/trustedTypes-test.internal.js | 14 +-- .../__tests__/ReactFabric-test.internal.js | 86 ++++++++++--------- .../ReactNativeEvents-test.internal.js | 43 +++++----- .../ReactNativeMount-test.internal.js | 33 +++---- .../__tests__/ReactFlightDOMBrowser-test.js | 52 +++++++---- .../src/__tests__/ReactFlightDOMEdge-test.js | 21 +++-- .../src/__tests__/ReactFlightDOMForm-test.js | 13 ++- .../src/__tests__/ReactTestRenderer-test.js | 23 +++-- 10 files changed, 189 insertions(+), 144 deletions(-) diff --git a/packages/react-cache/src/__tests__/ReactCacheOld-test.internal.js b/packages/react-cache/src/__tests__/ReactCacheOld-test.internal.js index 0e9cb549f653a..554e6e4bfb29a 100644 --- a/packages/react-cache/src/__tests__/ReactCacheOld-test.internal.js +++ b/packages/react-cache/src/__tests__/ReactCacheOld-test.internal.js @@ -22,6 +22,7 @@ let waitForPaint; let assertLog; let waitForThrow; let act; +let assertConsoleErrorDev; describe('ReactCache', () => { beforeEach(() => { @@ -39,6 +40,7 @@ describe('ReactCache', () => { assertLog = InternalTestUtils.assertLog; waitForThrow = InternalTestUtils.waitForThrow; waitForPaint = InternalTestUtils.waitForPaint; + assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev; act = InternalTestUtils.act; TextResource = createResource( @@ -190,20 +192,31 @@ describe('ReactCache', () => { ); if (__DEV__) { - await expect(async () => { - await waitForAll([ - 'App', - 'Loading...', - - ...(gate('enableSiblingPrerendering') ? ['App'] : []), - ]); - }).toErrorDev([ + await waitForAll([ + 'App', + 'Loading...', + + ...(gate('enableSiblingPrerendering') ? ['App'] : []), + ]); + assertConsoleErrorDev([ 'Invalid key type. Expected a string, number, symbol, or ' + "boolean, but instead received: [ 'Hi', 100 ]\n\n" + 'To use non-primitive values as keys, you must pass a hash ' + - 'function as the second argument to createResource().', - - ...(gate('enableSiblingPrerendering') ? ['Invalid key type'] : []), + 'function as the second argument to createResource().\n' + + ' in App (at **)' + + (gate(flags => flags.enableOwnerStacks) + ? '' + : '\n in Suspense (at **)'), + + ...(gate('enableSiblingPrerendering') + ? [ + 'Invalid key type. Expected a string, number, symbol, or ' + + "boolean, but instead received: [ 'Hi', 100 ]\n\n" + + 'To use non-primitive values as keys, you must pass a hash ' + + 'function as the second argument to createResource().\n' + + ' in App (at **)', + ] + : []), ]); } else { await waitForAll([ diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js index ff8e7e1ac8683..87f98b99f2534 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js @@ -14,6 +14,7 @@ let React; let ReactTestRenderer; let ReactDebugTools; let act; +let assertConsoleErrorDev; let useMemoCache; function normalizeSourceLoc(tree) { @@ -33,7 +34,7 @@ describe('ReactHooksInspectionIntegration', () => { jest.resetModules(); React = require('react'); ReactTestRenderer = require('react-test-renderer'); - act = require('internal-test-utils').act; + ({act, assertConsoleErrorDev} = require('internal-test-utils')); ReactDebugTools = require('react-debug-tools'); useMemoCache = require('react/compiler-runtime').c; }); @@ -2344,10 +2345,12 @@ describe('ReactHooksInspectionIntegration', () => { , ); - await expect(async () => { - await act(async () => await LazyFoo); - }).toErrorDev([ - 'Foo: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.', + await act(async () => await LazyFoo); + assertConsoleErrorDev([ + 'Foo: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.' + + (gate(flags => flags.enableOwnerStacks) + ? '' + : '\n in Foo (at **)\n' + ' in Suspense (at **)'), ]); const childFiber = renderer.root._currentFiber(); diff --git a/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js b/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js index 923ee1f5d81a6..5a43a9ec2f06c 100644 --- a/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js +++ b/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js @@ -14,6 +14,7 @@ describe('when Trusted Types are available in global object', () => { let ReactDOMClient; let ReactFeatureFlags; let act; + let assertConsoleErrorDev; let container; let ttObject1; let ttObject2; @@ -36,7 +37,7 @@ describe('when Trusted Types are available in global object', () => { ReactFeatureFlags.enableTrustedTypesIntegration = true; React = require('react'); ReactDOMClient = require('react-dom/client'); - act = require('internal-test-utils').act; + ({act, assertConsoleErrorDev} = require('internal-test-utils')); ttObject1 = { toString() { return 'Hi'; @@ -208,17 +209,16 @@ describe('when Trusted Types are available in global object', () => { it('should warn once when rendering script tag in jsx on client', async () => { const root = ReactDOMClient.createRoot(container); - await expect(async () => { - await act(() => { - root.render(); - }); - }).toErrorDev( + await act(() => { + root.render(); + }); + assertConsoleErrorDev([ 'Encountered a script tag while rendering React component. ' + 'Scripts inside React components are never executed when rendering ' + 'on the client. Consider using template tag instead ' + '(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).\n' + ' in script (at **)', - ); + ]); // check that the warning is printed only once await act(() => { diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index 03f0cd0a6c0f3..05116be30110f 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -16,6 +16,7 @@ let ReactNativePrivateInterface; let createReactNativeComponentClass; let StrictMode; let act; +let assertConsoleErrorDev; const DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT = "dispatchCommand was called with a ref that isn't a " + @@ -38,7 +39,7 @@ describe('ReactFabric', () => { createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .ReactNativeViewConfigRegistry.register; - act = require('internal-test-utils').act; + ({act, assertConsoleErrorDev} = require('internal-test-utils')); }); it('should be able to create and render a native component', async () => { @@ -459,9 +460,8 @@ describe('ReactFabric', () => { }); expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); - expect(() => { - ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]); - }).toErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { + ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]); + assertConsoleErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { withoutStack: true, }); @@ -525,9 +525,8 @@ describe('ReactFabric', () => { }); expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled(); - expect(() => { - ReactFabric.sendAccessibilityEvent(viewRef, 'eventTypeName'); - }).toErrorDev([SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT], { + ReactFabric.sendAccessibilityEvent(viewRef, 'eventTypeName'); + assertConsoleErrorDev([SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT], { withoutStack: true, }); @@ -856,24 +855,31 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - await expect(async () => { - await act(() => { - ReactFabric.render(this should warn, 11, null, true); - }); - }).toErrorDev(['Text strings must be rendered within a component.']); + await act(() => { + ReactFabric.render(this should warn, 11, null, true); + }); + assertConsoleErrorDev([ + 'Text strings must be rendered within a component.\n' + + ' in RCTView (at **)', + ]); - await expect(async () => { - await act(() => { - ReactFabric.render( - - hi hello hi - , - 11, - null, - true, - ); - }); - }).toErrorDev(['Text strings must be rendered within a component.']); + await act(() => { + ReactFabric.render( + + hi hello hi + , + 11, + null, + true, + ); + }); + assertConsoleErrorDev([ + 'Text strings must be rendered within a component.\n' + + ' in RCTScrollView (at **)' + + (gate(flags => !flags.enableOwnerStacks) + ? '\n in RCTText (at **)' + : ''), + ]); }); it('should not throw for text inside of an indirect ancestor', async () => { @@ -1166,10 +1172,8 @@ describe('ReactFabric', () => { ); }); - let match; - expect( - () => (match = ReactFabric.findHostInstance_DEPRECATED(parent)), - ).toErrorDev([ + const match = ReactFabric.findHostInstance_DEPRECATED(parent); + assertConsoleErrorDev([ 'findHostInstance_DEPRECATED is deprecated in StrictMode. ' + 'findHostInstance_DEPRECATED was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -1207,10 +1211,8 @@ describe('ReactFabric', () => { ); }); - let match; - expect( - () => (match = ReactFabric.findHostInstance_DEPRECATED(parent)), - ).toErrorDev([ + const match = ReactFabric.findHostInstance_DEPRECATED(parent); + assertConsoleErrorDev([ 'findHostInstance_DEPRECATED is deprecated in StrictMode. ' + 'findHostInstance_DEPRECATED was passed an instance of IsInStrictMode which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -1250,8 +1252,8 @@ describe('ReactFabric', () => { ); }); - let match; - expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([ + const match = ReactFabric.findNodeHandle(parent); + assertConsoleErrorDev([ 'findNodeHandle is deprecated in StrictMode. ' + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -1291,8 +1293,8 @@ describe('ReactFabric', () => { ); }); - let match; - expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([ + const match = ReactFabric.findNodeHandle(parent); + assertConsoleErrorDev([ 'findNodeHandle is deprecated in StrictMode. ' + 'findNodeHandle was passed an instance of IsInStrictMode which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -1313,16 +1315,16 @@ describe('ReactFabric', () => { return null; } } - await expect(async () => { - await act(() => { - ReactFabric.render(, 11, null, true); - }); - }).toErrorDev([ + await act(() => { + ReactFabric.render(, 11, null, true); + }); + assertConsoleErrorDev([ 'TestComponent is accessing findNodeHandle inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', + 'componentDidUpdate instead.\n' + + ' in TestComponent (at **)', ]); }); diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js index 46b2ad9cf1fc7..4ad8f94af3b05 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js @@ -227,29 +227,28 @@ test('handles events on text nodes', () => { } const log = []; - expect(() => { - ReactNative.render( - - - log.push('string touchend')} - onTouchEndCapture={() => log.push('string touchend capture')} - onTouchStart={() => log.push('string touchstart')} - onTouchStartCapture={() => log.push('string touchstart capture')}> - Text Content - - log.push('number touchend')} - onTouchEndCapture={() => log.push('number touchend capture')} - onTouchStart={() => log.push('number touchstart')} - onTouchStartCapture={() => log.push('number touchstart capture')}> - {123} - + ReactNative.render( + + + log.push('string touchend')} + onTouchEndCapture={() => log.push('string touchend capture')} + onTouchStart={() => log.push('string touchstart')} + onTouchStartCapture={() => log.push('string touchstart capture')}> + Text Content - , - 1, - ); - }).toErrorDev([ + log.push('number touchend')} + onTouchEndCapture={() => log.push('number touchend capture')} + onTouchStart={() => log.push('number touchstart')} + onTouchStartCapture={() => log.push('number touchstart capture')}> + {123} + + + , + 1, + ); + assertConsoleErrorDev([ 'ContextHack uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.', ]); diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js index 790078b224b83..0aa1c3f0ba0af 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js @@ -18,6 +18,7 @@ let UIManager; let TextInputState; let ReactNativePrivateInterface; let act; +let assertConsoleErrorDev; const DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT = "dispatchCommand was called with a ref that isn't a " + @@ -32,7 +33,7 @@ describe('ReactNative', () => { jest.resetModules(); React = require('react'); - act = require('internal-test-utils').act; + ({act, assertConsoleErrorDev} = require('internal-test-utils')); StrictMode = React.StrictMode; ReactNative = require('react-native-renderer'); ReactNativePrivateInterface = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'); @@ -158,9 +159,8 @@ describe('ReactNative', () => { ); expect(UIManager.dispatchViewManagerCommand).not.toBeCalled(); - expect(() => { - ReactNative.dispatchCommand(viewRef, 'updateCommand', [10, 20]); - }).toErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { + ReactNative.dispatchCommand(viewRef, 'updateCommand', [10, 20]); + assertConsoleErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], { withoutStack: true, }); @@ -219,9 +219,8 @@ describe('ReactNative', () => { ); expect(UIManager.sendAccessibilityEvent).not.toBeCalled(); - expect(() => { - ReactNative.sendAccessibilityEvent(viewRef, 'updateCommand', [10, 20]); - }).toErrorDev([SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT], { + ReactNative.sendAccessibilityEvent(viewRef, 'updateCommand', [10, 20]); + assertConsoleErrorDev([SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT], { withoutStack: true, }); @@ -614,10 +613,8 @@ describe('ReactNative', () => { ReactNative.render( (parent = n)} />, 11); - let match; - expect( - () => (match = ReactNative.findHostInstance_DEPRECATED(parent)), - ).toErrorDev([ + const match = ReactNative.findHostInstance_DEPRECATED(parent); + assertConsoleErrorDev([ 'findHostInstance_DEPRECATED is deprecated in StrictMode. ' + 'findHostInstance_DEPRECATED was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -652,10 +649,8 @@ describe('ReactNative', () => { 11, ); - let match; - expect( - () => (match = ReactNative.findHostInstance_DEPRECATED(parent)), - ).toErrorDev([ + const match = ReactNative.findHostInstance_DEPRECATED(parent); + assertConsoleErrorDev([ 'findHostInstance_DEPRECATED is deprecated in StrictMode. ' + 'findHostInstance_DEPRECATED was passed an instance of IsInStrictMode which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -689,8 +684,8 @@ describe('ReactNative', () => { ReactNative.render( (parent = n)} />, 11); - let match; - expect(() => (match = ReactNative.findNodeHandle(parent))).toErrorDev([ + const match = ReactNative.findNodeHandle(parent); + assertConsoleErrorDev([ 'findNodeHandle is deprecated in StrictMode. ' + 'findNodeHandle was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -725,8 +720,8 @@ describe('ReactNative', () => { 11, ); - let match; - expect(() => (match = ReactNative.findNodeHandle(parent))).toErrorDev([ + const match = ReactNative.findNodeHandle(parent); + assertConsoleErrorDev([ 'findNodeHandle is deprecated in StrictMode. ' + 'findNodeHandle was passed an instance of IsInStrictMode which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js index 3eccca1a9ba70..040bb046b5518 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js @@ -38,6 +38,7 @@ let ReactServerDOM; let Scheduler; let ReactServerScheduler; let reactServerAct; +let assertConsoleErrorDev; describe('ReactFlightDOMBrowser', () => { beforeEach(() => { @@ -75,7 +76,7 @@ describe('ReactFlightDOMBrowser', () => { Scheduler = require('scheduler'); patchMessageChannel(Scheduler); - act = require('internal-test-utils').act; + ({act, assertConsoleErrorDev} = require('internal-test-utils')); React = require('react'); ReactDOM = require('react-dom'); ReactDOMClient = require('react-dom/client'); @@ -1156,25 +1157,38 @@ describe('ReactFlightDOMBrowser', () => { const container = document.createElement('div'); const root = ReactDOMClient.createRoot(container); - await expect(async () => { - const stream = await serverAct(() => - ReactServerDOMServer.renderToReadableStream( - <> - {Array(6).fill(
no key
)}
- - {Array(6).fill(
no key
)} -
- , - webpackMap, - ), - ); - const result = - await ReactServerDOMClient.createFromReadableStream(stream); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream( + <> + {Array(6).fill(
no key
)}
+ + {Array(6).fill(
no key
)} +
+ , + webpackMap, + ), + ); + const result = await ReactServerDOMClient.createFromReadableStream(stream); - await act(() => { - root.render(result); - }); - }).toErrorDev('Each child in a list should have a unique "key" prop.'); + if (!gate(flags => flags.enableOwnerStacks)) { + assertConsoleErrorDev([ + 'Each child in a list should have a unique "key" prop. ' + + 'See https://react.dev/link/warning-keys for more information.\n' + + ' in div (at **)', + ]); + } + + await act(() => { + root.render(result); + }); + if (gate(flags => flags.enableOwnerStacks)) { + assertConsoleErrorDev([ + 'Each child in a list should have a unique "key" prop.\n\n' + + 'Check the top-level render call using . ' + + 'See https://react.dev/link/warning-keys for more information.\n' + + ' in div (at **)', + ]); + } }); it('basic use(promise)', async () => { diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js index f2814f250a2df..603dbbf09e5ca 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js @@ -37,6 +37,7 @@ let ReactServerDOMStaticServer; let ReactServerDOMClient; let use; let reactServerAct; +let assertConsoleErrorDev; function normalizeCodeLocInfo(str) { return ( @@ -66,6 +67,8 @@ describe('ReactFlightDOMEdge', () => { jest.resetModules(); reactServerAct = require('internal-test-utils').serverAct; + assertConsoleErrorDev = + require('internal-test-utils').assertConsoleErrorDev; // Simulate the condition resolution jest.mock('react', () => require('react/react.react-server')); @@ -802,17 +805,19 @@ describe('ReactFlightDOMEdge', () => { ), }; - expect(() => { - ServerModule.greet.bind({}, 'hi'); - }).toErrorDev( - 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().', + ServerModule.greet.bind({}, 'hi'); + assertConsoleErrorDev( + [ + 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().', + ], {withoutStack: true}, ); - expect(() => { - ServerModuleImportedOnClient.greet.bind({}, 'hi'); - }).toErrorDev( - 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().', + ServerModuleImportedOnClient.greet.bind({}, 'hi'); + assertConsoleErrorDev( + [ + 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().', + ], {withoutStack: true}, ); }); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMForm-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMForm-test.js index 0b4549d5bac47..bb7c2c955bcb4 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMForm-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMForm-test.js @@ -50,6 +50,7 @@ let ReactServerDOMClient; let ReactDOMClient; let useActionState; let act; +let assertConsoleErrorDev; describe('ReactFlightDOMForm', () => { beforeEach(() => { @@ -72,6 +73,8 @@ describe('ReactFlightDOMForm', () => { ReactDOMServer = require('react-dom/server.edge'); ReactDOMClient = require('react-dom/client'); act = React.act; + assertConsoleErrorDev = + require('internal-test-utils').assertConsoleErrorDev; // TODO: Test the old api but it warns so needs warnings to be asserted. // if (__VARIANT__) { @@ -959,12 +962,13 @@ describe('ReactFlightDOMForm', () => { await readIntoContainer(postbackSsrStream); } - await expect(submitTheForm).toErrorDev( + await submitTheForm(); + assertConsoleErrorDev([ 'Failed to serialize an action for progressive enhancement:\n' + 'Error: React Element cannot be passed to Server Functions from the Client without a temporary reference set. Pass a TemporaryReferenceSet to the options.\n' + ' [
]\n' + ' ^^^^^^', - ); + ]); // The error message was returned as JSX. const form2 = container.getElementsByTagName('form')[0]; @@ -1035,10 +1039,11 @@ describe('ReactFlightDOMForm', () => { await readIntoContainer(postbackSsrStream); } - await expect(submitTheForm).toErrorDev( + await submitTheForm(); + assertConsoleErrorDev([ 'Failed to serialize an action for progressive enhancement:\n' + 'Error: File/Blob fields are not yet supported in progressive forms. Will fallback to client hydration.', - ); + ]); expect(blob instanceof Blob).toBe(true); expect(blob.size).toBe(2); diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js index e3400b173a21d..0b08cde378c45 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js @@ -14,6 +14,7 @@ let React; let ReactCache; let ReactTestRenderer; let act; +let assertConsoleErrorDev; describe('ReactTestRenderer', () => { beforeEach(() => { @@ -27,19 +28,27 @@ describe('ReactTestRenderer', () => { ReactTestRenderer = require('react-test-renderer'); const InternalTestUtils = require('internal-test-utils'); act = InternalTestUtils.act; + assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev; }); it('should warn if used to render a ReactDOM portal', async () => { const container = document.createElement('div'); let error; - await expect(async () => { - await act(() => { - ReactTestRenderer.create(ReactDOM.createPortal('foo', container)); - }).catch(e => (error = e)); - }).toErrorDev('An invalid container has been provided.', { - withoutStack: true, - }); + await act(() => { + ReactTestRenderer.create(ReactDOM.createPortal('foo', container)); + }).catch(e => (error = e)); + assertConsoleErrorDev( + [ + 'An invalid container has been provided. ' + + 'This may indicate that another renderer is being used in addition to the test renderer. ' + + '(For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) ' + + 'This is not supported.', + ], + { + withoutStack: true, + }, + ); // After the update throws, a subsequent render is scheduled to // unmount the whole tree. This update also causes an error, so React From ef32edd6928ed398d3173e590712bc9b8a638d08 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Thu, 19 Dec 2024 17:33:42 -0500 Subject: [PATCH 2/2] fix test --- .../src/__tests__/ReactNativeEvents-test.internal.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js index 4ad8f94af3b05..f4ab24d71d429 100644 --- a/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js @@ -18,6 +18,7 @@ let ReactNative; let ResponderEventPlugin; let UIManager; let createReactNativeComponentClass; +let assertConsoleErrorDev; // Parallels requireNativeComponent() in that it lazily constructs a view config, // And registers view manager event types with ReactNativeViewConfigRegistry. @@ -69,6 +70,7 @@ beforeEach(() => { require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').RCTEventEmitter; React = require('react'); act = require('internal-test-utils').act; + assertConsoleErrorDev = require('internal-test-utils').assertConsoleErrorDev; ReactNative = require('react-native-renderer'); ResponderEventPlugin = require('react-native-renderer/src/legacy-events/ResponderEventPlugin').default; @@ -249,7 +251,10 @@ test('handles events on text nodes', () => { 1, ); assertConsoleErrorDev([ - 'ContextHack uses the legacy childContextTypes API which will soon be removed. Use React.createContext() instead.', + 'ContextHack uses the legacy childContextTypes API which will soon be removed. ' + + 'Use React.createContext() instead. ' + + '(https://react.dev/link/legacy-context)' + + '\n in ContextHack (at **)', ]); expect(UIManager.createView).toHaveBeenCalledTimes(5);