From f7897d4c388bf6f0197503d75fdc81119f3b344f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E4=B9=99=E5=B1=B1?= Date: Wed, 29 May 2019 20:38:45 +0800 Subject: [PATCH] [Tests] Add `useCallback` tests `shallow`: Note that the `get same callback when using `useCallback` and rerender with same prop in dependencies` is skipped because react shallow renderer doesn't memoize callback function value. Pending https://github.com/facebook/react/issues/15774 --- .../test/ReactWrapper-spec.jsx | 43 +++++++++++++++- .../test/ShallowWrapper-spec.jsx | 51 ++++++++++++++++--- 2 files changed, 86 insertions(+), 8 deletions(-) diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index fdf924633..2057ce6ca 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -29,6 +29,7 @@ import { Profiler, PureComponent, Suspense, + useCallback, useEffect, useLayoutEffect, useMemo, @@ -613,7 +614,7 @@ describeWithDOM('mount', () => { ); const context = { name: 'foo' }; - expect(() => mount(, { context })).to.not.throw(); + expect(() => mount(, { context })).not.to.throw(); }); itIf(is('< 16'), 'is introspectable through context API', () => { @@ -1069,7 +1070,45 @@ describeWithDOM('mount', () => { const initialValue = wrapper.find(Child).prop('memoized'); wrapper.setProps({ relatedProp: '123' }); const nextValue = wrapper.find(Child).prop('memoized'); - expect(initialValue).to.not.equal(nextValue); + expect(initialValue).not.to.equal(nextValue); + }); + + it('get same callback when using `useCallback` and rerender with same prop in dependencies', () => { + function Child() { + return null; + } + function ComponentUsingCallbackHook(props) { + const { onChange } = props; + const callback = useCallback(value => onChange(value), [onChange]); + return ( + + ); + } + const onChange = () => {}; + const wrapper = mount(); + const initialCallback = wrapper.find(Child).prop('callback'); + wrapper.setProps({ unRelatedProp: '123' }); + const nextCallback = wrapper.find(Child).prop('callback'); + expect(initialCallback).to.equal(nextCallback); + }); + + it('get different callback when using `useCallback` and rerender with different prop in dependencies', () => { + function Child() { + return null; + } + function ComponentUsingCallbackHook(props) { + const { onChange, relatedProp } = props; + const callback = useCallback(value => onChange(value), [onChange, relatedProp]); + return ( + + ); + } + const onChange = () => {}; + const wrapper = mount(); + const initialCallback = wrapper.find(Child).prop('callback'); + wrapper.setProps({ relatedProp: '123' }); + const nextCallback = wrapper.find(Child).prop('callback'); + expect(initialCallback).not.to.equal(nextCallback); }); }); diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 26e8ec803..d4f6e507e 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -26,6 +26,7 @@ import { lazy, PureComponent, Suspense, + useCallback, useEffect, useMemo, useLayoutEffect, @@ -412,7 +413,7 @@ describe('shallow', () => { }); const context = { name: 'foo' }; - expect(() => shallow(, { context })).to.not.throw(); + expect(() => shallow(, { context })).not.to.throw(); }); it('is introspectable through context API', () => { @@ -1214,7 +1215,7 @@ describe('shallow', () => { it('get same value when using `useMemo` and rerender with same prop in dependencies', () => { function Child() { - return false; + return null; } function ComponentUsingMemoHook(props) { const { count } = props; @@ -1232,7 +1233,7 @@ describe('shallow', () => { it('get different value when using `useMemo` and rerender with different prop in dependencies', () => { function Child() { - return false; + return null; } function ComponentUsingMemoHook(props) { const { count, relatedProp } = props; @@ -1245,7 +1246,45 @@ describe('shallow', () => { const initialValue = wrapper.find(Child).prop('memoized'); wrapper.setProps({ relatedProp: '123' }); const nextValue = wrapper.find(Child).prop('memoized'); - expect(initialValue).to.not.equal(nextValue); + expect(initialValue).not.to.equal(nextValue); + }); + + it.skip('get same callback when using `useCallback` and rerender with same prop in dependencies', () => { + function Child() { + return false; + } + function ComponentUsingCallbackHook(props) { + const { onChange } = props; + const callback = useCallback(value => onChange(value), [onChange]); + return ( + + ); + } + const onChange = () => { }; + const wrapper = shallow(); + const initialCallback = wrapper.find(Child).prop('callback'); + wrapper.setProps({ unRelatedProp: '123' }); + const nextCallback = wrapper.find(Child).prop('callback'); + expect(initialCallback).to.equal(nextCallback); + }); + + it('get different callback when using `useCallback` and rerender with different prop in dependencies', () => { + function Child() { + return false; + } + function ComponentUsingCallbackHook(props) { + const { onChange, relatedProp } = props; + const callback = useCallback(value => onChange(value), [onChange, relatedProp]); + return ( + + ); + } + const onChange = () => { }; + const wrapper = shallow(); + const initialCallback = wrapper.find(Child).prop('callback'); + wrapper.setProps({ relatedProp: '123' }); + const nextCallback = wrapper.find(Child).prop('callback'); + expect(initialCallback).not.to.equal(nextCallback); }); }); @@ -1399,7 +1438,7 @@ describe('shallow', () => { const context = { name: 'foo' }; const wrapper = shallow(); - expect(() => wrapper.find(Bar).shallow({ context })).to.not.throw(); + expect(() => wrapper.find(Bar).shallow({ context })).not.to.throw(); }); it('is introspectable through context API', () => { @@ -1501,7 +1540,7 @@ describe('shallow', () => { const context = { name: 'foo' }; const wrapper = shallow(); - expect(() => wrapper.find(Bar).shallow({ context })).to.not.throw(); + expect(() => wrapper.find(Bar).shallow({ context })).not.to.throw(); }); itIf(is('< 16'), 'is introspectable through context API', () => {