Skip to content

Commit

Permalink
Check for existence of Element when comparing DOM-nody-things (#7786)…
Browse files Browse the repository at this point in the history
… (clean cherry pick version) (#7995)

* Check for existence of `Element` when comparing DOM-nody-things (#7786)

* Fall back to deep equality for presumed DOM nodes if `Element` is not in scope (#7786)

* Remove IE<9 specific fallback DOM node comparison (#7786)

* Check for global DOM `Node` in `isDomNode` (#7786)

In a real browser and JSDOM the check will use DOM-Level-3 `Node.isEqualNode`
and for everything else a deep equality check should do the trick.

* Check that `isEqualNode` is a function and remove duck typing from `isDomNode` (#7786)

* Add changelog entry for streamlined DOM node comparisons in `expect` (#7786)

* Correct visible PR number in CHANGELOG.md
  • Loading branch information
mfeineis authored and pedrottimark committed Mar 1, 2019
1 parent 1983ad1 commit 494d477
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -29,6 +29,7 @@
- `[expect]` Fix non-object received value in toHaveProperty ([#7986](https://github.com/facebook/jest/pull/7986))
- `[jest-jasmine2]`: Throw explicit error when errors happen after test is considered complete ([#8005](https://github.com/facebook/jest/pull/8005))
- `[jest-circus]`: Throw explicit error when errors happen after test is considered complete ([#8005](https://github.com/facebook/jest/pull/8005))
- `[expect]` Remove duck typing and obsolete browser support code when comparing DOM nodes and use DOM-Level-3 API instead ([#7995](https://github.com/facebook/jest/pull/7995))

### Chore & Maintenance

Expand Down
22 changes: 22 additions & 0 deletions packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap
Expand Up @@ -1996,6 +1996,28 @@ Expected: <green>{\\"a\\": 99}</>
Received: <red>{\\"a\\": 99}</>"
`;

exports[`.toEqual() {pass: false} expect({"nodeName": "div", "nodeType": 1}).not.toEqual({"nodeName": "div", "nodeType": 1}) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expected: <green>{\\"nodeName\\": \\"div\\", \\"nodeType\\": 1}</>
Received: <red>{\\"nodeName\\": \\"div\\", \\"nodeType\\": 1}</>"
`;

exports[`.toEqual() {pass: false} expect({"nodeName": "div", "nodeType": 1}).toEqual({"nodeName": "p", "nodeType": 1}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Difference:

<green>- Expected</>
<red>+ Received</>

<dim> Object {</>
<green>- \\"nodeName\\": \\"p\\",</>
<red>+ \\"nodeName\\": \\"div\\",</>
<dim> \\"nodeType\\": 1,</>
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect({"target": {"nodeType": 1, "value": "a"}}).toEqual({"target": {"nodeType": 1, "value": "b"}}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expand Down
20 changes: 20 additions & 0 deletions packages/expect/src/__tests__/matchers.test.js
Expand Up @@ -417,6 +417,16 @@ describe('.toEqual()', () => {
},
},
],
[
{
nodeName: 'div',
nodeType: 1,
},
{
nodeName: 'p',
nodeType: 1,
},
],
].forEach(([a, b]) => {
test(`{pass: false} expect(${stringify(a)}).toEqual(${stringify(
b,
Expand Down Expand Up @@ -537,6 +547,16 @@ describe('.toEqual()', () => {
},
},
],
[
{
nodeName: 'div',
nodeType: 1,
},
{
nodeName: 'div',
nodeType: 1,
},
],
].forEach(([a, b]) => {
test(`{pass: false} expect(${stringify(a)}).not.toEqual(${stringify(
b,
Expand Down
30 changes: 6 additions & 24 deletions packages/expect/src/jasmineUtils.ts
Expand Up @@ -129,24 +129,9 @@ function eq(

var aIsDomNode = isDomNode(a);
var bIsDomNode = isDomNode(b);
if (aIsDomNode && bIsDomNode) {
// At first try to use DOM3 method isEqualNode
if (a.isEqualNode) {
return a.isEqualNode(b);
}
// IE8 doesn't support isEqualNode, try to use outerHTML && innerText
var aIsElement = a instanceof Element;
var bIsElement = b instanceof Element;
if (aIsElement && bIsElement) {
return a.outerHTML == b.outerHTML;
}
if (aIsElement || bIsElement) {
return false;
}
return a.innerText == b.innerText && a.textContent == b.textContent;
}
if (aIsDomNode || bIsDomNode) {
return false;
// Use DOM3 method isEqualNode (IE>=9)
if (aIsDomNode && typeof a.isEqualNode === 'function' && bIsDomNode) {
return a.isEqualNode(b);
}

// Used to detect circular references.
Expand Down Expand Up @@ -263,12 +248,9 @@ export function isA(typeName: string, value: unknown) {
}

function isDomNode(obj: any): obj is Node {
return (
obj !== null &&
typeof obj === 'object' &&
typeof obj.nodeType === 'number' &&
typeof obj.nodeName === 'string'
);
// In some test environments (e.g. "node") there is no `Node` even though
// we might be comparing things that look like DOM nodes.
return typeof Node !== 'undefined' && obj instanceof Node;
}

export function fnNameFor(func: Function) {
Expand Down

0 comments on commit 494d477

Please sign in to comment.