test(getComponentName): Increase test coverage (#18149)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
Sebastian Silbermann committed
Mar 17, 2020 at 22:47 UTC
22cab1cbd6ad52925828643c8c6d0d4fd7890c54
6 files changed
+92
-8
packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
+3
-3
@@ -542,7 +542,7 @@ describe('ReactCompositeComponent', () => {
542
});
543
544
it('should warn when shouldComponentUpdate() returns undefined', () => {
545
- class Component extends React.Component {
545
+ class ClassComponent extends React.Component {
546
state = {bogus: false};
547
548
shouldComponentUpdate() {
@@ -554,10 +554,10 @@ describe('ReactCompositeComponent', () => {
554
}
555
}
556
557
- const instance = ReactTestUtils.renderIntoDocument(<Component />);
557
+ const instance = ReactTestUtils.renderIntoDocument(<ClassComponent />);
558
559
expect(() => instance.setState({bogus: true})).toErrorDev(
560
- 'Warning: Component.shouldComponentUpdate(): Returned undefined instead of a ' +
560
+ 'Warning: ClassComponent.shouldComponentUpdate(): Returned undefined instead of a ' +
561
'boolean value. Make sure to return true or false.',
562
);
563
});
packages/react-dom/src/__tests__/ReactDOMServerIntegrationLegacyContext-test.js
+18
@@ -291,5 +291,23 @@ describe('ReactDOMServerIntegration', () => {
291
},
292
'MyComponent.getChildContext(): key "value2" is not defined in childContextTypes.',
293
);
294
+
295
+ it('warns when childContextTypes is not defined', () => {
296
+ class MyComponent extends React.Component {
297
+ render() {
298
+ return <div />;
299
+ }
300
+ getChildContext() {
301
+ return {value1: 'foo', value2: 'bar'};
302
+ }
303
+ }
304
+
305
+ expect(() => {
306
+ ReactDOMServer.renderToString(<MyComponent />);
307
+ }).toErrorDev(
308
+ 'Warning: MyComponent.getChildContext(): childContextTypes must be defined in order to use getChildContext().\n' +
309
+ ' in MyComponent (at **)',
310
+ );
311
+ });
312
});
313
});
packages/react-dom/src/__tests__/ReactDOMServerLifecycles-test.js
+6
-4
@@ -285,19 +285,21 @@ describe('ReactDOMServerLifecycles', () => {
285
});
286
287
it('should warn about deprecated lifecycle hooks', () => {
288
- class Component extends React.Component {
288
+ class MyComponent extends React.Component {
289
componentWillMount() {}
290
render() {
291
return null;
292
}
293
}
294
295
- expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
296
- 'componentWillMount has been renamed',
295
+ expect(() => ReactDOMServer.renderToString(<MyComponent />)).toWarnDev(
296
+ 'componentWillMount has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' +
297
+ '* Move code from componentWillMount to componentDidMount (preferred in most cases) or the constructor.\n\n' +
298
+ 'Please update the following components: MyComponent',
299
);
300
301
// De-duped
300
- ReactDOMServer.renderToString(<Component />);
302
+ ReactDOMServer.renderToString(<MyComponent />);
303
});
304
305
describe('react-lifecycles-compat', () => {
packages/react-dom/src/__tests__/ReactLegacyContextDisabled-test.internal.js
+28
@@ -11,6 +11,7 @@
11
12
let React;
13
let ReactDOM;
14
+let ReactDOMServer;
15
let ReactFeatureFlags;
16
17
describe('ReactLegacyContextDisabled', () => {
@@ -19,6 +20,7 @@ describe('ReactLegacyContextDisabled', () => {
20
21
React = require('react');
22
ReactDOM = require('react-dom');
23
+ ReactDOMServer = require('react-dom/server');
24
ReactFeatureFlags = require('shared/ReactFeatureFlags');
25
ReactFeatureFlags.disableLegacyContext = true;
26
});
@@ -115,6 +117,32 @@ describe('ReactLegacyContextDisabled', () => {
117
expect(container.textContent).toBe('{}undefinedundefined');
118
expect(lifecycleContextLog).toEqual([{}, {}, {}]);
119
ReactDOM.unmountComponentAtNode(container);
120
+
121
+ // test server path.
122
+ let text;
123
+ expect(() => {
124
+ text = ReactDOMServer.renderToString(
125
+ <LegacyProvider>
126
+ <span>
127
+ <LegacyClsConsumer />
128
+ <LegacyFnConsumer />
129
+ <RegularFn />
130
+ </span>
131
+ </LegacyProvider>,
132
+ container,
133
+ );
134
+ }).toErrorDev([
135
+ 'LegacyProvider uses the legacy childContextTypes API which is no longer supported. ' +
136
+ 'Use React.createContext() instead.',
137
+ 'LegacyClsConsumer uses the legacy contextTypes API which is no longer supported. ' +
138
+ 'Use React.createContext() with static contextType instead.',
139
+ 'LegacyFnConsumer uses the legacy contextTypes API which is no longer supported. ' +
140
+ 'Use React.createContext() with React.useContext() instead.',
141
+ ]);
142
+ expect(text).toBe(
143
+ '<span data-reactroot="">{}<!-- -->undefined<!-- -->undefined</span>',
144
+ );
145
+ expect(lifecycleContextLog).toEqual([{}, {}, {}]);
146
});
147
148
it('renders a tree with modern context', () => {
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js
+36
@@ -339,6 +339,42 @@ describe('ReactHooksWithNoopRenderer', () => {
339
);
340
});
341
342
+ it('dedupes the warning by component name', () => {
343
+ let _updateCountA;
344
+ function CounterA(props, ref) {
345
+ const [, updateCount] = useState(0);
346
+ _updateCountA = updateCount;
347
+ return null;
348
+ }
349
+ let _updateCountB;
350
+ function CounterB(props, ref) {
351
+ const [, updateCount] = useState(0);
352
+ _updateCountB = updateCount;
353
+ return null;
354
+ }
355
+
356
+ ReactNoop.render([<CounterA key="A" />, <CounterB key="B" />]);
357
+ expect(Scheduler).toFlushWithoutYielding();
358
+ ReactNoop.render(null);
359
+ expect(Scheduler).toFlushWithoutYielding();
360
+ expect(() => act(() => _updateCountA(1))).toErrorDev(
361
+ "Warning: Can't perform a React state update on an unmounted " +
362
+ 'component. This is a no-op, but it indicates a memory leak in your ' +
363
+ 'application. To fix, cancel all subscriptions and asynchronous ' +
364
+ 'tasks in a useEffect cleanup function.\n' +
365
+ ' in CounterA (at **)',
366
+ );
367
+ // already cached so this logs no error
368
+ act(() => _updateCountA(2));
369
+ expect(() => act(() => _updateCountB(1))).toErrorDev(
370
+ "Warning: Can't perform a React state update on an unmounted " +
371
+ 'component. This is a no-op, but it indicates a memory leak in your ' +
372
+ 'application. To fix, cancel all subscriptions and asynchronous ' +
373
+ 'tasks in a useEffect cleanup function.\n' +
374
+ ' in CounterB (at **)',
375
+ );
376
+ });
377
+
378
it('works with memo', () => {
379
let _updateCount;
380
function Counter(props) {
packages/react/src/ReactElement.js
+1
-1
@@ -114,7 +114,7 @@ function warnIfStringRefCannotBeAutoConverted(config) {
114
'We ask you to manually fix this case by using useRef() or createRef() instead. ' +
115
'Learn more about using refs safely here: ' +
116
'https://fb.me/react-strict-mode-string-ref',
117
- getComponentName(ReactCurrentOwner.current.type),
117
+ componentName,
118
config.ref,
119
);
120
didWarnAboutStringRefs[componentName] = true;