Skip to content

Commit

Permalink
add toMatchElement
Browse files Browse the repository at this point in the history
  • Loading branch information
finnigantime committed Jun 19, 2017
1 parent 0cf7039 commit 3a6392f
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 13 deletions.
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ This library supports several testing frameworks including [Jest](https://github
* [toHaveText()](#tohavetexttextstring)
* [toIncludeText()](#toincludetexttextstring)
* [toHaveValue()](#tohavevaluevalueany)
* [toMatchElement()](#tomatchelementreactinstanceobject)
* [toMatchSelector()](#tomatchselectorselectorstring)

_Other_
Expand Down Expand Up @@ -150,7 +151,7 @@ expect(wrapper.find('span')).toBePresent();
expect(wrapper.find('ul')).not.toBePresent();
```

#### `toContainReact(ReactInstance:Object)`
#### `toContainReact(reactInstance:Object)`

| render | mount | shallow |
| -------|-------|-------- |
Expand Down Expand Up @@ -454,6 +455,34 @@ expect(wrapper.find('input').at(0)).toHaveValue('test');
expect(wrapper.find('input').at(1)).toHaveValue('bar');
```

#### `toMatchElement(reactInstance:Object)`

| render | mount | shallow |
| -------|-------|-------- |
| no | yes | yes |

Assert the wrapper matches the provided react instance. This is a matcher form of Enzyme's wrapper.matchesElement(), which returns a bool with no indication of what caused a failed match. This matcher includes the actual and expected debug trees as contextual information when it fails. NOTE: The semantics are slightly different than enzyme's wrapper.matchesElement(), which ignores props. This matcher does consider props when comparing the actual to the expected values.

Example:

```js
function Fixture() {
return (
<div>
<span id="foo" className="bar" />
</div>
);
}

const wrapper = shallow(<Fixture />); // mount/render/shallow when applicable

expect(wrapper).toMatchElement(<Fixture />);
expect(wrapper.find('span')).toMatchElement(
<span id="foo" className="bar" />
);
expect(wrapper).not.toMatchElement(<div />);
```

#### `toMatchSelector(selector:string)`

| render | mount | shallow |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`toMatchElement mount provides contextual information for the message 1`] = `
"
actual:
<Fixture>
<div>
<span id=\\"child\\" className=\\"foo\\" />
</div>
</Fixture>
expected:
<Fixture>
<div>
<span id=\\"child\\" className=\\"foo\\" />
</div>
</Fixture>
"
`;

exports[`toMatchElement mount provides contextual information for the message 2`] = `
"
actual:
<span id=\\"child\\" className=\\"foo\\" />
expected:
<span id=\\"child\\" className=\\"foo\\" />
"
`;

exports[`toMatchElement mount provides contextual information for the message 3`] = `
"
actual:
<Fixture>
<div>
<span id=\\"child\\" className=\\"foo\\" />
</div>
</Fixture>
expected:
<div />
"
`;

exports[`toMatchElement mount returns the message with the proper fail verbage 1`] = `"Did not expect actual value to match the expected value."`;

exports[`toMatchElement mount returns the message with the proper fail verbage 2`] = `"Did not expect actual value to match the expected value."`;

exports[`toMatchElement mount returns the message with the proper fail verbage 3`] = `"Did not expect actual value to match the expected value."`;

exports[`toMatchElement mount returns the message with the proper pass verbage 1`] = `"Expected actual value to match the expected value."`;

exports[`toMatchElement mount returns the message with the proper pass verbage 2`] = `"Expected actual value to match the expected value."`;

exports[`toMatchElement mount returns the message with the proper pass verbage 3`] = `"Expected actual value to match the expected value."`;

exports[`toMatchElement shallow provides contextual information for the message 1`] = `
"
actual:
<div>
<span id=\\"child\\" className=\\"foo\\" />
</div>
expected:
<div>
<span id=\\"child\\" className=\\"foo\\" />
</div>
"
`;

exports[`toMatchElement shallow provides contextual information for the message 2`] = `
"
actual:
<span id=\\"child\\" className=\\"foo\\" />
expected:
<span id=\\"child\\" className=\\"foo\\" />
"
`;

exports[`toMatchElement shallow provides contextual information for the message 3`] = `
"
actual:
<div>
<span id=\\"child\\" className=\\"foo\\" />
</div>
expected:
<div />
"
`;

exports[`toMatchElement shallow returns the message with the proper fail verbage 1`] = `"Did not expect actual value to match the expected value."`;

exports[`toMatchElement shallow returns the message with the proper fail verbage 2`] = `"Did not expect actual value to match the expected value."`;

exports[`toMatchElement shallow returns the message with the proper fail verbage 3`] = `"Did not expect actual value to match the expected value."`;

exports[`toMatchElement shallow returns the message with the proper pass verbage 1`] = `"Expected actual value to match the expected value."`;

exports[`toMatchElement shallow returns the message with the proper pass verbage 2`] = `"Expected actual value to match the expected value."`;

exports[`toMatchElement shallow returns the message with the proper pass verbage 3`] = `"Expected actual value to match the expected value."`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const { shallow, mount } = require('enzyme');
const React = require('react');

const toMatchElement = require('../toMatchElement');

function Fixture() {
return (
<div>
<span id="child" className="foo" />
</div>
);
}

describe('toMatchElement', () => {
[shallow, mount].forEach(builder => {
describe(builder.name, () => {
const wrapper = builder(<Fixture />);
const truthyResults = toMatchElement(wrapper, <Fixture />);
const truthyResults2 = toMatchElement(wrapper.find('span'),
<span id="child" className="foo" />
);
const falsyResults = toMatchElement(wrapper, <div />);

it('returns the pass flag properly', () => {
expect(truthyResults.pass).toBeTruthy();
expect(truthyResults2.pass).toBeTruthy();
expect(falsyResults.pass).toBeFalsy();
});

it('returns the message with the proper pass verbage', () => {
expect(truthyResults.message).toMatchSnapshot();
expect(truthyResults2.message).toMatchSnapshot();
expect(falsyResults.message).toMatchSnapshot();
});

it('returns the message with the proper fail verbage', () => {
expect(truthyResults.negatedMessage).toMatchSnapshot();
expect(truthyResults2.negatedMessage).toMatchSnapshot();
expect(falsyResults.negatedMessage).toMatchSnapshot();
});

it('provides contextual information for the message', () => {
expect(truthyResults.contextualInformation).toMatchSnapshot();
expect(truthyResults2.contextualInformation).toMatchSnapshot();
expect(falsyResults.contextualInformation).toMatchSnapshot();
});
});
});
});
35 changes: 35 additions & 0 deletions packages/enzyme-matchers/src/assertions/toMatchElement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* This source code is licensed under the MIT-style license found in the
* LICENSE file in the root directory of this source tree. *
*
* @providesModule toMatchElementAssertion
* @flow
*/

import { shallow, mount } from 'enzyme';
import type { Matcher } from '../../../../types/Matcher';
import type { EnzymeObject } from '../../../../types/EnzymeObject';
import isShallowWrapper from '../utils/isShallowWrapper';
import single from '../utils/single';

function toMatchElement(actualEnzymeWrapper:EnzymeObject, reactInstance:Object) : Matcher {
let expectedWrapper:EnzymeObject;
if (!isShallowWrapper(actualEnzymeWrapper)) {
expectedWrapper = mount(reactInstance);
} else {
expectedWrapper = shallow(reactInstance);
}

const actual = actualEnzymeWrapper.debug();
const expected = expectedWrapper.debug();
const pass = actual === expected;

return {
pass,
message: 'Expected actual value to match the expected value.',
negatedMessage: 'Did not expect actual value to match the expected value.',
contextualInformation: `\nactual:\n${actual}\n\nexpected:\n${expected}\n`,
};
}

export default single(toMatchElement);
13 changes: 1 addition & 12 deletions packages/enzyme-matchers/src/utils/html.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
import instance from './instance';
import isShallowWrapper from './isShallowWrapper';
import getConsoleObject from './getConsoleObject';

const consoleObject = getConsoleObject();
const noop = () => {};
const error = consoleObject.error;
const SHALLOW_WRAPPER_CONSTRUCTOR = 'ShallowWrapper';

function isShallowWrapper(wrapper) : boolean {
let isShallow;
if (wrapper.constructor.name !== undefined) {
isShallow = wrapper.constructor.name === SHALLOW_WRAPPER_CONSTRUCTOR;
} else {
// function.name isn't available on IE 11, so fall back to turning the function into
// a string and checking its name this way.
isShallow = !!(`${wrapper.constructor}`).match(/^function ShallowWrapper\(/);
}
return isShallow;
}

function mapWrappersHTML(wrapper) : string {
return wrapper.nodes.map(node => {
Expand Down
11 changes: 11 additions & 0 deletions packages/enzyme-matchers/src/utils/isShallowWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const SHALLOW_WRAPPER_CONSTRUCTOR = 'ShallowWrapper';

export default function isShallowWrapper(wrapper) : boolean {
let isShallow;
if (wrapper.constructor.name !== undefined) {
isShallow = wrapper.constructor.name === SHALLOW_WRAPPER_CONSTRUCTOR;
} else {
isShallow = !!(`${wrapper.constructor}`).match(/^function ShallowWrapper\(/);
}
return isShallow;
}

0 comments on commit 3a6392f

Please sign in to comment.