Skip to content

Commit

Permalink
More robust naming collision warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
helloitsjoe committed Sep 5, 2019
1 parent 7ce1137 commit 62bdc3e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 17 deletions.
46 changes: 31 additions & 15 deletions src/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const useChange = (initialValue = INITIAL_VALUE) => {

const useUseState = () => useState(INITIAL_COUNT);

const TestComponent = () => <div>Test</div>;
const TestComponent = ({ text = 'Test' }) => <div>{text}</div>;

test('passes custom hooks to component', () => {
const Container = composeHooks({ useCount, useChange })(TestComponent);
Expand Down Expand Up @@ -98,33 +98,49 @@ test('can pass props to hooks via function', () => {
describe('Edge cases', () => {
it('returns component if no hooks', () => {
const Container = composeHooks()(TestComponent);
const wrapper = shallow(<Container />);
expect(wrapper.html()).toMatchInlineSnapshot(`"<div>Test</div>"`);
const wrapper = shallow(<Container text="some text" />);
expect(wrapper.html()).toMatchInlineSnapshot(`"<div>some text</div>"`);
});

it('throws if no component', () => {
expect(() => composeHooks()()).toThrowErrorMatchingInlineSnapshot(
`"Component must be provided to compose"`
);
});
});

describe('Naming collisions', () => {
const useOne = () => ({ text: 'one' });
const useTwo = () => ({ text: 'two' });
const useNumber = () => ({ number: 1 });
const useBool = () => ({ bool: true });
const useNull = () => ({ null: 'not-null' });

it('if prop and hook names collide, props win', () => {
const Container = composeHooks({ useChange })(TestComponent);
const wrapper = shallow(<Container />);
expect(wrapper.find(TestComponent).props().value).toBe('hi');
wrapper.setProps({ value: 'newValue' });
expect(wrapper.find(TestComponent).props().value).toBe('newValue');
jest.spyOn(console, 'warn');
const Container = composeHooks({ useOne, useNumber, useBool, useNull })(TestComponent);
// Check falsy values, should warn for everything but undefined
const wrapper = mount(<Container text="" number={0} bool={false} null={null} />);
const [first, second, third, fourth] = console.warn.mock.calls;
expect(first[0]).toMatchInlineSnapshot(`"prop 'text' exists, overriding with value: ''"`);
expect(second[0]).toMatchInlineSnapshot(`"prop 'number' exists, overriding with value: '0'"`);
expect(third[0]).toMatchInlineSnapshot(`"prop 'bool' exists, overriding with value: 'false'"`);
expect(fourth[0]).toMatchInlineSnapshot(`"prop 'null' exists, overriding with value: 'null'"`);
expect(wrapper.find(TestComponent).props().text).toBe('');
expect(wrapper.find(TestComponent).props().number).toBe(0);
expect(wrapper.find(TestComponent).props().bool).toBe(false);
expect(wrapper.find(TestComponent).props().null).toBe(null);
jest.restoreAllMocks();
});

it('warns on hook name collisions', () => {
console.warn = jest.fn().mockImplementationOnce(() => {});
const useChangeTwo = () => ({ value: 'duplicate-hook-prop' });
const Container = composeHooks({ useChange, useChangeTwo })(TestComponent);
const wrapper = shallow(<Container />);
it('if multiple hook value names collide, last one wins', () => {
jest.spyOn(console, 'warn');
const Container = composeHooks({ useOne, useTwo })(TestComponent);
const wrapper = mount(<Container />);
expect(console.warn.mock.calls[0][0]).toMatchInlineSnapshot(
`"prop 'value' exists, overriding with value: duplicate-hook-prop"`
`"prop 'text' exists, overriding with value: 'two'"`
);
expect(wrapper.find(TestComponent).props().value).toBe('duplicate-hook-prop');
expect(wrapper.find(TestComponent).text()).toBe('two');
jest.restoreAllMocks();
});
});
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ const composeHooks = hooks => Component => {
}

Object.entries(hookValue).forEach(([key, value]) => {
if (acc[key]) {
console.warn(`prop '${key}' exists, overriding with value: ${value}`);
const duplicate = acc[key] ? value : props[key];

if (typeof duplicate !== 'undefined') {
console.warn(`prop '${key}' exists, overriding with value: '${duplicate}'`);
}
acc[key] = value;
});
Expand Down

0 comments on commit 62bdc3e

Please sign in to comment.