Skip to content

Commit

Permalink
Merge pull request #876 from kentcdodds/pr/support-15.5
Browse files Browse the repository at this point in the history
[Compat] support React@15.5
  • Loading branch information
ljharb committed Apr 12, 2017
2 parents a8cf810 + 21f6e7a commit 75d1390
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 117 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Expand Up @@ -35,6 +35,8 @@ matrix:
env: KARMA=true REACT=0.13
- node_js: "6"
env: KARMA=true REACT=0.14
- node_js: "6"
env: KARMA=true REACT=15.4
- node_js: "6"
env: KARMA=true REACT=15
allow_failures:
Expand All @@ -43,4 +45,5 @@ matrix:
env:
- REACT=0.13
- REACT=0.14
- REACT=15.4
- REACT=15
12 changes: 9 additions & 3 deletions README.md
Expand Up @@ -60,12 +60,18 @@ npm i --save-dev enzyme
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` or `React 15.x`, in addition to `enzyme`, you will have to ensure that
If you are using `React 0.14` or `React <15.5`, 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
npm i --save-dev react-dom
npm i --save-dev react-addons-test-utils react-dom
```

If you are using `React >=15.5`, 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-test-renderer react-dom
```


Expand Down
4 changes: 4 additions & 0 deletions install-relevant-react.sh
Expand Up @@ -12,6 +12,10 @@ if [ "$REACT" = "0.14" ]; then
npm run react:14
fi

if [ "$REACT" = "15.4" ]; then
npm run react:15.4
fi

if [ "$REACT" = "15" ]; then
npm run react:15
fi
45 changes: 32 additions & 13 deletions karma.conf.js
Expand Up @@ -4,6 +4,36 @@ require('babel-register');

var IgnorePlugin = require('webpack').IgnorePlugin;
var REACT013 = require('./src/version').REACT013;
var REACT155 = require('./src/version').REACT155;

function getPlugins() {
var plugins = [];

/*
this list of conditional IgnorePlugins mirrors the conditional
requires in src/react-compat.js and exists to avoid error
output from the webpack compilation
*/

if (!REACT013) {
plugins.push(new IgnorePlugin(/react\/lib\/ExecutionEnvironment/));
plugins.push(new IgnorePlugin(/react\/lib\/ReactContext/));
plugins.push(new IgnorePlugin(/react\/addons/));
}
if (REACT013) {
plugins.push(new IgnorePlugin(/react-dom/));
}
if (REACT013 || REACT155) {
plugins.push(new IgnorePlugin(/react-addons-test-utils/));
}
if (!REACT155) {
plugins.push(new IgnorePlugin(/react-test-renderer/));
plugins.push(new IgnorePlugin(/react-dom\/test-utils/));
plugins.push(new IgnorePlugin(/create-react-class/));
}

return plugins;
}

module.exports = function karma(config) {
config.set({
Expand Down Expand Up @@ -33,7 +63,7 @@ module.exports = function karma(config) {
],

exclude: [
'test/_*.{jsx,js}',
'test/_helpers/index.jsx',
],

browsers: [
Expand Down Expand Up @@ -71,18 +101,7 @@ module.exports = function karma(config) {
},
],
},
plugins: [
/*
this list of conditional IgnorePlugins mirrors the conditional
requires in src/react-compat.js and exists to avoid error
output from the webpack compilation
*/
!REACT013 && new IgnorePlugin(/react\/lib\/ExecutionEnvironment/),
!REACT013 && new IgnorePlugin(/react\/lib\/ReactContext/),
!REACT013 && new IgnorePlugin(/react\/addons/),
REACT013 && new IgnorePlugin(/react-dom/),
REACT013 && new IgnorePlugin(/react-addons-test-utils/),
].filter(function filterPlugins(plugin) { return plugin !== false; }),
plugins: getPlugins(),
},

webpackServer: {
Expand Down
11 changes: 7 additions & 4 deletions package.json
Expand Up @@ -19,17 +19,18 @@
"test:watch": "mocha --recursive --watch test",
"test:karma": "karma start",
"test:env": "sh ./example-test.sh",
"test:all": "npm run react:13 && npm run test:only && npm run react:14 && npm run test:only && npm run react:15 && npm run test:only",
"react:clean": "rimraf node_modules/react node_modules/react-dom node_modules/react-addons-test-utils",
"test:all": "npm run react:13 && npm run test:only && npm run react:14 && npm run test:only && npm run react:15.4 && npm run test:only && npm run react:15 && npm run test:only",
"react:clean": "rimraf node_modules/react node_modules/react-dom node_modules/react-addons-test-utils node_modules/react-test-renderer",
"react:13": "rimraf node_modules/.bin/npm && npm run react:clean && npm i react@0.13 && npm install",
"react:14": "rimraf node_modules/.bin/npm && npm run react:clean && npm i react@0.14 react-dom@0.14 react-addons-test-utils@0.14 && npm install",
"react:15": "rimraf node_modules/.bin/npm && npm run react:clean && npm i react@15 react-dom@15 react-addons-test-utils@15 && npm install",
"react:15.4": "rimraf node_modules/.bin/npm && npm run react:clean && npm i react@15.4 react-dom@15.4 react-addons-test-utils@15.4 && npm install",
"react:15": "rimraf node_modules/.bin/npm && npm run react:clean && npm i react@15 react-dom@15 create-react-class@15 react-test-renderer@^15.5.4 && npm install",
"docs:clean": "rimraf _book",
"docs:prepare": "gitbook install",
"docs:build": "npm run docs:prepare && gitbook build",
"docs:watch": "npm run docs:prepare && gitbook serve",
"docs:publish": "npm run docs:clean && npm run docs:build && cd _book && git init && git commit --allow-empty -m 'update book' && git fetch git@github.com:airbnb/enzyme.git gh-pages && git checkout -b gh-pages && git add . && git commit -am 'update book' && git push git@github.com:airbnb/enzyme.git gh-pages --force",
"travis": "babel-node ./node_modules/.bin/istanbul cover --report html _mocha -- test --recursive"
"travis": "babel-node \"$(which istanbul)\" cover --report html _mocha -- test --recursive"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -60,6 +61,7 @@
"object.assign": "^4.0.4",
"object.entries": "^1.0.3",
"object.values": "^1.0.3",
"prop-types": "^15.5.4",
"uuid": "^2.0.3"
},
"devDependencies": {
Expand All @@ -71,6 +73,7 @@
"babel-register": "^6.24.1",
"chai": "^3.5.0",
"coveralls": "^2.13.0",
"create-react-class": "^15.5.2",
"enzyme-example-jest": "^0.1.0",
"enzyme-example-karma": "^0.1.1",
"enzyme-example-karma-webpack": "^0.1.4",
Expand Down
3 changes: 2 additions & 1 deletion src/ReactWrapperComponent.jsx
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import objectAssign from 'object.assign';

/* eslint react/forbid-prop-types: 0 */
Expand Down
18 changes: 15 additions & 3 deletions src/ShallowWrapper.js
Expand Up @@ -37,6 +37,7 @@ import {
batchedUpdates,
isDOMComponentElement,
} from './react-compat';
import { REACT155 } from './version';

/**
* Finds all nodes in the current wrapper nodes' render trees that match the provided predicate
Expand Down Expand Up @@ -98,6 +99,17 @@ function validateOptions(options) {
}
}


function performBatchedUpdates(wrapper, fn) {
const renderer = wrapper.root.renderer;
if (REACT155) {
// React 15.5+ exposes batching on shallow renderer itself
return renderer.unstable_batchedUpdates(fn);
}
// React <15.5: Fallback to ReactDOM
return batchedUpdates(fn);
}

/**
* @class ShallowWrapper
*/
Expand All @@ -110,7 +122,7 @@ class ShallowWrapper {
this.unrendered = nodes;
this.renderer = createShallowRenderer();
withSetStateAllowed(() => {
batchedUpdates(() => {
performBatchedUpdates(this, () => {
this.renderer.render(nodes, options.context);
const instance = this.instance();
if (
Expand Down Expand Up @@ -223,7 +235,7 @@ class ShallowWrapper {
const prevContext = instance.context;
const nextProps = props || prevProps;
const nextContext = context || prevContext;
batchedUpdates(() => {
performBatchedUpdates(this, () => {
let shouldRender = true;
// dirty hack:
// make sure that componentWillReceiveProps is called before shouldComponentUpdate
Expand Down Expand Up @@ -611,7 +623,7 @@ class ShallowWrapper {
withSetStateAllowed(() => {
// TODO(lmr): create/use synthetic events
// TODO(lmr): emulate React's event propagation
batchedUpdates(() => {
performBatchedUpdates(this, () => {
handler(...args);
});
this.root.update();
Expand Down
43 changes: 38 additions & 5 deletions src/react-compat.js
Expand Up @@ -7,7 +7,7 @@
*/

import objectAssign from 'object.assign';
import { REACT013 } from './version';
import { REACT013, REACT155 } from './version';

let TestUtils;
let createShallowRenderer;
Expand All @@ -18,6 +18,7 @@ let childrenToArray;
let renderWithOptions;
let unmountComponentAtNode;
let batchedUpdates;
let shallowRendererFactory;

const React = require('react');

Expand Down Expand Up @@ -95,12 +96,44 @@ if (REACT013) {
// to list this as a dependency in package.json and have 0.13 work properly.
// As a result, right now this is basically an implicit dependency.
try {
// eslint-disable-next-line import/no-extraneous-dependencies
TestUtils = require('react-addons-test-utils');
if (REACT155) {
// eslint-disable-next-line import/no-extraneous-dependencies
TestUtils = require('react-dom/test-utils');
} else {
// eslint-disable-next-line import/no-extraneous-dependencies
TestUtils = require('react-addons-test-utils');
}
} catch (e) {
if (REACT155) {
console.error( // eslint-disable-line no-console
'react-dom@15.5+ is an implicit dependency when using react@15.5+ with enzyme. ' +
'Please add the appropriate version to your devDependencies. ' +
'See https://github.com/airbnb/enzyme#installation',
);
} else {
console.error( // eslint-disable-line no-console
'react-addons-test-utils is an implicit dependency in order to support react@0.13-14. ' +
'Please add the appropriate version to your devDependencies. ' +
'See https://github.com/airbnb/enzyme#installation',
);
}
throw e;
}

// Shallow renderer is accessible via the react-test-renderer package for React 15.5+.
// This is a separate package though and may not be installed.
try {
if (REACT155) {
// eslint-disable-next-line import/no-extraneous-dependencies
shallowRendererFactory = require('react-test-renderer/shallow').createRenderer;
} else {
// eslint-disable-next-line import/no-extraneous-dependencies
shallowRendererFactory = TestUtils.createRenderer;
}
} catch (e) {
// eslint-disable-next-line no-console
console.error(
'react-addons-test-utils is an implicit dependency in order to support react@0.13-14. ' +
'react-test-renderer is an implicit dependency in order to support react@15.5+. ' +
'Please add the appropriate version to your devDependencies. ' +
'See https://github.com/airbnb/enzyme#installation',
);
Expand All @@ -115,7 +148,7 @@ if (REACT013) {
// is essentially a replacement for `TestUtils.createRenderer` that doesn't use
// shallow rendering when it's just a DOM element.
createShallowRenderer = function createRendererCompatible() {
const renderer = TestUtils.createRenderer();
const renderer = shallowRendererFactory();
const originalRender = renderer.render;
const originalRenderOutput = renderer.getRenderOutput;
let isDOM = false;
Expand Down
6 changes: 5 additions & 1 deletion src/version.js
@@ -1,6 +1,10 @@
import React from 'react';

export const VERSION = React.version;

const [major, minor] = VERSION.split('.');

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.';
export const REACT15 = major === '15';
export const REACT155 = REACT15 && minor >= 5;

0 comments on commit 75d1390

Please sign in to comment.