@samitouri / QOS-React / commits / 9d310e0bc7

ShallowRenderer should filter context by contextTypes (#11922)

Toru Kobayashi committed Jan 6, 2018 at 03:49 UTC 9d310e0bc7b9d5ce39d82536dfcb67f98462a346
2 files changed +41 -6
packages/react-test-renderer/src/ReactShallowRenderer.js
+17 -6
@@ -70,15 +70,15 @@ class ReactShallowRenderer {
70
71 this._rendering = true;
72 this._element = element;
73 - this._context = context;
73 + this._context = getMaskedContext(element.type.contextTypes, context);
74
75 if (this._instance) {
76 - this._updateClassComponent(element.type, element.props, context);
76 + this._updateClassComponent(element.type, element.props, this._context);
77 } else {
78 if (shouldConstruct(element.type)) {
79 this._instance = new element.type(
80 element.props,
81 - context,
81 + this._context,
82 this._updater,
83 );
84
@@ -87,7 +87,7 @@ class ReactShallowRenderer {
87
88 checkPropTypes(
89 element.type.contextTypes,
90 - context,
90 + this._context,
91 'context',
92 getName(element.type, this._instance),
93 getStackAddendum,
@@ -96,9 +96,9 @@ class ReactShallowRenderer {
96 currentlyValidatingElement = null;
97 }
98
99 - this._mountClassComponent(element.props, context);
99 + this._mountClassComponent(element.props, this._context);
100 } else {
101 - this._rendered = element.type(element.props, context);
101 + this._rendered = element.type(element.props, this._context);
102 }
103 }
104
@@ -290,4 +290,15 @@ function shouldConstruct(Component) {
290 return !!(Component.prototype && Component.prototype.isReactComponent);
291 }
292
293 +function getMaskedContext(contextTypes, unmaskedContext) {
294 + if (!contextTypes) {
295 + return emptyObject;
296 + }
297 + const context = {};
298 + for (let key in contextTypes) {
299 + context[key] = unmaskedContext[key];
300 + }
301 + return context;
302 +}
303 +
304 export default ReactShallowRenderer;
packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js
+24
@@ -216,6 +216,9 @@ describe('ReactShallowRenderer', () => {
216 </div>
217 );
218 }
219 + SomeComponent.contextTypes = {
220 + bar: PropTypes.string,
221 + };
222
223 const shallowRenderer = createRenderer();
224 const result = shallowRenderer.render(<SomeComponent foo={'FOO'} />, {
@@ -428,6 +431,9 @@ describe('ReactShallowRenderer', () => {
431 super(props, context);
432 this.state = initialState;
433 }
434 + static contextTypes = {
435 + context: PropTypes.string,
436 + };
437 componentDidUpdate(...args) {
438 componentDidUpdateParams.push(...args);
439 }
@@ -770,6 +776,24 @@ describe('ReactShallowRenderer', () => {
776 expect(result).toEqual(<div>foo:baz</div>);
777 });
778
779 + it('should filter context by contextTypes', () => {
780 + class SimpleComponent extends React.Component {
781 + static contextTypes = {
782 + foo: PropTypes.string,
783 + };
784 + render() {
785 + return <div>{`${this.context.foo}:${this.context.bar}`}</div>;
786 + }
787 + }
788 +
789 + const shallowRenderer = createRenderer();
790 + let result = shallowRenderer.render(<SimpleComponent />, {
791 + foo: 'foo',
792 + bar: 'bar',
793 + });
794 + expect(result).toEqual(<div>foo:undefined</div>);
795 + });
796 +
797 it('can fail context when shallowly rendering', () => {
798 class SimpleComponent extends React.Component {
799 static contextTypes = {