Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81155 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @emails react-core
10
*/
11
12
"use strict";
13
14
var React;
15
var ReactElement;
16
var ReactTestUtils;
17
18
describe('ReactElement', function() {
19
var ComponentFactory;
20
var ComponentClass;
21
22
beforeEach(function() {
23
React = require('React');
24
ReactElement = require('ReactElement');
25
ReactTestUtils = require('ReactTestUtils');
26
ComponentFactory = React.createClass({
27
render: function() { return <div />; }
28
});
29
ComponentClass = ComponentFactory.type;
30
});
31
32
it('returns a complete element according to spec', function() {
33
var element = React.createFactory(ComponentFactory)();
34
expect(element.type).toBe(ComponentClass);
35
expect(element.key).toBe(null);
36
expect(element.ref).toBe(null);
37
expect(element.props).toEqual({});
38
});
39
40
it('allows a string to be passed as the type', function() {
41
var element = React.createFactory('div')();
42
expect(element.type).toBe('div');
43
expect(element.key).toBe(null);
44
expect(element.ref).toBe(null);
45
expect(element.props).toEqual({});
46
});
47
48
it('returns an immutable element', function() {
49
var element = React.createFactory(ComponentFactory)();
50
expect(() => element.type = 'div').toThrow();
51
});
52
53
it('does not reuse the original config object', function() {
54
var config = { foo: 1 };
55
var element = React.createFactory(ComponentFactory)(config);
56
expect(element.props.foo).toBe(1);
57
config.foo = 2;
58
expect(element.props.foo).toBe(1);
59
});
60
61
it('extracts key and ref from the config', function() {
62
var element = React.createFactory(ComponentFactory)({
63
key: '12',
64
ref: '34',
65
foo: '56'
66
});
67
expect(element.type).toBe(ComponentClass);
68
expect(element.key).toBe('12');
69
expect(element.ref).toBe('34');
70
expect(element.props).toEqual({foo:'56'});
71
});
72
73
it('coerces the key to a string', function() {
74
var element = React.createFactory(ComponentFactory)({
75
key: 12,
76
foo: '56'
77
});
78
expect(element.type).toBe(ComponentClass);
79
expect(element.key).toBe('12');
80
expect(element.ref).toBe(null);
81
expect(element.props).toEqual({foo:'56'});
82
});
83
84
it('treats a null key as omitted but warns', function() {
85
spyOn(console, 'warn');
86
var element = React.createFactory(ComponentFactory)({
87
key: null,
88
foo: '56'
89
});
90
expect(element.type).toBe(ComponentClass);
91
expect(element.key).toBe(null); // as opposed to string 'null'
92
expect(element.ref).toBe(null);
93
expect(element.props).toEqual({foo:'56'});
94
expect(console.warn.argsForCall.length).toBe(1);
95
expect(console.warn.argsForCall[0][0]).toContain(
96
'will be treated as equivalent to the string \'null\''
97
);
98
});
99
100
it('preserves the context on the element', function() {
101
var Component = React.createFactory(ComponentFactory);
102
var element;
103
104
var Wrapper = React.createClass({
105
childContextTypes: {
106
foo: React.PropTypes.string
107
},
108
getChildContext: function() {
109
return { foo: 'bar' };
110
},
111
render: function() {
112
element = Component();
113
return element;
114
}
115
});
116
117
ReactTestUtils.renderIntoDocument(<Wrapper />);
118
119
expect(element._context).toEqual({ foo: 'bar' });
120
});
121
122
it('preserves the owner on the element', function() {
123
var Component = React.createFactory(ComponentFactory);
124
var element;
125
126
var Wrapper = React.createClass({
127
childContextTypes: {
128
foo: React.PropTypes.string
129
},
130
getChildContext: function() {
131
return { foo: 'bar' };
132
},
133
render: function() {
134
element = Component();
135
return element;
136
}
137
});
138
139
var instance = ReactTestUtils.renderIntoDocument(<Wrapper />);
140
141
expect(element._owner).toBe(instance);
142
});
143
144
it('merges an additional argument onto the children prop', function() {
145
spyOn(console, 'warn');
146
var a = 1;
147
var element = React.createFactory(ComponentFactory)({
148
children: 'text'
149
}, a);
150
expect(element.props.children).toBe(a);
151
expect(console.warn.argsForCall.length).toBe(0);
152
});
153
154
it('does not override children if no rest args are provided', function() {
155
spyOn(console, 'warn');
156
var element = React.createFactory(ComponentFactory)({
157
children: 'text'
158
});
159
expect(element.props.children).toBe('text');
160
expect(console.warn.argsForCall.length).toBe(0);
161
});
162
163
it('overrides children if null is provided as an argument', function() {
164
spyOn(console, 'warn');
165
var element = React.createFactory(ComponentFactory)({
166
children: 'text'
167
}, null);
168
expect(element.props.children).toBe(null);
169
expect(console.warn.argsForCall.length).toBe(0);
170
});
171
172
it('merges rest arguments onto the children prop in an array', function() {
173
spyOn(console, 'warn');
174
var a = 1, b = 2, c = 3;
175
var element = React.createFactory(ComponentFactory)(null, a, b, c);
176
expect(element.props.children).toEqual([1, 2, 3]);
177
expect(console.warn.argsForCall.length).toBe(0);
178
});
179
180
it('warns for keys for arrays of elements in rest args', function() {
181
spyOn(console, 'warn');
182
var Component = React.createFactory(ComponentFactory);
183
184
Component(null, [ Component(), Component() ]);
185
186
expect(console.warn.argsForCall.length).toBe(1);
187
expect(console.warn.argsForCall[0][0]).toContain(
188
'Each child in an array should have a unique "key" prop'
189
);
190
});
191
192
it('does not warn when the element is directly in rest args', function() {
193
spyOn(console, 'warn');
194
var Component = React.createFactory(ComponentFactory);
195
196
Component(null, Component(), Component());
197
198
expect(console.warn.argsForCall.length).toBe(0);
199
});
200
201
it('does not warn when the array contains a non-element', function() {
202
spyOn(console, 'warn');
203
var Component = React.createFactory(ComponentFactory);
204
205
Component(null, [ {}, {} ]);
206
207
expect(console.warn.argsForCall.length).toBe(0);
208
});
209
210
it('allows static methods to be called using the type property', function() {
211
spyOn(console, 'warn');
212
213
var ComponentClass = React.createClass({
214
statics: {
215
someStaticMethod: function() {
216
return 'someReturnValue';
217
}
218
},
219
getInitialState: function() {
220
return {valueToReturn: 'hi'};
221
},
222
render: function() {
223
return <div></div>;
224
}
225
});
226
227
var element = <ComponentClass />;
228
expect(element.type.someStaticMethod()).toBe('someReturnValue');
229
expect(console.warn.argsForCall.length).toBe(0);
230
});
231
232
it('identifies valid elements', function() {
233
var Component = React.createClass({
234
render: function() {
235
return <div />;
236
}
237
});
238
239
expect(ReactElement.isValidElement(<div />)).toEqual(true);
240
expect(ReactElement.isValidElement(<Component />)).toEqual(true);
241
242
expect(ReactElement.isValidElement(null)).toEqual(false);
243
expect(ReactElement.isValidElement(true)).toEqual(false);
244
expect(ReactElement.isValidElement({})).toEqual(false);
245
expect(ReactElement.isValidElement("string")).toEqual(false);
246
expect(ReactElement.isValidElement(React.DOM.div)).toEqual(false);
247
expect(ReactElement.isValidElement(Component)).toEqual(false);
248
});
249
250
it('warns but allow a plain function in a factory to be invoked', function() {
251
spyOn(console, 'warn');
252
// This is a temporary helper to allow JSX with plain functions.
253
// This allow you to track down these callers and replace them with regular
254
// function calls.
255
var factory = React.createFactory(function (x) {
256
return 21 + x;
257
});
258
expect(factory(21)).toBe(42);
259
expect(console.warn.argsForCall.length).toBe(1);
260
expect(console.warn.argsForCall[0][0]).toContain(
261
'This JSX uses a plain function.'
262
);
263
});
264
265
it('warns but allow a plain function to be immediately invoked', function() {
266
spyOn(console, 'warn');
267
var result = React.createElement(function (x, y) {
268
return 21 + x + y;
269
}, 11, 10);
270
expect(result).toBe(42);
271
expect(console.warn.argsForCall.length).toBe(1);
272
expect(console.warn.argsForCall[0][0]).toContain(
273
'This JSX uses a plain function.'
274
);
275
});
276
277
it('warns but does not fail on undefined results', function() {
278
spyOn(console, 'warn');
279
var fn = function () { };
280
var result = React.createElement(fn, 1, 2, null);
281
expect(result).toBe(undefined);
282
expect(console.warn.argsForCall.length).toBe(1);
283
expect(console.warn.argsForCall[0][0]).toContain(
284
'This JSX uses a plain function.'
285
);
286
});
287
288
289
it('should expose the underlying class from a legacy factory', function() {
290
var Legacy = React.createClass({ render: function() { } });
291
var factory = React.createFactory(Legacy);
292
expect(factory.type).toBe(Legacy.type);
293
expect(factory().type).toBe(Legacy.type);
294
});
295
296
it('allows the use of PropTypes validators in statics', function() {
297
var Component = React.createClass({
298
render: () => null,
299
statics: {
300
specialType: React.PropTypes.shape({monkey: React.PropTypes.any})
301
}
302
});
303
304
expect(typeof Component.specialType).toBe("function");
305
expect(typeof Component.specialType.isRequired).toBe("function");
306
});
307
308
it('allows a DOM element to be used with a string', function() {
309
var element = React.createElement('div', { className: 'foo' });
310
var instance = ReactTestUtils.renderIntoDocument(element);
311
expect(instance.getDOMNode().tagName).toBe('DIV');
312
});
313
314
it('is indistinguishable from a plain object', function() {
315
var element = React.createElement('div', { className: 'foo' });
316
var object = {};
317
expect(element.constructor).toBe(object.constructor);
318
});
319
320
});
321
322