Don't transfer props to mocked empty component
We currently automatically render empty components in place of mocks. However, we were accidentally transferring the props from the mocked descriptor to the empty component placeholder. Even children. This change just cleans that up and should only affect unit tests.
Sebastian Markbage committed
Aug 29, 2014 at 08:51 UTC
3c6c437d07bdcd16c42e081fb8442ad54a0b2ff3
1 file changed
+30
-40
src/core/instantiateReactComponent.js
+30
-40
@@ -26,26 +26,36 @@ var ReactLegacyDescriptor = require('ReactLegacyDescriptor');
26
var ReactEmptyComponent = require('ReactEmptyComponent');
27
28
/**
29
- * Given `type` and `props` invoke the type function and create an instance from
30
- * it. For the normal case it just runs the constructor. For mocks we need to
31
- * invoke the convenience constructor and resolve that into an instance.
29
+ * Given a `componentDescriptor` create an instance that will actually be
30
+ * mounted.
31
*
33
- * @param {function} type
34
- * @param {*} props
35
- * @return {object} A new instance of `type`.
32
+ * @param {object} descriptor
33
+ * @return {object} A new instance of componentDescriptor's constructor.
34
* @protected
35
*/
38
-function createInstance(type, props) {
36
+function instantiateReactComponent(descriptor) {
37
+ var instance;
38
+
39
if (__DEV__) {
40
- if (type._mockedReactClassConstructor) {
40
+ warning(
41
+ descriptor && (typeof descriptor.type === 'function' ||
42
+ typeof descriptor.type === 'string'),
43
+ 'Only functions or strings can be mounted as React components.'
44
+ // Not really strings yet, but as soon as I solve the cyclic dep, they
45
+ // will be allowed here.
46
+ );
47
+
48
+ // Resolve mock instances
49
+ if (descriptor.type._mockedReactClassConstructor) {
50
// If this is a mocked class, we treat the legacy factory as if it was the
51
// class constructor for future proofing unit tests. Because this might
52
// be mocked as a legacy factory, we ignore any warnings triggerd by
53
// this temporary hack.
54
ReactLegacyDescriptor._isLegacyCallWarningEnabled = false;
46
- var instance;
55
try {
48
- instance = new type._mockedReactClassConstructor(props);
56
+ instance = new descriptor.type._mockedReactClassConstructor(
57
+ descriptor.props
58
+ );
59
} finally {
60
ReactLegacyDescriptor._isLegacyCallWarningEnabled = true;
61
}
@@ -53,9 +63,7 @@ function createInstance(type, props) {
63
// If the mock implementation was a legacy factory, then it returns a
64
// descriptor. We need to turn this into a real component instance.
65
if (ReactDescriptor.isValidDescriptor(instance)) {
56
- type = instance.type;
57
- props = instance.props;
58
- instance = new type(props);
66
+ instance = new instance.type(instance.props);
67
}
68
69
var render = instance.render;
@@ -63,10 +71,10 @@ function createInstance(type, props) {
71
// For auto-mocked factories, the prototype isn't shimmed and therefore
72
// there is no render function on the instance. We replace the whole
73
// component with an empty component instance instead.
66
- var descriptor = ReactEmptyComponent.getEmptyComponent();
67
- type = descriptor.type;
68
- props = descriptor.props;
69
- instance = new type(props);
74
+ descriptor = ReactEmptyComponent.getEmptyComponent();
75
+ instance = new descriptor.type(descriptor.props);
76
+ instance.construct(descriptor);
77
+ return instance;
78
} else if (render._isMockFunction && !render._getMockImplementation()) {
79
// Auto-mocked components may have a prototype with a mocked render
80
// function. For those, we'll need to mock the result of the render
@@ -75,32 +83,13 @@ function createInstance(type, props) {
83
ReactEmptyComponent.getEmptyComponent
84
);
85
}
86
+ instance.construct(descriptor);
87
+ return instance;
88
}
89
}
80
- // Normal case for non-mocks
81
- return new type(props);
82
-}
83
-
84
-/**
85
- * Given a `componentDescriptor` create an instance that will actually be
86
- * mounted.
87
- *
88
- * @param {object} descriptor
89
- * @return {object} A new instance of componentDescriptor's constructor.
90
- * @protected
91
- */
92
-function instantiateReactComponent(descriptor) {
93
- if (__DEV__) {
94
- warning(
95
- descriptor && (typeof descriptor.type === 'function' ||
96
- typeof descriptor.type === 'string'),
97
- 'Only functions or strings can be mounted as React components.'
98
- // Not really strings yet, but as soon as I solve the cyclic dep, they
99
- // will be allowed here.
100
- );
101
- }
90
103
- var instance = createInstance(descriptor.type, descriptor.props);
91
+ // Normal case for non-mocks
92
+ instance = new descriptor.type(descriptor.props);
93
94
if (__DEV__) {
95
warning(
@@ -114,6 +103,7 @@ function instantiateReactComponent(descriptor) {
103
// This actually sets up the internal instance. This will become decoupled
104
// from the public instance in a future diff.
105
instance.construct(descriptor);
106
+
107
return instance;
108
}
109