Skip to content

Commit

Permalink
Provider API change. some tests updated as well
Browse files Browse the repository at this point in the history
  • Loading branch information
gnoff committed Aug 24, 2015
1 parent 45654b7 commit aec29d8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 43 deletions.
62 changes: 32 additions & 30 deletions src/components/createProvider.js
Expand Up @@ -18,8 +18,10 @@ export default function createProvider(React) {

static propTypes = {
children: PropTypes.func.isRequired,
allowOverload: PropTypes.bool,
forwardProvided: PropTypes.bool,
provide: PropTypes.oneOfType([
PropTypes.object,
PropTypes.func,
]),
};

getChildContext() {
Expand All @@ -44,41 +46,41 @@ export default function createProvider(React) {
providedFromPropsAndContext(props, context) {
const isNestedProvider = isPlainObject(context.provided);
const parentProvided = isNestedProvider ? context.provided : {};
const { children, allowOverload, forwardProvided, ...provided} = props;

if (!isNestedProvider) {
return provided;
if (isNestedProvider) {
invariant(
isPlainObject(parentProvided),
'This Provider appears to be nested inside another provider but received a parent `provided` ' +
'is not a plain Object. `provided` must be always be a plain Object. %s',
parentProvided
);
}


const { provide } = props;
let provider = provide;

if (isPlainObject(provide)) {
provider = (parentProvided) => ({...parentProvided, ...provide})
}

let provided = provider(parentProvided);

invariant(
forwardProvided === true || forwardProvided === false,
'This Provider appears to be nested inside another provider. `forwardProvided` must be ' +
'specified (`true` or `false` boolean values only). Instead received %s.',
forwardProvided
);

if (!forwardProvided) {
return provided;
} else {
invariant(
allowOverload === true || allowOverload === false,
'This Provider appears to be nested inside another provider and configured to forward ' +
'`provided` from parent. `allowOverload` must be specified (`true` or `false` boolean ' +
'values only). Instead received %s.',
allowOverload
);
invariant(
allowOverload || hasEmptyIntersection(parentProvided, provided),
'This Provider is configured via `allowOverload` to disallow `provided` overloading but finds its ' +
'`provided props` conflicts with `provided props` from a parent Provider. the following `provided ' +
'props` would overload a parent `provided props`: %s.',
sharedKeys(parentProvided, provided)
);
return {...parentProvided, ...provided};
}
isPlainObject(provided),
'This Provider is attempting to provide something other than a plain Object. ' +
'the `provide` prop must either be a plain object itself or a function that returns ' +
'a plain Object. `provide` is or returned %s',
provided
);

return provided;
}

isNested() {

}

render() {
const { children } = this.props;
return children();
Expand Down
35 changes: 22 additions & 13 deletions test/components/Provider.spec.js
Expand Up @@ -32,7 +32,7 @@ describe('React', () => {
const obj = {a: 1};
const fn = () => obj;

it('should add the arbitrary props to the child context', () => {
it('should add the `provide` prop to the child context, if plain Object', () => {

const targetProvided = {
string: "a string",
Expand All @@ -42,7 +42,7 @@ describe('React', () => {
}

const tree = TestUtils.renderIntoDocument(
<Provider {...targetProvided}>
<Provider provide={targetProvided}>
{() => <Child />}
</Provider>
);
Expand All @@ -53,26 +53,35 @@ describe('React', () => {
expect(child.context.provided.object).toBe(obj);
});

it('should detect if it is a nested Provider', () => {
it('should add the `provide` prop return value to the child context, if function', () => {

const targetProvided = {
string: "a string",
number: 1,
func: fn,
object: obj,
}
const tree = TestUtils.renderIntoDocument(
<Provider provide={() => ({any: 'thing'})}>
{() => <Child />}
</Provider>
);

expect(() => TestUtils.renderIntoDocument(
<Provider {...targetProvided}>
const child = TestUtils.findRenderedComponentWithType(tree, Child);
expect(child.context.provided.any).toBe('thing');
});

it('should forward parent provided values if nested Provider', () => {

const forwardingTree = TestUtils.renderIntoDocument(
<Provider provide={{one: 1}}>
{() => (
<Child>
<Provider other="prop">
<Provider provide={{two: 2}}>
{() => <DeepChild />}
</Provider>
</Child>
)}
</Provider>
)).toThrow(/nested/)
)

const deepChild = TestUtils.findRenderedComponentWithType(forwardingTree, DeepChild);
expect(deepChild.context.provided).toEqual({one: 1, two: 2});

});

it('should require `forwardProps` prop if nested', () => {
Expand Down

0 comments on commit aec29d8

Please sign in to comment.