Skip to content

Commit

Permalink
Add compatibility for React 15 RC1
Browse files Browse the repository at this point in the history
This adds compatibility for React 15 RC1. The most painful/icky
change is in retrieving the internal instance, which has a random
number appended to its key.

There's also a hack to work around a bug in React 15 where warnings
on ref and key are throwing for nodes with string types.
  • Loading branch information
iancmyers committed Mar 9, 2016
1 parent 4c903a7 commit 7efeda3
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 18 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
"check": "npm run lint && npm run test:all",
"build": "babel src --out-dir build",
"test": "npm run lint && npm run test:only",
"test:only": "mocha --require withDom.js --compilers js:babel-core/register --recursive test/*.js",
"test:single": "mocha --require withDom.js --compilers js:babel-core/register --watch",
"test:watch": "mocha --require withDom.js --compilers js:babel-core/register --recursive test/*.js --watch",
"test:only": "mocha --require withDom.js --compilers js:babel-core/register --recursive test/*.js --reporter dot",
"test:single": "mocha --require withDom.js --compilers js:babel-core/register --watch --reporter dot",
"test:watch": "mocha --require withDom.js --compilers js:babel-core/register --recursive test/*.js --watch --reporter dot",
"test:env": "sh ./example-test.sh",
"test:all": "npm run react:13 && npm test && npm run react:14 && npm test && npm run react:15 && npm test",
"react:clean": "rimraf node_modules/react node_modules/react-dom node_modules/react-addons-test-utils",
Expand Down
7 changes: 3 additions & 4 deletions src/Debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
childrenOfNode,
} from './ShallowTraversal';
import {
internalInstance,
renderedChildrenOfInst,
} from './MountedTraversal';
import {
Expand All @@ -11,12 +10,13 @@ import {
isElement,
} from './react-compat';
import {
internalInstance,
propsOfNode,
} from './Utils';
import without from 'lodash/without';
import escape from 'lodash/escape';
import compact from 'lodash/compact';
import { REACT013, REACT014 } from './version';
import { REACT013 } from './version';
import objectValues from 'object.values';

export function typeName(node) {
Expand Down Expand Up @@ -85,7 +85,6 @@ export function debugInst(inst, indentLength = 2) {
const internal = internalInstance(inst);
return debugInst(internal, indentLength);
}

const publicInst = inst.getPublicInstance();

if (typeof publicInst === 'string' || typeof publicInst === 'number') return escape(publicInst);
Expand All @@ -104,7 +103,7 @@ export function debugInst(inst, indentLength = 2) {
children.push(...objectValues(renderedChildren));
}
} else if (
REACT014 &&
!REACT013 &&
isElement(currentElement) &&
typeof currentElement.type === 'function'
) {
Expand Down
19 changes: 12 additions & 7 deletions src/MountedTraversal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import isEmpty from 'lodash/isEmpty';
import isSubset from 'is-subset';
import {
internalInstance,
coercePropValue,
nodeEqual,
propsOfNode,
Expand All @@ -20,11 +21,7 @@ import {
isElement,
findDOMNode,
} from './react-compat';
import { REACT013, REACT014 } from './version';

export function internalInstance(inst) {
return inst._reactInternalInstance;
}
import { REACT013 } from './version';

export function getNode(inst) {
if (!inst || inst._store || typeof inst === 'string') {
Expand All @@ -36,6 +33,9 @@ export function getNode(inst) {
if (internalInstance(inst)) {
return internalInstance(inst)._currentElement;
}
if (inst._reactInternalInstance) {
return inst._reactInternalInstance._currentElement;
}
if (inst._reactInternalComponent) {
return inst._reactInternalComponent._currentElement;
}
Expand Down Expand Up @@ -75,6 +75,10 @@ export function instHasProperty(inst, propKey, stringifiedPropValue) {
if (!isDOMComponent(inst)) return false;
const node = getNode(inst);
const nodeProps = propsOfNode(node);
const descriptor = Object.getOwnPropertyDescriptor(nodeProps, propKey);
if (descriptor && descriptor.get) {
return false;
}
const nodePropValue = nodeProps[propKey];

const propValue = coercePropValue(propKey, stringifiedPropValue);
Expand Down Expand Up @@ -107,6 +111,7 @@ export function childrenOfInstInternal(inst) {
const internal = internalInstance(inst);
return childrenOfInstInternal(internal);
}

const publicInst = inst.getPublicInstance();
const currentElement = inst._currentElement;
if (isDOMComponent(publicInst)) {
Expand All @@ -124,7 +129,7 @@ export function childrenOfInstInternal(inst) {
}
return children;
} else if (
REACT014 &&
!REACT013 &&
isElement(currentElement) &&
typeof currentElement.type === 'function'
) {
Expand Down Expand Up @@ -259,7 +264,7 @@ function findAllInRenderedTreeInternal(inst, test) {
);
}
} else if (
REACT014 &&
!REACT013 &&
isElement(currentElement) &&
typeof currentElement.type === 'function'
) {
Expand Down
4 changes: 2 additions & 2 deletions src/ReactWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ export default class ReactWrapper {
const predicate = Array.isArray(nodeOrNodes)
? other => containsChildrenSubArray(instEqual, other, nodeOrNodes)
: other => instEqual(nodeOrNodes, other);

return findWhereUnwrapped(this, predicate).length > 0;
}

Expand Down Expand Up @@ -343,7 +342,8 @@ export default class ReactWrapper {
html() {
return this.single(n => {
const node = findDOMNode(n);
return node === null ? null : node.outerHTML.replace(/\sdata-reactid+="[^"]+"/g, '');
return node === null ? null :
node.outerHTML.replace(/\sdata-(reactid|reactroot)+="([^"]*)+"/g, '');
});
}

Expand Down
4 changes: 4 additions & 0 deletions src/ShallowTraversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export function nodeHasId(node, id) {
export function nodeHasProperty(node, propKey, stringifiedPropValue) {
const nodeProps = propsOfNode(node);
const propValue = coercePropValue(propKey, stringifiedPropValue);
const descriptor = Object.getOwnPropertyDescriptor(nodeProps, propKey);
if (descriptor && descriptor.get) {
return false;
}
const nodePropValue = nodeProps[propKey];

if (nodePropValue === undefined) {
Expand Down
19 changes: 17 additions & 2 deletions src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,31 @@ import {
} from './react-compat';
import {
REACT013,
REACT014,
REACT15,
} from './version';

function internalInstanceKey(node) {
return Object.keys(Object(node)).filter(key => key.match(/^__reactInternalInstance\$/))[0];
}

export function internalInstance(inst) {
return inst._reactInternalInstance ||
inst[internalInstanceKey(inst)];
}

export function propsOfNode(node) {
if (REACT013 && node && node._store) {
return (node._store.props) || {};
}
if (node && node._reactInternalComponent && node._reactInternalComponent._currentElement) {
return (node._reactInternalComponent._currentElement.props) || {};
}
if (REACT15 && node) {
if (internalInstance(node) && internalInstance(node)._currentElement) {
return (internalInstance(node)._currentElement.props) || {};
}
}

return (node && node.props) || {};
}

Expand Down Expand Up @@ -232,7 +247,7 @@ export function mapNativeEventNames(event) {
volumechange: 'volumeChange',
};

if (REACT014) {
if (!REACT013) {
// these could not be simulated in React 0.13:
// https://github.com/facebook/react/issues/1297
nativeToReactEventMap.mouseenter = 'mouseEnter';
Expand Down

0 comments on commit 7efeda3

Please sign in to comment.