diff --git a/packages/internal-test-utils/consoleMock.js b/packages/internal-test-utils/consoleMock.js index 6d03c74c1dfee..561004a4dea76 100644 --- a/packages/internal-test-utils/consoleMock.js +++ b/packages/internal-test-utils/consoleMock.js @@ -273,6 +273,7 @@ function normalizeCodeLocInfo(str) { // We strip that out in our normalization to make it look more like component stacks. name = name.slice(0, name.length - 7); } + name = name.replace(/.*\/([^\/]+):\d+:\d+/, '**/$1:**:**'); return '\n in ' + name + ' (at **)'; }); } diff --git a/packages/react/src/__tests__/forwardRef-test.js b/packages/react/src/__tests__/forwardRef-test.js index f0f3bb4d5023d..e08990c806355 100644 --- a/packages/react/src/__tests__/forwardRef-test.js +++ b/packages/react/src/__tests__/forwardRef-test.js @@ -13,6 +13,7 @@ describe('forwardRef', () => { let React; let ReactNoop; let waitForAll; + let assertConsoleErrorDev; beforeEach(() => { jest.resetModules(); @@ -21,6 +22,7 @@ describe('forwardRef', () => { const InternalTestUtils = require('internal-test-utils'); waitForAll = InternalTestUtils.waitForAll; + assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev; }); it('should update refs when switching between children', async () => { @@ -114,25 +116,31 @@ describe('forwardRef', () => { }); it('should warn if not provided a callback during creation', () => { - expect(() => React.forwardRef(undefined)).toErrorDev( - 'forwardRef requires a render function but was given undefined.', + React.forwardRef(undefined); + assertConsoleErrorDev( + ['forwardRef requires a render function but was given undefined.'], {withoutStack: true}, ); - expect(() => React.forwardRef(null)).toErrorDev( - 'forwardRef requires a render function but was given null.', + + React.forwardRef(null); + assertConsoleErrorDev( + ['forwardRef requires a render function but was given null.'], { withoutStack: true, }, ); - expect(() => React.forwardRef('foo')).toErrorDev( - 'forwardRef requires a render function but was given string.', + + React.forwardRef('foo'); + assertConsoleErrorDev( + ['forwardRef requires a render function but was given string.'], {withoutStack: true}, ); }); it('should warn if no render function is provided', () => { - expect(React.forwardRef).toErrorDev( - 'forwardRef requires a render function but was given undefined.', + React.forwardRef(); + assertConsoleErrorDev( + ['forwardRef requires a render function but was given undefined.'], {withoutStack: true}, ); }); @@ -143,9 +151,12 @@ describe('forwardRef', () => { } renderWithDefaultProps.defaultProps = {}; - expect(() => React.forwardRef(renderWithDefaultProps)).toErrorDev( - 'forwardRef render functions do not support defaultProps. ' + - 'Did you accidentally pass a React component?', + React.forwardRef(renderWithDefaultProps); + assertConsoleErrorDev( + [ + 'forwardRef render functions do not support defaultProps. ' + + 'Did you accidentally pass a React component?', + ], {withoutStack: true}, ); }); @@ -159,9 +170,12 @@ describe('forwardRef', () => { it('should warn if the render function provided does not use the forwarded ref parameter', () => { const arityOfOne = props =>
; - expect(() => React.forwardRef(arityOfOne)).toErrorDev( - 'forwardRef render functions accept exactly two parameters: props and ref. ' + - 'Did you forget to use the ref parameter?', + React.forwardRef(arityOfOne); + assertConsoleErrorDev( + [ + 'forwardRef render functions accept exactly two parameters: props and ref. ' + + 'Did you forget to use the ref parameter?', + ], {withoutStack: true}, ); }); @@ -174,9 +188,12 @@ describe('forwardRef', () => { it('should warn if the render function provided expects to use more than two parameters', () => { const arityOfThree = (props, ref, x) =>
; - expect(() => React.forwardRef(arityOfThree)).toErrorDev( - 'forwardRef render functions accept exactly two parameters: props and ref. ' + - 'Any additional parameter will be undefined.', + React.forwardRef(arityOfThree); + assertConsoleErrorDev( + [ + 'forwardRef render functions accept exactly two parameters: props and ref. ' + + 'Any additional parameter will be undefined.', + ], {withoutStack: true}, ); }); @@ -190,15 +207,16 @@ describe('forwardRef', () => {

, ); - await expect(async () => { - await waitForAll([]); - }).toErrorDev( + await waitForAll([]); + assertConsoleErrorDev([ 'Each child in a list should have a unique "key" prop.' + '\n\nCheck the top-level render call using . It was passed a child from ForwardRef. ' + 'See https://react.dev/link/warning-keys for more information.\n' + ' in span (at **)\n' + - ' in ', - ); + (gate(flags => flags.enableOwnerStacks) + ? ' in **/forwardRef-test.js:**:** (at **)' + : ' in p (at **)'), + ]); }); it('should use the inner function name for the stack', async () => { @@ -210,16 +228,16 @@ describe('forwardRef', () => {

, ); - await expect(async () => { - await waitForAll([]); - }).toErrorDev( + + await waitForAll([]); + assertConsoleErrorDev([ 'Each child in a list should have a unique "key" prop.' + '\n\nCheck the top-level render call using . It was passed a child from ForwardRef(Inner). ' + 'See https://react.dev/link/warning-keys for more information.\n' + ' in span (at **)\n' + ' in Inner (at **)' + (gate(flags => flags.enableOwnerStacks) ? '' : '\n in p (at **)'), - ); + ]); }); it('should use the inner name in the stack', async () => { @@ -233,16 +251,15 @@ describe('forwardRef', () => {

, ); - await expect(async () => { - await waitForAll([]); - }).toErrorDev( + await waitForAll([]); + assertConsoleErrorDev([ 'Each child in a list should have a unique "key" prop.' + '\n\nCheck the top-level render call using . It was passed a child from ForwardRef(Inner). ' + 'See https://react.dev/link/warning-keys for more information.\n' + ' in span (at **)\n' + ' in Inner (at **)' + (gate(flags => flags.enableOwnerStacks) ? '' : '\n in p (at **)'), - ); + ]); }); it('can use the outer displayName in the stack', async () => { @@ -255,16 +272,15 @@ describe('forwardRef', () => {

, ); - await expect(async () => { - await waitForAll([]); - }).toErrorDev( + await waitForAll([]); + assertConsoleErrorDev([ 'Each child in a list should have a unique "key" prop.' + '\n\nCheck the top-level render call using . It was passed a child from Outer. ' + 'See https://react.dev/link/warning-keys for more information.\n' + ' in span (at **)\n' + ' in Outer (at **)' + (gate(flags => flags.enableOwnerStacks) ? '' : '\n in p (at **)'), - ); + ]); }); it('should prefer the inner name to the outer displayName in the stack', async () => { @@ -279,16 +295,15 @@ describe('forwardRef', () => {

, ); - await expect(async () => { - await waitForAll([]); - }).toErrorDev( + await waitForAll([]); + assertConsoleErrorDev([ 'Each child in a list should have a unique "key" prop.' + '\n\nCheck the top-level render call using . It was passed a child from Outer. ' + 'See https://react.dev/link/warning-keys for more information.\n' + ' in span (at **)\n' + ' in Inner (at **)' + (gate(flags => flags.enableOwnerStacks) ? '' : '\n in p (at **)'), - ); + ]); }); it('should not bailout if forwardRef is not wrapped in memo', async () => { @@ -419,13 +434,12 @@ describe('forwardRef', () => { }); it('warns on forwardRef(memo(...))', () => { - expect(() => { - React.forwardRef( - React.memo((props, ref) => { - return null; - }), - ); - }).toErrorDev( + React.forwardRef( + React.memo((props, ref) => { + return null; + }), + ); + assertConsoleErrorDev( [ 'forwardRef requires a render function but received a `memo` ' + 'component. Instead of forwardRef(memo(...)), use ' +