Skip to content

Commit

Permalink
[enzyme-adapter-react-16] [new] Wrap renders in TestUtils.act
Browse files Browse the repository at this point in the history
  • Loading branch information
chenesan authored and ljharb committed Mar 6, 2019
1 parent df0c326 commit 35ec8fb
Showing 1 changed file with 84 additions and 71 deletions.
155 changes: 84 additions & 71 deletions packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ function getEmptyStateValue() {
return testRenderer._instance.state;
}

function wrapAct(fn) {
if (typeof TestUtils.act !== 'function') {
return fn();
}
let returnVal;
TestUtils.act(() => { returnVal = fn(); });
return returnVal;
}

class ReactSixteenAdapter extends EnzymeAdapter {
constructor() {
super();
Expand Down Expand Up @@ -316,25 +325,27 @@ class ReactSixteenAdapter extends EnzymeAdapter {
const adapter = this;
return {
render(el, context, callback) {
if (instance === null) {
const { type, props, ref } = el;
const wrapperProps = {
Component: type,
props,
context,
...(ref && { ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = hydrateIn
? ReactDOM.hydrate(wrappedEl, domNode)
: ReactDOM.render(wrappedEl, domNode);
if (typeof callback === 'function') {
callback();
return wrapAct(() => {
if (instance === null) {
const { type, props, ref } = el;
const wrapperProps = {
Component: type,
props,
context,
...(ref && { ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = hydrateIn
? ReactDOM.hydrate(wrappedEl, domNode)
: ReactDOM.render(wrappedEl, domNode);
if (typeof callback === 'function') {
callback();
}
} else {
instance.setChildProps(el.props, context, callback);
}
} else {
instance.setChildProps(el.props, context, callback);
}
});
},
unmount() {
ReactDOM.unmountComponentAtNode(domNode);
Expand Down Expand Up @@ -378,63 +389,65 @@ class ReactSixteenAdapter extends EnzymeAdapter {
let cachedNode = null;
return {
render(el, unmaskedContext) {
cachedNode = el;
/* eslint consistent-return: 0 */
if (typeof el.type === 'string') {
isDOM = true;
} else {
isDOM = false;
const { type: Component } = el;

const isStateful = Component.prototype && (
Component.prototype.isReactComponent
|| Array.isArray(Component.__reactAutoBindPairs) // fallback for createClass components
);

const context = getMaskedContext(Component.contextTypes, unmaskedContext);

if (!isStateful && isMemo(el.type)) {
const InnerComp = el.type.type;
const wrappedEl = Object.assign(
(...args) => InnerComp(...args), // eslint-disable-line new-cap
InnerComp,
return wrapAct(() => {
cachedNode = el;
/* eslint consistent-return: 0 */
if (typeof el.type === 'string') {
isDOM = true;
} else {
isDOM = false;
const { type: Component } = el;

const isStateful = Component.prototype && (
Component.prototype.isReactComponent
|| Array.isArray(Component.__reactAutoBindPairs) // fallback for createClass components
);
return withSetStateAllowed(() => renderer.render({ ...el, type: wrappedEl }, context));
}

if (!isStateful && typeof Component === 'function') {
const wrappedEl = Object.assign(
(...args) => Component(...args), // eslint-disable-line new-cap
Component,
);
return withSetStateAllowed(() => renderer.render({ ...el, type: wrappedEl }, context));
}
if (isStateful) {
// fix react bug; see implementation of `getEmptyStateValue`
const emptyStateValue = getEmptyStateValue();
if (emptyStateValue) {
Object.defineProperty(Component.prototype, 'state', {
configurable: true,
enumerable: true,
get() {
return null;
},
set(value) {
if (value !== emptyStateValue) {
Object.defineProperty(this, 'state', {
configurable: true,
enumerable: true,
value,
writable: true,
});
}
return true;
},
});
const context = getMaskedContext(Component.contextTypes, unmaskedContext);

if (!isStateful && isMemo(el.type)) {
const InnerComp = el.type.type;
const wrappedEl = Object.assign(
(...args) => InnerComp(...args), // eslint-disable-line new-cap
InnerComp,
);
return withSetStateAllowed(() => renderer.render({ ...el, type: wrappedEl }, context));
}

if (!isStateful && typeof Component === 'function') {
const wrappedEl = Object.assign(
(...args) => Component(...args), // eslint-disable-line new-cap
Component,
);
return withSetStateAllowed(() => renderer.render({ ...el, type: wrappedEl }, context));
}
if (isStateful) {
// fix react bug; see implementation of `getEmptyStateValue`
const emptyStateValue = getEmptyStateValue();
if (emptyStateValue) {
Object.defineProperty(Component.prototype, 'state', {
configurable: true,
enumerable: true,
get() {
return null;
},
set(value) {
if (value !== emptyStateValue) {
Object.defineProperty(this, 'state', {
configurable: true,
enumerable: true,
value,
writable: true,
});
}
return true;
},
});
}
}
return withSetStateAllowed(() => renderer.render(el, context));
}
return withSetStateAllowed(() => renderer.render(el, context));
}
});
},
unmount() {
renderer.unmount();
Expand Down

0 comments on commit 35ec8fb

Please sign in to comment.