Skip to content

Commit

Permalink
[enzyme-adapter-react-{16,16.3,16.2,16.1}] [fix] .setContext(): cal…
Browse files Browse the repository at this point in the history
…ls cWRP

Fixes #2258
  • Loading branch information
mul53 authored and ljharb committed Nov 13, 2020
1 parent 2dbc816 commit 34828de
Show file tree
Hide file tree
Showing 12 changed files with 262 additions and 38 deletions.
1 change: 1 addition & 0 deletions packages/enzyme-adapter-react-14/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"license": "MIT",
"dependencies": {
"enzyme-adapter-utils": "^1.14.0",
"enzyme-shallow-equal": "^1.0.4",
"object.assign": "^4.1.0",
"object.values": "^1.1.1",
"prop-types": "^15.7.2",
Expand Down
47 changes: 47 additions & 0 deletions packages/enzyme-adapter-react-14/src/ReactFourteenAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import {
getNodeFromRootFinder,
wrapWithWrappingComponent,
getWrappingComponentMountRenderer,
spyMethod,
} from 'enzyme-adapter-utils';
import shallowEqual from 'enzyme-shallow-equal';

function typeToNodeType(type) {
if (typeof type === 'function') {
Expand Down Expand Up @@ -172,6 +174,51 @@ class ReactFourteenAdapter extends EnzymeAdapter {
isDOM = true;
} else {
isDOM = false;

const inst = renderer._instance;
if (inst) {
const { restore: restoreUpdateComponent } = spyMethod(
inst,
'updateComponent',
(originalUpadateComponentMethod) => function updateComponent(
transaction,
prevParentElement,
nextParentElement,
prevUnmaskedContext,
nextUnmaskedContext,
) {
if (prevParentElement === nextParentElement) {
const { restore: restoreProcessPendingState } = spyMethod(
inst,
'_processPendingState',
(originalProcessPendingStateMethod) => function _processPendingState(nextProps, nextContext) {
if (!shallowEqual(prevUnmaskedContext, nextUnmaskedContext)) {
if (inst._instance.componentWillReceiveProps) {
inst._instance.componentWillReceiveProps(nextProps, nextContext);
}
}

const result = originalProcessPendingStateMethod.call(inst, nextProps, nextContext);
restoreProcessPendingState();
return result;
},
);
}

const result = originalUpadateComponentMethod.call(
inst,
transaction,
prevParentElement,
nextParentElement,
prevUnmaskedContext,
nextUnmaskedContext,
);
restoreUpdateComponent();
return result;
},
);
}

return withSetStateAllowed(() => renderer.render(el, context));
}
},
Expand Down
1 change: 1 addition & 0 deletions packages/enzyme-adapter-react-16.1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"license": "MIT",
"dependencies": {
"enzyme-adapter-utils": "^1.14.0",
"enzyme-shallow-equal": "^1.0.4",
"object.assign": "^4.1.0",
"prop-types": "^15.7.2",
"react-is": "^16.13.1",
Expand Down
25 changes: 25 additions & 0 deletions packages/enzyme-adapter-react-16.1/src/ReactSixteenOneAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
Portal,
} from 'react-is';
import { EnzymeAdapter } from 'enzyme';
import shallowEqual from 'enzyme-shallow-equal';
import {
displayNameOfNode,
elementToTree as utilElementToTree,
Expand All @@ -36,6 +37,7 @@ import {
getNodeFromRootFinder,
wrapWithWrappingComponent,
getWrappingComponentMountRenderer,
spyMethod,
} from 'enzyme-adapter-utils';
import { findCurrentFiberUsingSlowPath } from 'react-reconciler/reflection';

Expand Down Expand Up @@ -373,6 +375,29 @@ class ReactSixteenOneAdapter extends EnzymeAdapter {
return withSetStateAllowed(() => renderer.render({ ...el, type: wrappedEl }, context));
}
if (isStateful) {
if (
renderer._instance
&& el.props === renderer._instance.props
&& !shallowEqual(context, renderer._instance.context)
) {
const { restore } = spyMethod(
renderer,
'_updateClassComponent',
(originalMethod) => function _updateClassComponent(...args) {
const { props } = renderer._instance;
const clonedProps = { ...props };
renderer._instance.props = clonedProps;

const result = originalMethod.apply(renderer, args);

renderer._instance.props = props;
restore();

return result;
},
);
}

// fix react bug; see implementation of `getEmptyStateValue`
const emptyStateValue = getEmptyStateValue();
if (emptyStateValue) {
Expand Down
1 change: 1 addition & 0 deletions packages/enzyme-adapter-react-16.2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"license": "MIT",
"dependencies": {
"enzyme-adapter-utils": "^1.14.0",
"enzyme-shallow-equal": "^1.0.4",
"object.assign": "^4.1.0",
"object.values": "^1.1.1",
"prop-types": "^15.7.2",
Expand Down
25 changes: 25 additions & 0 deletions packages/enzyme-adapter-react-16.2/src/ReactSixteenTwoAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from 'react-is';
import { EnzymeAdapter } from 'enzyme';
import { typeOfNode } from 'enzyme/build/Utils';
import shallowEqual from 'enzyme-shallow-equal';
import {
displayNameOfNode,
elementToTree as utilElementToTree,
Expand All @@ -37,6 +38,7 @@ import {
getNodeFromRootFinder,
wrapWithWrappingComponent,
getWrappingComponentMountRenderer,
spyMethod,
} from 'enzyme-adapter-utils';
import { findCurrentFiberUsingSlowPath } from 'react-reconciler/reflection';

Expand Down Expand Up @@ -375,6 +377,29 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter {
return withSetStateAllowed(() => renderer.render({ ...el, type: wrappedEl }, context));
}
if (isStateful) {
if (
renderer._instance
&& el.props === renderer._instance.props
&& !shallowEqual(context, renderer._instance.context)
) {
const { restore } = spyMethod(
renderer,
'_updateClassComponent',
(originalMethod) => function _updateClassComponent(...args) {
const { props } = renderer._instance;
const clonedProps = { ...props };
renderer._instance.props = clonedProps;

const result = originalMethod.apply(renderer, args);

renderer._instance.props = props;
restore();

return result;
},
);
}

// fix react bug; see implementation of `getEmptyStateValue`
const emptyStateValue = getEmptyStateValue();
if (emptyStateValue) {
Expand Down
1 change: 1 addition & 0 deletions packages/enzyme-adapter-react-16.3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"license": "MIT",
"dependencies": {
"enzyme-adapter-utils": "^1.14.0",
"enzyme-shallow-equal": "^1.0.4",
"object.assign": "^4.1.0",
"object.values": "^1.1.1",
"prop-types": "^15.7.2",
Expand Down
28 changes: 28 additions & 0 deletions packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from 'react-is';
import { EnzymeAdapter } from 'enzyme';
import { typeOfNode } from 'enzyme/build/Utils';
import shallowEqual from 'enzyme-shallow-equal';
import {
displayNameOfNode,
elementToTree as utilElementToTree,
Expand All @@ -45,6 +46,7 @@ import {
getNodeFromRootFinder,
wrapWithWrappingComponent,
getWrappingComponentMountRenderer,
spyMethod,
} from 'enzyme-adapter-utils';
import { findCurrentFiberUsingSlowPath } from 'react-reconciler/reflection';

Expand Down Expand Up @@ -411,6 +413,32 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter {
);
return withSetStateAllowed(() => renderer.render({ ...el, type: wrappedEl }, context));
}

if (isStateful) {
if (
renderer._instance
&& el.props === renderer._instance.props
&& !shallowEqual(context, renderer._instance.context)
) {
const { restore } = spyMethod(
renderer,
'_updateClassComponent',
(originalMethod) => function _updateClassComponent(...args) {
const { props } = renderer._instance;
const clonedProps = { ...props };
renderer._instance.props = clonedProps;

const result = originalMethod.apply(renderer, args);

renderer._instance.props = props;
restore();

return result;
},
);
}
}

return withSetStateAllowed(() => renderer.render(el, context));
}
},
Expand Down
30 changes: 28 additions & 2 deletions packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
wrapWithWrappingComponent,
getWrappingComponentMountRenderer,
compareNodeTypeOf,
spyMethod,
} from 'enzyme-adapter-utils';
import findCurrentFiberUsingSlowPath from './findCurrentFiberUsingSlowPath';
import detectFiberTags from './detectFiberTags';
Expand Down Expand Up @@ -700,14 +701,39 @@ class ReactSixteenAdapter extends EnzymeAdapter {
));
}

if (!isStateful(Component) && typeof Component === 'function') {
const isComponentStateful = isStateful(Component);

if (!isComponentStateful && typeof Component === 'function') {
return withSetStateAllowed(() => renderElement(
{ ...renderedEl, type: wrapFunctionalComponent(Component) },
context,
));
}

if (isStateful) {
if (isComponentStateful) {
if (
renderer._instance
&& el.props === renderer._instance.props
&& !shallowEqual(context, renderer._instance.context)
) {
const { restore } = spyMethod(
renderer,
'_updateClassComponent',
(originalMethod) => function _updateClassComponent(...args) {
const { props } = renderer._instance;
const clonedProps = { ...props };
renderer._instance.props = clonedProps;

const result = originalMethod.apply(renderer, args);

renderer._instance.props = props;
restore();

return result;
},
);
}

// fix react bug; see implementation of `getEmptyStateValue`
const emptyStateValue = getEmptyStateValue();
if (emptyStateValue) {
Expand Down
1 change: 0 additions & 1 deletion packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ describeWithDOM('mount', () => {
expect(document.createElement('div')).to.be.instanceOf(HTMLElement);

const [[firstArg]] = spy.args;
console.log(firstArg);
expect(firstArg).to.be.instanceOf(HTMLElement);
});

Expand Down
42 changes: 7 additions & 35 deletions packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,10 @@ describe('shallow', () => {
}
}

Foo.contextTypes = {
foo: PropTypes.string,
};

const options = {
disableLifecycleMethods: true,
context: {
Expand Down Expand Up @@ -2122,51 +2126,19 @@ describe('shallow', () => {
]);
});

describeIf(is('0.13 || 15 || > 16'), 'setContext', () => {
describe('setContext', () => {
it('calls expected methods when receiving new context', () => {
const wrapper = shallow(<Foo />, options);
expect(spy.args).to.deep.equal([
['componentWillMount'],
['render'],
]);
spy.resetHistory();
wrapper.setContext({ foo: 'foo' });
expect(spy.args).to.deep.equal([
['componentWillReceiveProps'],
['shouldComponentUpdate'],
['componentWillUpdate'],
['render'],
]);
});
});

describeIf(is('16'), 'setContext', () => {
it('calls expected methods when receiving new context', () => {
const wrapper = shallow(<Foo />, options);
expect(spy.args).to.deep.equal([
['componentWillMount'],
['render'],
]);
spy.resetHistory();
wrapper.setContext({ foo: 'foo' });
expect(spy.args).to.deep.equal([
['shouldComponentUpdate'],
['componentWillUpdate'],
['render'],
]);
});
});
wrapper.setContext({ foo: 'bar' });

describeIf(is('0.14'), 'setContext', () => {
it('calls expected methods when receiving new context', () => {
const wrapper = shallow(<Foo />, options);
expect(spy.args).to.deep.equal([
['componentWillMount'],
['render'],
]);
spy.resetHistory();
wrapper.setContext({ foo: 'foo' });
expect(spy.args).to.deep.equal([
['componentWillReceiveProps'],
['shouldComponentUpdate'],
['componentWillUpdate'],
['render'],
Expand Down
Loading

0 comments on commit 34828de

Please sign in to comment.