From 2c4921f6f243e1f9c1908cb72807b590d4e61de9 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Tue, 3 Mar 2020 22:11:33 +0100 Subject: [PATCH 1/3] test: Add test for current behavior of displayName --- .../react/src/__tests__/ReactContext-test.js | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 packages/react/src/__tests__/ReactContext-test.js diff --git a/packages/react/src/__tests__/ReactContext-test.js b/packages/react/src/__tests__/ReactContext-test.js new file mode 100644 index 0000000000000..54b890d0f6563 --- /dev/null +++ b/packages/react/src/__tests__/ReactContext-test.js @@ -0,0 +1,45 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + */ + +'use strict'; + +let PropTypes; +let React; +let ReactDOMServer; + +describe('ReactContext', () => { + beforeEach(() => { + jest.resetModules(); + PropTypes = require('prop-types'); + React = require('react'); + ReactDOMServer = require('react-dom/server'); + }); + + it('ignores displayName on the context type', () => { + const Context = React.createContext(null); + Context.displayName = 'MyContextType'; + function Validator() { + return null; + } + Validator.propTypes = {dontPassToSeeErrorStack: PropTypes.bool.isRequired}; + + expect(() => { + ReactDOMServer.renderToStaticMarkup( + + {() => } + , + ); + }).toErrorDev( + 'Warning: Failed prop type: The prop `dontPassToSeeErrorStack` is marked as required in `Validator`, but its value is `undefined`.\n' + + ' in Validator (at **)\n' + + ' in Context.Consumer (at **)\n' + + ' in Context.Provider (at **)', + ); + }); +}); From 0728d1fb2e5eaca3630eed03d084965fb4be7a94 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Tue, 3 Mar 2020 22:12:03 +0100 Subject: [PATCH 2/3] feat: consider displayName of context types --- packages/react/src/ReactContext.js | 5 +++++ packages/react/src/__tests__/ReactContext-test.js | 6 +++--- packages/shared/getComponentName.js | 11 +++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/react/src/ReactContext.js b/packages/react/src/ReactContext.js index cbcd3373c8166..af97b903cf734 100644 --- a/packages/react/src/ReactContext.js +++ b/packages/react/src/ReactContext.js @@ -120,6 +120,11 @@ export function createContext( return context.Consumer; }, }, + displayName: { + get() { + return context.displayName; + }, + }, }); // $FlowFixMe: Flow complains about missing properties because it doesn't understand defineProperty context.Consumer = Consumer; diff --git a/packages/react/src/__tests__/ReactContext-test.js b/packages/react/src/__tests__/ReactContext-test.js index 54b890d0f6563..22248338de362 100644 --- a/packages/react/src/__tests__/ReactContext-test.js +++ b/packages/react/src/__tests__/ReactContext-test.js @@ -21,7 +21,7 @@ describe('ReactContext', () => { ReactDOMServer = require('react-dom/server'); }); - it('ignores displayName on the context type', () => { + it('should honor a displayName if set on the context type', () => { const Context = React.createContext(null); Context.displayName = 'MyContextType'; function Validator() { @@ -38,8 +38,8 @@ describe('ReactContext', () => { }).toErrorDev( 'Warning: Failed prop type: The prop `dontPassToSeeErrorStack` is marked as required in `Validator`, but its value is `undefined`.\n' + ' in Validator (at **)\n' + - ' in Context.Consumer (at **)\n' + - ' in Context.Provider (at **)', + ' in MyContextType.Consumer (at **)\n' + + ' in MyContextType.Provider (at **)', ); }); }); diff --git a/packages/shared/getComponentName.js b/packages/shared/getComponentName.js index e2ad538e584a9..9694732ce5d96 100644 --- a/packages/shared/getComponentName.js +++ b/packages/shared/getComponentName.js @@ -24,6 +24,7 @@ import { REACT_BLOCK_TYPE, } from 'shared/ReactSymbols'; import {refineResolvedLazyComponent} from 'shared/ReactLazyComponent'; +import type {ReactContext, ReactProviderType} from 'shared/ReactTypes'; function getWrappedName( outerType: mixed, @@ -37,6 +38,10 @@ function getWrappedName( ); } +function getContextName(type: ReactContext) { + return type.displayName || 'Context'; +} + function getComponentName(type: mixed): string | null { if (type == null) { // Host root, text node or just invalid type. @@ -73,9 +78,11 @@ function getComponentName(type: mixed): string | null { if (typeof type === 'object') { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return 'Context.Consumer'; + const context: ReactContext = (type: any); + return getContextName(context) + '.Consumer'; case REACT_PROVIDER_TYPE: - return 'Context.Provider'; + const provider: ReactProviderType = (type: any); + return getContextName(provider._context) + '.Provider'; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, 'ForwardRef'); case REACT_MEMO_TYPE: From 3968e0b6e4c2775c38a2ab7bd0b21c33af4d3abb Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Wed, 4 Mar 2020 23:22:10 +0100 Subject: [PATCH 3/3] Move test to ReactContextValidator --- .../react/src/__tests__/ReactContext-test.js | 45 ------------------- .../__tests__/ReactContextValidator-test.js | 24 ++++++++++ 2 files changed, 24 insertions(+), 45 deletions(-) delete mode 100644 packages/react/src/__tests__/ReactContext-test.js diff --git a/packages/react/src/__tests__/ReactContext-test.js b/packages/react/src/__tests__/ReactContext-test.js deleted file mode 100644 index 22248338de362..0000000000000 --- a/packages/react/src/__tests__/ReactContext-test.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @emails react-core - */ - -'use strict'; - -let PropTypes; -let React; -let ReactDOMServer; - -describe('ReactContext', () => { - beforeEach(() => { - jest.resetModules(); - PropTypes = require('prop-types'); - React = require('react'); - ReactDOMServer = require('react-dom/server'); - }); - - it('should honor a displayName if set on the context type', () => { - const Context = React.createContext(null); - Context.displayName = 'MyContextType'; - function Validator() { - return null; - } - Validator.propTypes = {dontPassToSeeErrorStack: PropTypes.bool.isRequired}; - - expect(() => { - ReactDOMServer.renderToStaticMarkup( - - {() => } - , - ); - }).toErrorDev( - 'Warning: Failed prop type: The prop `dontPassToSeeErrorStack` is marked as required in `Validator`, but its value is `undefined`.\n' + - ' in Validator (at **)\n' + - ' in MyContextType.Consumer (at **)\n' + - ' in MyContextType.Provider (at **)', - ); - }); -}); diff --git a/packages/react/src/__tests__/ReactContextValidator-test.js b/packages/react/src/__tests__/ReactContextValidator-test.js index 0123d7091755f..f751dc70727e0 100644 --- a/packages/react/src/__tests__/ReactContextValidator-test.js +++ b/packages/react/src/__tests__/ReactContextValidator-test.js @@ -18,6 +18,7 @@ let PropTypes; let React; let ReactDOM; +let ReactDOMServer; let ReactTestUtils; describe('ReactContextValidator', () => { @@ -27,6 +28,7 @@ describe('ReactContextValidator', () => { PropTypes = require('prop-types'); React = require('react'); ReactDOM = require('react-dom'); + ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); }); @@ -671,4 +673,26 @@ describe('ReactContextValidator', () => { 'Warning: ComponentB: Function components do not support contextType.', ); }); + + it('should honor a displayName if set on the context type', () => { + const Context = React.createContext(null); + Context.displayName = 'MyContextType'; + function Validator() { + return null; + } + Validator.propTypes = {dontPassToSeeErrorStack: PropTypes.bool.isRequired}; + + expect(() => { + ReactDOMServer.renderToStaticMarkup( + + {() => } + , + ); + }).toErrorDev( + 'Warning: Failed prop type: The prop `dontPassToSeeErrorStack` is marked as required in `Validator`, but its value is `undefined`.\n' + + ' in Validator (at **)\n' + + ' in MyContextType.Consumer (at **)\n' + + ' in MyContextType.Provider (at **)', + ); + }); });