Give useful error when using two copies of React
If we don't error here, we end up with a confusing error later on in this.getDOMNode() where ReactMount doesn't have the proper container registered in its object.
Ben Alpert committed
May 14, 2014 at 19:12 UTC
70bf3e1306395a2bd1e65bce60b5511875b00800
3 files changed
+668
-619
src/browser/ui/ReactMount.js
+17
-1
@@ -19,8 +19,9 @@
19
"use strict";
20
21
var DOMProperty = require('DOMProperty');
22
-var ReactCurrentOwner = require('ReactCurrentOwner');
22
var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
23
+var ReactCurrentOwner = require('ReactCurrentOwner');
24
+var ReactDescriptor = require('ReactDescriptor');
25
var ReactInstanceHandles = require('ReactInstanceHandles');
26
var ReactPerf = require('ReactPerf');
27
@@ -335,6 +336,21 @@ var ReactMount = {
336
* @return {ReactComponent} Component instance rendered in `container`.
337
*/
338
renderComponent: function(nextDescriptor, container, callback) {
339
+ invariant(
340
+ ReactDescriptor.isValidDescriptor(nextDescriptor),
341
+ 'renderComponent(): Invalid component descriptor.%s',
342
+ (
343
+ ReactDescriptor.isValidFactory(nextDescriptor) ?
344
+ ' Instead of passing a component class, make sure to instantiate ' +
345
+ 'it first by calling it with props.' :
346
+ // Check if it quacks like a descriptor
347
+ typeof nextDescriptor.props !== "undefined" ?
348
+ ' This may be caused by unintentionally loading two independent ' +
349
+ 'copies of React.' :
350
+ ''
351
+ )
352
+ );
353
+
354
var prevComponent = instancesByReactRootID[getReactRootID(container)];
355
356
if (prevComponent) {
src/browser/ui/__tests__/ReactMount-test.js
+24
@@ -24,6 +24,7 @@ var mocks = require('mocks');
24
describe('ReactMount', function() {
25
var React = require('React');
26
var ReactMount = require('ReactMount');
27
+ var ReactTestUtils = require('ReactTestUtils');
28
29
describe('constructAndRenderComponentByID', function() {
30
it('throws if given an id for a component that doesn\'t exist', function() {
@@ -37,6 +38,29 @@ describe('ReactMount', function() {
38
});
39
});
40
41
+ it('throws when given a factory', function() {
42
+ expect(function() {
43
+ ReactTestUtils.renderIntoDocument(React.DOM.div);
44
+ }).toThrow(
45
+ 'Invariant Violation: renderComponent(): Invalid component descriptor. ' +
46
+ 'Instead of passing a component class, make sure to instantiate it ' +
47
+ 'first by calling it with props.'
48
+ );
49
+
50
+ var Component = React.createClass({
51
+ render: function() {
52
+ return <div />;
53
+ }
54
+ });
55
+ expect(function() {
56
+ ReactTestUtils.renderIntoDocument(Component);
57
+ }).toThrow(
58
+ 'Invariant Violation: renderComponent(): Invalid component descriptor. ' +
59
+ 'Instead of passing a component class, make sure to instantiate it ' +
60
+ 'first by calling it with props.'
61
+ );
62
+ });
63
+
64
it('should render different components in same root', function() {
65
var container = document.createElement('container');
66
document.documentElement.appendChild(container);
src/core/__tests__/ReactPropTypes-test.js
+627
-618
@@ -19,12 +19,11 @@
19
20
"use strict";
21
22
+var PropTypes;
23
+var React;
24
+var ReactPropTypeLocations;
25
var ReactTestUtils;
26
24
-var PropTypes = require('ReactPropTypes');
25
-var React = require('React');
26
-var ReactPropTypeLocations = require('ReactPropTypeLocations');
27
-
27
var Component;
28
var MyComponent;
29
var requiredMessage =
@@ -53,713 +52,701 @@ function typeCheckPass(declaration, value) {
52
expect(error).toBe(undefined);
53
}
54
56
-describe('Primitive Types', function() {
57
- it("should warn for invalid strings", function() {
58
- typeCheckFail(
59
- PropTypes.string,
60
- [],
61
- 'Invalid prop `testProp` of type `array` supplied to `testComponent`, ' +
62
- 'expected `string`.'
63
- );
64
- typeCheckFail(
65
- PropTypes.string,
66
- false,
67
- 'Invalid prop `testProp` of type `boolean` supplied to ' +
68
- '`testComponent`, expected `string`.'
69
- );
70
- typeCheckFail(
71
- PropTypes.string,
72
- 0,
73
- 'Invalid prop `testProp` of type `number` supplied to ' +
74
- '`testComponent`, expected `string`.'
75
- );
76
- typeCheckFail(
77
- PropTypes.string,
78
- {},
79
- 'Invalid prop `testProp` of type `object` supplied to ' +
80
- '`testComponent`, expected `string`.'
81
- );
55
+describe('ReactPropTypes', function() {
56
+ beforeEach(function() {
57
+ PropTypes = require('ReactPropTypes');
58
+ React = require('React');
59
+ ReactPropTypeLocations = require('ReactPropTypeLocations');
60
+ ReactTestUtils = require('ReactTestUtils');
61
});
62
84
- it('should fail date and regexp correctly', function() {
85
- typeCheckFail(
86
- PropTypes.string,
87
- new Date(),
88
- 'Invalid prop `testProp` of type `date` supplied to ' +
89
- '`testComponent`, expected `string`.'
90
- );
91
- typeCheckFail(
92
- PropTypes.string,
93
- /please/,
94
- 'Invalid prop `testProp` of type `regexp` supplied to ' +
95
- '`testComponent`, expected `string`.'
96
- );
97
- });
63
+ describe('Primitive Types', function() {
64
+ it("should warn for invalid strings", function() {
65
+ typeCheckFail(
66
+ PropTypes.string,
67
+ [],
68
+ 'Invalid prop `testProp` of type `array` supplied to ' +
69
+ '`testComponent`, expected `string`.'
70
+ );
71
+ typeCheckFail(
72
+ PropTypes.string,
73
+ false,
74
+ 'Invalid prop `testProp` of type `boolean` supplied to ' +
75
+ '`testComponent`, expected `string`.'
76
+ );
77
+ typeCheckFail(
78
+ PropTypes.string,
79
+ 0,
80
+ 'Invalid prop `testProp` of type `number` supplied to ' +
81
+ '`testComponent`, expected `string`.'
82
+ );
83
+ typeCheckFail(
84
+ PropTypes.string,
85
+ {},
86
+ 'Invalid prop `testProp` of type `object` supplied to ' +
87
+ '`testComponent`, expected `string`.'
88
+ );
89
+ });
90
99
- it("should not warn for valid values", function() {
100
- typeCheckPass(PropTypes.array, []);
101
- typeCheckPass(PropTypes.bool, false);
102
- typeCheckPass(PropTypes.func, function() {});
103
- typeCheckPass(PropTypes.number, 0);
104
- typeCheckPass(PropTypes.string, '');
105
- typeCheckPass(PropTypes.object, {});
106
- typeCheckPass(PropTypes.object, new Date());
107
- typeCheckPass(PropTypes.object, /please/);
108
- });
91
+ it('should fail date and regexp correctly', function() {
92
+ typeCheckFail(
93
+ PropTypes.string,
94
+ new Date(),
95
+ 'Invalid prop `testProp` of type `date` supplied to ' +
96
+ '`testComponent`, expected `string`.'
97
+ );
98
+ typeCheckFail(
99
+ PropTypes.string,
100
+ /please/,
101
+ 'Invalid prop `testProp` of type `regexp` supplied to ' +
102
+ '`testComponent`, expected `string`.'
103
+ );
104
+ });
105
110
- it("should be implicitly optional and not warn without values", function() {
111
- typeCheckPass(PropTypes.string, null);
112
- typeCheckPass(PropTypes.string, undefined);
113
- });
106
+ it("should not warn for valid values", function() {
107
+ typeCheckPass(PropTypes.array, []);
108
+ typeCheckPass(PropTypes.bool, false);
109
+ typeCheckPass(PropTypes.func, function() {});
110
+ typeCheckPass(PropTypes.number, 0);
111
+ typeCheckPass(PropTypes.string, '');
112
+ typeCheckPass(PropTypes.object, {});
113
+ typeCheckPass(PropTypes.object, new Date());
114
+ typeCheckPass(PropTypes.object, /please/);
115
+ });
116
115
- it("should warn for missing required values", function() {
116
- typeCheckFail(PropTypes.string.isRequired, null, requiredMessage);
117
- typeCheckFail(PropTypes.string.isRequired, undefined, requiredMessage);
118
- });
119
-});
117
+ it("should be implicitly optional and not warn without values", function() {
118
+ typeCheckPass(PropTypes.string, null);
119
+ typeCheckPass(PropTypes.string, undefined);
120
+ });
121
121
-describe('Any type', function() {
122
- it('should should accept any value', function() {
123
- typeCheckPass(PropTypes.any, 0);
124
- typeCheckPass(PropTypes.any, 'str');
125
- typeCheckPass(PropTypes.any, []);
122
+ it("should warn for missing required values", function() {
123
+ typeCheckFail(PropTypes.string.isRequired, null, requiredMessage);
124
+ typeCheckFail(PropTypes.string.isRequired, undefined, requiredMessage);
125
+ });
126
});
127
128
- it("should be implicitly optional and not warn without values", function() {
129
- typeCheckPass(PropTypes.any, null);
130
- typeCheckPass(PropTypes.any, undefined);
131
- });
128
+ describe('Any type', function() {
129
+ it('should should accept any value', function() {
130
+ typeCheckPass(PropTypes.any, 0);
131
+ typeCheckPass(PropTypes.any, 'str');
132
+ typeCheckPass(PropTypes.any, []);
133
+ });
134
133
- it("should warn for missing required values", function() {
134
- typeCheckFail(PropTypes.any.isRequired, null, requiredMessage);
135
- typeCheckFail(PropTypes.any.isRequired, undefined, requiredMessage);
136
- });
137
-});
135
+ it("should be implicitly optional and not warn without values", function() {
136
+ typeCheckPass(PropTypes.any, null);
137
+ typeCheckPass(PropTypes.any, undefined);
138
+ });
139
139
-describe('ArrayOf Type', function() {
140
- it('should support the arrayOf propTypes', function() {
141
- typeCheckPass(PropTypes.arrayOf(PropTypes.number), [1, 2, 3]);
142
- typeCheckPass(PropTypes.arrayOf(PropTypes.string), ['a', 'b', 'c']);
143
- typeCheckPass(PropTypes.arrayOf(PropTypes.oneOf(['a', 'b'])), ['a', 'b']);
140
+ it("should warn for missing required values", function() {
141
+ typeCheckFail(PropTypes.any.isRequired, null, requiredMessage);
142
+ typeCheckFail(PropTypes.any.isRequired, undefined, requiredMessage);
143
+ });
144
});
145
146
- it('should support arrayOf with complex types', function() {
147
- typeCheckPass(
148
- PropTypes.arrayOf(PropTypes.shape({a: PropTypes.number.isRequired})),
149
- [{a: 1}, {a: 2}]
150
- );
146
+ describe('ArrayOf Type', function() {
147
+ it('should support the arrayOf propTypes', function() {
148
+ typeCheckPass(PropTypes.arrayOf(PropTypes.number), [1, 2, 3]);
149
+ typeCheckPass(PropTypes.arrayOf(PropTypes.string), ['a', 'b', 'c']);
150
+ typeCheckPass(PropTypes.arrayOf(PropTypes.oneOf(['a', 'b'])), ['a', 'b']);
151
+ });
152
152
- function Thing() {}
153
- typeCheckPass(
154
- PropTypes.arrayOf(PropTypes.instanceOf(Thing)),
155
- [new Thing(), new Thing()]
156
- );
157
- });
153
+ it('should support arrayOf with complex types', function() {
154
+ typeCheckPass(
155
+ PropTypes.arrayOf(PropTypes.shape({a: PropTypes.number.isRequired})),
156
+ [{a: 1}, {a: 2}]
157
+ );
158
159
- it('should warn with invalid items in the array', function() {
160
- typeCheckFail(
161
- PropTypes.arrayOf(PropTypes.number),
162
- [1, 2, 'b'],
163
- 'Invalid prop `2` of type `string` supplied to `testComponent`, ' +
164
- 'expected `number`.'
165
- );
166
- });
159
+ function Thing() {}
160
+ typeCheckPass(
161
+ PropTypes.arrayOf(PropTypes.instanceOf(Thing)),
162
+ [new Thing(), new Thing()]
163
+ );
164
+ });
165
168
- it('should warn with invalid complex types', function() {
169
- function Thing() {}
170
- var name = Thing.name || '<<anonymous>>';
166
+ it('should warn with invalid items in the array', function() {
167
+ typeCheckFail(
168
+ PropTypes.arrayOf(PropTypes.number),
169
+ [1, 2, 'b'],
170
+ 'Invalid prop `2` of type `string` supplied to `testComponent`, ' +
171
+ 'expected `number`.'
172
+ );
173
+ });
174
172
- typeCheckFail(
173
- PropTypes.arrayOf(PropTypes.instanceOf(Thing)),
174
- [new Thing(), 'xyz'],
175
- 'Invalid prop `1` supplied to `testComponent`, expected instance of `' +
176
- name + '`.'
177
- );
178
- });
175
+ it('should warn with invalid complex types', function() {
176
+ function Thing() {}
177
+ var name = Thing.name || '<<anonymous>>';
178
180
- it('should warn when passed something other than an array', function() {
181
- typeCheckFail(
182
- PropTypes.arrayOf(PropTypes.number),
183
- {'0': 'maybe-array', length: 1},
184
- 'Invalid prop `testProp` of type `object` supplied to `testComponent`, ' +
185
- 'expected an array.'
186
- );
187
- typeCheckFail(
188
- PropTypes.arrayOf(PropTypes.number),
189
- 123,
190
- 'Invalid prop `testProp` of type `number` supplied to `testComponent`, ' +
191
- 'expected an array.'
192
- );
193
- typeCheckFail(
194
- PropTypes.arrayOf(PropTypes.number),
195
- 'string',
196
- 'Invalid prop `testProp` of type `string` supplied to `testComponent`, ' +
197
- 'expected an array.'
198
- );
199
- });
179
+ typeCheckFail(
180
+ PropTypes.arrayOf(PropTypes.instanceOf(Thing)),
181
+ [new Thing(), 'xyz'],
182
+ 'Invalid prop `1` supplied to `testComponent`, expected instance of `' +
183
+ name + '`.'
184
+ );
185
+ });
186
201
- it('should not warn when passing an empty array', function() {
202
- typeCheckPass(PropTypes.arrayOf(PropTypes.number), []);
203
- });
187
+ it('should warn when passed something other than an array', function() {
188
+ typeCheckFail(
189
+ PropTypes.arrayOf(PropTypes.number),
190
+ {'0': 'maybe-array', length: 1},
191
+ 'Invalid prop `testProp` of type `object` supplied to ' +
192
+ '`testComponent`, expected an array.'
193
+ );
194
+ typeCheckFail(
195
+ PropTypes.arrayOf(PropTypes.number),
196
+ 123,
197
+ 'Invalid prop `testProp` of type `number` supplied to ' +
198
+ '`testComponent`, expected an array.'
199
+ );
200
+ typeCheckFail(
201
+ PropTypes.arrayOf(PropTypes.number),
202
+ 'string',
203
+ 'Invalid prop `testProp` of type `string` supplied to ' +
204
+ '`testComponent`, expected an array.'
205
+ );
206
+ });
207
205
- it("should be implicitly optional and not warn without values", function() {
206
- typeCheckPass(PropTypes.arrayOf(PropTypes.number), null);
207
- typeCheckPass(PropTypes.arrayOf(PropTypes.number), undefined);
208
- });
208
+ it('should not warn when passing an empty array', function() {
209
+ typeCheckPass(PropTypes.arrayOf(PropTypes.number), []);
210
+ });
211
210
- it("should warn for missing required values", function() {
211
- typeCheckFail(
212
- PropTypes.arrayOf(PropTypes.number).isRequired, null, requiredMessage
213
- );
214
- typeCheckFail(
215
- PropTypes.arrayOf(PropTypes.number).isRequired, undefined, requiredMessage
216
- );
212
+ it("should be implicitly optional and not warn without values", function() {
213
+ typeCheckPass(PropTypes.arrayOf(PropTypes.number), null);
214
+ typeCheckPass(PropTypes.arrayOf(PropTypes.number), undefined);
215
+ });
216
+
217
+ it("should warn for missing required values", function() {
218
+ typeCheckFail(
219
+ PropTypes.arrayOf(PropTypes.number).isRequired,
220
+ null,
221
+ requiredMessage
222
+ );
223
+ typeCheckFail(
224
+ PropTypes.arrayOf(PropTypes.number).isRequired,
225
+ undefined,
226
+ requiredMessage
227
+ );
228
+ });
229
});
218
-});
230
220
-describe('Component Type', function() {
221
- beforeEach(function() {
222
- require('mock-modules').dumpCache();
223
- ReactTestUtils = require('ReactTestUtils');
224
- Component = React.createClass({
225
- propTypes: {
226
- label: PropTypes.component.isRequired
227
- },
231
+ describe('Component Type', function() {
232
+ beforeEach(function() {
233
+ Component = React.createClass({
234
+ propTypes: {
235
+ label: PropTypes.component.isRequired
236
+ },
237
229
- render: function() {
230
- return <div>{this.props.label}</div>;
231
- }
238
+ render: function() {
239
+ return <div>{this.props.label}</div>;
240
+ }
241
+ });
242
+ spyOn(console, 'warn');
243
});
233
- spyOn(console, 'warn');
234
- });
244
236
- it('should support components', () => {
237
- typeCheckPass(PropTypes.component, <div />);
238
- });
245
+ it('should support components', () => {
246
+ typeCheckPass(PropTypes.component, <div />);
247
+ });
248
240
- it('should not support multiple components or scalar values', () => {
241
- var message = 'Invalid prop `testProp` supplied to `testComponent`, ' +
242
- 'expected a React component.';
243
- typeCheckFail(PropTypes.component, [<div />, <div />], message);
244
- typeCheckFail(PropTypes.component, 123, message);
245
- typeCheckFail(PropTypes.component, 'foo', message);
246
- typeCheckFail(PropTypes.component, false, message);
247
- });
249
+ it('should not support multiple components or scalar values', () => {
250
+ var message = 'Invalid prop `testProp` supplied to `testComponent`, ' +
251
+ 'expected a React component.';
252
+ typeCheckFail(PropTypes.component, [<div />, <div />], message);
253
+ typeCheckFail(PropTypes.component, 123, message);
254
+ typeCheckFail(PropTypes.component, 'foo', message);
255
+ typeCheckFail(PropTypes.component, false, message);
256
+ });
257
249
- it('should be able to define a single child as label', () => {
250
- var instance = <Component label={<div />} />;
251
- instance = ReactTestUtils.renderIntoDocument(instance);
258
+ it('should be able to define a single child as label', () => {
259
+ var instance = <Component label={<div />} />;
260
+ instance = ReactTestUtils.renderIntoDocument(instance);
261
253
- expect(console.warn.argsForCall.length).toBe(0);
254
- });
262
+ expect(console.warn.argsForCall.length).toBe(0);
263
+ });
264
256
- it('should warn when passing no label and isRequired is set', () => {
257
- var instance = <Component />;
258
- instance = ReactTestUtils.renderIntoDocument(instance);
265
+ it('should warn when passing no label and isRequired is set', () => {
266
+ var instance = <Component />;
267
+ instance = ReactTestUtils.renderIntoDocument(instance);
268
260
- expect(console.warn.argsForCall.length).toBe(1);
261
- });
269
+ expect(console.warn.argsForCall.length).toBe(1);
270
+ });
271
263
- it("should be implicitly optional and not warn without values", function() {
264
- typeCheckPass(PropTypes.component, null);
265
- typeCheckPass(PropTypes.component, undefined);
266
- });
272
+ it("should be implicitly optional and not warn without values", function() {
273
+ typeCheckPass(PropTypes.component, null);
274
+ typeCheckPass(PropTypes.component, undefined);
275
+ });
276
268
- it("should warn for missing required values", function() {
269
- typeCheckFail(PropTypes.component.isRequired, null, requiredMessage);
270
- typeCheckFail(PropTypes.component.isRequired, undefined, requiredMessage);
277
+ it("should warn for missing required values", function() {
278
+ typeCheckFail(PropTypes.component.isRequired, null, requiredMessage);
279
+ typeCheckFail(PropTypes.component.isRequired, undefined, requiredMessage);
280
+ });
281
});
272
-});
282
274
-describe('Instance Types', function() {
275
- it("should warn for invalid instances", function() {
276
- function Person() {}
277
- var personName = Person.name || '<<anonymous>>';
278
- var dateName = Date.name || '<<anonymous>>';
279
- var regExpName = RegExp.name || '<<anonymous>>';
280
-
281
- typeCheckFail(
282
- PropTypes.instanceOf(Person),
283
- false,
284
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
285
- 'instance of `' + personName + '`.'
286
- );
287
- typeCheckFail(
288
- PropTypes.instanceOf(Person),
289
- {},
290
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
291
- 'instance of `' + personName + '`.'
292
- );
293
- typeCheckFail(
294
- PropTypes.instanceOf(Person),
295
- '',
296
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
297
- 'instance of `' + personName + '`.'
298
- );
299
- typeCheckFail(
300
- PropTypes.instanceOf(Date),
301
- {},
302
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
303
- 'instance of `' + dateName + '`.'
304
- );
305
- typeCheckFail(
306
- PropTypes.instanceOf(RegExp),
307
- {},
308
- 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
309
- 'instance of `' + regExpName + '`.'
310
- );
311
- });
283
+ describe('Instance Types', function() {
284
+ it("should warn for invalid instances", function() {
285
+ function Person() {}
286
+ var personName = Person.name || '<<anonymous>>';
287
+ var dateName = Date.name || '<<anonymous>>';
288
+ var regExpName = RegExp.name || '<<anonymous>>';
289
313
- it("should not warn for valid values", function() {
314
- function Person() {}
315
- function Engineer() {}
316
- Engineer.prototype = new Person();
290
+ typeCheckFail(
291
+ PropTypes.instanceOf(Person),
292
+ false,
293
+ 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
294
+ 'instance of `' + personName + '`.'
295
+ );
296
+ typeCheckFail(
297
+ PropTypes.instanceOf(Person),
298
+ {},
299
+ 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
300
+ 'instance of `' + personName + '`.'
301
+ );
302
+ typeCheckFail(
303
+ PropTypes.instanceOf(Person),
304
+ '',
305
+ 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
306
+ 'instance of `' + personName + '`.'
307
+ );
308
+ typeCheckFail(
309
+ PropTypes.instanceOf(Date),
310
+ {},
311
+ 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
312
+ 'instance of `' + dateName + '`.'
313
+ );
314
+ typeCheckFail(
315
+ PropTypes.instanceOf(RegExp),
316
+ {},
317
+ 'Invalid prop `testProp` supplied to `testComponent`, expected ' +
318
+ 'instance of `' + regExpName + '`.'
319
+ );
320
+ });
321
318
- typeCheckPass(PropTypes.instanceOf(Person), new Person());
319
- typeCheckPass(PropTypes.instanceOf(Person), new Engineer());
322
+ it("should not warn for valid values", function() {
323
+ function Person() {}
324
+ function Engineer() {}
325
+ Engineer.prototype = new Person();
326
321
- typeCheckPass(PropTypes.instanceOf(Date), new Date());
322
- typeCheckPass(PropTypes.instanceOf(RegExp), /please/);
323
- });
327
+ typeCheckPass(PropTypes.instanceOf(Person), new Person());
328
+ typeCheckPass(PropTypes.instanceOf(Person), new Engineer());
329
325
- it("should be implicitly optional and not warn without values", function() {
326
- typeCheckPass(PropTypes.instanceOf(String), null);
327
- typeCheckPass(PropTypes.instanceOf(String), undefined);
328
- });
330
+ typeCheckPass(PropTypes.instanceOf(Date), new Date());
331
+ typeCheckPass(PropTypes.instanceOf(RegExp), /please/);
332
+ });
333
330
- it("should warn for missing required values", function() {
331
- typeCheckFail(
332
- PropTypes.instanceOf(String).isRequired, null, requiredMessage
333
- );
334
- typeCheckFail(
335
- PropTypes.instanceOf(String).isRequired, undefined, requiredMessage
336
- );
337
- });
338
-});
334
+ it("should be implicitly optional and not warn without values", function() {
335
+ typeCheckPass(PropTypes.instanceOf(String), null);
336
+ typeCheckPass(PropTypes.instanceOf(String), undefined);
337
+ });
338
340
-describe('React Component Types', function() {
341
- beforeEach(function() {
342
- MyComponent = React.createClass({
343
- render: function() {
344
- return <div />;
345
- }
339
+ it("should warn for missing required values", function() {
340
+ typeCheckFail(
341
+ PropTypes.instanceOf(String).isRequired, null, requiredMessage
342
+ );
343
+ typeCheckFail(
344
+ PropTypes.instanceOf(String).isRequired, undefined, requiredMessage
345
+ );
346
});
347
});
348
349
- it('should warn for invalid values', function() {
350
- var failMessage = 'Invalid prop `testProp` supplied to `testComponent`, ' +
351
- 'expected a renderable prop.';
352
- typeCheckFail(PropTypes.renderable, true, failMessage);
353
- typeCheckFail(PropTypes.renderable, function() {}, failMessage);
354
- typeCheckFail(PropTypes.renderable, {key: function() {}}, failMessage);
355
- });
349
+ describe('React Component Types', function() {
350
+ beforeEach(function() {
351
+ MyComponent = React.createClass({
352
+ render: function() {
353
+ return <div />;
354
+ }
355
+ });
356
+ });
357
357
- it('should not warn for valid values', function() {
358
- typeCheckPass(PropTypes.renderable, <div />);
359
- typeCheckPass(PropTypes.renderable, false);
360
- typeCheckPass(PropTypes.renderable, <MyComponent />);
361
- typeCheckPass(PropTypes.renderable, 'Some string');
362
- typeCheckPass(PropTypes.renderable, []);
363
- typeCheckPass(PropTypes.renderable, {});
364
- typeCheckPass(PropTypes.renderable, [
365
- 123,
366
- 'Some string',
367
- <div />,
368
- ['Another string', [456], <span />, <MyComponent />],
369
- <MyComponent />
370
- ]);
371
-
372
- // Object of rendereable things
373
- typeCheckPass(PropTypes.renderable, {
374
- k0: 123,
375
- k1: 'Some string',
376
- k2: <div />,
377
- k3: {
378
- k30: <MyComponent />,
379
- k31: {k310: <a />},
380
- k32: 'Another string'
381
- }
358
+ it('should warn for invalid values', function() {
359
+ var failMessage = 'Invalid prop `testProp` supplied to ' +
360
+ '`testComponent`, expected a renderable prop.';
361
+ typeCheckFail(PropTypes.renderable, true, failMessage);
362
+ typeCheckFail(PropTypes.renderable, function() {}, failMessage);
363
+ typeCheckFail(PropTypes.renderable, {key: function() {}}, failMessage);
364
});
383
- });
365
385
- it('should not warn for null/undefined if not required', function() {
386
- typeCheckPass(PropTypes.renderable, null);
387
- typeCheckPass(PropTypes.renderable, undefined);
388
- });
366
+ it('should not warn for valid values', function() {
367
+ typeCheckPass(PropTypes.renderable, <div />);
368
+ typeCheckPass(PropTypes.renderable, false);
369
+ typeCheckPass(PropTypes.renderable, <MyComponent />);
370
+ typeCheckPass(PropTypes.renderable, 'Some string');
371
+ typeCheckPass(PropTypes.renderable, []);
372
+ typeCheckPass(PropTypes.renderable, {});
373
+ typeCheckPass(PropTypes.renderable, [
374
+ 123,
375
+ 'Some string',
376
+ <div />,
377
+ ['Another string', [456], <span />, <MyComponent />],
378
+ <MyComponent />
379
+ ]);
380
+
381
+ // Object of rendereable things
382
+ typeCheckPass(PropTypes.renderable, {
383
+ k0: 123,
384
+ k1: 'Some string',
385
+ k2: <div />,
386
+ k3: {
387
+ k30: <MyComponent />,
388
+ k31: {k310: <a />},
389
+ k32: 'Another string'
390
+ }
391
+ });
392
+ });
393
390
- it('should warn for missing required values', function() {
391
- typeCheckFail(
392
- PropTypes.renderable.isRequired,
393
- null,
394
- 'Required prop `testProp` was not specified in `testComponent`.'
395
- );
396
- typeCheckFail(
397
- PropTypes.renderable.isRequired,
398
- undefined,
399
- 'Required prop `testProp` was not specified in `testComponent`.'
400
- );
401
- });
394
+ it('should not warn for null/undefined if not required', function() {
395
+ typeCheckPass(PropTypes.renderable, null);
396
+ typeCheckPass(PropTypes.renderable, undefined);
397
+ });
398
403
- it('should accept empty array & object for required props', function() {
404
- typeCheckPass(PropTypes.renderable.isRequired, []);
405
- typeCheckPass(PropTypes.renderable.isRequired, {});
406
- });
407
-});
399
+ it('should warn for missing required values', function() {
400
+ typeCheckFail(
401
+ PropTypes.renderable.isRequired,
402
+ null,
403
+ 'Required prop `testProp` was not specified in `testComponent`.'
404
+ );
405
+ typeCheckFail(
406
+ PropTypes.renderable.isRequired,
407
+ undefined,
408
+ 'Required prop `testProp` was not specified in `testComponent`.'
409
+ );
410
+ });
411
409
-describe('ObjectOf Type', function() {
410
- it('should support the objectOf propTypes', function() {
411
- typeCheckPass(PropTypes.objectOf(PropTypes.number), {a: 1, b: 2, c: 3});
412
- typeCheckPass(
413
- PropTypes.objectOf(PropTypes.string),
414
- {a: 'a', b: 'b', c: 'c'}
415
- );
416
- typeCheckPass(
417
- PropTypes.objectOf(PropTypes.oneOf(['a', 'b'])),
418
- {a: 'a', b: 'b'}
419
- );
412
+ it('should accept empty array & object for required props', function() {
413
+ typeCheckPass(PropTypes.renderable.isRequired, []);
414
+ typeCheckPass(PropTypes.renderable.isRequired, {});
415
+ });
416
});
417
422
- it('should support objectOf with complex types', function() {
423
- typeCheckPass(
424
- PropTypes.objectOf(PropTypes.shape({a: PropTypes.number.isRequired})),
425
- {a: {a: 1}, b: {a: 2}}
426
- );
427
-
428
- function Thing() {}
429
- typeCheckPass(
430
- PropTypes.objectOf(PropTypes.instanceOf(Thing)),
431
- {a: new Thing(), b: new Thing()}
432
- );
433
- });
418
+ describe('ObjectOf Type', function() {
419
+ it('should support the objectOf propTypes', function() {
420
+ typeCheckPass(PropTypes.objectOf(PropTypes.number), {a: 1, b: 2, c: 3});
421
+ typeCheckPass(
422
+ PropTypes.objectOf(PropTypes.string),
423
+ {a: 'a', b: 'b', c: 'c'}
424
+ );
425
+ typeCheckPass(
426
+ PropTypes.objectOf(PropTypes.oneOf(['a', 'b'])),
427
+ {a: 'a', b: 'b'}
428
+ );
429
+ });
430
435
- it('should warn with invalid items in the object', function() {
436
- typeCheckFail(
437
- PropTypes.objectOf(PropTypes.number),
438
- {a: 1, b: 2, c: 'b'},
439
- 'Invalid prop `c` of type `string` supplied to `testComponent`, ' +
440
- 'expected `number`.'
441
- );
442
- });
431
+ it('should support objectOf with complex types', function() {
432
+ typeCheckPass(
433
+ PropTypes.objectOf(PropTypes.shape({a: PropTypes.number.isRequired})),
434
+ {a: {a: 1}, b: {a: 2}}
435
+ );
436
444
- it('should warn with invalid complex types', function() {
445
- function Thing() {}
446
- var name = Thing.name || '<<anonymous>>';
437
+ function Thing() {}
438
+ typeCheckPass(
439
+ PropTypes.objectOf(PropTypes.instanceOf(Thing)),
440
+ {a: new Thing(), b: new Thing()}
441
+ );
442
+ });
443
448
- typeCheckFail(
449
- PropTypes.objectOf(PropTypes.instanceOf(Thing)),
450
- {a: new Thing(), b: 'xyz'},
451
- 'Invalid prop `b` supplied to `testComponent`, expected instance of `' +
452
- name + '`.'
453
- );
454
- });
444
+ it('should warn with invalid items in the object', function() {
445
+ typeCheckFail(
446
+ PropTypes.objectOf(PropTypes.number),
447
+ {a: 1, b: 2, c: 'b'},
448
+ 'Invalid prop `c` of type `string` supplied to `testComponent`, ' +
449
+ 'expected `number`.'
450
+ );
451
+ });
452
456
- it('should warn when passed something other than an object', function() {
457
- typeCheckFail(
458
- PropTypes.objectOf(PropTypes.number),
459
- [1, 2],
460
- 'Invalid prop `testProp` of type `array` supplied to `testComponent`, ' +
461
- 'expected an object.'
462
- );
463
- typeCheckFail(
464
- PropTypes.objectOf(PropTypes.number),
465
- 123,
466
- 'Invalid prop `testProp` of type `number` supplied to `testComponent`, ' +
467
- 'expected an object.'
468
- );
469
- typeCheckFail(
470
- PropTypes.objectOf(PropTypes.number),
471
- 'string',
472
- 'Invalid prop `testProp` of type `string` supplied to `testComponent`, ' +
473
- 'expected an object.'
474
- );
475
- });
453
+ it('should warn with invalid complex types', function() {
454
+ function Thing() {}
455
+ var name = Thing.name || '<<anonymous>>';
456
477
- it('should not warn when passing an empty object', function() {
478
- typeCheckPass(PropTypes.objectOf(PropTypes.number), {});
479
- });
457
+ typeCheckFail(
458
+ PropTypes.objectOf(PropTypes.instanceOf(Thing)),
459
+ {a: new Thing(), b: 'xyz'},
460
+ 'Invalid prop `b` supplied to `testComponent`, expected instance of `' +
461
+ name + '`.'
462
+ );
463
+ });
464
481
- it("should be implicitly optional and not warn without values", function() {
482
- typeCheckPass(PropTypes.objectOf(PropTypes.number), null);
483
- typeCheckPass(PropTypes.objectOf(PropTypes.number), undefined);
484
- });
465
+ it('should warn when passed something other than an object', function() {
466
+ typeCheckFail(
467
+ PropTypes.objectOf(PropTypes.number),
468
+ [1, 2],
469
+ 'Invalid prop `testProp` of type `array` supplied to ' +
470
+ '`testComponent`, expected an object.'
471
+ );
472
+ typeCheckFail(
473
+ PropTypes.objectOf(PropTypes.number),
474
+ 123,
475
+ 'Invalid prop `testProp` of type `number` supplied to ' +
476
+ '`testComponent`, expected an object.'
477
+ );
478
+ typeCheckFail(
479
+ PropTypes.objectOf(PropTypes.number),
480
+ 'string',
481
+ 'Invalid prop `testProp` of type `string` supplied to ' +
482
+ '`testComponent`, expected an object.'
483
+ );
484
+ });
485
486
- it("should warn for missing required values", function() {
487
- typeCheckFail(
488
- PropTypes.objectOf(PropTypes.number).isRequired,
489
- null,
490
- requiredMessage
491
- );
492
- typeCheckFail(
493
- PropTypes.objectOf(PropTypes.number).isRequired,
494
- undefined,
495
- requiredMessage
496
- );
497
- });
498
-});
486
+ it('should not warn when passing an empty object', function() {
487
+ typeCheckPass(PropTypes.objectOf(PropTypes.number), {});
488
+ });
489
500
-describe('OneOf Types', function() {
501
- it("should warn for invalid strings", function() {
502
- typeCheckFail(
503
- PropTypes.oneOf(['red', 'blue']),
504
- true,
505
- 'Invalid prop `testProp` of value `true` supplied to `testComponent`, ' +
506
- 'expected one of ["red","blue"].'
507
- );
508
- typeCheckFail(
509
- PropTypes.oneOf(['red', 'blue']),
510
- [],
511
- 'Invalid prop `testProp` of value `` supplied to `testComponent`, ' +
512
- 'expected one of ["red","blue"].'
513
- );
514
- typeCheckFail(
515
- PropTypes.oneOf(['red', 'blue']),
516
- '',
517
- 'Invalid prop `testProp` of value `` supplied to `testComponent`, ' +
518
- 'expected one of ["red","blue"].'
519
- );
520
- typeCheckFail(
521
- PropTypes.oneOf([0, 'false']),
522
- false,
523
- 'Invalid prop `testProp` of value `false` supplied to `testComponent`, ' +
524
- 'expected one of [0,"false"].'
525
- );
526
- });
490
+ it("should be implicitly optional and not warn without values", function() {
491
+ typeCheckPass(PropTypes.objectOf(PropTypes.number), null);
492
+ typeCheckPass(PropTypes.objectOf(PropTypes.number), undefined);
493
+ });
494
528
- it("should not warn for valid values", function() {
529
- typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'red');
530
- typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'blue');
495
+ it("should warn for missing required values", function() {
496
+ typeCheckFail(
497
+ PropTypes.objectOf(PropTypes.number).isRequired,
498
+ null,
499
+ requiredMessage
500
+ );
501
+ typeCheckFail(
502
+ PropTypes.objectOf(PropTypes.number).isRequired,
503
+ undefined,
504
+ requiredMessage
505
+ );
506
+ });
507
});
508
533
- it("should be implicitly optional and not warn without values", function() {
534
- typeCheckPass(PropTypes.oneOf(['red', 'blue']), null);
535
- typeCheckPass(PropTypes.oneOf(['red', 'blue']), undefined);
536
- });
509
+ describe('OneOf Types', function() {
510
+ it("should warn for invalid strings", function() {
511
+ typeCheckFail(
512
+ PropTypes.oneOf(['red', 'blue']),
513
+ true,
514
+ 'Invalid prop `testProp` of value `true` supplied to ' +
515
+ '`testComponent`, expected one of ["red","blue"].'
516
+ );
517
+ typeCheckFail(
518
+ PropTypes.oneOf(['red', 'blue']),
519
+ [],
520
+ 'Invalid prop `testProp` of value `` supplied to `testComponent`, ' +
521
+ 'expected one of ["red","blue"].'
522
+ );
523
+ typeCheckFail(
524
+ PropTypes.oneOf(['red', 'blue']),
525
+ '',
526
+ 'Invalid prop `testProp` of value `` supplied to `testComponent`, ' +
527
+ 'expected one of ["red","blue"].'
528
+ );
529
+ typeCheckFail(
530
+ PropTypes.oneOf([0, 'false']),
531
+ false,
532
+ 'Invalid prop `testProp` of value `false` supplied to ' +
533
+ '`testComponent`, expected one of [0,"false"].'
534
+ );
535
+ });
536
538
- it("should warn for missing required values", function() {
539
- typeCheckFail(
540
- PropTypes.oneOf(['red', 'blue']).isRequired,
541
- null,
542
- requiredMessage
543
- );
544
- typeCheckFail(
545
- PropTypes.oneOf(['red', 'blue']).isRequired,
546
- undefined,
547
- requiredMessage
548
- );
549
- });
550
-});
537
+ it("should not warn for valid values", function() {
538
+ typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'red');
539
+ typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'blue');
540
+ });
541
552
-describe('Union Types', function() {
553
- it('should warn if none of the types are valid', function() {
554
- typeCheckFail(
555
- PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
556
- [],
557
- 'Invalid prop `testProp` supplied to `testComponent`.'
558
- );
542
+ it("should be implicitly optional and not warn without values", function() {
543
+ typeCheckPass(PropTypes.oneOf(['red', 'blue']), null);
544
+ typeCheckPass(PropTypes.oneOf(['red', 'blue']), undefined);
545
+ });
546
560
- var checker = PropTypes.oneOfType([
561
- PropTypes.shape({a: PropTypes.number.isRequired}),
562
- PropTypes.shape({b: PropTypes.number.isRequired})
563
- ]);
564
- typeCheckFail(
565
- checker,
566
- {c: 1},
567
- 'Invalid prop `testProp` supplied to `testComponent`.'
568
- );
547
+ it("should warn for missing required values", function() {
548
+ typeCheckFail(
549
+ PropTypes.oneOf(['red', 'blue']).isRequired,
550
+ null,
551
+ requiredMessage
552
+ );
553
+ typeCheckFail(
554
+ PropTypes.oneOf(['red', 'blue']).isRequired,
555
+ undefined,
556
+ requiredMessage
557
+ );
558
+ });
559
});
560
571
- it('should not warn if one of the types are valid', function() {
572
- var checker = PropTypes.oneOfType([
573
- PropTypes.string,
574
- PropTypes.number
575
- ]);
576
- typeCheckPass(checker, null);
577
- typeCheckPass(checker, 'foo');
578
- typeCheckPass(checker, 123);
579
-
580
- checker = PropTypes.oneOfType([
581
- PropTypes.shape({a: PropTypes.number.isRequired}),
582
- PropTypes.shape({b: PropTypes.number.isRequired})
583
- ]);
584
- typeCheckPass(checker, {a: 1});
585
- typeCheckPass(checker, {b: 1});
586
- });
561
+ describe('Union Types', function() {
562
+ it('should warn if none of the types are valid', function() {
563
+ typeCheckFail(
564
+ PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
565
+ [],
566
+ 'Invalid prop `testProp` supplied to `testComponent`.'
567
+ );
568
588
- it("should be implicitly optional and not warn without values", function() {
589
- typeCheckPass(
590
- PropTypes.oneOfType([PropTypes.string, PropTypes.number]), null
591
- );
592
- typeCheckPass(
593
- PropTypes.oneOfType([PropTypes.string, PropTypes.number]), undefined
594
- );
595
- });
569
+ var checker = PropTypes.oneOfType([
570
+ PropTypes.shape({a: PropTypes.number.isRequired}),
571
+ PropTypes.shape({b: PropTypes.number.isRequired})
572
+ ]);
573
+ typeCheckFail(
574
+ checker,
575
+ {c: 1},
576
+ 'Invalid prop `testProp` supplied to `testComponent`.'
577
+ );
578
+ });
579
597
- it("should warn for missing required values", function() {
598
- typeCheckFail(
599
- PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
600
- null,
601
- requiredMessage
602
- );
603
- typeCheckFail(
604
- PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
605
- undefined,
606
- requiredMessage
607
- );
608
- });
609
-});
580
+ it('should not warn if one of the types are valid', function() {
581
+ var checker = PropTypes.oneOfType([
582
+ PropTypes.string,
583
+ PropTypes.number
584
+ ]);
585
+ typeCheckPass(checker, null);
586
+ typeCheckPass(checker, 'foo');
587
+ typeCheckPass(checker, 123);
588
+
589
+ checker = PropTypes.oneOfType([
590
+ PropTypes.shape({a: PropTypes.number.isRequired}),
591
+ PropTypes.shape({b: PropTypes.number.isRequired})
592
+ ]);
593
+ typeCheckPass(checker, {a: 1});
594
+ typeCheckPass(checker, {b: 1});
595
+ });
596
611
-describe('Shape Types', function() {
612
- it("should warn for non objects", function() {
613
- typeCheckFail(
614
- PropTypes.shape({}),
615
- 'some string',
616
- 'Invalid prop `testProp` of type `string` supplied to `testComponent`, ' +
617
- 'expected `object`.'
618
- );
619
- typeCheckFail(
620
- PropTypes.shape({}),
621
- ['array'],
622
- 'Invalid prop `testProp` of type `array` supplied to `testComponent`, ' +
623
- 'expected `object`.'
624
- );
625
- });
597
+ it("should be implicitly optional and not warn without values", function() {
598
+ typeCheckPass(
599
+ PropTypes.oneOfType([PropTypes.string, PropTypes.number]), null
600
+ );
601
+ typeCheckPass(
602
+ PropTypes.oneOfType([PropTypes.string, PropTypes.number]), undefined
603
+ );
604
+ });
605
627
- it("should not warn for empty values", function() {
628
- typeCheckPass(PropTypes.shape({}), undefined);
629
- typeCheckPass(PropTypes.shape({}), null);
630
- typeCheckPass(PropTypes.shape({}), {});
606
+ it("should warn for missing required values", function() {
607
+ typeCheckFail(
608
+ PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
609
+ null,
610
+ requiredMessage
611
+ );
612
+ typeCheckFail(
613
+ PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
614
+ undefined,
615
+ requiredMessage
616
+ );
617
+ });
618
});
619
633
- it("should not warn for an empty object", function() {
634
- typeCheckPass(PropTypes.shape({}).isRequired, {});
635
- });
620
+ describe('Shape Types', function() {
621
+ it("should warn for non objects", function() {
622
+ typeCheckFail(
623
+ PropTypes.shape({}),
624
+ 'some string',
625
+ 'Invalid prop `testProp` of type `string` supplied to ' +
626
+ '`testComponent`, expected `object`.'
627
+ );
628
+ typeCheckFail(
629
+ PropTypes.shape({}),
630
+ ['array'],
631
+ 'Invalid prop `testProp` of type `array` supplied to ' +
632
+ '`testComponent`, expected `object`.'
633
+ );
634
+ });
635
637
- it("should not warn for non specified types", function() {
638
- typeCheckPass(PropTypes.shape({}), {key: 1});
639
- });
636
+ it("should not warn for empty values", function() {
637
+ typeCheckPass(PropTypes.shape({}), undefined);
638
+ typeCheckPass(PropTypes.shape({}), null);
639
+ typeCheckPass(PropTypes.shape({}), {});
640
+ });
641
641
- it("should not warn for valid types", function() {
642
- typeCheckPass(PropTypes.shape({key: PropTypes.number}), {key: 1});
643
- });
642
+ it("should not warn for an empty object", function() {
643
+ typeCheckPass(PropTypes.shape({}).isRequired, {});
644
+ });
645
645
- it("should warn for required valid types", function() {
646
- typeCheckFail(
647
- PropTypes.shape({key: PropTypes.number.isRequired}),
648
- {},
649
- 'Required prop `key` was not specified in `testComponent`.'
650
- );
651
- });
646
+ it("should not warn for non specified types", function() {
647
+ typeCheckPass(PropTypes.shape({}), {key: 1});
648
+ });
649
653
- it("should warn for the first required type", function() {
654
- typeCheckFail(
655
- PropTypes.shape({
656
- key: PropTypes.number.isRequired,
657
- secondKey: PropTypes.number.isRequired
658
- }),
659
- {},
660
- 'Required prop `key` was not specified in `testComponent`.'
661
- );
662
- });
650
+ it("should not warn for valid types", function() {
651
+ typeCheckPass(PropTypes.shape({key: PropTypes.number}), {key: 1});
652
+ });
653
664
- it("should warn for invalid key types", function() {
665
- typeCheckFail(PropTypes.shape({key: PropTypes.number}),
666
- {key: 'abc'},
667
- 'Invalid prop `key` of type `string` supplied to `testComponent`, ' +
668
- 'expected `number`.'
669
- );
670
- });
654
+ it("should warn for required valid types", function() {
655
+ typeCheckFail(
656
+ PropTypes.shape({key: PropTypes.number.isRequired}),
657
+ {},
658
+ 'Required prop `key` was not specified in `testComponent`.'
659
+ );
660
+ });
661
672
- it("should be implicitly optional and not warn without values", function() {
673
- typeCheckPass(
674
- PropTypes.shape(PropTypes.shape({key: PropTypes.number})), null
675
- );
676
- typeCheckPass(
677
- PropTypes.shape(PropTypes.shape({key: PropTypes.number})), undefined
678
- );
679
- });
662
+ it("should warn for the first required type", function() {
663
+ typeCheckFail(
664
+ PropTypes.shape({
665
+ key: PropTypes.number.isRequired,
666
+ secondKey: PropTypes.number.isRequired
667
+ }),
668
+ {},
669
+ 'Required prop `key` was not specified in `testComponent`.'
670
+ );
671
+ });
672
681
- it("should warn for missing required values", function() {
682
- typeCheckFail(
683
- PropTypes.shape({key: PropTypes.number}).isRequired,
684
- null,
685
- requiredMessage
686
- );
687
- typeCheckFail(
688
- PropTypes.shape({key: PropTypes.number}).isRequired,
689
- undefined,
690
- requiredMessage
691
- );
692
- });
693
-});
673
+ it("should warn for invalid key types", function() {
674
+ typeCheckFail(PropTypes.shape({key: PropTypes.number}),
675
+ {key: 'abc'},
676
+ 'Invalid prop `key` of type `string` supplied to `testComponent`, ' +
677
+ 'expected `number`.'
678
+ );
679
+ });
680
695
-describe('Custom validator', function() {
696
- beforeEach(function() {
697
- require('mock-modules').dumpCache();
698
- ReactTestUtils = require('ReactTestUtils');
699
- spyOn(console, 'warn');
700
- });
681
+ it("should be implicitly optional and not warn without values", function() {
682
+ typeCheckPass(
683
+ PropTypes.shape(PropTypes.shape({key: PropTypes.number})), null
684
+ );
685
+ typeCheckPass(
686
+ PropTypes.shape(PropTypes.shape({key: PropTypes.number})), undefined
687
+ );
688
+ });
689
702
- it('should have been called with the right params', function() {
703
- var spy = jasmine.createSpy();
704
- var Component = React.createClass({
705
- propTypes: {num: spy},
690
+ it("should warn for missing required values", function() {
691
+ typeCheckFail(
692
+ PropTypes.shape({key: PropTypes.number}).isRequired,
693
+ null,
694
+ requiredMessage
695
+ );
696
+ typeCheckFail(
697
+ PropTypes.shape({key: PropTypes.number}).isRequired,
698
+ undefined,
699
+ requiredMessage
700
+ );
701
+ });
702
+ });
703
707
- render: function() {
708
- return <div />;
709
- }
704
+ describe('Custom validator', function() {
705
+ beforeEach(function() {
706
+ require('mock-modules').dumpCache();
707
+ spyOn(console, 'warn');
708
});
709
712
- var instance = <Component num={5} />;
713
- instance = ReactTestUtils.renderIntoDocument(instance);
710
+ it('should have been called with the right params', function() {
711
+ var spy = jasmine.createSpy();
712
+ var Component = React.createClass({
713
+ propTypes: {num: spy},
714
715
- expect(spy.argsForCall.length).toBe(2); // temp double validation
716
- expect(spy.argsForCall[0][1]).toBe('num');
717
- expect(spy.argsForCall[0][2]).toBe('Component');
718
- });
715
+ render: function() {
716
+ return <div />;
717
+ }
718
+ });
719
720
- it('should have been called even if the prop is not present', function() {
721
- var spy = jasmine.createSpy();
722
- var Component = React.createClass({
723
- propTypes: {num: spy},
720
+ var instance = <Component num={5} />;
721
+ instance = ReactTestUtils.renderIntoDocument(instance);
722
725
- render: function() {
726
- return <div />;
727
- }
723
+ expect(spy.argsForCall.length).toBe(2); // temp double validation
724
+ expect(spy.argsForCall[0][1]).toBe('num');
725
+ expect(spy.argsForCall[0][2]).toBe('Component');
726
});
727
730
- var instance = <Component bla={5} />;
731
- instance = ReactTestUtils.renderIntoDocument(instance);
732
-
733
- expect(spy.argsForCall.length).toBe(2); // temp double validation
734
- });
728
+ it('should have been called even if the prop is not present', function() {
729
+ var spy = jasmine.createSpy();
730
+ var Component = React.createClass({
731
+ propTypes: {num: spy},
732
736
- it('should have received the validator\'s return value', function() {
737
- var spy = jasmine.createSpy().andCallFake(
738
- function(props, propName, componentName) {
739
- if (props[propName] !== 5) {
740
- return new Error('num must be 5!');
733
+ render: function() {
734
+ return <div />;
735
}
742
- }
743
- );
744
- var Component = React.createClass({
745
- propTypes: {num: spy},
736
+ });
737
747
- render: function() {
748
- return <div />;
749
- }
750
- });
738
+ var instance = <Component bla={5} />;
739
+ instance = ReactTestUtils.renderIntoDocument(instance);
740
752
- var instance = <Component num={6} />;
753
- instance = ReactTestUtils.renderIntoDocument(instance);
754
- expect(console.warn.argsForCall.length).toBe(1);
755
- expect(console.warn.argsForCall[0][0]).toBe('Warning: num must be 5!');
756
- });
741
+ expect(spy.argsForCall.length).toBe(2); // temp double validation
742
+ });
743
758
- it('should not warn if the validator returned anything else than an error',
759
- function() {
744
+ it('should have received the validator\'s return value', function() {
745
var spy = jasmine.createSpy().andCallFake(
746
function(props, propName, componentName) {
762
- return 'This message will never reach anyone';
747
+ if (props[propName] !== 5) {
748
+ return new Error('num must be 5!');
749
+ }
750
}
751
);
752
var Component = React.createClass({
@@ -770,9 +757,31 @@ describe('Custom validator', function() {
757
}
758
});
759
773
- var instance = <Component num={5} />;
760
+ var instance = <Component num={6} />;
761
instance = ReactTestUtils.renderIntoDocument(instance);
775
- expect(console.warn.argsForCall.length).toBe(0);
776
- }
777
- );
762
+ expect(console.warn.argsForCall.length).toBe(1);
763
+ expect(console.warn.argsForCall[0][0]).toBe('Warning: num must be 5!');
764
+ });
765
+
766
+ it('should not warn if the validator returned anything else than an error',
767
+ function() {
768
+ var spy = jasmine.createSpy().andCallFake(
769
+ function(props, propName, componentName) {
770
+ return 'This message will never reach anyone';
771
+ }
772
+ );
773
+ var Component = React.createClass({
774
+ propTypes: {num: spy},
775
+
776
+ render: function() {
777
+ return <div />;
778
+ }
779
+ });
780
+
781
+ var instance = <Component num={5} />;
782
+ instance = ReactTestUtils.renderIntoDocument(instance);
783
+ expect(console.warn.argsForCall.length).toBe(0);
784
+ }
785
+ );
786
+ });
787
});