diff --git a/packages/react-devtools-shared/src/__tests__/componentStacks-test.js b/packages/react-devtools-shared/src/__tests__/componentStacks-test.js index f32e0d097e8de..6bbdc899b55bb 100644 --- a/packages/react-devtools-shared/src/__tests__/componentStacks-test.js +++ b/packages/react-devtools-shared/src/__tests__/componentStacks-test.js @@ -14,6 +14,7 @@ describe('component stack', () => { let act; let mockError; let mockWarn; + let supportsOwnerStacks; beforeEach(() => { // Intercept native console methods before DevTools bootstraps. @@ -31,6 +32,12 @@ describe('component stack', () => { act = utils.act; React = require('react'); + if ( + React.version.startsWith('19') && + React.version.includes('experimental') + ) { + supportsOwnerStacks = true; + } }); const {render} = getVersionedRenderImplementation(); @@ -49,13 +56,13 @@ describe('component stack', () => { expect(mockError).toHaveBeenCalledWith( 'Test error.', - '\n in Child (at **)' + + (supportsOwnerStacks ? '' : '\n in Child (at **)') + '\n in Parent (at **)' + '\n in Grandparent (at **)', ); expect(mockWarn).toHaveBeenCalledWith( 'Test warning.', - '\n in Child (at **)' + + (supportsOwnerStacks ? '' : '\n in Child (at **)') + '\n in Parent (at **)' + '\n in Grandparent (at **)', ); @@ -112,17 +119,21 @@ describe('component stack', () => { expect(mockError).toHaveBeenCalledWith( 'Test error.', - '\n in Child (at **)' + - '\n in ServerComponent (at **)' + - '\n in Parent (at **)' + - '\n in Grandparent (at **)', + supportsOwnerStacks + ? '\n in Child (at **)' + : '\n in Child (at **)' + + '\n in ServerComponent (at **)' + + '\n in Parent (at **)' + + '\n in Grandparent (at **)', ); expect(mockWarn).toHaveBeenCalledWith( 'Test warning.', - '\n in Child (at **)' + - '\n in ServerComponent (at **)' + - '\n in Parent (at **)' + - '\n in Grandparent (at **)', + supportsOwnerStacks + ? '\n in Child (at **)' + : '\n in Child (at **)' + + '\n in ServerComponent (at **)' + + '\n in Parent (at **)' + + '\n in Grandparent (at **)', ); }); }); diff --git a/packages/react-devtools-shared/src/__tests__/console-test.js b/packages/react-devtools-shared/src/__tests__/console-test.js index 75e7dc1c87b84..56ff240170dcd 100644 --- a/packages/react-devtools-shared/src/__tests__/console-test.js +++ b/packages/react-devtools-shared/src/__tests__/console-test.js @@ -22,6 +22,7 @@ let mockWarn; let patchConsole; let unpatchConsole; let rendererID; +let supportsOwnerStacks = false; describe('console', () => { beforeEach(() => { @@ -62,6 +63,12 @@ describe('console', () => { }; React = require('react'); + if ( + React.version.startsWith('19') && + React.version.includes('experimental') + ) { + supportsOwnerStacks = true; + } ReactDOMClient = require('react-dom/client'); const utils = require('./utils'); @@ -224,13 +231,17 @@ describe('console', () => { expect(mockWarn.mock.calls[0]).toHaveLength(2); expect(mockWarn.mock.calls[0][0]).toBe('warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError).toHaveBeenCalledTimes(1); expect(mockError.mock.calls[0]).toHaveLength(2); expect(mockError.mock.calls[0][0]).toBe('error'); expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); }); @@ -267,23 +278,31 @@ describe('console', () => { expect(mockWarn.mock.calls[0]).toHaveLength(2); expect(mockWarn.mock.calls[0][0]).toBe('active warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockWarn.mock.calls[1]).toHaveLength(2); expect(mockWarn.mock.calls[1][0]).toBe('passive warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError).toHaveBeenCalledTimes(2); expect(mockError.mock.calls[0]).toHaveLength(2); expect(mockError.mock.calls[0][0]).toBe('active error'); expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError.mock.calls[1]).toHaveLength(2); expect(mockError.mock.calls[1][0]).toBe('passive error'); expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); }); @@ -325,23 +344,31 @@ describe('console', () => { expect(mockWarn.mock.calls[0]).toHaveLength(2); expect(mockWarn.mock.calls[0][0]).toBe('didMount warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockWarn.mock.calls[1]).toHaveLength(2); expect(mockWarn.mock.calls[1][0]).toBe('didUpdate warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError).toHaveBeenCalledTimes(2); expect(mockError.mock.calls[0]).toHaveLength(2); expect(mockError.mock.calls[0][0]).toBe('didMount error'); expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError.mock.calls[1]).toHaveLength(2); expect(mockError.mock.calls[1][0]).toBe('didUpdate error'); expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); }); @@ -375,13 +402,17 @@ describe('console', () => { expect(mockWarn.mock.calls[0]).toHaveLength(2); expect(mockWarn.mock.calls[0][0]).toBe('warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError).toHaveBeenCalledTimes(1); expect(mockError.mock.calls[0]).toHaveLength(2); expect(mockError.mock.calls[0][0]).toBe('error'); expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); }); @@ -465,13 +496,17 @@ describe('console', () => { expect(mockWarn.mock.calls[0]).toHaveLength(2); expect(mockWarn.mock.calls[0][0]).toBe('warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError).toHaveBeenCalledTimes(1); expect(mockError.mock.calls[0]).toHaveLength(2); expect(mockError.mock.calls[0][0]).toBe('error'); expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); }); @@ -996,7 +1031,9 @@ describe('console', () => { expect(mockWarn).toHaveBeenCalledTimes(2); expect(mockWarn.mock.calls[0]).toHaveLength(2); expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockWarn.mock.calls[1]).toHaveLength(3); expect(mockWarn.mock.calls[1][0]).toEqual( @@ -1004,13 +1041,17 @@ describe('console', () => { ); expect(mockWarn.mock.calls[1][1]).toMatch('warn'); expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][2]).trim()).toEqual( - 'in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? 'in Parent (at **)' + : 'in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError).toHaveBeenCalledTimes(2); expect(mockError.mock.calls[0]).toHaveLength(2); expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toEqual( - '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? '\n in Parent (at **)' + : '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); expect(mockError.mock.calls[1]).toHaveLength(3); expect(mockError.mock.calls[1][0]).toEqual( @@ -1018,7 +1059,9 @@ describe('console', () => { ); expect(mockError.mock.calls[1][1]).toEqual('error'); expect(normalizeCodeLocInfo(mockError.mock.calls[1][2]).trim()).toEqual( - 'in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', + supportsOwnerStacks + ? 'in Parent (at **)' + : 'in Child (at **)\n in Intermediate (at **)\n in Parent (at **)', ); }); }); diff --git a/scripts/jest/devtools/setupEnv.js b/scripts/jest/devtools/setupEnv.js index 1021fbb587c54..1e6ab7c0ea866 100644 --- a/scripts/jest/devtools/setupEnv.js +++ b/scripts/jest/devtools/setupEnv.js @@ -70,9 +70,14 @@ function lazyRequireFunctionExports(moduleName) { // If this export is a function, return a wrapper function that lazily // requires the implementation from the current module cache. if (typeof originalModule[prop] === 'function') { - return function () { - return jest.requireActual(moduleName)[prop].apply(this, arguments); - }; + // eslint-disable-next-line no-eval + const wrapper = eval(` + (function () { + return jest.requireActual(moduleName)[prop].apply(this, arguments); + }) + // We use this to trick the filtering of Flight to exclude this frame. + //# sourceURL=`); + return wrapper; } else { return originalModule[prop]; }