Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShallowWrapper::dive fails when Context and React.memo is used #2103

Closed
2 tasks done
andris-silis opened this issue Apr 17, 2019 · 1 comment
Closed
2 tasks done

ShallowWrapper::dive fails when Context and React.memo is used #2103

andris-silis opened this issue Apr 17, 2019 · 1 comment

Comments

@andris-silis
Copy link

Current behavior

dive() throws TypeError: ShallowWrapper::dive() can only be called on components when diving into component wrapped with Context Provider/Consumer and React.memo.

Started to work as expected when isMemo(type) was added to condition in ReactSixteenAdapter.js::isCustomComponent. Not sure if this is a right change so no PR yet.

Expected behavior

dive() dives into deepest components just as it does when React.memo is not used:

>>>  console.log(subject.dive().debug());
<App />

>>>  console.log(subject.dive().dive().debug());
<ContextConsumer>
  [function]
</ContextConsumer>

>>>  console.log(subject.dive().dive().dive().debug());
<div>
  {{ name: 'Guest' }}
</div>

Example

const UserContext = React.createContext({
  name: 'Guest',
});

const App = () => (
  <UserContext.Consumer>
    {(user) => <div>{user}</div>}
  </UserContext.Consumer>
);

const AppMemoized = React.memo(App);

const WithProvider = () => (
  <UserContext.Provider value='test'>
    <AppMemoized />
  </UserContext.Provider>
);

const subject = shallow(<WithProvider />);

>>> subject.dive().debug();
<App />

>>> subject.dive().dive().debug();
TypeError: ShallowWrapper::dive() can only be called on components

Your environment

API

  • shallow

Version

library version
enzyme 3.9.0
react 16.8.6
react-dom 16.8.6
react-test-renderer 16.8.6
adapter (below)

Adapter

  • enzyme-adapter-react-16
@ljharb
Copy link
Member

ljharb commented May 6, 2019

Interesting:

shallow(React.createElement(() => <App />)).dive() // works, is ContextConsumer
shallow(React.createElement(() => <App />)).dive().dive() // works, is App's div
shallow(React.createElement(() => <App />)).dive().dive().dive() // throws, should throw

shallow(React.createElement(() => <AppMemoized />)).dive() // throws, should be ContextConsumer

Looks like this is specific to memo, and doesn't have anything to do with createContext. Fix coming shortly.

@ljharb ljharb self-assigned this May 6, 2019
ljharb added a commit that referenced this issue May 6, 2019
@ljharb ljharb added this to v16.6+: memo, lazy, suspense in React 16 May 6, 2019
@ljharb ljharb closed this as completed in d885c34 May 6, 2019
ljharb added a commit that referenced this issue May 12, 2019
 - [new] support `suspenseFallback` option; support `Suspense`/`Lazy` (#1975)
 - [fix] `shallow`: properly dive through `memo` components (#2103, #2068)
 - [fix] avoid a Context.Provider deprecation warning
 - [fix] shallow renderer for `memo` does not respect `defaultProps` (#2115)
 - [fix] Don’t show wrapped component displayName in lazy component (#1975)
 - [fix] `simulateEvent`: call the adapter’s implementation, not the raw one (#2100)
 - [deps] update `enzyme-adapter-utils`
 - [dev deps] update `eslint-plugin-react`, `eslint-plugin-import`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
React 16
  
v16.6+: memo, lazy, suspense
Development

No branches or pull requests

2 participants