The code calls Object.defineProperties(target, props), where props is an array - the result of the map method. However Object.defineProperties() receives an object as a second param.
The result is that the properties of jsdom.window are not copied correctly to node's global.
What happens then is that you might get errors such as "ReferenceError: HTMLElement is not defined" when running your tests (in my case using mocha and chai).
When I came across this I found countless of examples in the web recommending hacks like:
// original code sample
// and then:
global.HTMLElement = () => {}
global.HTMLInputElement = () => {}
// etc'...
Whereas the solution should be to use something like:
const copyProps = (src, target) => {
const props = Object.getOwnPropertyNames(src)
.filter((prop) => typeof target[prop] === 'undefined')
.reduce((result, prop) => {
result[prop] = Object.getOwnPropertyDescriptor(src, prop);
return result;
}, {});
Object.defineProperties(target, props);
};
(I switched the map with reduce).
WDYT?
I can create a PR if you'd like.
The reduce should use object spread, and not mutate the accumulator, but otherwise that looks like a great change in https://github.com/airbnb/enzyme/blob/master/docs/guides/jsdom.md - a PR would be great!
Cool. Will create a PR in the next few days.
BTW - any reason not to mutate the accumulator within the reduce?
Mutation should always be avoided; and the airbnb eslint config will warn you about mutating the accumulator anyways :-)
Ok. Will do it your way.
Just FYI, as I was curious about immutability here, I came across this thread:
https://www.reddit.com/r/reactjs/comments/5xg6ky/react_trend/deie19b/
Note there a comment from Dan Abramov:
Mutability has its set of problems, but unobservable mutability (such as it is here, when you鈥檙e just accumulating an object before returning it) is always fine.
Indeed; in this example even though the reducer is impure, the overall reduce is. However, there needs to be a reason to choose mutability - immutability/purity should be the default.
PR: jdom docs: correct usage of defineProperties