Skip to content

Commit f960c22

Browse files
Merge pull request #215 from koba04/add-unmount-into-shallow-render
Add ShallowWrapper#unmount
2 parents b776b5a + 55a7808 commit f960c22

File tree

6 files changed

+79
-6
lines changed

6 files changed

+79
-6
lines changed

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* [closest(selector)](/docs/api/ShallowWrapper/closest.md)
3131
* [shallow()](/docs/api/ShallowWrapper/shallow.md)
3232
* [render()](/docs/api/ShallowWrapper/render.md)
33+
* [unmount()](/docs/api/ShallowWrapper/unmount.md)
3334
* [text()](/docs/api/ShallowWrapper/text.md)
3435
* [html()](/docs/api/ShallowWrapper/html.md)
3536
* [get(index)](/docs/api/ShallowWrapper/get.md)

docs/api/ShallowWrapper/unmount.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# `.unmount() => Self`
2+
3+
A method that unmounts the component. This can be used to simulate a component going through
4+
an unmount/mount lifecycle.
5+
6+
#### Returns
7+
8+
`ShallowWrapper`: Returns itself.
9+
10+
11+
12+
#### Example
13+
14+
```jsx
15+
const spy = sinon.spy();
16+
17+
class Foo extends React.Component {
18+
constructor(props) {
19+
super(props);
20+
this.componentWillUnmount = spy;
21+
}
22+
render() {
23+
return (
24+
<div className={this.props.id}>
25+
{this.props.id}
26+
</div>
27+
);
28+
}
29+
}
30+
const wrapper = shallow(<Foo id="foo" />);
31+
expect(spy.calledOnce).to.equal(false);
32+
wrapper.unmount();
33+
expect(spy.calledOnce).to.equal(true);
34+
```

docs/api/shallow.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ Shallow renders the current node and returns a shallow wrapper around it.
103103
#### [`.render() => CheerioWrapper`](ShallowWrapper/render.md)
104104
Returns a CheerioWrapper of the current node's subtree.
105105

106+
#### [`.unmount() => ShallowWrapper`](ShallowWrapper/unmount.md)
107+
A method that un-mounts the component.
108+
106109
#### [`.text() => String`](ShallowWrapper/text.md)
107110
Returns a string representation of the text nodes in the current render tree.
108111

src/ShallowWrapper.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,16 @@ export default class ShallowWrapper {
324324
return this.type() === null ? cheerio() : cheerio.load(this.html()).root();
325325
}
326326

327+
/**
328+
* A method that unmounts the component. This can be used to simulate a component going through
329+
* and unmount/mount lifecycle.
330+
* @returns {ShallowWrapper}
331+
*/
332+
unmount() {
333+
this.renderer.unmount();
334+
return this;
335+
}
336+
327337
/**
328338
* Used to simulate events. Pass an eventname and (optionally) event arguments. This method of
329339
* testing events should be met with some skepticism.

src/react-compat.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint react/no-deprecated: 0 */
22
import { REACT013 } from './version';
3+
import objectAssign from 'object.assign';
34

45
let TestUtils;
56
let createShallowRenderer;
@@ -80,27 +81,27 @@ if (REACT013) {
8081
// shallow rendering when it's just a DOM element.
8182
createShallowRenderer = function createRendererCompatible() {
8283
const renderer = TestUtils.createRenderer();
84+
const originalRender = renderer.render;
85+
const originalRenderOutput = renderer.getRenderOutput;
8386
let isDOM = false;
8487
let _node;
85-
return {
86-
_instance: renderer._instance,
88+
return objectAssign(renderer, {
8789
render(node, context) {
8890
if (typeof node.type === 'string') {
8991
isDOM = true;
9092
_node = node;
9193
} else {
9294
isDOM = false;
93-
renderer.render(node, context);
94-
this._instance = renderer._instance;
95+
return originalRender.call(this, node, context);
9596
}
9697
},
9798
getRenderOutput() {
9899
if (isDOM) {
99100
return _node;
100101
}
101-
return renderer.getRenderOutput();
102+
return originalRenderOutput.call(this);
102103
},
103-
};
104+
});
104105
};
105106
renderIntoDocument = TestUtils.renderIntoDocument;
106107
childrenToArray = React.Children.toArray;

test/ShallowWrapper-spec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,30 @@ describe('shallow', () => {
16441644

16451645
});
16461646

1647+
describe('.unmount()', () => {
1648+
it('should call componentWillUnmount()', () => {
1649+
const spy = sinon.spy();
1650+
1651+
class Foo extends React.Component {
1652+
constructor(props) {
1653+
super(props);
1654+
this.componentWillUnmount = spy;
1655+
}
1656+
render() {
1657+
return (
1658+
<div className={this.props.id}>
1659+
{this.props.id}
1660+
</div>
1661+
);
1662+
}
1663+
}
1664+
const wrapper = shallow(<Foo id="foo" />);
1665+
expect(spy.calledOnce).to.equal(false);
1666+
wrapper.unmount();
1667+
expect(spy.calledOnce).to.equal(true);
1668+
});
1669+
});
1670+
16471671
describe('.render()', () => {
16481672

16491673
it('should return a cheerio wrapper around the current node', () => {

0 commit comments

Comments
 (0)