Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compatibility for React 15 RC1 #240

Merged
merged 4 commits into from
Mar 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ after_script:
env:
- REACT=0.13
- REACT=0.14
- REACT=15
- EXAMPLE=mocha
- EXAMPLE=karma
- EXAMPLE=react-native
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ To get started with enzyme, you can simply install it with npm:
npm i --save-dev enzyme
```

Enzyme is currently compatible with both `React 0.14.x` and `React 0.13.x`. In order to achieve
this compatibility, some dependencies cannot be explicitly listed in our `package.json`.
Enzyme is currently compatible with `React 15.x`, `React 0.14.x` and `React 0.13.x`. In order to
achieve this compatibility, some dependencies cannot be explicitly listed in our `package.json`.

If you are using `React 0.14`, in addition to `enzyme`, you will have to ensure that you also
have the following npm modules installed if they were not already:
If you are using React 0.14` or `React 15.x`, in addition to `enzyme`, you will have to ensure that
you also have the following npm modules installed if they were not already:

```bash
npm i --save-dev react-addons-test-utils
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* [Installation](/docs/installation/README.md)
* [Working with React 0.13.x](/docs/installation/react-013.md)
* [Working with React 0.14.x](/docs/installation/react-014.md)
* [Working with React 15.x](/docs/installation/react-15.md)
* [API Reference](/docs/api/README.md)
* [Shallow Rendering](/docs/api/shallow.md)
* [at(index)](/docs/api/ShallowWrapper/at.md)
Expand Down
4 changes: 3 additions & 1 deletion docs/installation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ npm i --save-dev enzyme
```

Enzyme can be used with your test runner of choice. All examples in the documentation will be
provided using [mocha](https://mochajs.org/) and [BDD style chai](http://chaijs.com/api/bdd/),
provided using [mocha](https://mochajs.org/) and [BDD style chai](http://chaijs.com/api/bdd/),
although neither library is a dependency of enzyme.

{% include "./react-013.md" %}

{% include "./react-014.md" %}

{% include "./react-15.md" %}
34 changes: 34 additions & 0 deletions docs/installation/react-15.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Working with React 15

If you are wanting to use Enzyme with React 0.14, but don't already have React 15 and react-dom
installed, you should do so:

```bash
npm i --save react@15.0.0-rc.1 react-dom@15.0.0-rc.1
```

Further, enzyme requires the test utilities addon be installed:

```bash
npm i --save-dev react-addons-test-utils@15.0.0-rc.1
```

Next, to get started with enzyme, you can simply install it with npm:

```bash
npm i --save-dev enzyme
```

And then you're ready to go! In your test files you can simply `require` or `import` enzyme:

ES6:
```js
import { shallow, mount, render } from 'enzyme';
const wrapper = shallow(<Foo />);
```

ES5:
```js
var enzyme = require('enzyme');
var wrapper = enzyme.shallow(<Foo />);
```
4 changes: 4 additions & 0 deletions install-relevant-react.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ fi
if [ "$REACT" = "0.14" ]; then
npm run react:14
fi

if [ "$REACT" = "15" ]; then
npm run react:15
fi
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
"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",
"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",
"react:13": "npm run react:clean && npm i react@0.13",
"react:14": "npm run react:clean && npm i react@0.14 react-dom@0.14 react-addons-test-utils@0.14",
"react:15": "npm run react:clean && npm i react@15.0.0-rc.1 react-dom@15.0.0-rc.1 react-addons-test-utils@15.0.0-rc.1",
"docs:clean": "rimraf _book",
"docs:prepare": "gitbook install",
"docs:build": "npm run docs:prepare && gitbook build",
Expand Down Expand Up @@ -79,6 +80,6 @@
"sinon": "^1.15.4"
},
"peerDependencies": {
"react": "0.13.x || 0.14.x"
"react": "0.13.x || 0.14.x || 15.* || 15.0.0-rc.1"
}
}
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];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really?

cartoon drawing of a sad fox

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessible is public, Ben. ¯\_(ツ)_/¯

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next time I'm making it nonenumerable and monkey-patching Object.getOwnPropertyNames (and Reflect.ownKeys I guess).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spicyj also every goPD and ownKeys in every realm that i could possibly create!

}

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
1 change: 1 addition & 0 deletions src/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ import React from 'react';
export const VERSION = React.version;
export const REACT013 = VERSION.slice(0, 4) === '0.13';
export const REACT014 = VERSION.slice(0, 4) === '0.14';
export const REACT15 = VERSION.slice(0, 3) === '15.';