Merge pull request #6362 from gaearon/no-owner-in-test-utils

Elements from functional components in TestUtils should have no owner
(cherry picked from commit ae56910573)
This commit is contained in:
Dan Abramov
2016-04-27 22:59:40 -07:00
committed by Paul O’Shannessy
parent 3655e30adb
commit e88c96b1d7
3 changed files with 62 additions and 36 deletions
@@ -60,6 +60,10 @@ function warnIfInvalidElement(Component, element) {
}
}
function shouldConstruct(Component) {
return Component.prototype && Component.prototype.isReactComponent;
}
/**
* ------------------ The Life-Cycle of a Composite Component ------------------
*
@@ -158,44 +162,22 @@ var ReactCompositeComponentMixin = {
var Component = this._currentElement.type;
// Initialize the public class
var inst;
var inst = this._constructComponent(publicProps, publicContext);
var renderedElement;
if (Component.prototype && Component.prototype.isReactComponent) {
if (__DEV__) {
ReactCurrentOwner.current = this;
try {
inst = new Component(publicProps, publicContext, ReactUpdateQueue);
} finally {
ReactCurrentOwner.current = null;
}
} else {
inst = new Component(publicProps, publicContext, ReactUpdateQueue);
}
} else {
if (__DEV__) {
ReactCurrentOwner.current = this;
try {
inst = Component(publicProps, publicContext, ReactUpdateQueue);
} finally {
ReactCurrentOwner.current = null;
}
} else {
inst = Component(publicProps, publicContext, ReactUpdateQueue);
}
if (inst == null || inst.render == null) {
renderedElement = inst;
warnIfInvalidElement(Component, renderedElement);
invariant(
inst === null ||
inst === false ||
ReactElement.isValidElement(inst),
'%s(...): A valid React element (or null) must be returned. You may have ' +
'returned undefined, an array or some other invalid object.',
Component.displayName || Component.name || 'Component'
);
inst = new StatelessComponent(Component);
}
// Support functional components
if (!shouldConstruct(Component) && (inst == null || inst.render == null)) {
renderedElement = inst;
warnIfInvalidElement(Component, renderedElement);
invariant(
inst === null ||
inst === false ||
ReactElement.isValidElement(inst),
'%s(...): A valid React element (or null) must be returned. You may have ' +
'returned undefined, an array or some other invalid object.',
Component.displayName || Component.name || 'Component'
);
inst = new StatelessComponent(Component);
}
if (__DEV__) {
@@ -323,6 +305,28 @@ var ReactCompositeComponentMixin = {
return markup;
},
_constructComponent: function(publicProps, publicContext) {
if (__DEV__) {
ReactCurrentOwner.current = this;
try {
return this._constructComponentWithoutOwner(publicProps, publicContext);
} finally {
ReactCurrentOwner.current = null;
}
} else {
return this._constructComponentWithoutOwner(publicProps, publicContext);
}
},
_constructComponentWithoutOwner: function(publicProps, publicContext) {
var Component = this._currentElement.type;
if (shouldConstruct(Component)) {
return new Component(publicProps, publicContext, ReactUpdateQueue);
} else {
return Component(publicProps, publicContext, ReactUpdateQueue);
}
},
performInitialMountWithErrorHandling: function(
renderedElement,
nativeParent,
+2
View File
@@ -399,6 +399,8 @@ var ShallowComponentWrapper = function(element) {
Object.assign(
ShallowComponentWrapper.prototype,
ReactCompositeComponent.Mixin, {
_constructComponent:
ReactCompositeComponent.Mixin._constructComponentWithoutOwner,
_instantiateReactComponent: function(element) {
return new NoopInternalComponent(element);
},
+20
View File
@@ -47,6 +47,26 @@ describe('ReactTestUtils', function() {
]);
});
it('should shallow render a functional component', function() {
function SomeComponent() {
return (
<div>
<span className="child1" />
<span className="child2" />
</div>
);
}
var shallowRenderer = ReactTestUtils.createRenderer();
var result = shallowRenderer.render(<SomeComponent />);
expect(result.type).toBe('div');
expect(result.props.children).toEqual([
<span className="child1" />,
<span className="child2" />,
]);
});
it('should throw for invalid elements', function() {
var SomeComponent = React.createClass({
render: function() {