diff --git a/.travis.yml b/.travis.yml index 87cc3f0cd..356457cad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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: @@ -43,4 +45,5 @@ matrix: env: - REACT=0.13 - REACT=0.14 + - REACT=15.4 - REACT=15 diff --git a/README.md b/README.md index 408e0598a..135392a77 100644 --- a/README.md +++ b/README.md @@ -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 ``` diff --git a/install-relevant-react.sh b/install-relevant-react.sh index 6619dda6b..6303d0ffe 100644 --- a/install-relevant-react.sh +++ b/install-relevant-react.sh @@ -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 diff --git a/karma.conf.js b/karma.conf.js index 8bbdc4da0..c2387224b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -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({ @@ -33,7 +63,7 @@ module.exports = function karma(config) { ], exclude: [ - 'test/_*.{jsx,js}', + 'test/_helpers/index.jsx', ], browsers: [ @@ -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: { diff --git a/package.json b/package.json index bfa21393f..04bb62646 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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": { @@ -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", diff --git a/src/ReactWrapperComponent.jsx b/src/ReactWrapperComponent.jsx index 4bba0d081..19a187d52 100644 --- a/src/ReactWrapperComponent.jsx +++ b/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 */ diff --git a/src/ShallowWrapper.js b/src/ShallowWrapper.js index 1567c689c..9d7b74ba9 100644 --- a/src/ShallowWrapper.js +++ b/src/ShallowWrapper.js @@ -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 @@ -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 */ @@ -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 ( @@ -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 @@ -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(); diff --git a/src/react-compat.js b/src/react-compat.js index 2d108bd30..204deab53 100644 --- a/src/react-compat.js +++ b/src/react-compat.js @@ -7,7 +7,7 @@ */ import objectAssign from 'object.assign'; -import { REACT013 } from './version'; +import { REACT013, REACT155 } from './version'; let TestUtils; let createShallowRenderer; @@ -18,6 +18,7 @@ let childrenToArray; let renderWithOptions; let unmountComponentAtNode; let batchedUpdates; +let shallowRendererFactory; const React = require('react'); @@ -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', ); @@ -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; diff --git a/src/version.js b/src/version.js index 8d64d2611..d55f7f3df 100644 --- a/src/version.js +++ b/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; diff --git a/test/ReactWrapper-spec.jsx b/test/ReactWrapper-spec.jsx index d80529b6a..0233beff7 100644 --- a/test/ReactWrapper-spec.jsx +++ b/test/ReactWrapper-spec.jsx @@ -1,9 +1,11 @@ /* globals document */ import React from 'react'; +import PropTypes from 'prop-types'; import { expect } from 'chai'; import sinon from 'sinon'; import { batchedUpdates } from '../src/react-compat'; +import { createClass } from './_helpers/react-compat'; import { describeWithDOM, @@ -23,9 +25,9 @@ import { REACT013, REACT014, REACT15 } from '../src/version'; describeWithDOM('mount', () => { describe('context', () => { it('can pass in context', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -38,22 +40,22 @@ describeWithDOM('mount', () => { }); it('can pass context to the child of mounted component', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; }, }); - const ComplexComponent = React.createClass({ + const ComplexComponent = createClass({ render() { return
; }, }); const childContextTypes = { - name: React.PropTypes.string.isRequired, + name: PropTypes.string.isRequired, }; const context = { name: 'foo' }; const wrapper = mount(, { context, childContextTypes }); @@ -61,7 +63,7 @@ describeWithDOM('mount', () => { }); it('should not throw if context is passed in but contextTypes is missing', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ render() { return
{this.context.name}
; }, @@ -72,9 +74,9 @@ describeWithDOM('mount', () => { }); it('is instrospectable through context API', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -93,7 +95,7 @@ describeWithDOM('mount', () => { const SimpleComponent = (props, context) => (
{context.name}
); - SimpleComponent.contextTypes = { name: React.PropTypes.string }; + SimpleComponent.contextTypes = { name: PropTypes.string }; const context = { name: 'foo' }; const wrapper = mount(, { context }); @@ -104,14 +106,14 @@ describeWithDOM('mount', () => { const SimpleComponent = (props, context) => (
{context.name}
); - SimpleComponent.contextTypes = { name: React.PropTypes.string }; + SimpleComponent.contextTypes = { name: PropTypes.string }; const ComplexComponent = () => (
); const childContextTypes = { - name: React.PropTypes.string.isRequired, + name: PropTypes.string.isRequired, }; const context = { name: 'foo' }; @@ -132,7 +134,7 @@ describeWithDOM('mount', () => { const SimpleComponent = (props, context) => (
{context.name}
); - SimpleComponent.contextTypes = { name: React.PropTypes.string }; + SimpleComponent.contextTypes = { name: PropTypes.string }; const context = { name: 'foo' }; const wrapper = mount(, { context }); @@ -150,7 +152,7 @@ describeWithDOM('mount', () => { ); Foo.contextTypes = { - _: React.PropTypes.string, + _: PropTypes.string, }; const wrapper = mount(, { @@ -1096,9 +1098,9 @@ describeWithDOM('mount', () => { describe('.setContext(newContext)', () => { it('should set context for a component multiple times', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -1115,9 +1117,9 @@ describeWithDOM('mount', () => { }); it('should throw if it is called when shallow didn’t include context', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -1136,7 +1138,7 @@ describeWithDOM('mount', () => { const SimpleComponent = (props, context) => (
{context.name}
); - SimpleComponent.contextTypes = { name: React.PropTypes.string }; + SimpleComponent.contextTypes = { name: PropTypes.string }; const context = { name: 'foo' }; const wrapper = mount(, { context }); @@ -1151,7 +1153,7 @@ describeWithDOM('mount', () => { const SimpleComponent = (props, context) => (
{context.name}
); - SimpleComponent.contextTypes = { name: React.PropTypes.string }; + SimpleComponent.contextTypes = { name: PropTypes.string }; const wrapper = mount(); expect(() => wrapper.setContext({ name: 'bar' })).to.throw( @@ -1466,7 +1468,7 @@ describeWithDOM('mount', () => { const emptyRenderValues = generateEmptyRenderData(); itWithData(emptyRenderValues, 'when a React class component returns: ', (data) => { - const Foo = React.createClass({ + const Foo = createClass({ render() { return data.value; }, @@ -3267,9 +3269,9 @@ describeWithDOM('mount', () => { }); }); - describe('React.createClass', () => { + describe('createClass', () => { it('should return the name of the node', () => { - const Foo = React.createClass({ + const Foo = createClass({ displayName: 'CustomWrapper', render() { return
; @@ -3302,19 +3304,6 @@ describeWithDOM('mount', () => { expect(wrapper.name()).to.equal('SFC'); }); }); - - describe('React.createClass', () => { - it('should return the name of the node', () => { - const Foo = React.createClass({ - render() { - return
; - }, - }); - - const wrapper = mount(); - expect(wrapper.name()).to.equal('Foo'); - }); - }); }); describe('DOM node', () => { diff --git a/test/ShallowWrapper-spec.jsx b/test/ShallowWrapper-spec.jsx index bf82dc7e6..e084718bb 100644 --- a/test/ShallowWrapper-spec.jsx +++ b/test/ShallowWrapper-spec.jsx @@ -1,7 +1,9 @@ import React from 'react'; +import PropTypes from 'prop-types'; import { expect } from 'chai'; import sinon from 'sinon'; +import { createClass } from './_helpers/react-compat'; import { shallow, render, ShallowWrapper } from '../src/'; import { describeIf, itIf, itWithData, generateEmptyRenderData } from './_helpers'; import { ITERATOR_SYMBOL, withSetStateAllowed } from '../src/Utils'; @@ -10,9 +12,9 @@ import { REACT013, REACT014, REACT15 } from '../src/version'; describe('shallow', () => { describe('context', () => { it('can pass in context', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -25,7 +27,7 @@ describe('shallow', () => { }); it('should not throw if context is passed in but contextTypes is missing', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ render() { return
{this.context.name}
; }, @@ -36,9 +38,9 @@ describe('shallow', () => { }); it('is instrospectable through context API', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -57,7 +59,7 @@ describe('shallow', () => { const SimpleComponent = (props, context) => (
{context.name}
); - SimpleComponent.contextTypes = { name: React.PropTypes.string }; + SimpleComponent.contextTypes = { name: PropTypes.string }; const context = { name: 'foo' }; const wrapper = shallow(, { context }); @@ -77,7 +79,7 @@ describe('shallow', () => { const SimpleComponent = (props, context) => (
{context.name}
); - SimpleComponent.contextTypes = { name: React.PropTypes.string }; + SimpleComponent.contextTypes = { name: PropTypes.string }; const wrapper = shallow(, { context }); @@ -892,7 +894,7 @@ describe('shallow', () => { } } - Foo.contextTypes = { x: React.PropTypes.string }; + Foo.contextTypes = { x: PropTypes.string }; const context = { x: 'yolo' }; const wrapper = shallow(, { context }); @@ -938,7 +940,7 @@ describe('shallow', () => { const Foo = (props, context) => (
{context.x}
); - Foo.contextTypes = { x: React.PropTypes.string }; + Foo.contextTypes = { x: PropTypes.string }; const context = { x: 'yolo' }; const wrapper = shallow(, { context }); @@ -951,9 +953,9 @@ describe('shallow', () => { }); describe('.setContext(newContext)', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -982,7 +984,7 @@ describe('shallow', () => { const SFC = (props, context) => (
{context.name}
); - SFC.contextTypes = { name: React.PropTypes.string }; + SFC.contextTypes = { name: PropTypes.string }; it('should set context for a component multiple times', () => { const context = { name: 'foo' }; @@ -1271,7 +1273,7 @@ describe('shallow', () => { const emptyRenderValues = generateEmptyRenderData(); itWithData(emptyRenderValues, 'when a React class component returns: ', (data) => { - const Foo = React.createClass({ + const Foo = createClass({ render() { return data.value; }, @@ -2309,7 +2311,7 @@ describe('shallow', () => { } } Bar.contextTypes = { - name: React.PropTypes.string, + name: PropTypes.string, }; class Foo extends React.Component { render() { @@ -2355,7 +2357,7 @@ describe('shallow', () => { } } Bar.contextTypes = { - name: React.PropTypes.string, + name: PropTypes.string, }; class Foo extends React.Component { render() { @@ -2399,7 +2401,7 @@ describe('shallow', () => { const Bar = (props, context) => (
{context.name}
); - Bar.contextTypes = { name: React.PropTypes.string }; + Bar.contextTypes = { name: PropTypes.string }; const Foo = () => (
@@ -2430,7 +2432,7 @@ describe('shallow', () => { const Bar = (props, context) => (
{context.name}
); - Bar.contextTypes = { name: React.PropTypes.string }; + Bar.contextTypes = { name: PropTypes.string }; const Foo = () => (
@@ -2921,7 +2923,7 @@ describe('shallow', () => { } } Foo.contextTypes = { - foo: React.PropTypes.string, + foo: PropTypes.string, }; const wrapper = shallow( @@ -3145,7 +3147,7 @@ describe('shallow', () => { } } Foo.contextTypes = { - foo: React.PropTypes.string, + foo: PropTypes.string, }; const wrapper = shallow( @@ -3304,7 +3306,7 @@ describe('shallow', () => { } } Foo.contextTypes = { - foo: React.PropTypes.string, + foo: PropTypes.string, }; const wrapper = shallow( , @@ -3363,7 +3365,7 @@ describe('shallow', () => { } } Foo.contextTypes = { - foo: React.PropTypes.string, + foo: PropTypes.string, }; const wrapper = shallow( , @@ -3906,15 +3908,15 @@ describe('shallow', () => { }); }); - describe('React.createClass', () => { + describe('createClass', () => { it('should return the name of the node', () => { - const Foo = React.createClass({ + const Foo = createClass({ displayName: 'CustomWrapper', render() { return
; }, }); - const Wrapper = React.createClass({ + const Wrapper = createClass({ render() { return ; }, @@ -3951,24 +3953,6 @@ describe('shallow', () => { expect(wrapper.name()).to.equal('SFC'); }); }); - - describe('React.createClass', () => { - it('should return the name of the node', () => { - const Foo = React.createClass({ - render() { - return
; - }, - }); - const Wrapper = React.createClass({ - render() { - return ; - }, - }); - - const wrapper = shallow(); - expect(wrapper.name()).to.equal('Foo'); - }); - }); }); describe('DOM node', () => { @@ -4005,7 +3989,7 @@ describe('shallow', () => { return ; } } - WrapsRendersDOM.contextTypes = { foo: React.PropTypes.string }; + WrapsRendersDOM.contextTypes = { foo: PropTypes.string }; class DoubleWrapsRendersDOM extends React.Component { render() { return ; @@ -4016,7 +4000,7 @@ describe('shallow', () => { return ; } } - ContextWrapsRendersDOM.contextTypes = { foo: React.PropTypes.string }; + ContextWrapsRendersDOM.contextTypes = { foo: PropTypes.string }; it('throws on a DOM node', () => { const wrapper = shallow(); diff --git a/test/_helpers.jsx b/test/_helpers/index.jsx similarity index 100% rename from test/_helpers.jsx rename to test/_helpers/index.jsx diff --git a/test/_helpers/react-compat.js b/test/_helpers/react-compat.js new file mode 100644 index 000000000..261ba2a8d --- /dev/null +++ b/test/_helpers/react-compat.js @@ -0,0 +1,20 @@ +/* eslint + global-require: 0, + import/no-mutable-exports: 0, + import/prefer-default-export: 0, +*/ + +import { REACT155 } from '../../src/version'; + +let createClass; + +if (REACT155) { + // eslint-disable-next-line import/no-extraneous-dependencies + createClass = require('create-react-class'); +} else { + createClass = require('react').createClass; +} + +export { + createClass, +}; diff --git a/test/staticRender-spec.jsx b/test/staticRender-spec.jsx index 39a1c663d..85566a6f5 100644 --- a/test/staticRender-spec.jsx +++ b/test/staticRender-spec.jsx @@ -1,15 +1,17 @@ import React from 'react'; +import PropTypes from 'prop-types'; import { expect } from 'chai'; import { describeWithDOM, describeIf } from './_helpers'; import { render } from '../src/'; import { REACT013 } from '../src/version'; +import { createClass } from './_helpers/react-compat'; describeWithDOM('render', () => { describeIf(!REACT013, 'context', () => { it('can pass in context', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; @@ -21,22 +23,22 @@ describeWithDOM('render', () => { expect(wrapper.text()).to.equal('foo'); }); it('can pass context to the child of mounted component', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ contextTypes: { - name: React.PropTypes.string, + name: PropTypes.string, }, render() { return
{this.context.name}
; }, }); - const ComplexComponent = React.createClass({ + const ComplexComponent = createClass({ render() { return
; }, }); const childContextTypes = { - name: React.PropTypes.string.isRequired, + name: PropTypes.string.isRequired, }; const context = { name: 'foo' }; const wrapper = render(, { context, childContextTypes }); @@ -44,7 +46,7 @@ describeWithDOM('render', () => { expect(wrapper.children().first().text()).to.equal('foo'); }); it('should not throw if context is passed in but contextTypes is missing', () => { - const SimpleComponent = React.createClass({ + const SimpleComponent = createClass({ render() { return
{this.context.name}
; },