Skip to content

Commit 696a272

Browse files
Matthew Howardljharb
Matthew Howard
authored andcommitted
[Fix] shallow: Share child context logic between shallow and dive
1 parent e57dbe8 commit 696a272

File tree

2 files changed

+81
-13
lines changed

2 files changed

+81
-13
lines changed

packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx

+61
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,67 @@ describe('shallow', () => {
604604
expect(consumer.text()).to.equal('howdy!');
605605
});
606606
});
607+
608+
describe('shallow() on Provider and Consumer', () => {
609+
let Provider;
610+
let Consumer;
611+
612+
beforeEach(() => {
613+
({ Provider, Consumer } = React.createContext('howdy!'));
614+
});
615+
616+
class Consumes extends React.Component {
617+
render() {
618+
return (
619+
<span>
620+
<Consumer>{(value) => <span>{value}</span>}</Consumer>
621+
</span>
622+
);
623+
}
624+
}
625+
626+
class Provides extends React.Component {
627+
render() {
628+
const { children } = this.props;
629+
630+
return (
631+
<Provider value="foo"><div><div />{children}</div></Provider>
632+
);
633+
}
634+
}
635+
636+
class MyComponent extends React.Component {
637+
render() {
638+
return (
639+
<Provides><Consumes /></Provides>
640+
);
641+
}
642+
}
643+
644+
it('works on a Provider', () => {
645+
const wrapper = shallow(<MyComponent />);
646+
const provides = wrapper.find(Provides).dive();
647+
const provider = provides.find(Provider).shallow();
648+
expect(provider.text()).to.equal('<Consumes />');
649+
});
650+
651+
it('always gives the default provider value if shallow() rendering a <Consumer /> directly', () => {
652+
// Diving directly on a consumer will give you the default value
653+
const wrapper = shallow(<MyComponent />);
654+
const consumes = wrapper.find(Consumes).shallow();
655+
const consumer = consumes.find(Consumer).shallow();
656+
expect(consumer.text()).to.equal('howdy!');
657+
});
658+
659+
it('gives the actual <Provider /> value if one dive()s it', () => {
660+
const wrapper = shallow(<MyComponent />);
661+
const provides = wrapper.find(Provides).shallow();
662+
const provider = provides.find(Provider).shallow();
663+
const consumes = provider.find(Consumes).shallow();
664+
const consumer = consumes.find(Consumer).shallow();
665+
expect(consumer.text()).to.equal('foo');
666+
});
667+
});
607668
});
608669

609670
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {

packages/enzyme/src/ShallowWrapper.js

+20-13
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,20 @@ function makeShallowOptions(nodes, root, passedOptions, wrapper) {
369369
}
370370

371371

372+
function makeInheritedChildOptions(wrapper, options = {}) {
373+
const childOptions = {
374+
...wrapper[OPTIONS],
375+
...options,
376+
context: options.context || {
377+
...wrapper[OPTIONS].context,
378+
...wrapper[ROOT][CHILD_CONTEXT],
379+
},
380+
};
381+
privateSet(childOptions, PROVIDER_VALUES, wrapper[ROOT][PROVIDER_VALUES]);
382+
return childOptions;
383+
}
384+
385+
372386
/**
373387
* @class ShallowWrapper
374388
*/
@@ -1280,10 +1294,11 @@ class ShallowWrapper {
12801294
* @param {Object} options
12811295
* @returns {ShallowWrapper}
12821296
*/
1283-
shallow(options) {
1284-
return this.single('shallow', (n) => (
1285-
this.wrap(getAdapter(this[OPTIONS]).nodeToElement(n), null, options)
1286-
));
1297+
shallow(options = {}) {
1298+
return this.single('shallow', (n) => {
1299+
const childOptions = makeInheritedChildOptions(this, options);
1300+
return this.wrap(getAdapter(this[OPTIONS]).nodeToElement(n), null, childOptions);
1301+
});
12871302
}
12881303

12891304
/**
@@ -1694,15 +1709,7 @@ class ShallowWrapper {
16941709
if (!isCustomComponentElement(el, adapter)) {
16951710
throw new TypeError(`ShallowWrapper::${name}() can only be called on components`);
16961711
}
1697-
const childOptions = {
1698-
...this[OPTIONS],
1699-
...options,
1700-
context: options.context || {
1701-
...this[OPTIONS].context,
1702-
...this[ROOT][CHILD_CONTEXT],
1703-
},
1704-
};
1705-
privateSet(childOptions, PROVIDER_VALUES, this[ROOT][PROVIDER_VALUES]);
1712+
const childOptions = makeInheritedChildOptions(this, options);
17061713
return this.wrap(el, null, childOptions);
17071714
});
17081715
}

0 commit comments

Comments
 (0)