-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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 globals different from source code globals? #2048
Comments
Can you try "jest@test" and tell me if this fixes your problem? On Thu, Nov 3, 2016 at 9:01 PM +0000, "Kent C. Dodds" <notifications@github.commailto:notifications@github.com> wrote: Do you want to request a feature or report a bug? bug What is the current behavior? In some cases, when source code does stuff with built-in globals like Object, Array, etc. it appears that those built-in globals are not the same as the globals available in the test environment. 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. Still working on figuring out a reliable way to reproduce this in an isolated environment... Stand by... What is the expected behavior? The globals should be the same in both environments Run Jest again with --debug and provide the full configuration it prints. Please mention your node and npm version and operating system. forthcoming... You are receiving this because you are subscribed to this thread. |
Doesn't appear to. I'm still working on making a legit reproduction. I'm struggling to do so... Things are a little... complicated. And I'm not sure what's actually causing the issue. |
Ok, here's the repo. Here's the source: const Module = require('module')
const path = require('path')
module.exports = requireFromString('fake-thing.js', `
module.exports = function isObject(obj) {
return obj.constructor === Object
}
`)
/*
* copied and modified from require-from-string
*/
function requireFromString(filename, code) {
const m = new Module(filename, module.parent)
m.filename = filename
m.paths = Module._nodeModulePaths(path.dirname(filename))
m._compile(code, filename)
return m.exports
} I realize this is kinda weird. I'm actually not even sure whether this is specifically what's causing issues in my app, but my slice-js project does this to work some of its own magic for tests and I've definitely run into the problem (so far I've been able to work around it ok). Any ideas? I'm worried you're going to say: "Yeah, just don't do that." Haha |
So, here's a little more context. In my app, (one of) the specific line(s) that's having trouble is this one from obj && obj.constructor !== Object The So, if I add: console.log(new Error('confit').stack) To the top of the
So I'm thinking that confit is being compiled via Jest. And if I move that line to the
But I'm thinking that's irrelevant... So I'm not sure who's actually passing the |
Note, if I change that line in obj && obj.constructor.toString().indexOf('Object') === -1 Then that fixes the problem (and I'm pretty sure it also preserves the behavior, even if it is a bit hacky). |
If you are using the "module" module in Jest, it will get pulled in from the parent context with all the parent built-ins instead of the ones from the vm module. You can think of it like in a browser with an iframe. The "Array" constructor from the parent won't be the same as the one from the iframe, which is why you need to use Unfortunately I don't see a good way around this. I would recommend to do something like this:
is there a reason that wouldn't work for you and why you'd need to run it as a real module? Another workaround that will work just fine is to do this:
Closing for now as I don't think we'll add a require-string API to Jest and there is other ways to solve it. Happy to continue the discussion. |
🎉 🎉 🎉 🎉 🎉 🎉 I figured out the problem (Finally!) It's in the json branch on the reproduction repo. The issue happens when const obj = JSON.parse('{}')
test('should be an object', () => {
expect(obj.constructor === Object).toBe(true)
}) However, running with just const assert = require('assert')
const obj = JSON.parse('{}')
assert(obj.constructor === Object)
console.info('✅ passed') If you change |
Ah this is interesting. So the problem is that the I think the best way to solve this is to build a recursive function that updates the prototype, like this:
If you can figure out where the JSON built-in is and how to create a new version of it inside of a context, please let me know. Another alternative is to load a json polyfill in your test and do |
So this works in my example repo, but it's kinda scary :-/ global.JSON = {} // remove all JSON methods so it can be overridden
require('JSON') I put that in one of my |
Also, thanks so much @cpojer :) Jest does quite a bit of magic under the hood which leads to odd things like this sometimes, but for the most part, I've never been happier with a testing framework, so thank you so much for all your work on Jest! |
Does |
I don't know what |
It's the only module that I'm aware of that implements the |
Weird...
EDIT: Oh, nevermind, they're just not enumerable:
|
I ran into this same issue when using |
What if we added transformations for eg. |
Did you upgrade to Jest 18? This should all work now. |
@cpojer I'm still seeing this in Jest 18.1 - reproduced here: https://github.com/thomas-huston-zocdoc/jest-fetch-array-bug |
Would you mind opening a separate issue for that? |
You got it! #2549 |
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. |
Do you want to request a feature or report a bug?
bug
What is the current behavior?
In some cases, when source code does stuff with built-in globals like
Object
,Array
, etc. it appears that those built-in globals are not the same as the globals available in the test environment.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
andnpm test
.Still working on figuring out a reliable way to reproduce this in an isolated environment... Stand by...
What is the expected behavior?
The globals should be the same in both environments
Run Jest again with
--debug
and provide the full configuration it prints. Please mention your node and npm version and operating system.forthcoming...
The text was updated successfully, but these errors were encountered: