Skip to content

Commit

Permalink
Supporting all lifecycle methods is an opt-in feature when lifecycleE…
Browse files Browse the repository at this point in the history
…xperimental option is true
  • Loading branch information
koba04 committed May 27, 2016
1 parent f160fcf commit 8422734
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 31 deletions.
30 changes: 25 additions & 5 deletions src/ShallowWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ export default class ShallowWrapper {
batchedUpdates(() => {
this.renderer.render(nodes, options.context);
const instance = this.instance();
if (instance && typeof instance.componentDidMount === 'function') {
if (
options.lifecycleExperimental &&
instance &&
typeof instance.componentDidMount === 'function'
) {
instance.componentDidMount();
}
});
Expand Down Expand Up @@ -160,13 +164,21 @@ export default class ShallowWrapper {
const context = instance.context;
batchedUpdates(() => {
let shouldRender = true;
if (instance && typeof instance.shouldComponentUpdate === 'function') {
if (
this.options.lifecycleExperimental &&
instance &&
typeof instance.shouldComponentUpdate === 'function'
) {
shouldRender = instance.shouldComponentUpdate(props, state, context);
}
if (shouldRender) {
this.unrendered = React.cloneElement(this.unrendered, props);
this.renderer.render(this.unrendered, context);
if (instance && typeof instance.componentDidUpdate === 'function') {
if (
this.options.lifecycleExperimental &&
instance &&
typeof instance.componentDidUpdate === 'function'
) {
instance.componentDidUpdate(prevProps, state, context);
}
this.update();
Expand Down Expand Up @@ -231,12 +243,20 @@ export default class ShallowWrapper {
withSetStateAllowed(() => {
batchedUpdates(() => {
let shouldRender = true;
if (instance && typeof instance.shouldComponentUpdate === 'function') {
if (
this.options.lifecycleExperimental &&
instance &&
typeof instance.shouldComponentUpdate === 'function'
) {
shouldRender = instance.shouldComponentUpdate(props, state, context);
}
if (shouldRender) {
this.renderer.render(this.unrendered, context);
if (instance && typeof instance.componentDidUpdate === 'function') {
if (
this.options.lifecycleExperimental &&
instance &&
typeof instance.componentDidUpdate === 'function'
) {
instance.componentDidUpdate(props, state, prevContext);
}
this.update();
Expand Down
144 changes: 118 additions & 26 deletions test/ShallowWrapper-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2321,7 +2321,7 @@ describe('shallow', () => {

});

describe('Component Lifecycle methods', () => {
describe('lifecycleExperimental', () => {
context('mounting', () => {
it('should call componentWillMount', () => {
const spy = sinon.spy();
Expand All @@ -2333,7 +2333,7 @@ describe('shallow', () => {
return <div>foo</div>;
}
}
shallow(<Foo />);
shallow(<Foo />, { lifecycleExperimental: true });
expect(spy.calledOnce).to.equal(true);
});
it('should call componentDidMount', () => {
Expand All @@ -2346,7 +2346,7 @@ describe('shallow', () => {
return <div>foo</div>;
}
}
shallow(<Foo />);
shallow(<Foo />, { lifecycleExperimental: true });
expect(spy.calledOnce).to.equal(true);
});

Expand All @@ -2372,7 +2372,7 @@ describe('shallow', () => {
return <div>{this.state.count}</div>;
}
}
const result = shallow(<Foo />);
const result = shallow(<Foo />, { lifecycleExperimental: true });
expect(result.state('count')).to.equal(2);
expect(spy.callCount).to.equal(2);
});
Expand All @@ -2395,7 +2395,13 @@ describe('shallow', () => {
foo: React.PropTypes.string,
};

const wrapper = shallow(<Foo foo="bar" />, { context: { foo: 'context' } });
const wrapper = shallow(
<Foo foo="bar" />,
{
context: { foo: 'context' },
lifecycleExperimental: true,
}
);
wrapper.setProps({ foo: 'baz' });
expect(
spy.calledWith({ foo: 'bar' }, { foo: 'baz' }, { foo: 'context' })
Expand All @@ -2419,7 +2425,7 @@ describe('shallow', () => {
}
}

const wrapper = shallow(<Foo foo="bar" />);
const wrapper = shallow(<Foo foo="bar" />, { lifecycleExperimental: true });
wrapper.setProps({ foo: 'baz' });
expect(wrapper.state('foo')).to.equal('baz');
});
Expand All @@ -2446,7 +2452,13 @@ describe('shallow', () => {
foo: React.PropTypes.string,
};

const wrapper = shallow(<Foo foo="bar" />, { context: { foo: 'context' } });
const wrapper = shallow(
<Foo foo="bar" />,
{
context: { foo: 'context' },
lifecycleExperimental: true,
}
);
wrapper.setProps({ foo: 'baz' });
expect(
spy.calledWith({ foo: 'bar' }, { foo: 'baz' }, { foo: 'state' }, { foo: 'context' })
Expand Down Expand Up @@ -2474,7 +2486,13 @@ describe('shallow', () => {
foo: React.PropTypes.string,
};

const wrapper = shallow(<Foo foo="bar" />, { context: { foo: 'context' } });
const wrapper = shallow(
<Foo foo="bar" />,
{
context: { foo: 'context' },
lifecycleExperimental: true,
}
);
wrapper.setProps({ foo: 'baz' });
expect(
spy.calledWith({ foo: 'bar' }, { foo: 'baz' }, { foo: 'state' }, { foo: 'context' })
Expand All @@ -2501,7 +2519,13 @@ describe('shallow', () => {
foo: React.PropTypes.string,
};

const wrapper = shallow(<Foo foo="bar" />, { context: { foo: 'context' } });
const wrapper = shallow(
<Foo foo="bar" />,
{
context: { foo: 'context' },
lifecycleExperimental: true,
}
);
wrapper.setProps({ foo: 'baz' });
expect(
spy.calledWith({ foo: 'bar' }, { foo: 'baz' }, { foo: 'state' }, { foo: 'context' })
Expand All @@ -2526,7 +2550,7 @@ describe('shallow', () => {
}
}

const wrapper = shallow(<Foo foo="bar" />);
const wrapper = shallow(<Foo foo="bar" />, { lifecycleExperimental: true });
wrapper.setProps({ foo: 'baz' });
expect(spy.callCount).to.equal(0);
});
Expand All @@ -2549,7 +2573,7 @@ describe('shallow', () => {
return <div>{this.props.foo}</div>;
}
}
const result = shallow(<Foo />);
const result = shallow(<Foo />, { lifecycleExperimental: true });
result.setProps({ name: 'bar' });
expect(result.state('count')).to.equal(1);
expect(spy.callCount).to.equal(2);
Expand Down Expand Up @@ -2577,7 +2601,7 @@ describe('shallow', () => {
return <div>{this.props.foo}</div>;
}
}
const result = shallow(<Foo />);
const result = shallow(<Foo />, { lifecycleExperimental: true });
result.setProps({ name: 'bar' });
expect(result.state('count')).to.equal(1);
expect(spy.callCount).to.equal(3);
Expand Down Expand Up @@ -2607,7 +2631,7 @@ describe('shallow', () => {
return <div>{this.props.foo}</div>;
}
}
const result = shallow(<Foo />);
const result = shallow(<Foo />, { lifecycleExperimental: true });
result.setProps({ name: 'bar' });
expect(result.state('count')).to.equal(1);
expect(spy.callCount).to.equal(3);
Expand Down Expand Up @@ -2639,7 +2663,13 @@ describe('shallow', () => {
foo: React.PropTypes.string,
};

const wrapper = shallow(<Foo foo="props" />, { context: { foo: 'context' } });
const wrapper = shallow(
<Foo foo="props" />,
{
context: { foo: 'context' },
lifecycleExperimental: true,
}
);
wrapper.setState({ foo: 'baz' });
expect(
spy.calledWith({ foo: 'props' }, { foo: 'bar' }, { foo: 'baz' }, { foo: 'context' })
Expand Down Expand Up @@ -2667,7 +2697,13 @@ describe('shallow', () => {
foo: React.PropTypes.string,
};

const wrapper = shallow(<Foo foo="props" />, { context: { foo: 'context' } });
const wrapper = shallow(
<Foo foo="props" />,
{
context: { foo: 'context' },
lifecycleExperimental: true,
}
);
wrapper.setState({ foo: 'baz' });
expect(
spy.calledWith({ foo: 'props' }, { foo: 'bar' }, { foo: 'baz' }, { foo: 'context' })
Expand Down Expand Up @@ -2695,7 +2731,13 @@ describe('shallow', () => {
foo: React.PropTypes.string,
};

const wrapper = shallow(<Foo foo="props" />, { context: { foo: 'context' } });
const wrapper = shallow(
<Foo foo="props" />,
{
context: { foo: 'context' },
lifecycleExperimental: true,
}
);
wrapper.setState({ foo: 'baz' });
expect(
spy.calledWith({ foo: 'props' }, { foo: 'bar' }, { foo: 'baz' }, { foo: 'context' })
Expand Down Expand Up @@ -2724,7 +2766,7 @@ describe('shallow', () => {
return <div>foo</div>;
}
}
const wrapper = shallow(<Foo />);
const wrapper = shallow(<Foo />, { lifecycleExperimental: true });
wrapper.setState({ foo: 'baz' });
expect(spy.callCount).to.equal(0);
});
Expand Down Expand Up @@ -2752,7 +2794,7 @@ describe('shallow', () => {
return <div>{this.state.name}</div>;
}
}
const result = shallow(<Foo />);
const result = shallow(<Foo />, { lifecycleExperimental: true });
result.setState({ name: 'bar' });
expect(result.state('count')).to.equal(1);
expect(spy.callCount).to.equal(3);
Expand Down Expand Up @@ -2783,7 +2825,7 @@ describe('shallow', () => {
return <div>{this.state.name}</div>;
}
}
const result = shallow(<Foo />);
const result = shallow(<Foo />, { lifecycleExperimental: true });
result.setState({ name: 'bar' });
expect(result.state('count')).to.equal(1);
expect(spy.callCount).to.equal(3);
Expand All @@ -2807,7 +2849,13 @@ describe('shallow', () => {
Foo.contextTypes = {
foo: React.PropTypes.string,
};
const wrapper = shallow(<Foo />, { context: { foo: 'bar' } });
const wrapper = shallow(
<Foo />,
{
context: { foo: 'bar' },
lifecycleExperimental: true,
}
);
wrapper.setContext({ foo: 'baz' });
expect(spy.calledWith({ foo: 'bar' }, { foo: 'baz' })).to.equal(true);
});
Expand All @@ -2825,7 +2873,13 @@ describe('shallow', () => {
Foo.contextTypes = {
foo: React.PropTypes.string,
};
const wrapper = shallow(<Foo />, { context: { foo: 'bar' } });
const wrapper = shallow(
<Foo />,
{
context: { foo: 'bar' },
lifecycleExperimental: true,
}
);
wrapper.setContext({ foo: 'baz' });
expect(spy.calledWith({ foo: 'bar' }, { foo: 'baz' })).to.equal(true);
});
Expand All @@ -2843,7 +2897,13 @@ describe('shallow', () => {
Foo.contextTypes = {
foo: React.PropTypes.string,
};
const wrapper = shallow(<Foo />, { context: { foo: 'bar' } });
const wrapper = shallow(
<Foo />,
{
context: { foo: 'bar' },
lifecycleExperimental: true,
}
);
wrapper.setContext({ foo: 'baz' });
expect(spy.calledWith({ foo: 'bar' }, { foo: 'baz' })).to.equal(true);
});
Expand All @@ -2867,7 +2927,13 @@ describe('shallow', () => {
Foo.contextTypes = {
foo: React.PropTypes.string,
};
const wrapper = shallow(<Foo />, { context: { foo: 'bar' } });
const wrapper = shallow(
<Foo />,
{
context: { foo: 'bar' },
lifecycleExperimental: true,
}
);
wrapper.setContext({ foo: 'baz' });
expect(spy.callCount).to.equal(0);
});
Expand All @@ -2894,7 +2960,13 @@ describe('shallow', () => {
return <div>{this.state.name}</div>;
}
}
const result = shallow(<Foo />, { context: { foo: 'bar' } });
const result = shallow(
<Foo />,
{
context: { foo: 'bar' },
lifecycleExperimental: true,
}
);
result.setContext({ foo: 'baz' });
expect(result.state('count')).to.equal(1);
expect(spy.callCount).to.equal(3);
Expand Down Expand Up @@ -2924,7 +2996,13 @@ describe('shallow', () => {
return <div>{this.state.name}</div>;
}
}
const result = shallow(<Foo />, { context: { foo: 'bar' } });
const result = shallow(
<Foo />,
{
context: { foo: 'bar' },
lifecycleExperimental: true,
}
);
result.setContext({ foo: 'baz' });
expect(result.state('count')).to.equal(1);
expect(spy.callCount).to.equal(3);
Expand All @@ -2944,11 +3022,25 @@ describe('shallow', () => {
return <div>foo</div>;
}
}
const wrapper = shallow(<Foo />);
const wrapper = shallow(<Foo />, { lifecycleExperimental: true });
wrapper.unmount();
expect(spy.calledOnce).to.equal(true);
});
});

it('should not call when lifecycleExperimental flag is false', () => {
const spy = sinon.spy();
class Foo extends React.Component {
componentDidMount() {
spy();
}
render() {
return <div>foo</div>;
}
}
shallow(<Foo />, { lifecycleExperimental: false });
expect(spy.calledOnce).to.equal(false);
});
});

it('works with class components that return null', () => {
Expand Down

0 comments on commit 8422734

Please sign in to comment.