Skip to content

Commit 58b987c

Browse files
committed
Rewrite tests that depend on propTypes warnings
1 parent 64e755d commit 58b987c

File tree

2 files changed

+151
-198
lines changed

2 files changed

+151
-198
lines changed

packages/react-reconciler/src/__tests__/ReactMemo-test.js

+75-76
Original file line numberDiff line numberDiff line change
@@ -657,97 +657,96 @@ describe('memo', () => {
657657
});
658658
});
659659

660-
it('should fall back to showing something meaningful if no displayName or name are present', () => {
661-
const MemoComponent = React.memo(props => <div {...props} />);
662-
MemoComponent.propTypes = {
663-
required: PropTypes.string.isRequired,
664-
};
665-
666-
expect(() =>
667-
ReactNoop.render(<MemoComponent optional="foo" />),
668-
).toErrorDev(
669-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
670-
'`Memo`, but its value is `undefined`.',
671-
// There's no component stack in this warning because the inner function is anonymous.
672-
// If we wanted to support this (for the Error frames / source location)
673-
// we could do this by updating ReactComponentStackFrame.
674-
{withoutStack: true},
660+
it('should skip memo in the stack if neither displayName nor name are present', async () => {
661+
const MemoComponent = React.memo(props => [<span />]);
662+
ReactNoop.render(
663+
<p>
664+
<MemoComponent />
665+
</p>,
666+
);
667+
await expect(async () => {
668+
await waitForAll([]);
669+
}).toErrorDev(
670+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
671+
' in p (at **)',
675672
);
676673
});
677674

678-
it('should honor a displayName if set on the inner component in warnings', () => {
679-
function Component(props) {
680-
return <div {...props} />;
681-
}
682-
Component.displayName = 'Inner';
683-
const MemoComponent = React.memo(Component);
684-
MemoComponent.propTypes = {
685-
required: PropTypes.string.isRequired,
686-
};
687-
688-
expect(() =>
689-
ReactNoop.render(<MemoComponent optional="foo" />),
690-
).toErrorDev(
691-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
692-
'`Inner`, but its value is `undefined`.\n' +
693-
' in Inner (at **)',
675+
it('should use the inner function name for the stack', async () => {
676+
const MemoComponent = React.memo(function Inner(props, ref) {
677+
return [<span />];
678+
});
679+
ReactNoop.render(
680+
<p>
681+
<MemoComponent />
682+
</p>,
683+
);
684+
await expect(async () => {
685+
await waitForAll([]);
686+
}).toErrorDev(
687+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
688+
' in Inner (at **)\n' +
689+
' in p (at **)',
694690
);
695691
});
696692

697-
it('should honor a displayName if set on the memo wrapper in warnings', () => {
698-
const MemoComponent = React.memo(function Component(props) {
699-
return <div {...props} />;
700-
});
701-
MemoComponent.displayName = 'Outer';
702-
MemoComponent.propTypes = {
703-
required: PropTypes.string.isRequired,
693+
it('should use the inner displayName in the stack', async () => {
694+
let fn = (props, ref) => {
695+
return [<span />];
704696
};
705-
706-
expect(() =>
707-
ReactNoop.render(<MemoComponent optional="foo" />),
708-
).toErrorDev(
709-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
710-
'`Outer`, but its value is `undefined`.\n' +
711-
' in Component (at **)',
697+
fn.displayName = 'Inner';
698+
const MemoComponent = React.memo(fn);
699+
ReactNoop.render(
700+
<p>
701+
<MemoComponent />
702+
</p>,
703+
);
704+
await expect(async () => {
705+
await waitForAll([]);
706+
}).toErrorDev(
707+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
708+
' in Inner (at **)\n' +
709+
' in p (at **)',
712710
);
713711
});
714712

715-
it('should pass displayName to an anonymous inner component so it shows up in component stacks', () => {
716-
const MemoComponent = React.memo(props => {
717-
return <div {...props} />;
713+
it('can use the outer displayName in the stack', async () => {
714+
const MemoComponent = React.memo((props, ref) => {
715+
return [<span />];
718716
});
719-
MemoComponent.displayName = 'Memo';
720-
MemoComponent.propTypes = {
721-
required: PropTypes.string.isRequired,
722-
};
723-
724-
expect(() =>
725-
ReactNoop.render(<MemoComponent optional="foo" />),
726-
).toErrorDev(
727-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
728-
'`Memo`, but its value is `undefined`.\n' +
729-
' in Memo (at **)',
717+
MemoComponent.displayName = 'Outer';
718+
ReactNoop.render(
719+
<p>
720+
<MemoComponent />
721+
</p>,
722+
);
723+
await expect(async () => {
724+
await waitForAll([]);
725+
}).toErrorDev(
726+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
727+
' in Outer (at **)\n' +
728+
' in p (at **)',
730729
);
731730
});
732731

733-
it('should honor a outer displayName when wrapped component and memo component set displayName at the same time.', () => {
734-
function Component(props) {
735-
return <div {...props} />;
736-
}
737-
Component.displayName = 'Inner';
738-
739-
const MemoComponent = React.memo(Component);
740-
MemoComponent.displayName = 'Outer';
741-
MemoComponent.propTypes = {
742-
required: PropTypes.string.isRequired,
732+
it('should prefer the inner to the outer displayName in the stack', async () => {
733+
let fn = (props, ref) => {
734+
return [<span />];
743735
};
744-
745-
expect(() =>
746-
ReactNoop.render(<MemoComponent optional="foo" />),
747-
).toErrorDev(
748-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
749-
'`Outer`, but its value is `undefined`.\n' +
750-
' in Inner (at **)',
736+
fn.displayName = 'Inner';
737+
const MemoComponent = React.memo(fn);
738+
MemoComponent.displayName = 'Outer';
739+
ReactNoop.render(
740+
<p>
741+
<MemoComponent />
742+
</p>,
743+
);
744+
await expect(async () => {
745+
await waitForAll([]);
746+
}).toErrorDev(
747+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
748+
' in Inner (at **)\n' +
749+
' in p (at **)',
751750
);
752751
});
753752
}

packages/react/src/__tests__/forwardRef-test.js

+76-122
Original file line numberDiff line numberDiff line change
@@ -204,144 +204,98 @@ describe('forwardRef', () => {
204204
);
205205
});
206206

207-
it('should fall back to showing something meaningful if no displayName or name are present', () => {
208-
const Component = props => <div {...props} />;
209-
210-
const RefForwardingComponent = React.forwardRef((props, ref) => (
211-
<Component {...props} forwardedRef={ref} />
212-
));
213-
214-
RefForwardingComponent.propTypes = {
215-
optional: PropTypes.string,
216-
required: PropTypes.string.isRequired,
217-
};
218-
219-
RefForwardingComponent.defaultProps = {
220-
optional: 'default',
221-
};
222-
223-
const ref = React.createRef();
224-
225-
expect(() =>
226-
ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />),
227-
).toErrorDev(
228-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
229-
'`ForwardRef`, but its value is `undefined`.',
230-
// There's no component stack in this warning because the inner function is anonymous.
231-
// If we wanted to support this (for the Error frames / source location)
232-
// we could do this by updating ReactComponentStackFrame.
233-
{withoutStack: true},
207+
it('should skip forwardRef in the stack if neither displayName nor name are present', async () => {
208+
const RefForwardingComponent = React.forwardRef(function (props, ref) {
209+
return [<span />];
210+
});
211+
ReactNoop.render(
212+
<p>
213+
<RefForwardingComponent />
214+
</p>,
215+
);
216+
await expect(async () => {
217+
await waitForAll([]);
218+
}).toErrorDev(
219+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
220+
' in p (at **)',
234221
);
235222
});
236223

237-
it('should honor a displayName if set on the forwardRef wrapper in warnings', () => {
238-
const Component = props => <div {...props} />;
239-
224+
it('should use the inner function name for the stack', async () => {
240225
const RefForwardingComponent = React.forwardRef(function Inner(props, ref) {
241-
<Component {...props} forwardedRef={ref} />;
226+
return [<span />];
242227
});
243-
RefForwardingComponent.displayName = 'Custom';
244-
245-
RefForwardingComponent.propTypes = {
246-
optional: PropTypes.string,
247-
required: PropTypes.string.isRequired,
248-
};
249-
250-
RefForwardingComponent.defaultProps = {
251-
optional: 'default',
252-
};
253-
254-
const ref = React.createRef();
255-
256-
expect(() =>
257-
ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />),
258-
).toErrorDev(
259-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
260-
'`Custom`, but its value is `undefined`.\n' +
261-
' in Inner (at **)',
228+
ReactNoop.render(
229+
<p>
230+
<RefForwardingComponent />
231+
</p>,
262232
);
263-
});
264-
265-
it('should pass displayName to an anonymous inner component so it shows up in component stacks', () => {
266-
const Component = props => <div {...props} />;
267-
268-
const RefForwardingComponent = React.forwardRef((props, ref) => (
269-
<Component {...props} forwardedRef={ref} />
270-
));
271-
RefForwardingComponent.displayName = 'Custom';
272-
273-
RefForwardingComponent.propTypes = {
274-
optional: PropTypes.string,
275-
required: PropTypes.string.isRequired,
276-
};
277-
278-
RefForwardingComponent.defaultProps = {
279-
optional: 'default',
280-
};
281-
282-
const ref = React.createRef();
283-
284-
expect(() =>
285-
ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />),
286-
).toErrorDev(
287-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
288-
'`Custom`, but its value is `undefined`.\n' +
289-
' in Custom (at **)',
233+
await expect(async () => {
234+
await waitForAll([]);
235+
}).toErrorDev(
236+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
237+
' in Inner (at **)\n' +
238+
' in p (at **)',
290239
);
291240
});
292241

293-
it('should honor a displayName in stacks if set on the inner function', () => {
294-
const Component = props => <div {...props} />;
295-
296-
const inner = (props, ref) => <Component {...props} forwardedRef={ref} />;
297-
inner.displayName = 'Inner';
298-
const RefForwardingComponent = React.forwardRef(inner);
299-
300-
RefForwardingComponent.propTypes = {
301-
optional: PropTypes.string,
302-
required: PropTypes.string.isRequired,
242+
it('should use the inner displayName in the stack', async () => {
243+
let fn = (props, ref) => {
244+
return [<span />];
303245
};
304-
305-
RefForwardingComponent.defaultProps = {
306-
optional: 'default',
307-
};
308-
309-
const ref = React.createRef();
310-
311-
expect(() =>
312-
ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />),
313-
).toErrorDev(
314-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
315-
'`ForwardRef(Inner)`, but its value is `undefined`.\n' +
316-
' in Inner (at **)',
246+
fn.displayName = 'Inner';
247+
const RefForwardingComponent = React.forwardRef(fn);
248+
ReactNoop.render(
249+
<p>
250+
<RefForwardingComponent />
251+
</p>,
252+
);
253+
await expect(async () => {
254+
await waitForAll([]);
255+
}).toErrorDev(
256+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
257+
' in Inner (at **)\n' +
258+
' in p (at **)',
317259
);
318260
});
319261

320-
it('should honor a outer displayName when wrapped component and memo component set displayName at the same time.', () => {
321-
const Component = props => <div {...props} />;
322-
323-
const inner = (props, ref) => <Component {...props} forwardedRef={ref} />;
324-
inner.displayName = 'Inner';
325-
const RefForwardingComponent = React.forwardRef(inner);
262+
it('can use the outer displayName in the stack', async () => {
263+
const RefForwardingComponent = React.forwardRef((props, ref) => {
264+
return [<span />];
265+
});
326266
RefForwardingComponent.displayName = 'Outer';
267+
ReactNoop.render(
268+
<p>
269+
<RefForwardingComponent />
270+
</p>,
271+
);
272+
await expect(async () => {
273+
await waitForAll([]);
274+
}).toErrorDev(
275+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
276+
' in Outer (at **)\n' +
277+
' in p (at **)',
278+
);
279+
});
327280

328-
RefForwardingComponent.propTypes = {
329-
optional: PropTypes.string,
330-
required: PropTypes.string.isRequired,
331-
};
332-
333-
RefForwardingComponent.defaultProps = {
334-
optional: 'default',
281+
it('should prefer the inner to the outer displayName in the stack', async () => {
282+
let fn = (props, ref) => {
283+
return [<span />];
335284
};
336-
337-
const ref = React.createRef();
338-
339-
expect(() =>
340-
ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />),
341-
).toErrorDev(
342-
'Warning: Failed prop type: The prop `required` is marked as required in ' +
343-
'`Outer`, but its value is `undefined`.\n' +
344-
' in Inner (at **)',
285+
fn.displayName = 'Inner';
286+
const RefForwardingComponent = React.forwardRef(fn);
287+
RefForwardingComponent.displayName = 'Outer';
288+
ReactNoop.render(
289+
<p>
290+
<RefForwardingComponent />
291+
</p>,
292+
);
293+
await expect(async () => {
294+
await waitForAll([]);
295+
}).toErrorDev(
296+
'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
297+
' in Inner (at **)\n' +
298+
' in p (at **)',
345299
);
346300
});
347301

0 commit comments

Comments
 (0)