From e403f30bca3af5b067bd7008bd6c37caf7d226c2 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sat, 13 May 2017 00:01:34 +0100 Subject: [PATCH 1/5] Provide non-standard stack with invalid type warnings --- .flowconfig | 2 + .../classic/element/ReactElementValidator.js | 7 +++ .../__tests__/ReactElementValidator-test.js | 45 ++++++++++++++++ .../hooks/ReactComponentTreeHook.js | 51 +++++++++++++++++++ .../ReactJSXElementValidator-test.js | 49 ++++++++++++++++++ 5 files changed, 154 insertions(+) diff --git a/.flowconfig b/.flowconfig index 3a962f8881555..6b1984b129844 100644 --- a/.flowconfig +++ b/.flowconfig @@ -3,6 +3,8 @@ /examples/.* /fixtures/.* /build/.* +/node_modules/chrome-devtools-frontend/.* +/.*/node_modules/chrome-devtools-frontend/.* /.*/node_modules/y18n/.* /.*/__mocks__/.* /.*/__tests__/.* diff --git a/src/isomorphic/classic/element/ReactElementValidator.js b/src/isomorphic/classic/element/ReactElementValidator.js index b840fc5885e33..f7ee32194eab9 100644 --- a/src/isomorphic/classic/element/ReactElementValidator.js +++ b/src/isomorphic/classic/element/ReactElementValidator.js @@ -223,6 +223,12 @@ var ReactElementValidator = { info += ReactComponentTreeHook.getCurrentStackAddendum(); + var currentSource = props !== null && + props !== undefined && + props.__source !== undefined + ? props.__source + : null; + ReactComponentTreeHook.pushNonStandardWarningStack(true, currentSource); warning( false, 'React.createElement: type is invalid -- expected a string (for ' + @@ -231,6 +237,7 @@ var ReactElementValidator = { type == null ? type : typeof type, info, ); + ReactComponentTreeHook.popNonStandardWarningStack(); } } diff --git a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js index fc43eacc526a7..80c0b0252de76 100644 --- a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js +++ b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js @@ -525,4 +525,49 @@ describe('ReactElementValidator', () => { "component from the file it's defined in. Check your code at **.", ); }); + + it('provides stack via non-standard console.stack for invalid types', () => { + spyOn(console, 'error'); + + function Foo() { + var Bad = undefined; + return React.createElement(Bad); + } + + function App() { + return React.createElement(Foo); + } + + try { + console.stack = jest.fn(); + console.stackEnd = jest.fn(); + + expect(() => { + ReactTestUtils.renderIntoDocument(React.createElement(App)); + }).toThrow( + 'Element type is invalid: expected a string (for built-in components) ' + + 'or a class/function (for composite components) but got: undefined. ' + + "You likely forgot to export your component from the file it's " + + 'defined in. Check the render method of `Foo`.', + ); + + expect(console.stack.mock.calls.length).toBe(1); + expect(console.stackEnd.mock.calls.length).toBe(1); + + var stack = console.stack.mock.calls[0][0]; + expect(Array.isArray(stack)).toBe(true); + expect(stack.map(frame => frame.functionName)).toEqual([ + 'Foo', + 'App', + null, + ]); + expect( + stack.map(frame => frame.fileName && frame.fileName.slice(-8)), + ).toEqual([null, null, null]); + expect(stack.map(frame => frame.lineNumber)).toEqual([null, null, null]); + } finally { + delete console.stack; + delete console.stackEnd; + } + }); }); diff --git a/src/isomorphic/hooks/ReactComponentTreeHook.js b/src/isomorphic/hooks/ReactComponentTreeHook.js index b29488151911e..a935fa71e675b 100644 --- a/src/isomorphic/hooks/ReactComponentTreeHook.js +++ b/src/isomorphic/hooks/ReactComponentTreeHook.js @@ -402,6 +402,57 @@ var ReactComponentTreeHook = { getRootIDs, getRegisteredIDs: getItemIDs, + + pushNonStandardWarningStack( + isCreatingElement: boolean, + currentSource: ?Source, + ) { + if (typeof console.stack !== 'function') { + return; + } + + var stack = []; + var currentOwner = ReactCurrentOwner.current; + var id = currentOwner && currentOwner._debugID; + + try { + if (isCreatingElement) { + stack.push({ + fileName: currentSource ? currentSource.fileName : null, + lineNumber: currentSource ? currentSource.lineNumber : null, + functionName: id ? ReactComponentTreeHook.getDisplayName(id) : null, + }); + } + + while (id) { + var element = ReactComponentTreeHook.getElement(id); + var ownerID = ReactComponentTreeHook.getOwnerID(id); + var ownerName = ownerID + ? ReactComponentTreeHook.getDisplayName(ownerID) + : null; + var source = element && element._source; + stack.push({ + fileName: source ? source.fileName : null, + lineNumber: source ? source.lineNumber : null, + functionName: ownerName, + }); + // Owner stack is more useful for visual representation + id = ownerID || ReactComponentTreeHook.getParentID(id); + } + } catch (err) { + // Internal state is messed up. + // Stop building the stack (it's just a nice to have). + } + + console.stack(stack); + }, + + popNonStandardWarningStack() { + if (typeof console.stackEnd !== 'function') { + return; + } + console.stackEnd(); + }, }; module.exports = ReactComponentTreeHook; diff --git a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js index b4f2697271ebc..2f8b8816b3eb7 100644 --- a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js +++ b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js @@ -400,4 +400,53 @@ describe('ReactJSXElementValidator', () => { ' Use a static property named `defaultProps` instead.', ); }); + + it('provides stack via non-standard console.stack for invalid types', () => { + spyOn(console, 'error'); + + function Foo() { + var Bad = undefined; + return ; + } + + function App() { + return ; + } + + try { + console.stack = jest.fn(); + console.stackEnd = jest.fn(); + + expect(() => { + ReactTestUtils.renderIntoDocument(); + }).toThrow( + 'Element type is invalid: expected a string (for built-in components) ' + + 'or a class/function (for composite components) but got: undefined. ' + + "You likely forgot to export your component from the file it's " + + 'defined in. Check the render method of `Foo`.', + ); + + expect(console.stack.mock.calls.length).toBe(1); + expect(console.stackEnd.mock.calls.length).toBe(1); + + var stack = console.stack.mock.calls[0][0]; + expect(Array.isArray(stack)).toBe(true); + expect(stack.map(frame => frame.functionName)).toEqual([ + 'Foo', + 'App', + null, + ]); + expect( + stack.map(frame => frame.fileName && frame.fileName.slice(-8)), + ).toEqual(['-test.js', '-test.js', '-test.js']); + expect(stack.map(frame => typeof frame.lineNumber)).toEqual([ + 'number', + 'number', + 'number', + ]); + } finally { + delete console.stack; + delete console.stackEnd; + } + }); }); From 579d9194f549510ef77d5a1d0be408380d1ad4cd Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sat, 13 May 2017 22:20:49 +0100 Subject: [PATCH 2/5] Include parent stack but mark owner chain as pertinent --- .../classic/element/ReactElementValidator.js | 6 ++++- .../__tests__/ReactElementValidator-test.js | 24 ++++++++++++++----- .../hooks/ReactComponentTreeHook.js | 19 +++++++++++---- .../ReactJSXElementValidator-test.js | 18 ++++++++++---- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/isomorphic/classic/element/ReactElementValidator.js b/src/isomorphic/classic/element/ReactElementValidator.js index f7ee32194eab9..4f17a1967020b 100644 --- a/src/isomorphic/classic/element/ReactElementValidator.js +++ b/src/isomorphic/classic/element/ReactElementValidator.js @@ -228,7 +228,11 @@ var ReactElementValidator = { props.__source !== undefined ? props.__source : null; - ReactComponentTreeHook.pushNonStandardWarningStack(true, currentSource); + ReactComponentTreeHook.pushNonStandardWarningStack( + true, + true, + currentSource, + ); warning( false, 'React.createElement: type is invalid -- expected a string (for ' + diff --git a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js index 80c0b0252de76..0a9e58251e46d 100644 --- a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js +++ b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js @@ -535,7 +535,7 @@ describe('ReactElementValidator', () => { } function App() { - return React.createElement(Foo); + return React.createElement('div', null, React.createElement(Foo)); } try { @@ -557,14 +557,26 @@ describe('ReactElementValidator', () => { var stack = console.stack.mock.calls[0][0]; expect(Array.isArray(stack)).toBe(true); expect(stack.map(frame => frame.functionName)).toEqual([ - 'Foo', - 'App', - null, + 'Foo', // is inside Foo + 'App', // is inside App + 'App', //
is inside App + null, // is outside a component + ]); + expect(stack.map(frame => frame.isPertinent)).toEqual([ + true, // caused the error + true, // caused to render + false, //
is not pertinent + true, // caused to render ]); expect( stack.map(frame => frame.fileName && frame.fileName.slice(-8)), - ).toEqual([null, null, null]); - expect(stack.map(frame => frame.lineNumber)).toEqual([null, null, null]); + ).toEqual([null, null, null, null]); + expect(stack.map(frame => frame.lineNumber)).toEqual([ + null, + null, + null, + null, + ]); } finally { delete console.stack; delete console.stackEnd; diff --git a/src/isomorphic/hooks/ReactComponentTreeHook.js b/src/isomorphic/hooks/ReactComponentTreeHook.js index a935fa71e675b..6a68e27899687 100644 --- a/src/isomorphic/hooks/ReactComponentTreeHook.js +++ b/src/isomorphic/hooks/ReactComponentTreeHook.js @@ -405,6 +405,7 @@ var ReactComponentTreeHook = { pushNonStandardWarningStack( isCreatingElement: boolean, + isOwnerChainPertinent: boolean, currentSource: ?Source, ) { if (typeof console.stack !== 'function') { @@ -414,30 +415,40 @@ var ReactComponentTreeHook = { var stack = []; var currentOwner = ReactCurrentOwner.current; var id = currentOwner && currentOwner._debugID; + var nextIDInOwnerChain = id; try { if (isCreatingElement) { stack.push({ + isPertinent: true, + functionName: id ? ReactComponentTreeHook.getDisplayName(id) : null, fileName: currentSource ? currentSource.fileName : null, lineNumber: currentSource ? currentSource.lineNumber : null, - functionName: id ? ReactComponentTreeHook.getDisplayName(id) : null, }); } while (id) { var element = ReactComponentTreeHook.getElement(id); + var parentID = ReactComponentTreeHook.getParentID(id); var ownerID = ReactComponentTreeHook.getOwnerID(id); var ownerName = ownerID ? ReactComponentTreeHook.getDisplayName(ownerID) : null; var source = element && element._source; + // For some warnings, only the owner chain is pertinent + var isPertintent = isOwnerChainPertinent + ? nextIDInOwnerChain === id || !nextIDInOwnerChain + : true; stack.push({ + isPertinent: isPertintent, + functionName: ownerName, fileName: source ? source.fileName : null, lineNumber: source ? source.lineNumber : null, - functionName: ownerName, }); - // Owner stack is more useful for visual representation - id = ownerID || ReactComponentTreeHook.getParentID(id); + if (isOwnerChainPertinent && isPertintent) { + nextIDInOwnerChain = ownerID; + } + id = parentID; } } catch (err) { // Internal state is messed up. diff --git a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js index 2f8b8816b3eb7..3093f8922b01c 100644 --- a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js +++ b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js @@ -410,7 +410,7 @@ describe('ReactJSXElementValidator', () => { } function App() { - return ; + return
; } try { @@ -432,17 +432,25 @@ describe('ReactJSXElementValidator', () => { var stack = console.stack.mock.calls[0][0]; expect(Array.isArray(stack)).toBe(true); expect(stack.map(frame => frame.functionName)).toEqual([ - 'Foo', - 'App', - null, + 'Foo', // is inside Foo + 'App', // is inside App + 'App', //
is inside App + null, // is outside a component + ]); + expect(stack.map(frame => frame.isPertinent)).toEqual([ + true, // caused the error + true, // caused to render + false, //
is unrelated + true, // caused to render ]); expect( stack.map(frame => frame.fileName && frame.fileName.slice(-8)), - ).toEqual(['-test.js', '-test.js', '-test.js']); + ).toEqual(['-test.js', '-test.js', '-test.js', '-test.js']); expect(stack.map(frame => typeof frame.lineNumber)).toEqual([ 'number', 'number', 'number', + 'number', ]); } finally { delete console.stack; From 23cd04bf902b491deb336f9de29cc0a3c09ec404 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sun, 14 May 2017 01:42:48 +0100 Subject: [PATCH 3/5] Just parent stack is enough for my needs Because to avoid noise it is enough to collapse too close frames in the UI. --- .../classic/element/ReactElementValidator.js | 6 +----- .../element/__tests__/ReactElementValidator-test.js | 6 ------ src/isomorphic/hooks/ReactComponentTreeHook.js | 11 ----------- .../__tests__/ReactJSXElementValidator-test.js | 6 ------ 4 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/isomorphic/classic/element/ReactElementValidator.js b/src/isomorphic/classic/element/ReactElementValidator.js index 4f17a1967020b..f7ee32194eab9 100644 --- a/src/isomorphic/classic/element/ReactElementValidator.js +++ b/src/isomorphic/classic/element/ReactElementValidator.js @@ -228,11 +228,7 @@ var ReactElementValidator = { props.__source !== undefined ? props.__source : null; - ReactComponentTreeHook.pushNonStandardWarningStack( - true, - true, - currentSource, - ); + ReactComponentTreeHook.pushNonStandardWarningStack(true, currentSource); warning( false, 'React.createElement: type is invalid -- expected a string (for ' + diff --git a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js index 0a9e58251e46d..8c1f4744e8d80 100644 --- a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js +++ b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js @@ -562,12 +562,6 @@ describe('ReactElementValidator', () => { 'App', //
is inside App null, // is outside a component ]); - expect(stack.map(frame => frame.isPertinent)).toEqual([ - true, // caused the error - true, // caused to render - false, //
is not pertinent - true, // caused to render - ]); expect( stack.map(frame => frame.fileName && frame.fileName.slice(-8)), ).toEqual([null, null, null, null]); diff --git a/src/isomorphic/hooks/ReactComponentTreeHook.js b/src/isomorphic/hooks/ReactComponentTreeHook.js index 6a68e27899687..2d16e89a99453 100644 --- a/src/isomorphic/hooks/ReactComponentTreeHook.js +++ b/src/isomorphic/hooks/ReactComponentTreeHook.js @@ -405,7 +405,6 @@ var ReactComponentTreeHook = { pushNonStandardWarningStack( isCreatingElement: boolean, - isOwnerChainPertinent: boolean, currentSource: ?Source, ) { if (typeof console.stack !== 'function') { @@ -415,12 +414,10 @@ var ReactComponentTreeHook = { var stack = []; var currentOwner = ReactCurrentOwner.current; var id = currentOwner && currentOwner._debugID; - var nextIDInOwnerChain = id; try { if (isCreatingElement) { stack.push({ - isPertinent: true, functionName: id ? ReactComponentTreeHook.getDisplayName(id) : null, fileName: currentSource ? currentSource.fileName : null, lineNumber: currentSource ? currentSource.lineNumber : null, @@ -435,19 +432,11 @@ var ReactComponentTreeHook = { ? ReactComponentTreeHook.getDisplayName(ownerID) : null; var source = element && element._source; - // For some warnings, only the owner chain is pertinent - var isPertintent = isOwnerChainPertinent - ? nextIDInOwnerChain === id || !nextIDInOwnerChain - : true; stack.push({ - isPertinent: isPertintent, functionName: ownerName, fileName: source ? source.fileName : null, lineNumber: source ? source.lineNumber : null, }); - if (isOwnerChainPertinent && isPertintent) { - nextIDInOwnerChain = ownerID; - } id = parentID; } } catch (err) { diff --git a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js index 3093f8922b01c..039030c78e3df 100644 --- a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js +++ b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js @@ -437,12 +437,6 @@ describe('ReactJSXElementValidator', () => { 'App', //
is inside App null, // is outside a component ]); - expect(stack.map(frame => frame.isPertinent)).toEqual([ - true, // caused the error - true, // caused to render - false, //
is unrelated - true, // caused to render - ]); expect( stack.map(frame => frame.fileName && frame.fileName.slice(-8)), ).toEqual(['-test.js', '-test.js', '-test.js', '-test.js']); From 01107b0908dc01449fbaf680d7457a5265c693eb Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 15 May 2017 19:38:43 +0100 Subject: [PATCH 4/5] functionName => name --- .../classic/element/__tests__/ReactElementValidator-test.js | 2 +- src/isomorphic/hooks/ReactComponentTreeHook.js | 4 ++-- .../modern/element/__tests__/ReactJSXElementValidator-test.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js index 8c1f4744e8d80..4111321990000 100644 --- a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js +++ b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js @@ -556,7 +556,7 @@ describe('ReactElementValidator', () => { var stack = console.stack.mock.calls[0][0]; expect(Array.isArray(stack)).toBe(true); - expect(stack.map(frame => frame.functionName)).toEqual([ + expect(stack.map(frame => frame.name)).toEqual([ 'Foo', // is inside Foo 'App', // is inside App 'App', //
is inside App diff --git a/src/isomorphic/hooks/ReactComponentTreeHook.js b/src/isomorphic/hooks/ReactComponentTreeHook.js index 2d16e89a99453..d772c51197a5f 100644 --- a/src/isomorphic/hooks/ReactComponentTreeHook.js +++ b/src/isomorphic/hooks/ReactComponentTreeHook.js @@ -418,7 +418,7 @@ var ReactComponentTreeHook = { try { if (isCreatingElement) { stack.push({ - functionName: id ? ReactComponentTreeHook.getDisplayName(id) : null, + name: id ? ReactComponentTreeHook.getDisplayName(id) : null, fileName: currentSource ? currentSource.fileName : null, lineNumber: currentSource ? currentSource.lineNumber : null, }); @@ -433,7 +433,7 @@ var ReactComponentTreeHook = { : null; var source = element && element._source; stack.push({ - functionName: ownerName, + name: ownerName, fileName: source ? source.fileName : null, lineNumber: source ? source.lineNumber : null, }); diff --git a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js index 039030c78e3df..f6a97b5f1ea68 100644 --- a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js +++ b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js @@ -431,7 +431,7 @@ describe('ReactJSXElementValidator', () => { var stack = console.stack.mock.calls[0][0]; expect(Array.isArray(stack)).toBe(true); - expect(stack.map(frame => frame.functionName)).toEqual([ + expect(stack.map(frame => frame.name)).toEqual([ 'Foo', // is inside Foo 'App', // is inside App 'App', //
is inside App From 5f8eea3ecc842df7bbf3b821d58da3cac47613a7 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 15 May 2017 20:25:25 +0100 Subject: [PATCH 5/5] Hide behind a feature flag --- .../__tests__/ReactElementValidator-test.js | 16 ++++++++-------- src/isomorphic/hooks/ReactComponentTreeHook.js | 8 ++++---- .../__tests__/ReactJSXElementValidator-test.js | 16 ++++++++-------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js index 4111321990000..26e1c7217905d 100644 --- a/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js +++ b/src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js @@ -526,7 +526,7 @@ describe('ReactElementValidator', () => { ); }); - it('provides stack via non-standard console.stack for invalid types', () => { + it('provides stack via non-standard console.reactStack for invalid types', () => { spyOn(console, 'error'); function Foo() { @@ -539,8 +539,8 @@ describe('ReactElementValidator', () => { } try { - console.stack = jest.fn(); - console.stackEnd = jest.fn(); + console.reactStack = jest.fn(); + console.reactStackEnd = jest.fn(); expect(() => { ReactTestUtils.renderIntoDocument(React.createElement(App)); @@ -551,10 +551,10 @@ describe('ReactElementValidator', () => { 'defined in. Check the render method of `Foo`.', ); - expect(console.stack.mock.calls.length).toBe(1); - expect(console.stackEnd.mock.calls.length).toBe(1); + expect(console.reactStack.mock.calls.length).toBe(1); + expect(console.reactStackEnd.mock.calls.length).toBe(1); - var stack = console.stack.mock.calls[0][0]; + var stack = console.reactStack.mock.calls[0][0]; expect(Array.isArray(stack)).toBe(true); expect(stack.map(frame => frame.name)).toEqual([ 'Foo', // is inside Foo @@ -572,8 +572,8 @@ describe('ReactElementValidator', () => { null, ]); } finally { - delete console.stack; - delete console.stackEnd; + delete console.reactStack; + delete console.reactStackEnd; } }); }); diff --git a/src/isomorphic/hooks/ReactComponentTreeHook.js b/src/isomorphic/hooks/ReactComponentTreeHook.js index d772c51197a5f..6ff41657ab090 100644 --- a/src/isomorphic/hooks/ReactComponentTreeHook.js +++ b/src/isomorphic/hooks/ReactComponentTreeHook.js @@ -407,7 +407,7 @@ var ReactComponentTreeHook = { isCreatingElement: boolean, currentSource: ?Source, ) { - if (typeof console.stack !== 'function') { + if (typeof console.reactStack !== 'function') { return; } @@ -444,14 +444,14 @@ var ReactComponentTreeHook = { // Stop building the stack (it's just a nice to have). } - console.stack(stack); + console.reactStack(stack); }, popNonStandardWarningStack() { - if (typeof console.stackEnd !== 'function') { + if (typeof console.reactStackEnd !== 'function') { return; } - console.stackEnd(); + console.reactStackEnd(); }, }; diff --git a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js index f6a97b5f1ea68..0502161aad8e6 100644 --- a/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js +++ b/src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js @@ -401,7 +401,7 @@ describe('ReactJSXElementValidator', () => { ); }); - it('provides stack via non-standard console.stack for invalid types', () => { + it('provides stack via non-standard console.reactStack for invalid types', () => { spyOn(console, 'error'); function Foo() { @@ -414,8 +414,8 @@ describe('ReactJSXElementValidator', () => { } try { - console.stack = jest.fn(); - console.stackEnd = jest.fn(); + console.reactStack = jest.fn(); + console.reactStackEnd = jest.fn(); expect(() => { ReactTestUtils.renderIntoDocument(); @@ -426,10 +426,10 @@ describe('ReactJSXElementValidator', () => { 'defined in. Check the render method of `Foo`.', ); - expect(console.stack.mock.calls.length).toBe(1); - expect(console.stackEnd.mock.calls.length).toBe(1); + expect(console.reactStack.mock.calls.length).toBe(1); + expect(console.reactStackEnd.mock.calls.length).toBe(1); - var stack = console.stack.mock.calls[0][0]; + var stack = console.reactStack.mock.calls[0][0]; expect(Array.isArray(stack)).toBe(true); expect(stack.map(frame => frame.name)).toEqual([ 'Foo', // is inside Foo @@ -447,8 +447,8 @@ describe('ReactJSXElementValidator', () => { 'number', ]); } finally { - delete console.stack; - delete console.stackEnd; + delete console.reactStack; + delete console.reactStackEnd; } }); });