Enzyme: A bug in "Using enzyme with JSDOM" code sample

Created on 28 Oct 2017  路  6Comments  路  Source: enzymejs/enzyme

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.

docs help wanted

All 6 comments

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.

1320

PR: jdom docs: correct usage of defineProperties

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blainekasten picture blainekasten  路  3Comments

potapovDim picture potapovDim  路  3Comments

mattkauffman23 picture mattkauffman23  路  3Comments

abe903 picture abe903  路  3Comments

heikkimu picture heikkimu  路  3Comments