Skip to content

Commit

Permalink
adds comment about where ReactTestInstance has come from
Browse files Browse the repository at this point in the history
  • Loading branch information
Pete Gleeson committed May 4, 2018
1 parent 6234142 commit 09be724
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 52 deletions.
9 changes: 8 additions & 1 deletion packages/enzyme-adapter-react-renderer/package.json
Expand Up @@ -36,10 +36,17 @@
"dependencies": {
"cheerio": "^1.0.0-rc.2",
"enzyme-adapter-utils": "^1.3.0",
"has": "^1.0.1",
"invariant": "^2.2.4",
"is-subset": "^0.1.1",
"lodash": "^4.17.4",
"object.entries": "^1.0.4",
"object.values": "^1.0.4",
"object-is": "^1.0.1",
"react-is": "^16.3.2",
"react-reconciler": "^0.7.0",
"react-test-renderer": "^16.3.2"
"react-test-renderer": "^16.3.2",
"rst-selector-parser": "^2.2.3"
},
"peerDependencies": {
"enzyme": "^3.0.0",
Expand Down
55 changes: 54 additions & 1 deletion packages/enzyme-adapter-react-renderer/src/ReactMountWrapper.js
Expand Up @@ -5,6 +5,8 @@ import ReactDOMServer from 'react-dom/server';
import ReactTestRendererAdapter from './ReactTestRendererAdapter';
import ReactTestInstance from './ReactTestInstance';

import { reduceTreesBySelector } from './selectors';

const noop = () => {};

const flatMap = (collection, fn) =>
Expand Down Expand Up @@ -70,14 +72,46 @@ class ReactMountWrapper {
return _context;
}

/**
* Finds every node in the render tree of the current wrapper that matches the provided selector.
*
* @param {String|Function} selector
* @returns {ReactWrapper}
*/
find(selector) {
return new ReactMountWrapper(
flatMap(this.instances, instance => instance.findAllByType(selector)),
reduceTreesBySelector(selector, this.instances),
this.rootWrapper,
this.rootNode,
);
}

/**
* Finds all nodes in the current wrapper nodes' render trees that match the provided predicate
* function.
*
* @param {Function} predicate
* @returns {ReactWrapper}
*/
findWhere(predicate) {
return new ReactMountWrapper(
flatMap(this.instances, instance =>
instance.findAll(testInstance =>
predicate(new ReactMountWrapper([testInstance], this.rootWrapper, this.rootNode)))),
this.rootWrapper,
this.rootNode,
);
}

/**
* Returns a wrapper around the first node of the current wrapper.
*
* @returns {ReactWrapper}
*/
first() {
return this.at(0);
}

/**
* Returns the HTML of the node.
*
Expand Down Expand Up @@ -119,6 +153,15 @@ class ReactMountWrapper {
return first && first.parent.instance !== this.rootWrapper;
}

/**
* Returns a wrapper around the last node of the current wrapper.
*
* @returns {ReactWrapper}
*/
last() {
return this.at(this.length - 1);
}

/**
* Returns the name of the root node of this wrapper.
*
Expand All @@ -133,6 +176,16 @@ class ReactMountWrapper {
});
}

/**
* Returns the value of prop with the given name of the root node.
*
* @param {String} propName
* @returns {*}
*/
prop(propName) {
return this.props()[propName];
}

/**
* Returns the props hash for the root node of the wrapper.
*
Expand Down
72 changes: 22 additions & 50 deletions packages/enzyme-adapter-react-renderer/src/ReactTestInstance.js
@@ -1,4 +1,7 @@
import {findCurrentFiberUsingSlowPath} from 'react-reconciler/reflection';
// COPIED FROM https://github.com/facebook/react/blob/master/packages/react-test-renderer/src/ReactTestRenderer.js
// Ideally ReactTestInstance would be exported from the react-test-renderer package

import { findCurrentFiberUsingSlowPath } from 'react-reconciler/reflection';
import invariant from 'invariant';

export const IndeterminateComponent = 0; // Before we know whether it is functional or class
Expand All @@ -17,12 +20,7 @@ export const ContextConsumer = 12;
export const ContextProvider = 13;
export const ForwardRef = 14;

const validWrapperTypes = new Set([
FunctionalComponent,
ClassComponent,
HostComponent,
ForwardRef,
]);
const validWrapperTypes = new Set([FunctionalComponent, ClassComponent, HostComponent, ForwardRef]);

function getPublicInstance(inst) {
switch (inst.tag) {
Expand Down Expand Up @@ -51,27 +49,18 @@ function wrapFiber(fiber) {
return wrapper;
}

function expectOne(
all,
message,
) {
function expectOne(all, message) {
if (all.length === 1) {
return all[0];
}

const prefix =
all.length === 0
? 'No instances found '
: `Expected 1 but found ${all.length} instances `;
all.length === 0 ? 'No instances found ' : `Expected 1 but found ${all.length} instances `;

throw new Error(prefix + message);
}

function findAll(
root,
predicate,
options,
) {
function findAll(root, predicate, options) {
const deep = options ? options.deep : true;
const results = [];

Expand Down Expand Up @@ -126,9 +115,8 @@ class ReactTestInstance {
get instance() {
if (this._fiber.tag === HostComponent) {
return getPublicInstance(this._fiber.stateNode);
} else {
return this._fiber.stateNode;
}
return this._fiber.stateNode;
}

get type() {
Expand All @@ -141,9 +129,7 @@ class ReactTestInstance {

get parent() {
const parent = this._fiber.return;
return parent === null || parent.tag === HostRoot
? null
: wrapFiber(parent);
return parent === null || parent.tag === HostRoot ? null : wrapFiber(parent);
}

get children() {
Expand All @@ -165,7 +151,7 @@ class ReactTestInstance {
children.push(wrapFiber(node));
break;
case HostText:
children.push('' + node.memoizedProps);
children.push(`${node.memoizedProps}`);
break;
case Fragment:
case ContextProvider:
Expand All @@ -176,8 +162,7 @@ class ReactTestInstance {
default:
invariant(
false,
'Unsupported component type %s in test renderer. ' +
'This is probably a bug in React.',
'Unsupported component type %s in test renderer. ' + 'This is probably a bug in React.',
node.tag,
);
}
Expand All @@ -190,59 +175,46 @@ class ReactTestInstance {
if (node.return === startingNode) {
break outer;
}
node = (node.return);
node = node.return;
}
(node.sibling).return = node.return;
node = (node.sibling);
node.sibling.return = node.return;
node = node.sibling;
}
return children;
}

// Custom search functions
find(predicate) {
return expectOne(
this.findAll(predicate, {deep: false}),
this.findAll(predicate, { deep: false }),
`matching custom predicate: ${predicate.toString()}`,
);
}

findByType(type) {
return expectOne(
this.findAllByType(type, {deep: false}),
this.findAllByType(type, { deep: false }),
`with node type: "${type.displayName || type.name}"`,
);
}

findByProps(props) {
return expectOne(
this.findAllByProps(props, {deep: false}),
this.findAllByProps(props, { deep: false }),
`with props: ${JSON.stringify(props)}`,
);
}

findAll(
predicate,
options = null,
) {
findAll(predicate, options = null) {
return findAll(this, predicate, options);
}

findAllByType(
type,
options = null,
) {
findAllByType(type, options = null) {
return findAll(this, node => node.type === type, options);
}

findAllByProps(
props,
options = null,
) {
return findAll(
this,
node => node.props && propsMatch(node.props, props),
options,
);
findAllByProps(props, options = null) {
return findAll(this, node => node.props && propsMatch(node.props, props), options);
}
}

Expand Down

0 comments on commit 09be724

Please sign in to comment.