Skip to content

Commit

Permalink
ShallowWrapper calls update() automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 committed Feb 12, 2018
1 parent 085e014 commit 013e85e
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 7 deletions.
71 changes: 71 additions & 0 deletions packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4656,4 +4656,75 @@ describe('shallow', () => {
});
});
});
describe('setState through a props method', () => {
it('should be able to get the latest state value', () => {
const Child = props => <button onClick={props.onClick}>click</button>;
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
onIncrement() {
this.setState({
count: this.state.count + 1,
});
}
render() {
return (
<div>
<Child onClick={() => this.onIncrement()} />
<p>{this.state.count}</p>
</div>
);
}
}
const wrapper = shallow(<App />);
const p = wrapper.find('p');
expect(wrapper.find('p').text()).to.equal('0');
wrapper.find(Child).prop('onClick')();
// this is still 0 because the wrapper won't be updated
expect(p.text()).to.equal('0');
expect(wrapper.find('p').text()).to.equal('1');
});
});
describe('setState through a props method in async', () => {
it('should be able to get the latest state value', (done) => {
const Child = props => <button onClick={props.onClick}>click</button>;
let App;
const promise = new Promise((resolve) => {
App = class extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
onIncrement() {
setTimeout(() => {
this.setState({
count: this.state.count + 1,
}, resolve);
});
}
render() {
return (
<div>
<Child onClick={() => this.onIncrement()} />
<p>{this.state.count}</p>
</div>
);
}
};
});
const wrapper = shallow(<App />);
promise.then(() => {
expect(wrapper.find('p').text()).to.equal('1');
done();
});
expect(wrapper.find('p').text()).to.equal('0');
wrapper.find(Child).prop('onClick')();
});
});
});
24 changes: 17 additions & 7 deletions packages/enzyme/src/ShallowWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,17 @@ class ShallowWrapper {
return this[ROOT];
}

getRootNodeInternal() {
return this[ROOT][NODE];
}

getNodeInternal() {
if (this.length !== 1) {
throw new Error('ShallowWrapper::getNode() can only be called when wrapping one node');
}
if (this[ROOT] === this) {
this.update();
}
return this[NODE];
}

Expand All @@ -169,7 +175,7 @@ class ShallowWrapper {
if (this.length !== 1) {
throw new Error('ShallowWrapper::getElement() can only be called when wrapping one node');
}
return getAdapter(this[OPTIONS]).nodeToElement(this[NODE]);
return getAdapter(this[OPTIONS]).nodeToElement(this.getNodeInternal());
}

/**
Expand All @@ -178,7 +184,7 @@ class ShallowWrapper {
* @return {Array<ReactElement>}
*/
getElements() {
return this[NODES].map(getAdapter(this[OPTIONS]).nodeToElement);
return this.getNodesInternal().map(getAdapter(this[OPTIONS]).nodeToElement);
}

// eslint-disable-next-line class-methods-use-this
Expand All @@ -187,6 +193,9 @@ class ShallowWrapper {
}

getNodesInternal() {
if (this[ROOT] === this && this.length === 1) {
this.update();
}
return this[NODES];
}

Expand Down Expand Up @@ -227,9 +236,10 @@ class ShallowWrapper {
if (this[ROOT] !== this) {
throw new Error('ShallowWrapper::update() can only be called on the root');
}
this.single('update', () => {
privateSetNodes(this, getRootNode(this[RENDERER].getNode()));
});
if (this.length !== 1) {
throw new Error('ShallowWrapper::update() can only be called when wrapping one node');
}
privateSetNodes(this, getRootNode(this[RENDERER].getNode()));
return this;
}

Expand Down Expand Up @@ -795,7 +805,7 @@ class ShallowWrapper {
* @returns {ShallowWrapper}
*/
parents(selector) {
const allParents = this.wrap(this.single('parents', n => parentsOfNode(n, this[ROOT][NODE])));
const allParents = this.wrap(this.single('parents', n => parentsOfNode(n, this.getRootNodeInternal())));
return selector ? allParents.filter(selector) : allParents;
}

Expand Down Expand Up @@ -1190,7 +1200,7 @@ if (ITERATOR_SYMBOL) {
Object.defineProperty(ShallowWrapper.prototype, ITERATOR_SYMBOL, {
configurable: true,
value: function iterator() {
const iter = this[NODES][ITERATOR_SYMBOL]();
const iter = this.getNodesInternal()[ITERATOR_SYMBOL]();
const adapter = getAdapter(this[OPTIONS]);
return {
next() {
Expand Down

0 comments on commit 013e85e

Please sign in to comment.