-
-
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
Prevent error in pretty-format for window in jsdom test env #4750
Conversation
packages/pretty-format/src/index.js
Outdated
} | ||
return val === theGlobalWindow; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just:
const isGlobalWindow = val => {
try {
/* global window */
return window === global;
} catch (error) {
return false;
}
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In answer to your question, must return result of comparison to val
The complexity is in case some overhead to enclose val === window
in try-catch
, lazy evaluation of window
at first attempt to serialize an object.
The more I think about it though, considering global
seems like a mistake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think I should do a set of perf measurements compared to simplest possible code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just referring to make it a bit simpler (I now see I forgot to include val
in the equation :D). If you could do some local perf testing, that's always nice 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changelog? :D
packages/pretty-format/src/index.js
Outdated
return false; | ||
} | ||
if (theWindow === undefined) { | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try catch feels like overkill. Why not just typeof window != 'undefined'
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It catches ReferenceError: window is not defined
for --env=node
in Jest or if pretty-format
package is used for other purpose than testing.
Keep the questions coming. This one caused me to add comments in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a new comment - it does not.
$ node -p 'typeof window'
undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or well, the current test throws, but that's because the test itself is referring to window
, not because it throws from inside pretty-format.
You can always typeof
anything - even stuff that is not defined.
And this way you avoid the try-catch entirely
packages/pretty-format/src/index.js
Outdated
// Return whether val is equal to global window object. | ||
let noWindow; | ||
let theWindow; | ||
const isWindow = val => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't think this is necessary. This change passes your test as well:
diff --git i/packages/pretty-format/src/index.js w/packages/pretty-format/src/index.js
index 35a591c9..ba4f91f1 100644
--- i/packages/pretty-format/src/index.js
+++ w/packages/pretty-format/src/index.js
@@ -41,6 +41,8 @@ const errorToString = Error.prototype.toString;
const regExpToString = RegExp.prototype.toString;
const symbolToString = Symbol.prototype.toString;
+const isWindow = val => typeof window !== 'undefined' && val === window;
+
const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/;
const NEWLINE_REGEXP = /\n/gi;
@@ -224,7 +226,7 @@ function printComplexValue(
'}';
}
- return hitMaxDepth
+ return hitMaxDepth || isWindow(val)
? '[' + (val.constructor ? val.constructor.name : 'Object') + ']'
: (min ? '' : (val.constructor ? val.constructor.name : 'Object') + ' ') +
'{' +
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose you can cache the typeof
check, but that doesn't seem like an optimization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes indeed, typeof window
works in my experimental codes where window
throws.
Thank you very much, I will update pull request according to your one liner above.
Performance value in each cell is geometric mean of time for 3 runs:
Interpretation
Simpler code for try-catch every call is slower enough that I did not commit the following change: try {
/* global window */
return val === window;
} catch (e) {
return false;
} |
Segmentation fault on node 4 :( how high is the chance that these changes caused it? |
Next to nil, I've seen it quite a few times before. Restarted the build |
I'm sorry to comment on such an old, already-merged PR, not even sure if people in the discussion will get notifications, but I'm stuck on something, this is the only relevant-looking result I've been able to find, and it made me wonder about the possibility of a regression with what's discussed above. I have a super-contrived test,
And running it yields me this:
If I remove the I'm using Jest 24.9.0 here. |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Summary
Fixes #4612
Instead of
RangeError: Invalid string length
return[Window]
the constructor name in jsdom.The serialization is not even relevant in snapshot if
window
is prop of React element.Add a condition where
pretty-format
short-circuits serialization of object at max depth.Theoretically it could serialize
window
ifglobal
is not defined (results would vary by browser) but so far I have not succeeded in configuring webpack for the bundle not to haveglobal
too.From that I hypothesize both
global
andwindow
will exist when running tests in-browser?However, I am happy to forget about
global
and simplify the code so it tests onlywindow
Test plan
Added a test (which failed first) to
dom_element.test.js
because although not related to plugin, that is only test file which specifies@jest-environment jsdom