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

Jest doesn't play nice with Node 8.3.0's object rest/spread properties. #4248

Closed
icylace opened this issue Aug 11, 2017 · 22 comments
Closed

Comments

@icylace
Copy link

icylace commented Aug 11, 2017

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

I'm reporting a bug regarding Node 8.3.0's object rest/spread properties.

What is the current behavior?

I had just updated to Node 8.3.0 and started using the object spread syntax in my code and it runs fine. However, when I test that same code, Jest errors out when it sees that type of syntax. I created a test demo repo to demonstrate: https://github.com/icylace/jest-vs-node-8.3.0

What is the expected behavior?

Jest should not complain about syntax that Node 8.3.0 can handle.

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

  • Jest 20.0.4
  • Node 8.3.0
  • Yarn 0.27.5
  • macOS Sierra 10.12.6
@rockchalkwushock
Copy link

@icylace

Do you know of a way to get back to a working jest? I don't have a version of node@8.2.1 still because I ran brew cleanup before I ran into this issue 😖. I tried removing node & reinstalling thinking it would install the LTS, but it gave me node@8.4.0 which still leaves jest hanging. I've been looking at homebrew for how to get a specific version of node but it looks like my options are node@6 & node@4 (not sure about the other options printed out when running brew search node).

@icylace
Copy link
Author

icylace commented Aug 18, 2017

@rockchalkwushock

I love Homebrew but would never use it directly for switching between Node versions. For that I use Node Version Manager.

For getting back Node 8.2.1, try running these commands in your terminal:

brew install nvm
nvm install 8.2.1
nvm use 8.2.1

@rockchalkwushock
Copy link

@icylace thanks so much man!

@ksmithut
Copy link

It concerns me that the version/features of node running my tests is not the version running in my production environment. I get the use case for mocking things for a browser environment, but for a node environment, I don't see why jest can't just use the existing runtime. That's likely ignorance on my part for not understanding the complexities of how jest is doing it's thing. I've also tried setting "testEnvironment": "node" in my jest config to no avail.

@thymikee
Copy link
Collaborator

@ksmithut you can always use whatever Node version you need and a babel transform just for the test, until this is resolved.

If you don't use Babel, It's as easy as running yarn add babel-plugin-transform-object-rest-spread --dev and adding .babelrc to your root and:

{
  "env": {
    "test": {
      "plugins": ["transform-object-rest-spread"]
    }
  }
}

@ksmithut
Copy link

ksmithut commented Aug 28, 2017

@thymikee Thanks :) I think I'll just avoid using object spread in my code for now. It's as easy as using Object.assign(). Not the prettiest, but I'd like to avoid any semblance of using babel, even if Jest is using it on my code.

Edit: To be clear, I like babel and what it does, but I'm literally using object spread in one place. Not worth a new dependency and a new file to fix. In face, I think I'm using object spread because of a bug in another library... Sometimes I think I need to rethink my life choices, lol

@pechitook
Copy link

pechitook commented Sep 14, 2017

Just bumped into this as well, and since using 8.4.0 removes the need to use babel on my node server (finally we have rest/spread operators!), I'm only adding a .babelrc file for jest.
I'm curious to understand why this happens, though. Does jest rely on a different version of node internally?

@ksmithut
Copy link

@p4bloch I don't think it uses a different version of node. I think it runs the code through the babel transpiler, and the babel transpiler doesn't understand the rest/spread syntax without a plugin. This is more of bug with babel.

@ghost
Copy link

ghost commented Sep 14, 2017

This plugin did the trick for me. It doesn't try to transpile the object spread to anything, simply makes babel aware of the syntax and doesn't touch it (since node already understands it).

yarn add --dev babel-plugin-syntax-object-rest-spread
{
  "plugins": ["syntax-object-rest-spread"]
}

@jquense
Copy link
Contributor

jquense commented Sep 14, 2017

The problem is not hte jest is running hte code in some different Node, but that its running babel over the source code, and BABEL doesn't understand object rest/spread syntax, and throwing a parser error, unless you add the syntax plugin as @Potz notes

@pechitook
Copy link

I see, thanks for the clarification. Is there a way to tell jest not to use Babel at all? That option would solve this in a very flexible way.

@thymikee
Copy link
Collaborator

It is, you can pass custom transformer doing nothing. However you'll loose the benefit of jest.mock() hoisting your code above ES modules.
I think we could include this syntax-object-rest-spread plugin in babel-jest, what do you think @cpojer?

@kachkaev
Copy link
Contributor

kachkaev commented Sep 20, 2017

Also facing this in node 8.5. Object rest/spread operators are now supported natively, even without the --harmony flag. Inspired by these awesome news, I switched a few Object.assign(...) cases to {a, b, c, ...rest} and enjoyed the node scripts working. However, jest failed to run all the new code, e.g.:

const { a, ...rest } = { a: 10, b: 20 };
console.log(a, rest);

When something like this is a part of a test, that test fails; otherwise, coverage reports generate with errors.

What's the mechanism behind this behaviour? How can jest not understand the syntax that my node runtime does? Any suggestions on how to pass the tests just by tweaking jest.config.js?

@SimenB
Copy link
Member

SimenB commented Sep 20, 2017

What's the mechanism behind this behaviour? How can jest not understand the syntax that my node runtime does?

Just read the comments in this issue. In particular #4248 (comment)

Any suggestions on how to pass the tests without introducing babel to the project?

Jest includes babel, so you just need to add the .babelrc with a single plugin.

@pechitook
Copy link

Would be interesting to know how much is babel baked into jest core. Could we add an option to make it bypass it and use node directly? Or there are core features that depend on babel?

SimenB added a commit to SimenB/jest that referenced this issue Sep 20, 2017
@SimenB
Copy link
Member

SimenB commented Sep 20, 2017

Mocking dependencies requires hoisting requires which depends on babel

@kachkaev
Copy link
Contributor

kachkaev commented Sep 20, 2017

Thanks for your comment @SimenB. I was able to overcome the issue by creating the .babelrc file with the content that @Potz suggests. This is quite confusing though: a project that uses node runtime without babel does need babel to run tests in the same (?) runtime.

The situation is counter-intuitive, so it'd be great to be able to remove .babelrc file from the project and still use jest (at least in future). Unfortunately, I'm struggling to understand what makes object rest/spread operators special given that they are native in node 8.5.

@pechitook
Copy link

Thanks @SimenB for pushing that PR. That will allow us to remove the .babelrc file and avoid confusions in babel free projects.

@ghost
Copy link

ghost commented Sep 20, 2017

@kachkaev is not that they are special, is just that they are not understood by Babel. Jest complains before even sending the code to node runtime, because it thinks that's a syntax error. Poor node runtime doesn't even have a chance to run the code, even though it understands the object spread natively.

The conversation goes like:
Node: - "hey Babel, you can send me this code, I can run this thing"
Babel: - "uh... no, this is like, syntax error. Never seen this spread thing before.. not sending it"
Node: - "damn, Babel! I said I could run it"

Then we add the plugin to the .babelrc file, and now Babel can now know that Node could run this thing all along in the first place, and simply ignore the syntax passing it along. Everybody's happy.

As for the object spread syntax not being included by default on Babel presets, that probably has to do with not being an 100% accepted proposal yet or something (this always confuses me as well).

@SimenB 's PR will make things less confusing from now on.

@ntucker
Copy link

ntucker commented Feb 11, 2019

my babel config is set to target the current node version if in test environment. this makes jest test work fine but with --coverage it fails

@ntucker
Copy link

ntucker commented Feb 11, 2019

Turned out to be a babel version mismatch. I had 7.1 of parser installed somewhere. Getting the latest of 7.3 made it work.

@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 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants