8000 Move ReactClass, ReactElement and ReactPropTypes into "traditional" · gitcommituser/react@801e953 · GitHub
[go: up one dir, main page]

Skip to content < 10000 script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_document-metadata_document-metadata_ts-ui_packages_hydro-analytics_hydro-analytic-f29230-07417997172c.js" defer="defer">

Commit 801e953

Browse files
committed
Move ReactClass, ReactElement and ReactPropTypes into "traditional"
This moves ReactClass, ReactElement and ReactPropTypes into a legacy folder but since it's not quite legacy yet, I call it "classic". These are "classic" because they are decoupled and can be replaced by ES6 classes, JSX and Flow respectively. This also extracts unit tests from ReactCompositeComponent, which was terribly overloaded, into the new corresponding test suites. There is one weird case for ReactContextValidator. This actually happens in core, and technically belongs to ReactCompositeComponent. I'm not sure we will be able to statically validate contexts so this might be a case for dynamic checks even in the future. Leaving the unit tests in classic until we can figure out what to do with them.
1 parent d1ab4cd commit 801e953

17 files changed

+1218
-1124
lines changed
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
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+
// This test doesn't really have a good home yet. I'm leaving it here since this
13+
// behavior belongs to the old propTypes system yet is currently implemented
14+
// in the core ReactCompositeComponent. It should technically live in core's
15+
// test suite but I'll leave it here to indicate that this is an issue that
16+
// needs to be fixed.
17+
18+
"use strict";
19+
20+
var React;
21+
var ReactTestUtils;
22+
23+
var reactComponentExpect;
24+
var mocks;
25+
26+
describe('ReactContextValidator', function() {
27+
beforeEach(function() {
28+
require('mock-modules').dumpCache();
29+
30+
React = require('React');
31+
ReactTestUtils = require('ReactTestUtils');
32+
reactComponentExpect = require('reactComponentExpect');
33+
mocks = require('mocks');
34+
35+
console.warn = mocks.getMockFunction();
36+
});
37+
38+
// TODO: This behavior creates a runtime dependency on propTypes. We should
39+
// ensure that this is not required for ES6 classes with Flow.
40+
41+
it('should filter out context not in contextTypes', function() {
42+
var Component = React.createClass({
43+
contextTypes: {
44+
foo: React.PropTypes.string
45+
},
46+
47+
render: function() {
48+
return <div />;
49+
}
50+
});
51+
52+
var ComponentInFooBarContext = React.createClass({
53+
childContextTypes: {
54+
foo: React.PropTypes.string,
55+
bar: React.PropTypes.number
56+
},
57+
58+
getChildContext: function() {
59+
return {
60+
foo: 'abc',
61+
bar: 123
62+
};
63+
},
64+
65+
render: function() {
66+
return <Component />;
67+
}
68+
});
69+
70+
var instance = ReactTestUtils.renderIntoDocument(<ComponentInFooBarContext />);
71+
reactComponentExpect(instance).expectRenderedChild().scalarContextEqual({foo: 'abc'});
72+
});
73+
74+
it('should filter context properly in callbacks', function() {
75+
var actualComponentWillReceiveProps;
76+
var actualShouldComponentUpdate;
77+
var actualComponentWillUpdate;
78+
var actualComponentDidUpdate;
79+
80+
var Parent = React.createClass({
81+
childContextTypes: {
82+
foo: React.PropTypes.string.isRequired,
83+
bar: React.PropTypes.string.isRequired
84+
},
85+
86+
getChildContext: function() {
87+
return {
88+
foo: this.props.foo,
89+
bar: "bar"
90+
};
91+
},
92+
93+
render: function() {
94+
return <Component />;
95+
}
96+
});
97+
98+
var Component = React.createClass({
99+
contextTypes: {
100+
foo: React.PropTypes.string
101+
},
102+
103+
componentWillReceiveProps: function(nextProps, nextContext) {
104+
actualComponentWillReceiveProps = nextContext;
105+
return true;
106+
},
107+
108+
shouldComponentUpdate: function(nextProps, nextState, nextContext) {
109+
actualShouldComponentUpdate = nextContext;
110+
return true;
111+
},
112+
113+
componentWillUpdate: function(nextProps, nextState, nextContext) {
114+
actualComponentWillUpdate = nextContext;
115+
},
116+
117+
componentDidUpdate: function(prevProps, prevState, prevContext) {
118+
actualComponentDidUpdate = prevContext;
119+
},
120+
121+
render: function() {
122+
return <div />;
123+
}
124+
});
125+
126+
var instance = <Parent foo="abc" />;
127+
instance = ReactTestUtils.renderIntoDocument(instance);
128+
instance.replaceProps({foo: "def"});
129+
expect(actualComponentWillReceiveProps).toEqual({foo: 'def'});
130+
expect(actualShouldComponentUpdate).toEqual({foo: 'def'});
131+
expect(actualComponentWillUpdate).toEqual({foo: 'def'});
132+
expect(actualComponentDidUpdate).toEqual({foo: 'abc'});
133+
});
134+
135+
it('should check context types', function() {
136+
var Component = React.createClass({
137+
contextTypes: {
138+
foo: React.PropTypes.string.isRequired
139+
},
140+
141+
render: function() {
142+
return <div />;
143+
}
144+
});
145+
146+
ReactTestUtils.renderIntoDocument(<Component />);
147+
148+
expect(console.warn.mock.calls.length).toBe(1);
149+
expect(console.warn.mock.calls[0][0]).toBe(
150+
'Warning: Required context `foo` was not specified in `Component`.'
151+
);
152+
153+
var ComponentInFooStringContext = React.createClass({
154+
childContextTypes: {
155+
foo: React.PropTypes.string
156+
},
157+
158+
getChildContext: function() {
159+
return {
160+
foo: this.props.fooValue
161+
};
162+
},
163+
164+
render: function() {
165+
return <Component />;
166+
}
167+
});
168+
169+
ReactTestUtils.renderIntoDocument(
170+
<ComponentInFooStringContext fooValue={'bar'} />
171+
);
172+
173+
// Previous call should not error
174+
expect(console.warn.mock.calls.length).toBe(1);
175+
176+
var ComponentInFooNumberContext = React.createClass({
177+
childContextTypes: {
178+
foo: React.PropTypes.number
179+
},
180+
181+
getChildContext: function() {
182+
return {
183+
foo: this.props.fooValue
184+
};
185+
},
186+
187+
render: function() {
188+
return <Component />;
189+
}
190+
});
191+
192+
ReactTestUtils.renderIntoDocument(<ComponentInFooNumberContext fooValue={123} />);
193+
194+
expect(console.warn.mock.calls.length).toBe(2);
195+
expect(console.warn.mock.calls[1][0]).toBe(
196+
'Warning: Invalid context `foo` of type `number` supplied ' +
197+
'to `Component`, expected `string`.' +
198+
' Check the render method of `ComponentInFooNumberContext`.'
199+
);
200+
});
201+
202+
it('should check child context types', function() {
203+
var Component = React.createClass({
204+
childContextTypes: {
205+
foo: React.PropTypes.string.isRequired,
206+
bar: React.PropTypes.number
207+
},
208+
209+
getChildContext: function() {
210+
return this.props.testContext;
211+
},
212+
213+
render: function() {
214+
return <div />;
215+
}
216+
});
217+
218+
ReactTestUtils.renderIntoDocument(<Component testContext={{bar: 123}} />);
219+
expect(console.warn.mock.calls.length).toBe(2);
220+
expect(console.warn.mock.calls[0][0]).toBe(
221+
'Warning: Required child context `foo` was not specified in `Component`.'
222+
);
223+
expect(console.warn.mock.calls[1][0]).toBe(
224+
'Warning: Required child context `foo` was not specified in `Component`.'
225+
);
226+
227+
ReactTestUtils.renderIntoDocument(<Component testContext={{foo: 123}} />);
228+
229+
expect(console.warn.mock.calls.length).toBe(4);
230+
expect(console.warn.mock.calls[3][0]).toBe(
231+
'Warning: Invalid child context `foo` of type `number` ' +
232+
'supplied to `Component`, expected `string`.'
233+
);
234+
235+
ReactTestUtils.renderIntoDocument(
236+
<Component testContext={{foo: 'foo', bar: 123}} />
237+
);
238+
239+
ReactTestUtils.renderIntoDocument(
240+
<Component testContext={{foo: 'foo'}} />
241+
);
242+
243+
// Previous calls should not log errors
244+
expect(console.warn.mock.calls.length).toBe(4);
245+
});
246+
247+
});
File renamed without changes.

0 commit comments

Comments
 (0)
0