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

Stateless component loses name when generating coverage #1824

Closed
esturcke opened this issue Sep 29, 2016 · 12 comments
Closed

Stateless component loses name when generating coverage #1824

esturcke opened this issue Sep 29, 2016 · 12 comments

Comments

@esturcke
Copy link

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

First, I'm not sure if this is a problem with Jest or with Enzyme, but I first noticed this when migrating another project from Mocha to Jest.

When mounting a stateless function component with Enzyme, the component name is
preserved when running jest, but not when running jest --coverage. This is
causing unit tests to fail when generating coverage that otherwise succeed.

For example, when mounting the component

const Foo = () => <div>Foo</div>

results in

<Foo>
  <div>
    Foo
  </div>
</Foo>

but when generating coverage, it results in

<Component>
  <div>
    Foo
  </div>
</Component>

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal repository on GitHub that we can npm install and npm test.

Attempt at minimal repository

git clone https://github.com/esturcke/jest-stateless-coverage-bug
npm install
CI=1 npm test
CI=1 npm test -- --coverage

What is the expected behavior?

Testing with --coverage succeeds.

Run Jest again with --debug and provide the full configuration it prints. Please mention your node and npm version and operating system.

node v6.4.0
npm v3.10.3
OS X 10.11.6
debug output

@cpojer
Copy link
Member

cpojer commented Sep 29, 2016

Can you try updating to Node 6.5 and see if this still happens? It does some things differently in how it infers function names.

@esturcke
Copy link
Author

Just updated to the latest via Homebrew:

$ node --version                                                                                                                                                                                                                                                       
v6.7.0

but I'm getting the same result.

@cpojer
Copy link
Member

cpojer commented Sep 29, 2016

yeah this kind of sucks. Istanbul wraps functions with other anonymous functions and we take the function name that node gives to the rendered component :(

@cpojer
Copy link
Member

cpojer commented Sep 29, 2016

You can also add displayName to the component.

@esturcke
Copy link
Author

Yup displayName works:

const Foo = () => <div>Foo</div>
Foo.displayName = "Foo"

So is the issue with Istanbul or is there something Jest/React can do? The interesting thing is that the way I had Mocha/Istanbul set up didn't seem to run into this problem. It only happened when I tried to use Jest to run the same tests.

Other than that the migration was very painless and Jest "just worked".

@esturcke
Copy link
Author

Passing the component to find() rather than a string looks like it might fix the unit tests as well:

describe("<Foo>", () => {
  it("renders 'Foo'", () => {
    const wrapper = mount(<Foo/>)
    console.log(wrapper.debug())
    return expect(wrapper.find(Foo).text()).to.be.equal("Foo")
  })
})

Maybe this is actually the correct way to use Enzyme and it just happened to usually work with strings.

@taylorcode
Copy link

@cpojer is there a potential solution for this in Instanbul, or is just setting displayName preferred over name anyway?

chrisdhanaraj pushed a commit to carbon-design-system/carbon-components-react that referenced this issue May 26, 2017
* Improve accuracy of code coverage with latest jest. Fixes #293

* Use constructor selector because Istanbul instrumentation wraps with anonymous functions. See jestjs/jest#1824
@wichert
Copy link

wichert commented Oct 24, 2017

I don't fully understand why this issue is closed - I am still running into it. The suggestion to pass the component instead of a string to .find() works fine, but this bug becomes problematic when you use expect(wrapper).toMatchSnapshot().

@stief510
Copy link

Same here

@tszajna0
Copy link

tszajna0 commented Oct 31, 2017

Try:

const Sfc = (props) => <div>{props.text}</div>;
Sfc.displayName = 'SfcWithAName';
export default Sfc;

See https://github.com/airbnb/enzyme/blob/master/packages/enzyme/src/Debug.js#L11-L15

@lemes
Copy link

lemes commented Feb 2, 2018

@stief510 I was able to make it work with a babel plugin: https://www.npmjs.com/package/babel-plugin-transform-react-stateless-component-name

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants