Enforce presence or absence of component stack in tests (#13215)
* Enforce presence or absence of stack in tests * Rename expectNoStack to withoutStack * Fix lint * Add some tests for toWarnDev()
Dan Abramov committed
Jul 16, 2018 at 20:20 UTC
467d1391016dd2df8e1946aa33c6d6e1219c9dbb
51 files changed
+584
-140
packages/create-subscription/src/__tests__/createSubscription-test.internal.js
+6
-2
@@ -450,7 +450,9 @@ describe('createSubscription', () => {
450
},
451
() => null,
452
);
453
- }).toWarnDev('Subscription must specify a getCurrentValue function');
453
+ }).toWarnDev('Subscription must specify a getCurrentValue function', {
454
+ withoutStack: true,
455
+ });
456
});
457
458
it('should warn for invalid missing subscribe', () => {
@@ -461,7 +463,9 @@ describe('createSubscription', () => {
463
},
464
() => null,
465
);
464
- }).toWarnDev('Subscription must specify a subscribe function');
466
+ }).toWarnDev('Subscription must specify a subscribe function', {
467
+ withoutStack: true,
468
+ });
469
});
470
471
it('should warn if subscribe does not return an unsubscribe method', () => {
packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.internal.js
+16
-13
@@ -43,19 +43,22 @@ describe('ReactComponentLifeCycle', () => {
43
const container = document.createElement('div');
44
expect(() =>
45
ReactDOM.render(<MyComponent x={1} />, container),
46
- ).toLowPriorityWarnDev([
47
- 'componentWillMount is deprecated and will be removed in the next major version. ' +
48
- 'Use componentDidMount instead. As a temporary workaround, ' +
49
- 'you can rename to UNSAFE_componentWillMount.' +
50
- '\n\nPlease update the following components: MyComponent',
51
- 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' +
52
- 'Use static getDerivedStateFromProps instead.' +
53
- '\n\nPlease update the following components: MyComponent',
54
- 'componentWillUpdate is deprecated and will be removed in the next major version. ' +
55
- 'Use componentDidUpdate instead. As a temporary workaround, ' +
56
- 'you can rename to UNSAFE_componentWillUpdate.' +
57
- '\n\nPlease update the following components: MyComponent',
58
- ]);
46
+ ).toLowPriorityWarnDev(
47
+ [
48
+ 'componentWillMount is deprecated and will be removed in the next major version. ' +
49
+ 'Use componentDidMount instead. As a temporary workaround, ' +
50
+ 'you can rename to UNSAFE_componentWillMount.' +
51
+ '\n\nPlease update the following components: MyComponent',
52
+ 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' +
53
+ 'Use static getDerivedStateFromProps instead.' +
54
+ '\n\nPlease update the following components: MyComponent',
55
+ 'componentWillUpdate is deprecated and will be removed in the next major version. ' +
56
+ 'Use componentDidUpdate instead. As a temporary workaround, ' +
57
+ 'you can rename to UNSAFE_componentWillUpdate.' +
58
+ '\n\nPlease update the following components: MyComponent',
59
+ ],
60
+ {withoutStack: true},
61
+ );
62
63
// Dedupe check (update and instantiate new
64
ReactDOM.render(<MyComponent x={2} />, container);
packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
+26
-3
@@ -218,6 +218,7 @@ describe('ReactComponentLifeCycle', () => {
218
'This is a no-op, but it might indicate a bug in your application. ' +
219
'Instead, assign to `this.state` directly or define a `state = {};` ' +
220
'class property with the desired state in the StatefulComponent component.',
221
+ {withoutStack: true},
222
);
223
224
// Check deduplication; (no extra warnings should be logged).
@@ -248,7 +249,9 @@ describe('ReactComponentLifeCycle', () => {
249
expect(() => {
250
const instance = ReactTestUtils.renderIntoDocument(element);
251
expect(instance._isMounted()).toBeTruthy();
251
- }).toWarnDev('Component is accessing isMounted inside its render()');
252
+ }).toWarnDev('Component is accessing isMounted inside its render()', {
253
+ withoutStack: true,
254
+ });
255
});
256
257
it('should correctly determine if a null component is mounted', () => {
@@ -275,7 +278,9 @@ describe('ReactComponentLifeCycle', () => {
278
expect(() => {
279
const instance = ReactTestUtils.renderIntoDocument(element);
280
expect(instance._isMounted()).toBeTruthy();
278
- }).toWarnDev('Component is accessing isMounted inside its render()');
281
+ }).toWarnDev('Component is accessing isMounted inside its render()', {
282
+ withoutStack: true,
283
+ });
284
});
285
286
it('isMounted should return false when unmounted', () => {
@@ -313,7 +318,9 @@ describe('ReactComponentLifeCycle', () => {
318
319
expect(() => {
320
ReactTestUtils.renderIntoDocument(<Component />);
316
- }).toWarnDev('Component is accessing findDOMNode inside its render()');
321
+ }).toWarnDev('Component is accessing findDOMNode inside its render()', {
322
+ withoutStack: true,
323
+ });
324
});
325
326
it('should carry through each of the phases of setup', () => {
@@ -379,6 +386,7 @@ describe('ReactComponentLifeCycle', () => {
386
instance = ReactDOM.render(<LifeCycleComponent />, container);
387
}).toWarnDev(
388
'LifeCycleComponent is accessing isMounted inside its render() function',
389
+ {withoutStack: true},
390
);
391
392
// getInitialState
@@ -674,6 +682,7 @@ describe('ReactComponentLifeCycle', () => {
682
const container = document.createElement('div');
683
expect(() => ReactDOM.render(<Component />, container)).toWarnDev(
684
'Unsafe legacy lifecycles will not be called for components using new component APIs.',
685
+ {withoutStack: true},
686
);
687
});
688
@@ -701,6 +710,7 @@ describe('ReactComponentLifeCycle', () => {
710
const container = document.createElement('div');
711
expect(() => ReactDOM.render(<Component value={1} />, container)).toWarnDev(
712
'Unsafe legacy lifecycles will not be called for components using new component APIs.',
713
+ {withoutStack: true},
714
);
715
ReactDOM.render(<Component value={2} />, container);
716
});
@@ -728,6 +738,7 @@ describe('ReactComponentLifeCycle', () => {
738
const container = document.createElement('div');
739
expect(() => ReactDOM.render(<Component value={1} />, container)).toWarnDev(
740
'Unsafe legacy lifecycles will not be called for components using new component APIs.',
741
+ {withoutStack: true},
742
);
743
ReactDOM.render(<Component value={2} />, container);
744
});
@@ -756,6 +767,7 @@ describe('ReactComponentLifeCycle', () => {
767
' componentWillUpdate\n\n' +
768
'The above lifecycles should be removed. Learn more about this warning here:\n' +
769
'https://fb.me/react-async-component-lifecycle-hooks',
770
+ {withoutStack: true},
771
);
772
773
class WillMount extends React.Component {
@@ -775,6 +787,7 @@ describe('ReactComponentLifeCycle', () => {
787
' UNSAFE_componentWillMount\n\n' +
788
'The above lifecycles should be removed. Learn more about this warning here:\n' +
789
'https://fb.me/react-async-component-lifecycle-hooks',
790
+ {withoutStack: true},
791
);
792
793
class WillMountAndUpdate extends React.Component {
@@ -796,6 +809,7 @@ describe('ReactComponentLifeCycle', () => {
809
' UNSAFE_componentWillUpdate\n\n' +
810
'The above lifecycles should be removed. Learn more about this warning here:\n' +
811
'https://fb.me/react-async-component-lifecycle-hooks',
812
+ {withoutStack: true},
813
);
814
815
class WillReceiveProps extends React.Component {
@@ -815,6 +829,7 @@ describe('ReactComponentLifeCycle', () => {
829
' componentWillReceiveProps\n\n' +
830
'The above lifecycles should be removed. Learn more about this warning here:\n' +
831
'https://fb.me/react-async-component-lifecycle-hooks',
832
+ {withoutStack: true},
833
);
834
});
835
@@ -841,6 +856,7 @@ describe('ReactComponentLifeCycle', () => {
856
' componentWillUpdate\n\n' +
857
'The above lifecycles should be removed. Learn more about this warning here:\n' +
858
'https://fb.me/react-async-component-lifecycle-hooks',
859
+ {withoutStack: true},
860
);
861
862
class WillMount extends React.Component {
@@ -859,6 +875,7 @@ describe('ReactComponentLifeCycle', () => {
875
' UNSAFE_componentWillMount\n\n' +
876
'The above lifecycles should be removed. Learn more about this warning here:\n' +
877
'https://fb.me/react-async-component-lifecycle-hooks',
878
+ {withoutStack: true},
879
);
880
881
class WillMountAndUpdate extends React.Component {
@@ -879,6 +896,7 @@ describe('ReactComponentLifeCycle', () => {
896
' UNSAFE_componentWillUpdate\n\n' +
897
'The above lifecycles should be removed. Learn more about this warning here:\n' +
898
'https://fb.me/react-async-component-lifecycle-hooks',
899
+ {withoutStack: true},
900
);
901
902
class WillReceiveProps extends React.Component {
@@ -897,6 +915,7 @@ describe('ReactComponentLifeCycle', () => {
915
' componentWillReceiveProps\n\n' +
916
'The above lifecycles should be removed. Learn more about this warning here:\n' +
917
'https://fb.me/react-async-component-lifecycle-hooks',
918
+ {withoutStack: true},
919
);
920
});
921
@@ -964,6 +983,7 @@ describe('ReactComponentLifeCycle', () => {
983
expect(() => ReactDOM.render(<MyComponent />, div)).toWarnDev(
984
'MyComponent.getDerivedStateFromProps(): A valid state object (or null) must ' +
985
'be returned. You have returned undefined.',
986
+ {withoutStack: true},
987
);
988
989
// De-duped
@@ -984,6 +1004,7 @@ describe('ReactComponentLifeCycle', () => {
1004
expect(() => ReactDOM.render(<MyComponent />, div)).toWarnDev(
1005
'MyComponent: Did not properly initialize state during construction. ' +
1006
'Expected state to be an object, but it was undefined.',
1007
+ {withoutStack: true},
1008
);
1009
1010
// De-duped
@@ -1209,6 +1230,7 @@ describe('ReactComponentLifeCycle', () => {
1230
expect(() => ReactDOM.render(<MyComponent value="bar" />, div)).toWarnDev(
1231
'MyComponent.getSnapshotBeforeUpdate(): A snapshot value (or null) must ' +
1232
'be returned. You have returned undefined.',
1233
+ {withoutStack: true},
1234
);
1235
1236
// De-duped
@@ -1229,6 +1251,7 @@ describe('ReactComponentLifeCycle', () => {
1251
expect(() => ReactDOM.render(<MyComponent />, div)).toWarnDev(
1252
'MyComponent: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' +
1253
'This component defines getSnapshotBeforeUpdate() only.',
1254
+ {withoutStack: true},
1255
);
1256
1257
// De-duped
packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
+11
@@ -163,6 +163,7 @@ describe('ReactCompositeComponent', () => {
163
'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' +
164
'will stop working in React v17. Replace the ReactDOM.render() call ' +
165
'with ReactDOM.hydrate() if you want React to attach to the server HTML.',
166
+ {withoutStack: true},
167
);
168
169
// New explicit API
@@ -279,6 +280,7 @@ describe('ReactCompositeComponent', () => {
280
'This is a no-op, but it might indicate a bug in your application. ' +
281
'Instead, assign to `this.state` directly or define a `state = {};` ' +
282
'class property with the desired state in the MyComponent component.',
283
+ {withoutStack: true},
284
);
285
286
// No additional warning should be recorded
@@ -303,6 +305,7 @@ describe('ReactCompositeComponent', () => {
305
'This is a no-op, but it might indicate a bug in your application. ' +
306
'Instead, assign to `this.state` directly or define a `state = {};` ' +
307
'class property with the desired state in the MyComponent component.',
308
+ {withoutStack: true},
309
);
310
311
// No additional warning should be recorded
@@ -466,6 +469,7 @@ describe('ReactCompositeComponent', () => {
469
"`render` or another component's constructor). Render methods should " +
470
'be a pure function of props and state; constructor side-effects are ' +
471
'an anti-pattern, but can be moved to `componentWillMount`.',
472
+ {withoutStack: true},
473
);
474
475
// The setState call is queued and then executed as a second pass. This
@@ -513,6 +517,7 @@ describe('ReactCompositeComponent', () => {
517
instance = ReactDOM.render(<Component />, container);
518
}).toWarnDev(
519
'Warning: setState(...): Cannot call setState() inside getChildContext()',
520
+ {withoutStack: true},
521
);
522
523
expect(renderPasses).toBe(2);
@@ -589,6 +594,7 @@ describe('ReactCompositeComponent', () => {
594
expect(() => instance.setState({bogus: true})).toWarnDev(
595
'Warning: Component.shouldComponentUpdate(): Returned undefined instead of a ' +
596
'boolean value. Make sure to return true or false.',
597
+ {withoutStack: true},
598
);
599
});
600
@@ -605,6 +611,7 @@ describe('ReactCompositeComponent', () => {
611
'Warning: Component has a method called ' +
612
'componentDidUnmount(). But there is no such lifecycle method. ' +
613
'Did you mean componentWillUnmount()?',
614
+ {withoutStack: true},
615
);
616
});
617
@@ -623,6 +630,7 @@ describe('ReactCompositeComponent', () => {
630
'If you meant to update the state in response to changing props, ' +
631
'use componentWillReceiveProps(). If you meant to fetch data or ' +
632
'run side-effects or mutations after React has updated the UI, use componentDidUpdate().',
633
+ {withoutStack: true},
634
);
635
});
636
@@ -641,6 +649,7 @@ describe('ReactCompositeComponent', () => {
649
expect(() => ReactTestUtils.renderIntoDocument(<Component />)).toWarnDev(
650
'Warning: Setting defaultProps as an instance property on Component is not supported ' +
651
'and will be ignored. Instead, define defaultProps as a static property on Component.',
652
+ {withoutStack: true},
653
);
654
});
655
@@ -1131,6 +1140,7 @@ describe('ReactCompositeComponent', () => {
1140
'triggering nested component updates from render is not allowed. If ' +
1141
'necessary, trigger nested updates in componentDidUpdate.\n\nCheck the ' +
1142
'render method of Outer.',
1143
+ {withoutStack: true},
1144
);
1145
});
1146
@@ -1422,6 +1432,7 @@ describe('ReactCompositeComponent', () => {
1432
expect(() => ReactDOM.render(<Foo idx="qwe" />, container)).toWarnDev(
1433
'Foo(...): When calling super() in `Foo`, make sure to pass ' +
1434
"up the same props that your component's constructor was passed.",
1435
+ {withoutStack: true},
1436
);
1437
});
1438
packages/react-dom/src/__tests__/ReactCompositeComponentState-test.js
+2
@@ -410,6 +410,7 @@ describe('ReactCompositeComponent-state', () => {
410
'Warning: Test.componentWillReceiveProps(): Assigning directly to ' +
411
"this.state is deprecated (except inside a component's constructor). " +
412
'Use setState instead.',
413
+ {withoutStack: true},
414
);
415
416
expect(ops).toEqual([
@@ -451,6 +452,7 @@ describe('ReactCompositeComponent-state', () => {
452
'Warning: Test.componentWillMount(): Assigning directly to ' +
453
"this.state is deprecated (except inside a component's constructor). " +
454
'Use setState instead.',
455
+ {withoutStack: true},
456
);
457
458
expect(ops).toEqual([
packages/react-dom/src/__tests__/ReactDOM-test.js
+1
@@ -450,6 +450,7 @@ describe('ReactDOM', () => {
450
jest.resetModules();
451
expect(() => require('react-dom')).toWarnDev(
452
"This browser doesn't support requestAnimationFrame.",
453
+ {withoutStack: true},
454
);
455
} finally {
456
global.requestAnimationFrame = previousRAF;
packages/react-dom/src/__tests__/ReactDOMComponent-test.js
+32
-8
@@ -567,6 +567,7 @@ describe('ReactDOMComponent', () => {
567
}
568
}).toWarnDev(
569
'Warning: Invalid attribute name: `blah" onclick="beevil" noise="hi`',
570
+ {withoutStack: true}, // TODO: add a stack
571
);
572
});
573
@@ -586,6 +587,7 @@ describe('ReactDOMComponent', () => {
587
}
588
}).toWarnDev(
589
'Warning: Invalid attribute name: `blah" onclick="beevil" noise="hi`',
590
+ {withoutStack: true}, // TODO: add a stack
591
);
592
});
593
@@ -1004,6 +1006,7 @@ describe('ReactDOMComponent', () => {
1006
'<BR /> is using incorrect casing. ' +
1007
'Use PascalCase for React components, ' +
1008
'or lowercase for HTML elements.',
1009
+ {withoutStack: true}, // TODO: add a stack
1010
);
1011
expect(returnedValue).not.toContain('</BR>');
1012
});
@@ -1020,6 +1023,7 @@ describe('ReactDOMComponent', () => {
1023
'<IMG /> is using incorrect casing. ' +
1024
'Use PascalCase for React components, ' +
1025
'or lowercase for HTML elements.',
1026
+ {withoutStack: true}, // TODO: add a stack
1027
);
1028
});
1029
@@ -1029,6 +1033,7 @@ describe('ReactDOMComponent', () => {
1033
).toWarnDev(
1034
'The `aria` attribute is reserved for future use in React. ' +
1035
'Pass individual `aria-` attributes instead.',
1036
+ {withoutStack: true}, // TODO: add a stack
1037
);
1038
});
1039
@@ -1051,10 +1056,12 @@ describe('ReactDOMComponent', () => {
1056
1057
expect(() => ReactTestUtils.renderIntoDocument(<bar />)).toWarnDev(
1058
'The tag <bar> is unrecognized in this browser',
1059
+ {withoutStack: true}, // TODO: add a stack
1060
);
1061
// Test deduplication
1062
expect(() => ReactTestUtils.renderIntoDocument(<foo />)).toWarnDev(
1063
'The tag <foo> is unrecognized in this browser',
1064
+ {withoutStack: true}, // TODO: add a stack
1065
);
1066
ReactTestUtils.renderIntoDocument(<foo />);
1067
// This is a funny case.
@@ -1066,12 +1073,15 @@ describe('ReactDOMComponent', () => {
1073
// Corner case. Make sure out deduplication logic doesn't break with weird tag.
1074
expect(() =>
1075
ReactTestUtils.renderIntoDocument(<hasOwnProperty />),
1069
- ).toWarnDev([
1070
- '<hasOwnProperty /> is using incorrect casing. ' +
1071
- 'Use PascalCase for React components, ' +
1072
- 'or lowercase for HTML elements.',
1073
- 'The tag <hasOwnProperty> is unrecognized in this browser',
1074
- ]);
1076
+ ).toWarnDev(
1077
+ [
1078
+ '<hasOwnProperty /> is using incorrect casing. ' +
1079
+ 'Use PascalCase for React components, ' +
1080
+ 'or lowercase for HTML elements.',
1081
+ 'The tag <hasOwnProperty> is unrecognized in this browser',
1082
+ ],
1083
+ {withoutStack: true}, // TODO: add a stack
1084
+ );
1085
} finally {
1086
Object.prototype.toString = realToString; // eslint-disable-line no-extend-native
1087
}
@@ -1130,6 +1140,7 @@ describe('ReactDOMComponent', () => {
1140
expect(() => ReactDOM.render(<ShadyComponent />, node)).toWarnDev(
1141
'ShadyComponent is using shady DOM. Using shady DOM with React can ' +
1142
'cause things to break subtly.',
1143
+ {withoutStack: true}, // TODO: add a stack
1144
);
1145
mountComponent({is: 'custom-shady-div2'});
1146
} finally {
@@ -1150,6 +1161,7 @@ describe('ReactDOMComponent', () => {
1161
expect(() => mountComponent({is: 'custom-shady-div'})).toWarnDev(
1162
'A component is using shady DOM. Using shady DOM with React can ' +
1163
'cause things to break subtly.',
1164
+ {withoutStack: true}, // TODO: add a stack
1165
);
1166
1167
// No additional warnings are expected
@@ -1197,13 +1209,17 @@ describe('ReactDOMComponent', () => {
1209
it('should validate against use of innerHTML', () => {
1210
expect(() =>
1211
mountComponent({innerHTML: '<span>Hi Jim!</span>'}),
1200
- ).toWarnDev('Directly setting property `innerHTML` is not permitted. ');
1212
+ ).toWarnDev('Directly setting property `innerHTML` is not permitted. ', {
1213
+ withoutStack: true, // TODO: add a stack
1214
+ });
1215
});
1216
1217
it('should validate against use of innerHTML without case sensitivity', () => {
1218
expect(() =>
1219
mountComponent({innerhtml: '<span>Hi Jim!</span>'}),
1206
- ).toWarnDev('Directly setting property `innerHTML` is not permitted. ');
1220
+ ).toWarnDev('Directly setting property `innerHTML` is not permitted. ', {
1221
+ withoutStack: true, // TODO: add a stack
1222
+ });
1223
});
1224
1225
it('should validate use of dangerouslySetInnerHTML', () => {
@@ -1796,11 +1812,13 @@ describe('ReactDOMComponent', () => {
1812
ReactTestUtils.renderIntoDocument(<div onFocusIn={() => {}} />),
1813
).toWarnDev(
1814
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1815
+ {withoutStack: true}, // TODO: add a stack
1816
);
1817
expect(() =>
1818
ReactTestUtils.renderIntoDocument(<div onFocusOut={() => {}} />),
1819
).toWarnDev(
1820
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1821
+ {withoutStack: true}, // TODO: add a stack
1822
);
1823
});
1824
@@ -1810,11 +1828,13 @@ describe('ReactDOMComponent', () => {
1828
ReactTestUtils.renderIntoDocument(<div onfocusin={() => {}} />),
1829
).toWarnDev(
1830
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1831
+ {withoutStack: true}, // TODO: add a stack
1832
);
1833
expect(() =>
1834
ReactTestUtils.renderIntoDocument(<div onfocusout={() => {}} />),
1835
).toWarnDev(
1836
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1837
+ {withoutStack: true}, // TODO: add a stack
1838
);
1839
});
1840
@@ -1824,11 +1844,13 @@ describe('ReactDOMComponent', () => {
1844
ReactDOMServer.renderToString(<div onFocusIn={() => {}} />),
1845
).toWarnDev(
1846
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1847
+ {withoutStack: true}, // TODO: add a stack
1848
);
1849
expect(() =>
1850
ReactDOMServer.renderToString(<div onFocusOut={() => {}} />),
1851
).toWarnDev(
1852
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1853
+ {withoutStack: true}, // TODO: add a stack
1854
);
1855
});
1856
@@ -1838,11 +1860,13 @@ describe('ReactDOMComponent', () => {
1860
ReactDOMServer.renderToString(<div onfocusin={() => {}} />),
1861
).toWarnDev(
1862
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1863
+ {withoutStack: true}, // TODO: add a stack
1864
);
1865
expect(() =>
1866
ReactDOMServer.renderToString(<div onfocusout={() => {}} />),
1867
).toWarnDev(
1868
'React uses onFocus and onBlur instead of onFocusIn and onFocusOut.',
1869
+ {withoutStack: true}, // TODO: add a stack
1870
);
1871
});
1872
packages/react-dom/src/__tests__/ReactDOMComponentTree-test.js
+2
@@ -195,6 +195,7 @@ describe('ReactDOMComponentTree', () => {
195
'was rendered by React and is not a top-level container. You may ' +
196
'have accidentally passed in a React root node instead of its ' +
197
'container.',
198
+ {withoutStack: true},
199
);
200
});
201
@@ -211,6 +212,7 @@ describe('ReactDOMComponentTree', () => {
212
'component. If you intended to update the children of this node, ' +
213
'you should instead have the existing children update their state ' +
214
'and render the new components instead of calling ReactDOM.render.',
215
+ {withoutStack: true},
216
);
217
});
218
});
packages/react-dom/src/__tests__/ReactDOMFiber-test.js
+4
@@ -256,6 +256,7 @@ describe('ReactDOMFiber', () => {
256
'and will be removed in React 17+. Update your code to use ' +
257
'ReactDOM.createPortal() instead. It has the exact same API, ' +
258
'but without the "unstable_" prefix.',
259
+ {withoutStack: true},
260
);
261
expect(portalContainer.innerHTML).toBe('<div>portal</div>');
262
expect(container.innerHTML).toBe('<div></div>');
@@ -1100,6 +1101,7 @@ describe('ReactDOMFiber', () => {
1101
'removed without using React. This is not supported and will ' +
1102
'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1103
'to empty a container.',
1104
+ {withoutStack: true},
1105
);
1106
}).toThrowError();
1107
});
@@ -1117,6 +1119,7 @@ describe('ReactDOMFiber', () => {
1119
'removed without using React. This is not supported and will ' +
1120
'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1121
'to empty a container.',
1122
+ {withoutStack: true},
1123
);
1124
});
1125
@@ -1133,6 +1136,7 @@ describe('ReactDOMFiber', () => {
1136
'removed without using React. This is not supported and will ' +
1137
'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1138
'to empty a container.',
1139
+ {withoutStack: true},
1140
);
1141
});
1142
packages/react-dom/src/__tests__/ReactDOMInput-test.js
+2
@@ -930,6 +930,7 @@ describe('ReactDOMInput', () => {
930
'both). Decide between using a controlled or uncontrolled input ' +
931
'element and remove one of these props. More info: ' +
932
'https://fb.me/react-controlled-components',
933
+ {withoutStack: true}, // TODO: add a stack
934
);
935
ReactDOM.unmountComponentAtNode(container);
936
@@ -957,6 +958,7 @@ describe('ReactDOMInput', () => {
958
'both). Decide between using a controlled or uncontrolled input ' +
959
'element and remove one of these props. More info: ' +
960
'https://fb.me/react-controlled-components',
961
+ {withoutStack: true}, // TODO: add a stack
962
);
963
ReactDOM.unmountComponentAtNode(container);
964
packages/react-dom/src/__tests__/ReactDOMRoot-test.js
+7
-4
@@ -143,7 +143,9 @@ describe('ReactDOMRoot', () => {
143
<span />
144
</div>,
145
);
146
- expect(jest.runAllTimers).toWarnDev('Extra attributes');
146
+ expect(jest.runAllTimers).toWarnDev('Extra attributes', {
147
+ withoutStack: true,
148
+ });
149
});
150
151
it('does not clear existing children', async () => {
@@ -358,9 +360,10 @@ describe('ReactDOMRoot', () => {
360
const root = ReactDOM.unstable_createRoot(container);
361
const batch = root.createBatch();
362
const InvalidType = undefined;
361
- expect(() => batch.render(<InvalidType />)).toWarnDev([
362
- 'React.createElement: type is invalid',
363
- ]);
363
+ expect(() => batch.render(<InvalidType />)).toWarnDev(
364
+ ['React.createElement: type is invalid'],
365
+ {withoutStack: true},
366
+ );
367
expect(() => batch.commit()).toThrow('Element type is invalid');
368
});
369
});
packages/react-dom/src/__tests__/ReactDOMSelect-test.js
+2
@@ -576,6 +576,7 @@ describe('ReactDOMSelect', () => {
576
).toWarnDev(
577
'Use the `defaultValue` or `value` props on <select> instead of ' +
578
'setting `selected` on <option>.',
579
+ {withoutStack: true}, // TODO: add a stack
580
);
581
582
ReactTestUtils.renderIntoDocument(
@@ -646,6 +647,7 @@ describe('ReactDOMSelect', () => {
647
'both). Decide between using a controlled or uncontrolled select ' +
648
'element and remove one of these props. More info: ' +
649
'https://fb.me/react-controlled-components',
650
+ {withoutStack: true}, // TODO: add a stack
651
);
652
653
ReactTestUtils.renderIntoDocument(
packages/react-dom/src/__tests__/ReactDOMServerIntegrationAttributes-test.js
+3
-1
@@ -598,7 +598,9 @@ describe('ReactDOMServerIntegration', () => {
598
// so that it gets deduplicated later, and doesn't fail the test.
599
expect(() => {
600
ReactDOM.render(<nonstandard />, document.createElement('div'));
601
- }).toWarnDev('The tag <nonstandard> is unrecognized in this browser.');
601
+ }).toWarnDev('The tag <nonstandard> is unrecognized in this browser.', {
602
+ withoutStack: true, // TODO: add a stack
603
+ });
604
605
const e = await render(<nonstandard foo="bar" />);
606
expect(e.getAttribute('foo')).toBe('bar');
packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
+6
-1
@@ -142,7 +142,9 @@ describe('ReactDOMServerIntegration', () => {
142
// so that it gets deduplicated later, and doesn't fail the test.
143
expect(() => {
144
ReactDOM.render(<nonstandard />, document.createElement('div'));
145
- }).toWarnDev('The tag <nonstandard> is unrecognized in this browser.');
145
+ }).toWarnDev('The tag <nonstandard> is unrecognized in this browser.', {
146
+ withoutStack: true, // TODO: add a stack
147
+ });
148
149
const e = await render(<nonstandard>Text</nonstandard>);
150
expect(e.tagName).toBe('NONSTANDARD');
@@ -885,6 +887,7 @@ describe('ReactDOMServerIntegration', () => {
887
'components) but got: object. You likely forgot to export your ' +
888
"component from the file it's defined in, or you might have mixed up " +
889
'default and named imports.',
890
+ {withoutStack: true},
891
);
892
await render(EmptyComponent);
893
},
@@ -906,6 +909,7 @@ describe('ReactDOMServerIntegration', () => {
909
'Warning: React.createElement: type is invalid -- expected a string ' +
910
'(for built-in components) or a class/function (for composite ' +
911
'components) but got: null.',
912
+ {withoutStack: true},
913
);
914
await render(NullComponent);
915
},
@@ -925,6 +929,7 @@ describe('ReactDOMServerIntegration', () => {
929
'components) but got: undefined. You likely forgot to export your ' +
930
"component from the file it's defined in, or you might have mixed up " +
931
'default and named imports.',
932
+ {withoutStack: true},
933
);
934
935
await render(UndefinedComponent);
packages/react-dom/src/__tests__/ReactDOMServerLifecycles-test.internal.js
+2
@@ -44,6 +44,7 @@ describe('ReactDOMServerLifecycles', () => {
44
ReactDOMServer.renderToString(<Component />),
45
).toLowPriorityWarnDev(
46
'Component: componentWillMount() is deprecated and will be removed in the next major version.',
47
+ {withoutStack: true},
48
);
49
});
50
@@ -62,6 +63,7 @@ describe('ReactDOMServerLifecycles', () => {
63
).toLowPriorityWarnDev(
64
'Warning: Component: componentWillMount() is deprecated and will be removed ' +
65
'in the next major version.',
66
+ {withoutStack: true},
67
);
68
69
// De-duped
packages/react-dom/src/__tests__/ReactDOMServerLifecycles-test.js
+3
@@ -183,6 +183,7 @@ describe('ReactDOMServerLifecycles', () => {
183
expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
184
'Component.getDerivedStateFromProps(): A valid state object (or null) must ' +
185
'be returned. You have returned undefined.',
186
+ {withoutStack: true},
187
);
188
189
// De-duped
@@ -202,6 +203,7 @@ describe('ReactDOMServerLifecycles', () => {
203
expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
204
'Component: Did not properly initialize state during construction. ' +
205
'Expected state to be an object, but it was undefined.',
206
+ {withoutStack: true},
207
);
208
209
// De-duped
@@ -258,6 +260,7 @@ describe('ReactDOMServerLifecycles', () => {
260
'usually means you called setState() outside componentWillMount() on ' +
261
'the server. This is a no-op.\n\n' +
262
'Please check the code for the Outer component.',
263
+ {withoutStack: true},
264
);
265
});
266
});
packages/react-dom/src/__tests__/ReactDOMTextarea-test.js
+7
@@ -267,6 +267,7 @@ describe('ReactDOMTextarea', () => {
267
node = renderTextarea(stub, container);
268
}).toWarnDev(
269
'Use the `defaultValue` or `value` props instead of setting children on <textarea>.',
270
+ {withoutStack: true}, // TODO: add a stack
271
);
272
273
expect(node.value).toBe('giraffe');
@@ -319,6 +320,7 @@ describe('ReactDOMTextarea', () => {
320
node = renderTextarea(<textarea>{17}</textarea>);
321
}).toWarnDev(
322
'Use the `defaultValue` or `value` props instead of setting children on <textarea>.',
323
+ {withoutStack: true}, // TODO: add a stack
324
);
325
expect(node.value).toBe('17');
326
});
@@ -329,6 +331,7 @@ describe('ReactDOMTextarea', () => {
331
node = renderTextarea(<textarea>{false}</textarea>);
332
}).toWarnDev(
333
'Use the `defaultValue` or `value` props instead of setting children on <textarea>.',
334
+ {withoutStack: true}, // TODO: add a stack
335
);
336
expect(node.value).toBe('false');
337
});
@@ -344,6 +347,7 @@ describe('ReactDOMTextarea', () => {
347
node = renderTextarea(<textarea>{obj}</textarea>);
348
}).toWarnDev(
349
'Use the `defaultValue` or `value` props instead of setting children on <textarea>.',
350
+ {withoutStack: true}, // TODO: add a stack
351
);
352
expect(node.value).toBe('sharkswithlasers');
353
});
@@ -359,6 +363,7 @@ describe('ReactDOMTextarea', () => {
363
),
364
).toWarnDev(
365
'Use the `defaultValue` or `value` props instead of setting children on <textarea>.',
366
+ {withoutStack: true}, // TODO: add a stack
367
);
368
}).toThrow();
369
@@ -373,6 +378,7 @@ describe('ReactDOMTextarea', () => {
378
)),
379
).toWarnDev(
380
'Use the `defaultValue` or `value` props instead of setting children on <textarea>.',
381
+ {withoutStack: true}, // TODO: add a stack
382
);
383
}).not.toThrow();
384
@@ -409,6 +415,7 @@ describe('ReactDOMTextarea', () => {
415
'both). Decide between using a controlled or uncontrolled textarea ' +
416
'and remove one of these props. More info: ' +
417
'https://fb.me/react-controlled-components',
418
+ {withoutStack: true}, // TODO: add a stack
419
);
420
421
// No additional warnings are expected
packages/react-dom/src/__tests__/ReactMount-test.js
+7
@@ -63,6 +63,7 @@ describe('ReactMount', () => {
63
'Functions are not valid as a React child. ' +
64
'This may happen if you return a Component instead of <Component /> from render. ' +
65
'Or maybe you meant to call this function rather than return it.',
66
+ {withoutStack: true},
67
);
68
});
69
@@ -126,6 +127,7 @@ describe('ReactMount', () => {
127
128
expect(() => ReactDOM.hydrate(<div />, container)).toWarnDev(
129
'Did not expect server HTML to contain the text node " " in <container>.',
130
+ {withoutStack: true},
131
);
132
});
133
@@ -135,6 +137,7 @@ describe('ReactMount', () => {
137
138
expect(() => ReactDOM.hydrate(<div />, container)).toWarnDev(
139
'Did not expect server HTML to contain the text node " " in <container>.',
140
+ {withoutStack: true},
141
);
142
});
143
@@ -153,6 +156,7 @@ describe('ReactMount', () => {
156
ReactDOM.render(<div />, iFrame.contentDocument.body),
157
).toWarnDev(
158
'Rendering components directly into document.body is discouraged',
159
+ {withoutStack: true},
160
);
161
});
162
@@ -171,6 +175,7 @@ describe('ReactMount', () => {
175
).toWarnDev(
176
'Server: "This markup contains an nbsp entity: server text" ' +
177
'Client: "This markup contains an nbsp entity: client text"',
178
+ {withoutStack: true},
179
);
180
});
181
@@ -197,6 +202,7 @@ describe('ReactMount', () => {
202
'root component. If you intended to update the children of this node, ' +
203
'you should instead have the existing children update their state and ' +
204
'render the new components instead of calling ReactDOM.render.',
205
+ {withoutStack: true},
206
);
207
});
208
@@ -222,6 +228,7 @@ describe('ReactMount', () => {
228
expect(() => ReactDOMOther.unmountComponentAtNode(container)).toWarnDev(
229
"Warning: unmountComponentAtNode(): The node you're attempting to unmount " +
230
'was rendered by another copy of React.',
231
+ {withoutStack: true},
232
);
233
234
// Don't throw a warning if the correct React copy unmounts the node
packages/react-dom/src/__tests__/ReactMountDestruction-test.js
+2
@@ -55,6 +55,7 @@ describe('ReactMount', () => {
55
'unmount was rendered by React and is not a top-level container. You ' +
56
'may have accidentally passed in a React root node instead of its ' +
57
'container.',
58
+ {withoutStack: true},
59
);
60
});
61
@@ -77,6 +78,7 @@ describe('ReactMount', () => {
78
'unmount was rendered by React and is not a top-level container. ' +
79
'Instead, have the parent component update its state and rerender in ' +
80
'order to remove this component.',
81
+ {withoutStack: true},
82
);
83
});
84
});
packages/react-dom/src/__tests__/ReactRenderDocument-test.js
+12
-3
@@ -39,6 +39,7 @@ describe('rendering React components at document', () => {
39
'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' +
40
'will stop working in React v17. Replace the ReactDOM.render() call ' +
41
'with ReactDOM.hydrate() if you want React to attach to the server HTML.',
42
+ {withoutStack: true},
43
);
44
}
45
@@ -200,8 +201,11 @@ describe('rendering React components at document', () => {
201
'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' +
202
'will stop working in React v17. Replace the ReactDOM.render() call ' +
203
'with ReactDOM.hydrate() if you want React to attach to the server HTML.',
204
+ {withoutStack: true},
205
);
204
- }).toWarnDev('Warning: Text content did not match.');
206
+ }).toWarnDev('Warning: Text content did not match.', {
207
+ withoutStack: true,
208
+ });
209
});
210
211
it('should throw on full document render w/ no markup', () => {
@@ -369,6 +373,7 @@ describe('rendering React components at document', () => {
373
container.textContent = 'potato';
374
expect(() => ReactDOM.hydrate(<div>parsnip</div>, container)).toWarnDev(
375
'Expected server HTML to contain a matching <div> in <div>.',
376
+ {withoutStack: true},
377
);
378
expect(container.textContent).toBe('parsnip');
379
});
@@ -394,7 +399,9 @@ describe('rendering React components at document', () => {
399
400
expect(() =>
401
ReactDOM.hydrate(<Component text="Hello world" />, testDocument),
397
- ).toWarnDev('Warning: Text content did not match.');
402
+ ).toWarnDev('Warning: Text content did not match.', {
403
+ withoutStack: true,
404
+ });
405
expect(testDocument.body.innerHTML).toBe('Hello world');
406
});
407
@@ -417,7 +424,9 @@ describe('rendering React components at document', () => {
424
// getTestDocument() has an extra <meta> that we didn't render.
425
expect(() =>
426
ReactDOM.hydrate(<Component text="Hello world" />, testDocument),
420
- ).toWarnDev('Did not expect server HTML to contain a <meta> in <head>.');
427
+ ).toWarnDev('Did not expect server HTML to contain a <meta> in <head>.', {
428
+ withoutStack: true,
429
+ });
430
expect(testDocument.body.innerHTML).toBe('Hello world');
431
});
432
packages/react-dom/src/__tests__/ReactServerRendering-test.js
+14
-9
@@ -519,6 +519,7 @@ describe('ReactDOMServer', () => {
519
'Warning: setState(...): Can only update a mounting component.' +
520
' This usually means you called setState() outside componentWillMount() on the server.' +
521
' This is a no-op.\n\nPlease check the code for the Foo component.',
522
+ {withoutStack: true},
523
);
524
525
const markup = ReactDOMServer.renderToStaticMarkup(<Foo />);
@@ -546,6 +547,7 @@ describe('ReactDOMServer', () => {
547
'Warning: forceUpdate(...): Can only update a mounting component. ' +
548
'This usually means you called forceUpdate() outside componentWillMount() on the server. ' +
549
'This is a no-op.\n\nPlease check the code for the Baz component.',
550
+ {withoutStack: true},
551
);
552
const markup = ReactDOMServer.renderToStaticMarkup(<Baz />);
553
expect(markup).toBe('<div></div>');
@@ -599,15 +601,18 @@ describe('ReactDOMServer', () => {
601
</svg>
602
</div>,
603
),
602
- ).toWarnDev([
603
- 'Warning: <inPUT /> is using incorrect casing. ' +
604
- 'Use PascalCase for React components, ' +
605
- 'or lowercase for HTML elements.',
606
- // linearGradient doesn't warn
607
- 'Warning: <iFrame /> is using incorrect casing. ' +
608
- 'Use PascalCase for React components, ' +
609
- 'or lowercase for HTML elements.',
610
- ]);
604
+ ).toWarnDev(
605
+ [
606
+ 'Warning: <inPUT /> is using incorrect casing. ' +
607
+ 'Use PascalCase for React components, ' +
608
+ 'or lowercase for HTML elements.',
609
+ // linearGradient doesn't warn
610
+ 'Warning: <iFrame /> is using incorrect casing. ' +
611
+ 'Use PascalCase for React components, ' +
612
+ 'or lowercase for HTML elements.',
613
+ ],
614
+ {withoutStack: true},
615
+ );
616
});
617
618
it('should warn about contentEditable and children', () => {
packages/react-dom/src/__tests__/ReactServerRenderingHydration.js
+9
-2
@@ -83,6 +83,7 @@ describe('ReactDOMServerHydration', () => {
83
'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' +
84
'will stop working in React v17. Replace the ReactDOM.render() call ' +
85
'with ReactDOM.hydrate() if you want React to attach to the server HTML.',
86
+ {withoutStack: true},
87
);
88
expect(mountCount).toEqual(3);
89
expect(element.innerHTML).toBe(lastMarkup);
@@ -101,7 +102,9 @@ describe('ReactDOMServerHydration', () => {
102
element.innerHTML = lastMarkup;
103
expect(() => {
104
instance = ReactDOM.render(<TestComponent name="y" />, element);
104
- }).toWarnDev('Text content did not match. Server: "x" Client: "y"');
105
+ }).toWarnDev('Text content did not match. Server: "x" Client: "y"', {
106
+ withoutStack: true,
107
+ });
108
expect(mountCount).toEqual(4);
109
expect(element.innerHTML.length > 0).toBe(true);
110
expect(element.innerHTML).not.toEqual(lastMarkup);
@@ -184,7 +187,9 @@ describe('ReactDOMServerHydration', () => {
187
element.innerHTML = lastMarkup;
188
expect(() => {
189
instance = ReactDOM.hydrate(<TestComponent name="y" />, element);
187
- }).toWarnDev('Text content did not match. Server: "x" Client: "y"');
190
+ }).toWarnDev('Text content did not match. Server: "x" Client: "y"', {
191
+ withoutStack: true,
192
+ });
193
expect(mountCount).toEqual(4);
194
expect(element.innerHTML.length > 0).toBe(true);
195
expect(element.innerHTML).not.toEqual(lastMarkup);
@@ -247,6 +252,7 @@ describe('ReactDOMServerHydration', () => {
252
ReactDOM.hydrate(<button autoFocus={false}>client</button>, element),
253
).toWarnDev(
254
'Warning: Text content did not match. Server: "server" Client: "client"',
255
+ {withoutStack: true},
256
);
257
258
expect(element.firstChild.focus).not.toHaveBeenCalled();
@@ -286,6 +292,7 @@ describe('ReactDOMServerHydration', () => {
292
293
expect(() => ReactDOM.hydrate(markup, element)).toWarnDev(
294
'Please update the following components to use componentDidMount instead: ComponentWithWarning',
295
+ {withoutStack: true},
296
);
297
expect(element.textContent).toBe('Hi');
298
});
packages/react-dom/src/__tests__/ReactStatelessComponent-test.js
+2
@@ -111,6 +111,7 @@ describe('ReactStatelessComponent', () => {
111
).toWarnDev(
112
'StatelessComponentWithChildContext: Stateless ' +
113
'functional components do not support getDerivedStateFromProps.',
114
+ {withoutStack: true},
115
);
116
});
117
@@ -133,6 +134,7 @@ describe('ReactStatelessComponent', () => {
134
).toWarnDev(
135
'StatelessComponentWithChildContext(...): childContextTypes cannot ' +
136
'be defined on a functional component.',
137
+ {withoutStack: true},
138
);
139
});
140
packages/react-dom/src/__tests__/ReactTestUtils-test.js
+1
@@ -59,6 +59,7 @@ describe('ReactTestUtils', () => {
59
'ReactTestUtils.mockComponent() is deprecated. ' +
60
'Use shallow rendering or jest.mock() instead.\n\n' +
61
'See https://fb.me/test-utils-mock-component for more information.',
62
+ {withoutStack: true},
63
);
64
65
// De-duplication check
packages/react-dom/src/__tests__/ReactUpdates-test.js
+1
@@ -1226,6 +1226,7 @@ describe('ReactUpdates', () => {
1226
const container = document.createElement('div');
1227
expect(() => ReactDOM.render(<Foo />, container)).toWarnDev(
1228
'Cannot update during an existing state transition',
1229
+ {withoutStack: true},
1230
);
1231
expect(ops).toEqual(['base: 0, memoized: 0', 'base: 1, memoized: 1']);
1232
});
packages/react-dom/src/__tests__/validateDOMNesting-test.js
+6
-2
@@ -12,7 +12,7 @@
12
const React = require('react');
13
const ReactDOM = require('react-dom');
14
15
-function expectWarnings(tags, warnings = []) {
15
+function expectWarnings(tags, warnings = [], withoutStack = 0) {
16
tags = [...tags];
17
warnings = [...warnings];
18
@@ -28,7 +28,9 @@ function expectWarnings(tags, warnings = []) {
28
element = <Tag>{element}</Tag>;
29
}
30
31
- expect(() => ReactDOM.render(element, container)).toWarnDev(warnings);
31
+ expect(() => ReactDOM.render(element, container)).toWarnDev(warnings, {
32
+ withoutStack,
33
+ });
34
}
35
36
describe('validateDOMNesting', () => {
@@ -39,6 +41,7 @@ describe('validateDOMNesting', () => {
41
[
42
'render(): Rendering components directly into document.body is discouraged',
43
],
44
+ 1,
45
);
46
expectWarnings(['div', 'a', 'object', 'a']);
47
expectWarnings(['div', 'p', 'button', 'p']);
@@ -106,6 +109,7 @@ describe('validateDOMNesting', () => {
109
'validateDOMNesting(...): <body> cannot appear as a child of <body>.\n' +
110
' in body (at **)',
111
],
112
+ 1,
113
);
114
expectWarnings(
115
['svg', 'foreignObject', 'body', 'p'],
packages/react-dom/src/events/__tests__/SyntheticEvent-test.js
+8
@@ -153,12 +153,15 @@ describe('SyntheticEvent', () => {
153
// once for each property accessed
154
expect(() => expect(syntheticEvent.type).toBe(null)).toWarnDev(
155
getExpectedWarning('type'),
156
+ {withoutStack: true},
157
);
158
expect(() => expect(syntheticEvent.nativeEvent).toBe(null)).toWarnDev(
159
getExpectedWarning('nativeEvent'),
160
+ {withoutStack: true},
161
);
162
expect(() => expect(syntheticEvent.target).toBe(null)).toWarnDev(
163
getExpectedWarning('target'),
164
+ {withoutStack: true},
165
);
166
167
expect(expectedCount).toBe(1);
@@ -188,6 +191,7 @@ describe('SyntheticEvent', () => {
191
'released/nullified synthetic event. This is effectively a no-op. If you must ' +
192
'keep the original synthetic event around, use event.persist(). ' +
193
'See https://fb.me/react-event-pooling for more information.',
194
+ {withoutStack: true},
195
);
196
expect(expectedCount).toBe(1);
197
});
@@ -213,6 +217,7 @@ describe('SyntheticEvent', () => {
217
'released/nullified synthetic event. This is a no-op function. If you must ' +
218
'keep the original synthetic event around, use event.persist(). ' +
219
'See https://fb.me/react-event-pooling for more information.',
220
+ {withoutStack: true},
221
);
222
expect(expectedCount).toBe(1);
223
});
@@ -239,6 +244,7 @@ describe('SyntheticEvent', () => {
244
'released/nullified synthetic event. This is a no-op function. If you must ' +
245
'keep the original synthetic event around, use event.persist(). ' +
246
'See https://fb.me/react-event-pooling for more information.',
247
+ {withoutStack: true},
248
);
249
expect(expectedCount).toBe(1);
250
});
@@ -260,6 +266,7 @@ describe('SyntheticEvent', () => {
266
'released/nullified synthetic event. This is set to null. If you must ' +
267
'keep the original synthetic event around, use event.persist(). ' +
268
'See https://fb.me/react-event-pooling for more information.',
269
+ {withoutStack: true},
270
);
271
});
272
@@ -277,6 +284,7 @@ describe('SyntheticEvent', () => {
284
"you're seeing this, you're adding a new property in the synthetic " +
285
'event object. The property is never released. ' +
286
'See https://fb.me/react-event-pooling for more information.',
287
+ {withoutStack: true},
288
);
289
} else {
290
e.foo = 'bar';
packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js
+1
@@ -2403,6 +2403,7 @@ describe('ReactIncremental', () => {
2403
expect(ReactNoop.flush).toWarnDev(
2404
'componentWillReceiveProps: Please update the following components ' +
2405
'to use static getDerivedStateFromProps instead: MyComponent',
2406
+ {withoutStack: true},
2407
);
2408
2409
expect(ops).toEqual([
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+1
@@ -1100,6 +1100,7 @@ describe('ReactIncrementalErrorHandling', () => {
1100
const InvalidType = undefined;
1101
expect(() => ReactNoop.render(<InvalidType />)).toWarnDev(
1102
'Warning: React.createElement: type is invalid -- expected a string',
1103
+ {withoutStack: true},
1104
);
1105
expect(ReactNoop.flush).toThrowError(
1106
'Element type is invalid: expected a string (for built-in components) or ' +
packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
+10
-6
@@ -314,12 +314,15 @@ describe('ReactDebugFiberPerf', () => {
314
</Parent>,
315
);
316
addComment('Should not print a warning');
317
- expect(ReactNoop.flush).toWarnDev([
318
- 'componentWillMount: Please update the following components ' +
319
- 'to use componentDidMount instead: NotCascading' +
320
- '\n\ncomponentWillReceiveProps: Please update the following components ' +
321
- 'to use static getDerivedStateFromProps instead: NotCascading',
322
- ]);
317
+ expect(ReactNoop.flush).toWarnDev(
318
+ [
319
+ 'componentWillMount: Please update the following components ' +
320
+ 'to use componentDidMount instead: NotCascading' +
321
+ '\n\ncomponentWillReceiveProps: Please update the following components ' +
322
+ 'to use static getDerivedStateFromProps instead: NotCascading',
323
+ ],
324
+ {withoutStack: true},
325
+ );
326
ReactNoop.render(
327
<Parent>
328
<NotCascading />
@@ -360,6 +363,7 @@ describe('ReactDebugFiberPerf', () => {
363
'to use static getDerivedStateFromProps instead: AllLifecycles' +
364
'\n\ncomponentWillUpdate: Please update the following components ' +
365
'to use componentDidUpdate instead: AllLifecycles',
366
+ {withoutStack: true},
367
);
368
ReactNoop.render(<AllLifecycles />);
369
addComment('Update');
packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js
+3
@@ -65,6 +65,7 @@ describe('ReactIncrementalReflection', () => {
65
expect(ReactNoop.flush).toWarnDev(
66
'componentWillMount: Please update the following components ' +
67
'to use componentDidMount instead: Component',
68
+ {withoutStack: true},
69
);
70
71
expect(ops).toEqual(['componentDidMount', true]);
@@ -106,6 +107,7 @@ describe('ReactIncrementalReflection', () => {
107
expect(ReactNoop.flush).toWarnDev(
108
'componentWillMount: Please update the following components ' +
109
'to use componentDidMount instead: Component',
110
+ {withoutStack: true},
111
);
112
113
expect(ops).toEqual(['Component']);
@@ -198,6 +200,7 @@ describe('ReactIncrementalReflection', () => {
200
'to use componentDidMount instead: Component' +
201
'\n\ncomponentWillUpdate: Please update the following components ' +
202
'to use componentDidUpdate instead: Component',
203
+ {withoutStack: true},
204
);
205
206
const hostSpan = classInstance.span;
packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.internal.js
+1
@@ -353,6 +353,7 @@ describe('ReactIncrementalScheduling', () => {
353
expect(ReactNoop.flush).toWarnDev(
354
'componentWillReceiveProps: Please update the following components ' +
355
'to use static getDerivedStateFromProps instead: Foo',
356
+ {withoutStack: true},
357
);
358
359
ReactNoop.render(<Foo step={2} />);
packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js
+2
@@ -345,6 +345,7 @@ describe('ReactIncrementalUpdates', () => {
345
expect(ReactNoop.flush).toWarnDev(
346
'componentWillReceiveProps: Please update the following components ' +
347
'to use static getDerivedStateFromProps instead: Foo',
348
+ {withoutStack: true},
349
);
350
351
ops = [];
@@ -385,6 +386,7 @@ describe('ReactIncrementalUpdates', () => {
386
'from inside an update function. Update functions should be pure, ' +
387
'with zero side-effects. Consider using componentDidUpdate or a ' +
388
'callback.',
389
+ {withoutStack: true},
390
);
391
expect(ops).toEqual([
392
// Initial render
packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
+1
@@ -720,6 +720,7 @@ describe('ReactNewContext', () => {
720
expect(console.error.calls.argsFor(0)[0]).toContain(
721
'calculateChangedBits: Expected the return value to be a 31-bit ' +
722
'integer. Instead received: 4294967295',
723
+ {withoutStack: true}, // TODO: add a stack
724
);
725
}
726
});
packages/react/src/__tests__/ReactChildren-test.js
+1
@@ -928,6 +928,7 @@ describe('ReactChildren', () => {
928
'Warning: ' +
929
'Each child in an array or iterator should have a unique "key" prop.' +
930
' See https://fb.me/react-warning-keys for more information.',
931
+ {withoutStack: true}, // There's nothing on the stack
932
);
933
});
934
});
packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
+17
-12
@@ -55,7 +55,7 @@ describe 'ReactCoffeeScriptClass', ->
55
# A failed component renders twice in DEV
56
'No `render` method found on the returned component instance',
57
'No `render` method found on the returned component instance',
58
- ])
58
+ ], {withoutStack: true})
59
undefined
60
61
it 'renders a simple stateless component with prop', ->
@@ -126,7 +126,7 @@ describe 'ReactCoffeeScriptClass', ->
126
{}
127
expect(->
128
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
129
- ).toWarnDev 'Foo: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.',
129
+ ).toWarnDev 'Foo: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.', {withoutStack: true}
130
undefined
131
132
it 'warns if getDerivedStateFromCatch is not static', ->
@@ -137,7 +137,7 @@ describe 'ReactCoffeeScriptClass', ->
137
{}
138
expect(->
139
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
140
- ).toWarnDev 'Foo: getDerivedStateFromCatch() is defined as an instance method and will be ignored. Instead, declare it as a static method.',
140
+ ).toWarnDev 'Foo: getDerivedStateFromCatch() is defined as an instance method and will be ignored. Instead, declare it as a static method.', {withoutStack: true}
141
undefined
142
143
it 'warns if getSnapshotBeforeUpdate is static', ->
@@ -148,7 +148,7 @@ describe 'ReactCoffeeScriptClass', ->
148
{}
149
expect(->
150
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
151
- ).toWarnDev 'Foo: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.',
151
+ ).toWarnDev 'Foo: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.', {withoutStack: true}
152
undefined
153
154
it 'warns if state not initialized before static getDerivedStateFromProps', ->
@@ -163,7 +163,7 @@ describe 'ReactCoffeeScriptClass', ->
163
}
164
expect(->
165
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
166
- ).toWarnDev 'Foo: Did not properly initialize state during construction. Expected state to be an object, but it was undefined.'
166
+ ).toWarnDev 'Foo: Did not properly initialize state during construction. Expected state to be an object, but it was undefined.', {withoutStack: true}
167
undefined
168
169
it 'updates initial state with values returned by static getDerivedStateFromProps', ->
@@ -262,7 +262,7 @@ describe 'ReactCoffeeScriptClass', ->
262
263
expect(->
264
test React.createElement(Foo), 'SPAN', ''
265
- ).toWarnDev('Foo.state: must be set to an object or null')
265
+ ).toWarnDev('Foo.state: must be set to an object or null', {withoutStack: true})
266
undefined
267
268
it 'should render with null in the initial state property', ->
@@ -408,7 +408,7 @@ describe 'ReactCoffeeScriptClass', ->
408
'getDefaultProps was defined on Foo, a plain JavaScript class.',
409
'propTypes was defined as an instance property on Foo.',
410
'contextTypes was defined as an instance property on Foo.',
411
- ])
411
+ ], {withoutStack: true})
412
expect(getInitialStateWasCalled).toBe false
413
expect(getDefaultPropsWasCalled).toBe false
414
undefined
@@ -444,7 +444,8 @@ describe 'ReactCoffeeScriptClass', ->
444
).toWarnDev(
445
'Warning: NamedComponent has a method called componentShouldUpdate().
446
Did you mean shouldComponentUpdate()? The name is phrased as a
447
- question because the function is expected to return a value.'
447
+ question because the function is expected to return a value.',
448
+ {withoutStack: true}
449
)
450
undefined
451
@@ -461,7 +462,8 @@ describe 'ReactCoffeeScriptClass', ->
462
test React.createElement(NamedComponent), 'SPAN', 'foo'
463
).toWarnDev(
464
'Warning: NamedComponent has a method called componentWillRecieveProps().
464
- Did you mean componentWillReceiveProps()?'
465
+ Did you mean componentWillReceiveProps()?',
466
+ {withoutStack: true}
467
)
468
undefined
469
@@ -478,7 +480,8 @@ describe 'ReactCoffeeScriptClass', ->
480
test React.createElement(NamedComponent), 'SPAN', 'foo'
481
).toWarnDev(
482
'Warning: NamedComponent has a method called UNSAFE_componentWillRecieveProps().
481
- Did you mean UNSAFE_componentWillReceiveProps()?'
483
+ Did you mean UNSAFE_componentWillReceiveProps()?',
484
+ {withoutStack: true}
485
)
486
undefined
487
@@ -488,12 +491,14 @@ describe 'ReactCoffeeScriptClass', ->
491
expect(->
492
expect(-> instance.replaceState {}).toThrow()
493
).toLowPriorityWarnDev(
491
- 'replaceState(...) is deprecated in plain JavaScript React classes'
494
+ 'replaceState(...) is deprecated in plain JavaScript React classes',
495
+ {withoutStack: true}
496
)
497
expect(->
498
expect(-> instance.isMounted()).toThrow()
499
).toLowPriorityWarnDev(
496
- 'isMounted(...) is deprecated in plain JavaScript React classes'
500
+ 'isMounted(...) is deprecated in plain JavaScript React classes',
501
+ {withoutStack: true}
502
)
503
undefined
504
packages/react/src/__tests__/ReactContextValidator-test.js
+12
-7
@@ -271,6 +271,7 @@ describe('ReactContextValidator', () => {
271
'Warning: ComponentA.childContextTypes is specified but there is no ' +
272
'getChildContext() method on the instance. You can either define ' +
273
'getChildContext() on ComponentA or remove childContextTypes from it.',
274
+ {withoutStack: true},
275
);
276
277
// Warnings should be deduped by component type
@@ -280,6 +281,7 @@ describe('ReactContextValidator', () => {
281
'Warning: ComponentB.childContextTypes is specified but there is no ' +
282
'getChildContext() method on the instance. You can either define ' +
283
'getChildContext() on ComponentB or remove childContextTypes from it.',
284
+ {withoutStack: true},
285
);
286
});
287
@@ -323,13 +325,16 @@ describe('ReactContextValidator', () => {
325
326
expect(() =>
327
ReactTestUtils.renderIntoDocument(<ParentContextProvider />),
326
- ).toWarnDev([
327
- 'Warning: MiddleMissingContext.childContextTypes is specified but there is no getChildContext() method on the ' +
328
- 'instance. You can either define getChildContext() on MiddleMissingContext or remove childContextTypes from ' +
329
- 'it.',
330
- 'Warning: Failed context type: The context `bar` is marked as required in `ChildContextConsumer`, but its ' +
331
- 'value is `undefined`.',
332
- ]);
328
+ ).toWarnDev(
329
+ [
330
+ 'Warning: MiddleMissingContext.childContextTypes is specified but there is no ' +
331
+ 'getChildContext() method on the instance. You can either define getChildContext() ' +
332
+ 'on MiddleMissingContext or remove childContextTypes from it.',
333
+ 'Warning: Failed context type: The context `bar` is marked as required ' +
334
+ 'in `ChildContextConsumer`, but its value is `undefined`.',
335
+ ],
336
+ {withoutStack: 1},
337
+ );
338
expect(childContext.bar).toBeUndefined();
339
expect(childContext.foo).toBe('FOO');
340
});
packages/react/src/__tests__/ReactES6Class-test.js
+29
-13
@@ -59,13 +59,16 @@ describe('ReactES6Class', () => {
59
class Foo extends React.Component {}
60
expect(() =>
61
expect(() => ReactDOM.render(<Foo />, container)).toThrow(),
62
- ).toWarnDev([
63
- // A failed component renders twice in DEV
64
- 'Warning: Foo(...): No `render` method found on the returned component ' +
65
- 'instance: you may have forgotten to define `render`.',
66
- 'Warning: Foo(...): No `render` method found on the returned component ' +
67
- 'instance: you may have forgotten to define `render`.',
68
- ]);
62
+ ).toWarnDev(
63
+ [
64
+ // A failed component renders twice in DEV
65
+ 'Warning: Foo(...): No `render` method found on the returned component ' +
66
+ 'instance: you may have forgotten to define `render`.',
67
+ 'Warning: Foo(...): No `render` method found on the returned component ' +
68
+ 'instance: you may have forgotten to define `render`.',
69
+ ],
70
+ {withoutStack: true},
71
+ );
72
});
73
74
it('renders a simple stateless component with prop', () => {
@@ -140,6 +143,7 @@ describe('ReactES6Class', () => {
143
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
144
'Foo: getDerivedStateFromProps() is defined as an instance method ' +
145
'and will be ignored. Instead, declare it as a static method.',
146
+ {withoutStack: true},
147
);
148
});
149
@@ -155,6 +159,7 @@ describe('ReactES6Class', () => {
159
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
160
'Foo: getDerivedStateFromCatch() is defined as an instance method ' +
161
'and will be ignored. Instead, declare it as a static method.',
162
+ {withoutStack: true},
163
);
164
});
165
@@ -168,6 +173,7 @@ describe('ReactES6Class', () => {
173
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
174
'Foo: getSnapshotBeforeUpdate() is defined as a static method ' +
175
'and will be ignored. Instead, declare it as an instance method.',
176
+ {withoutStack: true},
177
);
178
});
179
@@ -186,6 +192,7 @@ describe('ReactES6Class', () => {
192
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
193
'Foo: Did not properly initialize state during construction. ' +
194
'Expected state to be an object, but it was undefined.',
195
+ {withoutStack: true},
196
);
197
});
198
@@ -291,6 +298,7 @@ describe('ReactES6Class', () => {
298
}
299
expect(() => test(<Foo />, 'SPAN', '')).toWarnDev(
300
'Foo.state: must be set to an object or null',
301
+ {withoutStack: true},
302
);
303
});
304
});
@@ -440,12 +448,15 @@ describe('ReactES6Class', () => {
448
}
449
}
450
443
- expect(() => test(<Foo />, 'SPAN', 'foo')).toWarnDev([
444
- 'getInitialState was defined on Foo, a plain JavaScript class.',
445
- 'getDefaultProps was defined on Foo, a plain JavaScript class.',
446
- 'propTypes was defined as an instance property on Foo.',
447
- 'contextTypes was defined as an instance property on Foo.',
448
- ]);
451
+ expect(() => test(<Foo />, 'SPAN', 'foo')).toWarnDev(
452
+ [
453
+ 'getInitialState was defined on Foo, a plain JavaScript class.',
454
+ 'getDefaultProps was defined on Foo, a plain JavaScript class.',
455
+ 'propTypes was defined as an instance property on Foo.',
456
+ 'contextTypes was defined as an instance property on Foo.',
457
+ ],
458
+ {withoutStack: true},
459
+ );
460
expect(getInitialStateWasCalled).toBe(false);
461
expect(getDefaultPropsWasCalled).toBe(false);
462
});
@@ -478,6 +489,7 @@ describe('ReactES6Class', () => {
489
'NamedComponent has a method called componentShouldUpdate(). Did you ' +
490
'mean shouldComponentUpdate()? The name is phrased as a question ' +
491
'because the function is expected to return a value.',
492
+ {withoutStack: true},
493
);
494
});
495
@@ -495,6 +507,7 @@ describe('ReactES6Class', () => {
507
'Warning: ' +
508
'NamedComponent has a method called componentWillRecieveProps(). Did ' +
509
'you mean componentWillReceiveProps()?',
510
+ {withoutStack: true},
511
);
512
});
513
@@ -512,6 +525,7 @@ describe('ReactES6Class', () => {
525
'Warning: ' +
526
'NamedComponent has a method called UNSAFE_componentWillRecieveProps(). ' +
527
'Did you mean UNSAFE_componentWillReceiveProps()?',
528
+ {withoutStack: true},
529
);
530
});
531
@@ -521,11 +535,13 @@ describe('ReactES6Class', () => {
535
expect(() => instance.replaceState({})).toThrow(),
536
).toLowPriorityWarnDev(
537
'replaceState(...) is deprecated in plain JavaScript React classes',
538
+ {withoutStack: true},
539
);
540
expect(() =>
541
expect(() => instance.isMounted()).toThrow(),
542
).toLowPriorityWarnDev(
543
'isMounted(...) is deprecated in plain JavaScript React classes',
544
+ {withoutStack: true},
545
);
546
});
547
packages/react/src/__tests__/ReactElement-test.js
+3
@@ -80,6 +80,7 @@ describe('ReactElement', () => {
80
'in `undefined` being returned. If you need to access the same ' +
81
'value within the child component, you should pass it as a different ' +
82
'prop. (https://fb.me/react-special-props)',
83
+ {withoutStack: true},
84
);
85
});
86
@@ -90,6 +91,7 @@ describe('ReactElement', () => {
91
'in `undefined` being returned. If you need to access the same ' +
92
'value within the child component, you should pass it as a different ' +
93
'prop. (https://fb.me/react-special-props)',
94
+ {withoutStack: true},
95
);
96
});
97
@@ -114,6 +116,7 @@ describe('ReactElement', () => {
116
'in `undefined` being returned. If you need to access the same ' +
117
'value within the child component, you should pass it as a different ' +
118
'prop. (https://fb.me/react-special-props)',
119
+ {withoutStack: true},
120
);
121
});
122
packages/react/src/__tests__/ReactElementValidator-test.internal.js
+28
-21
@@ -235,27 +235,30 @@ describe('ReactElementValidator', () => {
235
React.createElement(true);
236
React.createElement({x: 17});
237
React.createElement({});
238
- }).toWarnDev([
239
- 'Warning: React.createElement: type is invalid -- expected a string ' +
240
- '(for built-in components) or a class/function (for composite ' +
241
- 'components) but got: undefined. You likely forgot to export your ' +
242
- "component from the file it's defined in, or you might have mixed up " +
243
- 'default and named imports.',
244
- 'Warning: React.createElement: type is invalid -- expected a string ' +
245
- '(for built-in components) or a class/function (for composite ' +
246
- 'components) but got: null.',
247
- 'Warning: React.createElement: type is invalid -- expected a string ' +
248
- '(for built-in components) or a class/function (for composite ' +
249
- 'components) but got: boolean.',
250
- 'Warning: React.createElement: type is invalid -- expected a string ' +
251
- '(for built-in components) or a class/function (for composite ' +
252
- 'components) but got: object.',
253
- 'Warning: React.createElement: type is invalid -- expected a string ' +
254
- '(for built-in components) or a class/function (for composite ' +
255
- 'components) but got: object. You likely forgot to export your ' +
256
- "component from the file it's defined in, or you might have mixed up " +
257
- 'default and named imports.',
258
- ]);
238
+ }).toWarnDev(
239
+ [
240
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
241
+ '(for built-in components) or a class/function (for composite ' +
242
+ 'components) but got: undefined. You likely forgot to export your ' +
243
+ "component from the file it's defined in, or you might have mixed up " +
244
+ 'default and named imports.',
245
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
246
+ '(for built-in components) or a class/function (for composite ' +
247
+ 'components) but got: null.',
248
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
249
+ '(for built-in components) or a class/function (for composite ' +
250
+ 'components) but got: boolean.',
251
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
252
+ '(for built-in components) or a class/function (for composite ' +
253
+ 'components) but got: object.',
254
+ 'Warning: React.createElement: type is invalid -- expected a string ' +
255
+ '(for built-in components) or a class/function (for composite ' +
256
+ 'components) but got: object. You likely forgot to export your ' +
257
+ "component from the file it's defined in, or you might have mixed up " +
258
+ 'default and named imports.',
259
+ ],
260
+ {withoutStack: true},
261
+ );
262
263
// Should not log any additional warnings
264
React.createElement('div');
@@ -372,6 +375,7 @@ describe('ReactElementValidator', () => {
375
'returned a function. You may have forgotten to pass an argument to ' +
376
'the type checker creator (arrayOf, instanceOf, objectOf, oneOf, ' +
377
'oneOfType, and shape all require an argument).',
378
+ {withoutStack: true},
379
);
380
});
381
@@ -392,6 +396,7 @@ describe('ReactElementValidator', () => {
396
}).toWarnDev(
397
'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
398
'instead of `propTypes`. Did you misspell the property assignment?',
399
+ {withoutStack: true},
400
);
401
});
402
@@ -404,6 +409,7 @@ describe('ReactElementValidator', () => {
409
expect(() => TestFactory.type).toLowPriorityWarnDev(
410
'Warning: Factory.type is deprecated. Access the class directly before ' +
411
'passing it to createFactory.',
412
+ {withoutStack: true},
413
);
414
415
// Warn once, not again
@@ -471,6 +477,7 @@ describe('ReactElementValidator', () => {
477
'components) but got: undefined. You likely forgot to export your ' +
478
"component from the file it's defined in, or you might have mixed up " +
479
'default and named imports.\n\nCheck your code at **.',
480
+ {withoutStack: true},
481
);
482
});
483
});
packages/react/src/__tests__/ReactJSXElementValidator-test.js
+8
-1
@@ -221,18 +221,21 @@ describe('ReactJSXElementValidator', () => {
221
"component from the file it's defined in, or you might have mixed up " +
222
'default and named imports.' +
223
'\n\nCheck your code at **.',
224
+ {withoutStack: true},
225
);
226
expect(() => void <Null />).toWarnDev(
227
'Warning: React.createElement: type is invalid -- expected a string ' +
228
'(for built-in components) or a class/function (for composite ' +
229
'components) but got: null.' +
230
'\n\nCheck your code at **.',
231
+ {withoutStack: true},
232
);
233
expect(() => void <True />).toWarnDev(
234
'Warning: React.createElement: type is invalid -- expected a string ' +
235
'(for built-in components) or a class/function (for composite ' +
236
'components) but got: boolean.' +
237
'\n\nCheck your code at **.',
238
+ {withoutStack: true},
239
);
240
// No error expected
241
void <Div />;
@@ -334,6 +337,7 @@ describe('ReactJSXElementValidator', () => {
337
).toWarnDev(
338
'getDefaultProps is only used on classic React.createClass definitions.' +
339
' Use a static property named `defaultProps` instead.',
340
+ {withoutStack: true},
341
);
342
});
343
@@ -353,6 +357,7 @@ describe('ReactJSXElementValidator', () => {
357
).toWarnDev(
358
'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
359
'instead of `propTypes`. Did you misspell the property assignment?',
360
+ {withoutStack: true},
361
);
362
});
363
@@ -406,6 +411,8 @@ describe('ReactJSXElementValidator', () => {
411
<span key="b">3</span>
412
</React.Fragment>,
413
),
409
- ).toWarnDev('Encountered two children with the same key, `a`.');
414
+ ).toWarnDev('Encountered two children with the same key, `a`.', {
415
+ withoutStack: true,
416
+ });
417
});
418
});
packages/react/src/__tests__/ReactPureComponent-test.js
+2
@@ -79,6 +79,7 @@ describe('ReactPureComponent', () => {
79
'Component has a method called shouldComponentUpdate(). ' +
80
'shouldComponentUpdate should not be used when extending React.PureComponent. ' +
81
'Please extend React.Component if shouldComponentUpdate is used.',
82
+ {withoutStack: true},
83
);
84
ReactDOM.render(<Component />, container);
85
expect(renders).toBe(2);
@@ -113,6 +114,7 @@ describe('ReactPureComponent', () => {
114
'PureComponent has a method called shouldComponentUpdate(). ' +
115
'shouldComponentUpdate should not be used when extending React.PureComponent. ' +
116
'Please extend React.Component if shouldComponentUpdate is used.',
117
+ {withoutStack: true},
118
);
119
});
120
});
packages/react/src/__tests__/ReactTypeScriptClass-test.ts
+26
-14
@@ -331,7 +331,7 @@ describe('ReactTypeScriptClass', function() {
331
'component instance: you may have forgotten to define `render`.',
332
'Warning: Empty(...): No `render` method found on the returned ' +
333
'component instance: you may have forgotten to define `render`.',
334
- ]);
334
+ ], {withoutStack: true});
335
});
336
337
it('renders a simple stateless component with prop', function() {
@@ -391,7 +391,8 @@ describe('ReactTypeScriptClass', function() {
391
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
392
}).toWarnDev(
393
'Foo: getDerivedStateFromProps() is defined as an instance method ' +
394
- 'and will be ignored. Instead, declare it as a static method.'
394
+ 'and will be ignored. Instead, declare it as a static method.',
395
+ {withoutStack: true}
396
);
397
});
398
@@ -408,7 +409,8 @@ describe('ReactTypeScriptClass', function() {
409
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
410
}).toWarnDev(
411
'Foo: getDerivedStateFromCatch() is defined as an instance method ' +
411
- 'and will be ignored. Instead, declare it as a static method.'
412
+ 'and will be ignored. Instead, declare it as a static method.',
413
+ {withoutStack: true}
414
);
415
});
416
@@ -424,7 +426,8 @@ describe('ReactTypeScriptClass', function() {
426
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
427
}).toWarnDev(
428
'Foo: getSnapshotBeforeUpdate() is defined as a static method ' +
427
- 'and will be ignored. Instead, declare it as an instance method.'
429
+ 'and will be ignored. Instead, declare it as an instance method.',
430
+ {withoutStack: true}
431
);
432
});
433
@@ -446,7 +449,8 @@ describe('ReactTypeScriptClass', function() {
449
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
450
}).toWarnDev(
451
'Foo: Did not properly initialize state during construction. ' +
449
- 'Expected state to be an object, but it was undefined.'
452
+ 'Expected state to be an object, but it was undefined.',
453
+ {withoutStack: true}
454
);
455
});
456
@@ -503,13 +507,16 @@ describe('ReactTypeScriptClass', function() {
507
508
it('should warn with non-object in the initial state property', function() {
509
expect(() => test(React.createElement(ArrayState), 'SPAN', '')).toWarnDev(
506
- 'ArrayState.state: must be set to an object or null'
510
+ 'ArrayState.state: must be set to an object or null',
511
+ {withoutStack: true}
512
);
513
expect(() => test(React.createElement(StringState), 'SPAN', '')).toWarnDev(
509
- 'StringState.state: must be set to an object or null'
514
+ 'StringState.state: must be set to an object or null',
515
+ {withoutStack: true}
516
);
517
expect(() => test(React.createElement(NumberState), 'SPAN', '')).toWarnDev(
512
- 'NumberState.state: must be set to an object or null'
518
+ 'NumberState.state: must be set to an object or null',
519
+ {withoutStack: true}
520
);
521
});
522
@@ -585,7 +592,7 @@ describe('ReactTypeScriptClass', function() {
592
'a plain JavaScript class.',
593
'propTypes was defined as an instance property on ClassicProperties.',
594
'contextTypes was defined as an instance property on ClassicProperties.',
588
- ]);
595
+ ], {withoutStack: true});
596
expect(getInitialStateWasCalled).toBe(false);
597
expect(getDefaultPropsWasCalled).toBe(false);
598
}
@@ -616,7 +623,8 @@ describe('ReactTypeScriptClass', function() {
623
'Warning: ' +
624
'MisspelledComponent1 has a method called componentShouldUpdate(). Did ' +
625
'you mean shouldComponentUpdate()? The name is phrased as a question ' +
619
- 'because the function is expected to return a value.'
626
+ 'because the function is expected to return a value.',
627
+ {withoutStack: true}
628
);
629
});
630
@@ -626,7 +634,8 @@ describe('ReactTypeScriptClass', function() {
634
).toWarnDev(
635
'Warning: ' +
636
'MisspelledComponent2 has a method called componentWillRecieveProps(). ' +
629
- 'Did you mean componentWillReceiveProps()?'
637
+ 'Did you mean componentWillReceiveProps()?',
638
+ {withoutStack: true}
639
);
640
});
641
@@ -636,7 +645,8 @@ describe('ReactTypeScriptClass', function() {
645
).toWarnDev(
646
'Warning: ' +
647
'MisspelledComponent3 has a method called UNSAFE_componentWillRecieveProps(). ' +
639
- 'Did you mean UNSAFE_componentWillReceiveProps()?'
648
+ 'Did you mean UNSAFE_componentWillReceiveProps()?',
649
+ {withoutStack: true}
650
);
651
});
652
@@ -649,12 +659,14 @@ describe('ReactTypeScriptClass', function() {
659
expect(() =>
660
expect(() => instance.replaceState({})).toThrow()
661
).toLowPriorityWarnDev(
652
- 'replaceState(...) is deprecated in plain JavaScript React classes'
662
+ 'replaceState(...) is deprecated in plain JavaScript React classes',
663
+ {withoutStack: true}
664
);
665
expect(() =>
666
expect(() => instance.isMounted()).toThrow()
667
).toLowPriorityWarnDev(
657
- 'isMounted(...) is deprecated in plain JavaScript React classes'
668
+ 'isMounted(...) is deprecated in plain JavaScript React classes',
669
+ {withoutStack: true}
670
);
671
});
672
packages/react/src/__tests__/createReactClassIntegration-test.internal.js
+3
@@ -91,6 +91,7 @@ describe('create-react-class-integration', () => {
91
'Warning: MyComponent: isMounted is deprecated. Instead, make sure to ' +
92
'clean up subscriptions and pending requests in componentWillUnmount ' +
93
'to prevent memory leaks.',
94
+ {withoutStack: true},
95
);
96
97
// Dedupe
@@ -149,6 +150,7 @@ describe('create-react-class-integration', () => {
150
'Use componentDidMount instead. As a temporary workaround, ' +
151
'you can rename to UNSAFE_componentWillMount.' +
152
'\n\nPlease update the following components: MyNativeComponent',
153
+ {withoutStack: true},
154
);
155
});
156
@@ -164,6 +166,7 @@ describe('create-react-class-integration', () => {
166
'componentWillReceiveProps is deprecated and will be removed in the next major version. ' +
167
'Use static getDerivedStateFromProps instead.' +
168
'\n\nPlease update the following components: MyNativeComponent',
169
+ {withoutStack: true},
170
);
171
});
172
});
packages/react/src/__tests__/createReactClassIntegration-test.js
+16
-1
@@ -66,6 +66,7 @@ describe('create-react-class-integration', () => {
66
).toWarnDev(
67
'Warning: Component: prop type `prop` is invalid; ' +
68
'it must be a function, usually from React.PropTypes.',
69
+ {withoutStack: true},
70
);
71
});
72
@@ -83,6 +84,7 @@ describe('create-react-class-integration', () => {
84
).toWarnDev(
85
'Warning: Component: context type `prop` is invalid; ' +
86
'it must be a function, usually from React.PropTypes.',
87
+ {withoutStack: true},
88
);
89
});
90
@@ -100,6 +102,7 @@ describe('create-react-class-integration', () => {
102
).toWarnDev(
103
'Warning: Component: child context type `prop` is invalid; ' +
104
'it must be a function, usually from React.PropTypes.',
105
+ {withoutStack: true},
106
);
107
});
108
@@ -117,6 +120,7 @@ describe('create-react-class-integration', () => {
120
'Warning: A component has a method called componentShouldUpdate(). Did you ' +
121
'mean shouldComponentUpdate()? The name is phrased as a question ' +
122
'because the function is expected to return a value.',
123
+ {withoutStack: true},
124
);
125
126
expect(() =>
@@ -133,6 +137,7 @@ describe('create-react-class-integration', () => {
137
'Warning: NamedComponent has a method called componentShouldUpdate(). Did you ' +
138
'mean shouldComponentUpdate()? The name is phrased as a question ' +
139
'because the function is expected to return a value.',
140
+ {withoutStack: true},
141
);
142
});
143
@@ -149,6 +154,7 @@ describe('create-react-class-integration', () => {
154
).toWarnDev(
155
'Warning: A component has a method called componentWillRecieveProps(). Did you ' +
156
'mean componentWillReceiveProps()?',
157
+ {withoutStack: true},
158
);
159
});
160
@@ -165,6 +171,7 @@ describe('create-react-class-integration', () => {
171
).toWarnDev(
172
'Warning: A component has a method called UNSAFE_componentWillRecieveProps(). ' +
173
'Did you mean UNSAFE_componentWillReceiveProps()?',
174
+ {withoutStack: true},
175
);
176
});
177
@@ -357,6 +364,7 @@ describe('create-react-class-integration', () => {
364
expect(() => expect(() => Component()).toThrow()).toWarnDev(
365
'Warning: Something is calling a React component directly. Use a ' +
366
'factory or JSX instead. See: https://fb.me/react-legacyfactory',
367
+ {withoutStack: true},
368
);
369
});
370
@@ -447,6 +455,7 @@ describe('create-react-class-integration', () => {
455
).toWarnDev(
456
'Component: getDerivedStateFromProps() is defined as an instance method ' +
457
'and will be ignored. Instead, declare it as a static method.',
458
+ {withoutStack: true},
459
);
460
});
461
@@ -464,6 +473,7 @@ describe('create-react-class-integration', () => {
473
).toWarnDev(
474
'Component: getDerivedStateFromCatch() is defined as an instance method ' +
475
'and will be ignored. Instead, declare it as a static method.',
476
+ {withoutStack: true},
477
);
478
});
479
@@ -483,6 +493,7 @@ describe('create-react-class-integration', () => {
493
).toWarnDev(
494
'Component: getSnapshotBeforeUpdate() is defined as a static method ' +
495
'and will be ignored. Instead, declare it as an instance method.',
496
+ {withoutStack: true},
497
);
498
});
499
@@ -499,7 +510,9 @@ describe('create-react-class-integration', () => {
510
});
511
expect(() =>
512
ReactDOM.render(<Component />, document.createElement('div')),
502
- ).toWarnDev('Did not properly initialize state during construction.');
513
+ ).toWarnDev('Did not properly initialize state during construction.', {
514
+ withoutStack: true,
515
+ });
516
});
517
518
it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {
@@ -536,6 +549,7 @@ describe('create-react-class-integration', () => {
549
' componentWillUpdate\n\n' +
550
'The above lifecycles should be removed. Learn more about this warning here:\n' +
551
'https://fb.me/react-async-component-lifecycle-hooks',
552
+ {withoutStack: true},
553
);
554
ReactDOM.render(<Component foo={1} />, document.createElement('div'));
555
});
@@ -570,6 +584,7 @@ describe('create-react-class-integration', () => {
584
' componentWillUpdate\n\n' +
585
'The above lifecycles should be removed. Learn more about this warning here:\n' +
586
'https://fb.me/react-async-component-lifecycle-hooks',
587
+ {withoutStack: true},
588
);
589
ReactDOM.render(<Component foo={1} />, document.createElement('div'));
590
});
packages/react/src/__tests__/forwardRef-test.js
+8
@@ -120,18 +120,22 @@ describe('forwardRef', () => {
120
it('should warn if not provided a callback during creation', () => {
121
expect(() => React.forwardRef(undefined)).toWarnDev(
122
'forwardRef requires a render function but was given undefined.',
123
+ {withoutStack: true},
124
);
125
expect(() => React.forwardRef(null)).toWarnDev(
126
'forwardRef requires a render function but was given null.',
127
+ {withoutStack: true},
128
);
129
expect(() => React.forwardRef('foo')).toWarnDev(
130
'forwardRef requires a render function but was given string.',
131
+ {withoutStack: true},
132
);
133
});
134
135
it('should warn if no render function is provided', () => {
136
expect(React.forwardRef).toWarnDev(
137
'forwardRef requires a render function but was given undefined.',
138
+ {withoutStack: true},
139
);
140
});
141
@@ -149,10 +153,12 @@ describe('forwardRef', () => {
153
expect(() => React.forwardRef(renderWithPropTypes)).toWarnDev(
154
'forwardRef render functions do not support propTypes or defaultProps. ' +
155
'Did you accidentally pass a React component?',
156
+ {withoutStack: true},
157
);
158
expect(() => React.forwardRef(renderWithDefaultProps)).toWarnDev(
159
'forwardRef render functions do not support propTypes or defaultProps. ' +
160
'Did you accidentally pass a React component?',
161
+ {withoutStack: true},
162
);
163
});
164
@@ -166,11 +172,13 @@ describe('forwardRef', () => {
172
expect(() => React.forwardRef(arityOfZero)).toWarnDev(
173
'forwardRef render functions accept two parameters: props and ref. ' +
174
'Did you forget to use the ref parameter?',
175
+ {withoutStack: true},
176
);
177
178
expect(() => React.forwardRef(arityOfOne)).toWarnDev(
179
'forwardRef render functions accept two parameters: props and ref. ' +
180
'Did you forget to use the ref parameter?',
181
+ {withoutStack: true},
182
);
183
});
184
});
packages/shared/__tests__/ReactDOMFrameScheduling-test.js
+1
@@ -17,6 +17,7 @@ describe('ReactDOMFrameScheduling', () => {
17
jest.resetModules();
18
expect(() => require('react-dom')).toWarnDev(
19
"This browser doesn't support requestAnimationFrame.",
20
+ {withoutStack: true},
21
);
22
} finally {
23
global.requestAnimationFrame = previousRAF;
packages/simple-cache-provider/src/__tests__/SimpleCacheProvider-test.js
+20
-14
@@ -149,14 +149,17 @@ describe('SimpleCacheProvider', () => {
149
}
150
151
if (__DEV__) {
152
- expect(fn).toWarnDev([
153
- 'Invalid resourceType: Expected a symbol, object, or function, but ' +
154
- 'instead received: foo. Strings and numbers are not permitted as ' +
155
- 'resource types.',
156
- 'Invalid resourceType: Expected a symbol, object, or function, but ' +
157
- 'instead received: 123. Strings and numbers are not permitted as ' +
158
- 'resource types.',
159
- ]);
152
+ expect(fn).toWarnDev(
153
+ [
154
+ 'Invalid resourceType: Expected a symbol, object, or function, but ' +
155
+ 'instead received: foo. Strings and numbers are not permitted as ' +
156
+ 'resource types.',
157
+ 'Invalid resourceType: Expected a symbol, object, or function, but ' +
158
+ 'instead received: 123. Strings and numbers are not permitted as ' +
159
+ 'resource types.',
160
+ ],
161
+ {withoutStack: true},
162
+ );
163
} else {
164
fn();
165
}
@@ -179,12 +182,15 @@ describe('SimpleCacheProvider', () => {
182
}
183
184
if (__DEV__) {
182
- expect(fn).toWarnDev([
183
- 'preload: Invalid key type. Expected a string, number, symbol, or ' +
184
- 'boolean, but instead received: 5,5\n\n' +
185
- 'To use non-primitive values as keys, you must pass a hash ' +
186
- 'function as the second argument to createResource().',
187
- ]);
185
+ expect(fn).toWarnDev(
186
+ [
187
+ 'preload: Invalid key type. Expected a string, number, symbol, or ' +
188
+ 'boolean, but instead received: 5,5\n\n' +
189
+ 'To use non-primitive values as keys, you must pass a hash ' +
190
+ 'function as the second argument to createResource().',
191
+ ],
192
+ {withoutStack: true},
193
+ );
194
} else {
195
fn();
196
}
scripts/jest/matchers/__tests__/toWarnDev-test.js
new
+137
@@ -0,0 +1,137 @@
1
+/**
2
+ * Copyright (c) 2013-present, Facebook, Inc.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @emails react-core
8
+ */
9
+
10
+'use strict';
11
+
12
+describe('toWarnDev', () => {
13
+ it('does not fail if a warning contains a stack', () => {
14
+ expect(() => {
15
+ console.error('Hello\n in div');
16
+ }).toWarnDev('Hello');
17
+ });
18
+
19
+ it('does not fail if all warnings contain a stack', () => {
20
+ expect(() => {
21
+ console.error('Hello\n in div');
22
+ console.error('Good day\n in div');
23
+ console.error('Bye\n in div');
24
+ }).toWarnDev(['Hello', 'Good day', 'Bye']);
25
+ });
26
+
27
+ it('does not fail if warnings without stack explicitly opt out', () => {
28
+ expect(() => {
29
+ console.error('Hello');
30
+ }).toWarnDev('Hello', {withoutStack: true});
31
+ expect(() => {
32
+ console.error('Hello');
33
+ console.error('Good day');
34
+ console.error('Bye');
35
+ }).toWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: true});
36
+ });
37
+
38
+ it('does not fail when expected stack-less warning number matches the actual one', () => {
39
+ expect(() => {
40
+ console.error('Hello\n in div');
41
+ console.error('Good day');
42
+ console.error('Bye\n in div');
43
+ }).toWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: 1});
44
+ });
45
+
46
+ it('fails if a warning does not contain a stack', () => {
47
+ expect(() => {
48
+ expect(() => {
49
+ console.error('Hello');
50
+ }).toWarnDev('Hello');
51
+ }).toThrow(
52
+ 'Received warning unexpectedly does not include a component stack'
53
+ );
54
+ });
55
+
56
+ it('fails if some warnings do not contain a stack', () => {
57
+ expect(() => {
58
+ expect(() => {
59
+ console.error('Hello\n in div');
60
+ console.error('Good day\n in div');
61
+ console.error('Bye');
62
+ }).toWarnDev(['Hello', 'Good day', 'Bye']);
63
+ }).toThrow(
64
+ 'Received warning unexpectedly does not include a component stack'
65
+ );
66
+ expect(() => {
67
+ expect(() => {
68
+ console.error('Hello');
69
+ console.error('Good day\n in div');
70
+ console.error('Bye\n in div');
71
+ }).toWarnDev(['Hello', 'Good day', 'Bye']);
72
+ }).toThrow(
73
+ 'Received warning unexpectedly does not include a component stack'
74
+ );
75
+ expect(() => {
76
+ expect(() => {
77
+ console.error('Hello\n in div');
78
+ console.error('Good day');
79
+ console.error('Bye\n in div');
80
+ }).toWarnDev(['Hello', 'Good day', 'Bye']);
81
+ }).toThrow(
82
+ 'Received warning unexpectedly does not include a component stack'
83
+ );
84
+ expect(() => {
85
+ expect(() => {
86
+ console.error('Hello');
87
+ console.error('Good day');
88
+ console.error('Bye');
89
+ }).toWarnDev(['Hello', 'Good day', 'Bye']);
90
+ }).toThrow(
91
+ 'Received warning unexpectedly does not include a component stack'
92
+ );
93
+ });
94
+
95
+ it('fails if warning is expected to not have a stack, but does', () => {
96
+ expect(() => {
97
+ expect(() => {
98
+ console.error('Hello\n in div');
99
+ }).toWarnDev('Hello', {withoutStack: true});
100
+ }).toThrow('Received warning unexpectedly includes a component stack');
101
+ expect(() => {
102
+ expect(() => {
103
+ console.error('Hello\n in div');
104
+ console.error('Good day');
105
+ console.error('Bye\n in div');
106
+ }).toWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: true});
107
+ }).toThrow('Received warning unexpectedly includes a component stack');
108
+ });
109
+
110
+ it('fails if expected stack-less warning number does not match the actual one', () => {
111
+ expect(() => {
112
+ expect(() => {
113
+ console.error('Hello\n in div');
114
+ console.error('Good day');
115
+ console.error('Bye\n in div');
116
+ }).toWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: 4});
117
+ }).toThrow('Expected 4 warnings without a component stack but received 1');
118
+ });
119
+
120
+ it('fails if withoutStack is invalid', () => {
121
+ expect(() => {
122
+ expect(() => {
123
+ console.error('Hi');
124
+ }).toWarnDev('Hi', {withoutStack: null});
125
+ }).toThrow('Instead received object');
126
+ expect(() => {
127
+ expect(() => {
128
+ console.error('Hi');
129
+ }).toWarnDev('Hi', {withoutStack: {}});
130
+ }).toThrow('Instead received object');
131
+ expect(() => {
132
+ expect(() => {
133
+ console.error('Hi');
134
+ }).toWarnDev('Hi', {withoutStack: 'haha'});
135
+ }).toThrow('Instead received string');
136
+ });
137
+});
scripts/jest/matchers/toWarnDev.js
+58
-1
@@ -7,7 +7,7 @@ function normalizeCodeLocInfo(str) {
7
}
8
9
const createMatcherFor = consoleMethod =>
10
- function matcher(callback, expectedMessages) {
10
+ function matcher(callback, expectedMessages, options = {}) {
11
if (__DEV__) {
12
// Warn about incorrect usage of matcher.
13
if (typeof expectedMessages === 'string') {
@@ -19,6 +19,9 @@ const createMatcherFor = consoleMethod =>
19
);
20
}
21
22
+ const withoutStack = options.withoutStack;
23
+ const warningsWithoutComponentStack = [];
24
+ const warningsWithComponentStack = [];
25
const unexpectedWarnings = [];
26
27
// Catch errors thrown by the callback,
@@ -36,6 +39,11 @@ const createMatcherFor = consoleMethod =>
39
normalizedMessage === expectedMessage ||
40
normalizedMessage.includes(expectedMessage)
41
) {
42
+ if (normalizedMessage.includes('\n in ')) {
43
+ warningsWithComponentStack.push(normalizedMessage);
44
+ } else {
45
+ warningsWithoutComponentStack.push(normalizedMessage);
46
+ }
47
expectedMessages.splice(index, 1);
48
return;
49
}
@@ -103,6 +111,55 @@ const createMatcherFor = consoleMethod =>
111
};
112
}
113
114
+ if (typeof withoutStack === 'number') {
115
+ // We're expecting a particular number of warnings without stacks.
116
+ if (withoutStack !== warningsWithoutComponentStack.length) {
117
+ return {
118
+ message: () =>
119
+ `Expected ${withoutStack} warnings without a component stack but received ${
120
+ warningsWithoutComponentStack.length
121
+ }:\n` +
122
+ warningsWithoutComponentStack.map(warning =>
123
+ this.utils.printReceived(warning)
124
+ ),
125
+ pass: false,
126
+ };
127
+ }
128
+ } else if (withoutStack === true) {
129
+ // We're expecting that all warnings won't have the stack.
130
+ // If some warnings have it, it's an error.
131
+ if (warningsWithComponentStack.length > 0) {
132
+ return {
133
+ message: () =>
134
+ `Received warning unexpectedly includes a component stack:\n ${this.utils.printReceived(
135
+ warningsWithComponentStack[0]
136
+ )}\nIf this warning intentionally includes the component stack, remove ` +
137
+ `{withoutStack: true} from the toWarnDev() call. If you have a mix of ` +
138
+ `warnings with and without stack in one toWarnDev() call, pass ` +
139
+ `{withoutStack: N} where N is the number of warnings without stacks.`,
140
+ pass: false,
141
+ };
142
+ }
143
+ } else if (withoutStack === false || withoutStack === undefined) {
144
+ // We're expecting that all warnings *do* have the stack (default).
145
+ // If some warnings don't have it, it's an error.
146
+ if (warningsWithoutComponentStack.length > 0) {
147
+ return {
148
+ message: () =>
149
+ `Received warning unexpectedly does not include a component stack:\n ${this.utils.printReceived(
150
+ warningsWithoutComponentStack[0]
151
+ )}\nIf this warning intentionally omits the component stack, add ` +
152
+ `{withoutStack: true} to the toWarnDev() call.`,
153
+ pass: false,
154
+ };
155
+ }
156
+ } else {
157
+ throw Error(
158
+ `The second argument for toWarnDev(), when specified, must be an object. It may have a ` +
159
+ `property called "withoutStack" whose value may be undefined, boolean, or a number. ` +
160
+ `Instead received ${typeof withoutStack}.`
161
+ );
162
+ }
163
return {pass: true};
164
}
165
} else {
scripts/jest/typescript/jest.d.ts
+2
-2
@@ -21,8 +21,8 @@ interface Expect {
21
not: Expect
22
toThrow(message?: string): void
23
toThrowError(message?: string): void
24
- toWarnDev(message?: string | Array<string>): void
25
- toLowPriorityWarnDev(message?: string | Array<string>): void
24
+ toWarnDev(message?: string | Array<string>, options?: any): void
25
+ toLowPriorityWarnDev(message?: string | Array<string>, options?: any): void
26
toBe(value: any): void
27
toEqual(value: any): void
28
toBeFalsy(): void