Skip to content

Commit

Permalink
Add contains* functions to the ReactWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieuancelin committed May 8, 2016
1 parent d57cc90 commit 5b8688a
Show file tree
Hide file tree
Showing 8 changed files with 453 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
* [Full DOM Rendering](/docs/api/mount.md)
* [at(index)](/docs/api/ReactWrapper/at.md)
* [contains(nodeOrNodes)](/docs/api/ReactWrapper/contains.md)
* [containsMatchingElement(node)](/docs/api/ReactWrapper/containsMatchingElement.md)
* [containsAllMatchingElements(nodes)](/docs/api/ReactWrapper/containsAllMatchingElements.md)
* [containsAnyMatchingElements(nodes)](/docs/api/ReactWrapper/containsAnyMatchingElements.md)
* [childAt()](/docs/api/ReactWrapper/childAt.md)
* [children()](/docs/api/ReactWrapper/children.md)
* [closest(selector)](/docs/api/ReactWrapper/closest.md)
Expand Down
45 changes: 45 additions & 0 deletions docs/api/ReactWrapper/containsAllMatchingElements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# `.containsAllMatchingElements(nodes) => Boolean`

Returns whether or not one of the given react elements are all matching one element in the render tree.
It will determine if an element in the wrapper __looks like__ one of the expected element by checking if all props of the expected element are present on the wrappers element and equals to each other.


#### Arguments

1. `nodes` (`Array<ReactElement>`): The array of nodes whose presence you are detecting in the current instance's
render tree.



#### Returns

`Boolean`: whether or not the current wrapper has nodes anywhere in its render tree that looks
like the nodes passed in.



#### Example


```jsx
const wrapper = mount(
<div>
<span className="foo">Hello</span>
<div style={{ fontSize: 13 }}>Goodbye</div>
<span>Again</span>
</div>
);

expect(wrapper.containsAllMatchingElements([
<span>Hello</span>,
<div>Goodbye</div>,
])).to.equal(true);
```


#### Common Gotchas

- `.containsAllMatchingElements()` expects an array of ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with an array of ReactElement or a JSX expression.
- Keep in mind that this method determines mathcing based on the matching of the node's children as
well.
45 changes: 45 additions & 0 deletions docs/api/ReactWrapper/containsAnyMatchingElements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# `.containsAnyMatchingElements(nodes) => Boolean`

Returns whether or not one of the given react elements is matching on element in the render tree.
It will determine if an element in the wrapper __looks like__ one of the expected element by checking if all props of the expected element are present on the wrappers element and equals to each other.


#### Arguments

1. `nodes` (`Array<ReactElement>`): The array of nodes whose presence you are detecting in the current instance's
render tree.



#### Returns

`Boolean`: whether or not the current wrapper has a node anywhere in its render tree that looks
like one of the array passed in.



#### Example


```jsx
const wrapper = mount(
<div>
<span className="foo">Hello</span>
<div style={{ fontSize: 13 }}>Goodbye</div>
<span>Again</span>
</div>
);

expect(wrapper.containsAnyMatchingElements([
<span>Bonjour</span>,
<div>Goodbye</div>,
])).to.equal(true);
```


#### Common Gotchas

- `.containsAnyMatchingElements()` expects an array of ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with an array ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
52 changes: 52 additions & 0 deletions docs/api/ReactWrapper/containsMatchingElement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# `.containsMatchingElement(node) => Boolean`

Returns whether or not a given react element is matching one element in the render tree.
It will determine if an element in the wrapper __looks like__ the expected element by checking if all props of the expected element are present on the wrappers element and equals to each other.


#### Arguments

1. `node` (`ReactElement`): The node whose presence you are detecting in the current instance's
render tree.



#### Returns

`Boolean`: whether or not the current wrapper has a node anywhere in its render tree that looks
like the one passed in.



#### Example


```jsx
const MyComponent = React.createClass({
handleClick() {
...
},
render() {
return (
<div>
<div onClick={this.handleClick} className="foo bar">Hello</div>
</div>
);
}
});

const wrapper = mount(<MyComponent />);
expect(wrapper.containsMatchingElement(
<div>Hello</div>
)).to.equal(true);
expect(wrapper.containsMatchingElement(
<div className="foo bar">Hello</div>
)).to.equal(true);
```

#### Common Gotchas

- `.containsMatchingElement()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
9 changes: 9 additions & 0 deletions docs/api/mount.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ Remove nodes in the current wrapper that do not return true for the provided pre
#### [`.contains(nodeOrNodes) => Boolean`](ReactWrapper/contains.md)
Returns whether or not a given node or array of nodes is somewhere in the render tree.

#### [`.containsMatchingElement(node) => Boolean`](ReactWrapper/containsMatchingElement.md)
Returns whether or not a given react element is somewhere in the render tree.

#### [`.containsAllMatchingElements(nodes) => Boolean`](ReactWrapper/containsAllMatchingElements.md)
Returns whether or not all the given react elements are somewhere in the render tree.

#### [`.containsAnyMatchingElements(nodes) => Boolean`](ReactWrapper/containsAnyMatchingElements.md)
Returns whether or not one of the given react elements is somewhere in the render tree.

#### [`.hasClass(className) => Boolean`](ReactWrapper/hasClass.md)
Returns whether or not the current root node has the given class name or not.

Expand Down
4 changes: 2 additions & 2 deletions src/MountedTraversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export function getNode(inst) {
return inst;
}

export function instEqual(a, b) {
return nodeEqual(getNode(a), getNode(b));
export function instEqual(a, b, lenComp) {
return nodeEqual(getNode(a), getNode(b), lenComp);
}

export function instHasClassName(inst, className) {
Expand Down
74 changes: 74 additions & 0 deletions src/ReactWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,80 @@ export default class ReactWrapper {
return findWhereUnwrapped(this, predicate).length > 0;
}

/**
* Whether or not a given react element exists in the shallow render tree.
* It will determine if one of the wrappers element "looks like" the expected
* element by checking if all props of the expected element are present
* on the wrappers element and equals to each other.
*
* Example:
* ```
* // MyComponent outputs <div><div class="foo">Hello</div></div>
* const wrapper = mount(<MyComponent />);
* expect(wrapper.containsMatchingElement(<div>Hello</div>)).to.equal(true);
* ```
*
* @param {ReactElement} node
* @returns {Boolean}
*/
containsMatchingElement(node) {
const predicate = other => instEqual(node, other, (a, b) => a <= b);
return findWhereUnwrapped(this, predicate).length > 0;
}

/**
* Whether or not all the given react elements exists in the shallow render tree.
* It will determine if one of the wrappers element "looks like" the expected
* element by checking if all props of the expected element are present
* on the wrappers element and equals to each other.
*
* Example:
* ```
* const wrapper = mount(<MyComponent />);
* expect(wrapper.containsAllMatchingElements([
* <div>Hello</div>,
* <div>Goodbye</div>,
* ])).to.equal(true);
* ```
*
* @param {Array<ReactElement>} nodes
* @returns {Boolean}
*/
containsAllMatchingElements(nodes) {
const invertedEquals = (n1, n2) => instEqual(n2, n1, (a, b) => a <= b);
const predicate = other => containsChildrenSubArray(invertedEquals, other, nodes);
return findWhereUnwrapped(this, predicate).length > 0;
}

/**
* Whether or not one of the given react elements exists in the shallow render tree.
* It will determine if one of the wrappers element "looks like" the expected
* element by checking if all props of the expected element are present
* on the wrappers element and equals to each other.
*
* Example:
* ```
* const wrapper = mount(<MyComponent />);
* expect(wrapper.containsAnyMatchingElements([
* <div>Hello</div>,
* <div>Goodbye</div>,
* ])).to.equal(true);
* ```
*
* @param {Array<ReactElement>} nodes
* @returns {Boolean}
*/
containsAnyMatchingElements(nodes) {
if (!Array.isArray(nodes)) return false;
if (nodes.length <= 0) return false;
for (let i = 0; i < nodes.length; i++) {
if (this.containsMatchingElement(nodes[i])) {
return true;
}
}
return false;
}

/**
* Finds every node in the render tree of the current wrapper that matches the provided selector.
*
Expand Down
Loading

0 comments on commit 5b8688a

Please sign in to comment.