-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Prevent error in pretty-format for window in jsdom test env #4750
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
Conversation
| } | ||
| 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 👍
SimenB
left a comment
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'
undefinedThere 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 lengthreturn[Window]the constructor name in jsdom.The serialization is not even relevant in snapshot if
windowis prop of React element.Add a condition where
pretty-formatshort-circuits serialization of object at max depth.Theoretically it could serialize
windowifglobalis not defined (results would vary by browser) but so far I have not succeeded in configuring webpack for the bundle not to haveglobaltoo.From that I hypothesize both
globalandwindowwill exist when running tests in-browser?However, I am happy to forget about
globaland simplify the code so it tests onlywindowTest plan
Added a test (which failed first) to
dom_element.test.jsbecause although not related to plugin, that is only test file which specifies@jest-environment jsdom