Skip to content

Commit

Permalink
Merge a137946 into 558d5cf
Browse files Browse the repository at this point in the history
  • Loading branch information
pgangwani committed Mar 17, 2019
2 parents 558d5cf + a137946 commit 2052306
Show file tree
Hide file tree
Showing 2 changed files with 629 additions and 48 deletions.
336 changes: 315 additions & 21 deletions packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ import {
forwardRef,
memo,
PureComponent,
useEffect,
useState,
useEffect,
act,
} from './_helpers/react-compat';
import {
describeWithDOM,
Expand Down Expand Up @@ -183,6 +184,7 @@ describeWithDOM('mount', () => {
expect(() => wrapper.state('key')).to.throw('ReactWrapper::state("key") requires that `state` not be `null` or `undefined`');
});

// TODO: to fix below test cases as it breaks on watch command
describeIf(is('>= 16.3'), 'uses the isValidElementType from the Adapter to validate the prop type of Component', () => {
const Foo = () => null;
const Bar = () => null;
Expand Down Expand Up @@ -656,40 +658,332 @@ describeWithDOM('mount', () => {
</Foo>`);
});
});

describeIf(is('>= 16.8'), 'hooks', () => {
it('works with `useEffect`', (done) => {
function ComponentUsingEffectHook() {
const [ctr, setCtr] = useState(0);
describe('useState', () => {
/*
Test Component
*/
function FooCounter({ initialCount = 0 }) {
const [count, setCount] = useState(+initialCount);

return (
<Fragment>
<button className="increment" type="button" onClick={() => setCount(count + 1)}>-</button>
<span className="counter">
{count}
</span>
<button className="decrement" type="button" onClick={() => setCount(count - 1)}>+</button>
</Fragment>
);
}

// Test data
let wrapper;
const initialCount = 5;

it('initial render', () => {
wrapper = mount(<FooCounter initialCount={initialCount} />);
expect(wrapper.find('.counter').text()).to.equal(String(initialCount));
});

it('lets increment', () => {
wrapper = mount(<FooCounter initialCount={initialCount} />);
// count: 5
wrapper.find('.increment').props().onClick();
// should be 6
expect(wrapper.find('.counter').text()).to.equal(String(initialCount + 1));
});

it('now decrement', () => {
// count: 6
wrapper = mount(<FooCounter initialCount={initialCount} />);
wrapper.find('.decrement').props().onClick();
// I dont know why this test case is breaking
// seems to be working fine in my project repo
// TODO: need to figure out why broken test cases here
// should be 5
expect(wrapper.find('.counter').text()).to.equal(String(initialCount - 1));
});
});
describe('useEffect with mount effect', () => {
// Test data
let wrapper;
const didMountCOunt = 9;

/*
Test Component
*/
function FooCounterWithMountEffect({ initialCount = 0 }) {
const [count, setCount] = useState(+initialCount);

useEffect(() => {
setCtr(1);
setTimeout(() => {
setCtr(2);
}, 1e3);
setCount(didMountCOunt);
}, []);
return (
<div>
{ctr}
</div>
<Fragment>
<span className="counter">
{count}
</span>
</Fragment>
);
}
const wrapper = mount(<ComponentUsingEffectHook />);

expect(wrapper.debug()).to.equal(`<ComponentUsingEffectHook>
it('initial render after did mount effect', () => {
wrapper = mount(<FooCounterWithMountEffect />);
expect(wrapper.find('.counter').text()).to.equal(String(didMountCOunt));
});
});
describe('useEffect with async effect', () => {
// TODO: enable when the shallow renderer fixes its bug
it('works with `useEffect`', (done) => {
function ComponentUsingEffectHook() {
const [ctr, setCtr] = useState(0);
useEffect(() => {
setCtr(1);
setTimeout(() => {
setCtr(2);
}, 1e3);
}, []);
return (
<div>
{ctr}
</div>
);
}
const wrapper = mount(<ComponentUsingEffectHook />);

expect(wrapper.debug()).to.equal(
`<ComponentUsingEffectHook>
<div>
1
</div>
</ComponentUsingEffectHook>`);
</ComponentUsingEffectHook>`,
);

setTimeout(() => {
wrapper.update();
expect(wrapper.debug()).to.equal(`<ComponentUsingEffectHook>
setTimeout(() => {
wrapper.update();
expect(wrapper.debug()).to.equal(
`<ComponentUsingEffectHook>
<div>
2
</div>
</ComponentUsingEffectHook>`);
done();
}, 1e3);
</ComponentUsingEffectHook>`,
);
done();
}, 1e3);
});
});

describe('useState with willReceive prop effect / simulate getDerivedStateFromProp', () => {
// Test data
let wrapper;
const initialCount = 5;
const newPropCount = 10;


/*
Test Component
*/
function FooCounter({ initialCount = 0 }) {
const [count, setCount] = useState(+initialCount);

useEffect(() => {
setCount(initialCount);
}, [initialCount]);

return (
<Fragment>
<span className="counter">
{count}
</span>
</Fragment>
);
}

it('initial render & new Props', () => {
wrapper = mount(<FooCounter initialCount={initialCount} />);
expect(wrapper.find('.counter').text()).to.equal(String(initialCount));

wrapper.setProps({ initialCount: newPropCount });

// works with act
// act( () => {
// wrapper.setProps({ initialCount: newPropCount});
// })
expect(wrapper.find('.counter').text()).to.equal(String(newPropCount));

});

});

describe('useEffect on componentDidUpdate & componentDidMount', () => {
const setDocumentTitle = sinon.stub();
function ClickCounterPage() {
const [count, setCount] = useState(0);

useEffect(() => {
setDocumentTitle(`You clicked ${count} times`);
});

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

let wrapper;

beforeEach(() => {
setDocumentTitle.reset();
});

it('on mount initial render', () => {
wrapper = mount(<ClickCounterPage />);
const expectedCountString = 'You clicked 0 times';
expect(wrapper.find('p').text()).to.eq(expectedCountString);

// TODO: Should be controlled Commit REnder here
// then test
expect(setDocumentTitle.calledOnceWith(expectedCountString)).to.true;
});
it('on didupdate', () => {
wrapper = mount(<ClickCounterPage />);
const click = wrapper.find('button').props().onClick;
click();
const expectedCountString = 'You clicked 1 times';
expect(wrapper.find('p').text()).to.eq(expectedCountString);

// TODO: Should be controlled Commit REnder here
// then test
expect(setDocumentTitle.calledOnceWith(expectedCountString)).to.true;

click();
click();
// TODO: Should be controlled Commit REnder here
expect(setDocumentTitle.calledThrice).to.true;
});
});

describe('useEffect with cleanup Effect', () => {
const ChatAPI = {
subscribeToFriendStatus: sinon.stub(),
unsubscribeFromFriendStatus: sinon.stub(),
};
function FriendStatus({ friend = {} }) {
const [isOnline, setIsOnline] = useState(null);

function handleStatusChange(status) {
setIsOnline(status.isOnline);
}

useEffect(() => {
ChatAPI.subscribeToFriendStatus(friend.id, handleStatusChange);
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(friend.id, handleStatusChange);
};
});

if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}

let wrapper;
const friend = { id: 'enzyme' };
let simulateChange;

it('on initial mount', () => {
wrapper = mount(<FriendStatus friend={friend} />);
expect(wrapper.debug()).to.eql(
`<FriendStatus friend={{...}}>
Loading...
</FriendStatus>`,
);
// TODO: uncomment later after fix
// expect(wrapper.html()).to.eql(`Loading...`);
expect(ChatAPI.subscribeToFriendStatus.calledOnceWith(friend.id)).to.true;
});

it('simulate status Change', () => {
wrapper = mount(<FriendStatus friend={friend} />);
simulateChange = ChatAPI.subscribeToFriendStatus.args[1];
simulateChange({ isOnline: true });
expect(wrapper.html()).to.eql('Online');
});
it('simulate status Change again', () => {
wrapper = mount(<FriendStatus friend={friend} />);
simulateChange = ChatAPI.subscribeToFriendStatus.args[1];
simulateChange({ isOnline: false });
expect(wrapper.html()).to.eql('Offline');
});
it('cleanup on unmount', () => {
wrapper = mount(<FriendStatus friend={friend} />);
wrapper.unmount();
expect(ChatAPI.unsubscribeFromFriendStatus.calledOnceWith(friend.id)).to.true;
});
});

describe('custom hook : useCounter', () => {
function useCounter({ initialCount = 0, step = 1 } = {}) {
const [count, setCount] = useState(initialCount);
const increment = () => setCount(c => c + step);
const decrement = () => setCount(c => c - step);
return { count, increment, decrement };
}
// testing custom hooks with renderProps
// may be we can think of adding in utils
// will be repeatedl
const Counter = ({ children, ...rest }) => children(useCounter(rest));

function setup(props) {
const returnVal = {};
mount(
<Counter {...props}>
{(val) => {
Object.assign(returnVal, val);
return null;
}}
</Counter>,
);
return returnVal;
}

it('useCounter', () => {
const counterData = setup();
counterData.increment();
expect(counterData).to.have.property('count', 1);
counterData.decrement();
expect(counterData).to.have.property('count', 0);
});

it('useCounter with initialCount', () => {
const counterData = setup({ initialCount: 2 });
counterData.increment();
expect(counterData).to.have.property('count', 3);
counterData.decrement();
expect(counterData).to.have.property('count', 2);
});

it('useCounter with step', () => {
const counterData = setup({ step: 2 });
counterData.increment();
expect(counterData).to.have.property('count', 2);
counterData.decrement();
expect(counterData).to.have.property('count', 0);
});

it('useCounter with step and initialCount', () => {
const counterData = setup({ step: 2, initialCount: 5 });
counterData.increment();
expect(counterData).to.have.property('count', 7);
counterData.decrement();
expect(counterData).to.have.property('count', 5);
});
});
});

Expand Down
Loading

0 comments on commit 2052306

Please sign in to comment.