diff --git a/.gitignore b/.gitignore index 37d08f874a..dbb9d4c83b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,3 @@ npm-debug.log dist lib coverage -react.js -react-native.js diff --git a/examples/counter/containers/App.js b/examples/counter/containers/App.js index 28ed8049b6..77ca8c0508 100644 --- a/examples/counter/containers/App.js +++ b/examples/counter/containers/App.js @@ -1,7 +1,7 @@ import React from 'react'; import CounterApp from './CounterApp'; import { createStore, applyMiddleware } from 'redux'; -import { Provider } from 'redux/react'; +import { Provider } from 'react-redux'; import * as reducers from '../reducers'; const createStoreWithMiddleware = applyMiddleware()(createStore); diff --git a/examples/counter/containers/CounterApp.js b/examples/counter/containers/CounterApp.js index f60d74c746..f2a9fa4219 100644 --- a/examples/counter/containers/CounterApp.js +++ b/examples/counter/containers/CounterApp.js @@ -1,6 +1,6 @@ import React from 'react'; import { bindActionCreators } from 'redux'; -import { connect } from 'redux/react'; +import { connect } from 'react-redux'; import Counter from '../components/Counter'; import * as CounterActions from '../actions/CounterActions'; diff --git a/examples/counter/package.json b/examples/counter/package.json index 4e5c64f72c..9206cb430a 100644 --- a/examples/counter/package.json +++ b/examples/counter/package.json @@ -28,7 +28,8 @@ "homepage": "https://github.com/gaearon/redux#readme", "dependencies": { "react": "^0.13.3", - "redux": "^0.12.0" + "redux": "^1.0.0-alpha", + "react-redux": "^1.0.0-alpha" }, "devDependencies": { "babel-core": "^5.5.8", diff --git a/examples/todomvc/containers/App.js b/examples/todomvc/containers/App.js index 1609f0ad33..127b37d23a 100644 --- a/examples/todomvc/containers/App.js +++ b/examples/todomvc/containers/App.js @@ -1,7 +1,7 @@ import React from 'react'; import TodoApp from './TodoApp'; import { createStore } from 'redux'; -import { Provider } from 'redux/react'; +import { Provider } from 'react-redux'; import * as reducers from '../reducers'; const store = createStore(reducers); diff --git a/examples/todomvc/containers/TodoApp.js b/examples/todomvc/containers/TodoApp.js index 03df600025..f1c1aa1495 100644 --- a/examples/todomvc/containers/TodoApp.js +++ b/examples/todomvc/containers/TodoApp.js @@ -1,6 +1,6 @@ import React from 'react'; import { bindActionCreators } from 'redux'; -import { Connector } from 'redux/react'; +import { Connector } from 'react-redux'; import Header from '../components/Header'; import MainSection from '../components/MainSection'; import * as TodoActions from '../actions/TodoActions'; diff --git a/examples/todomvc/package.json b/examples/todomvc/package.json index 58e7ea36d0..4e50e51038 100644 --- a/examples/todomvc/package.json +++ b/examples/todomvc/package.json @@ -30,7 +30,8 @@ "dependencies": { "classnames": "^2.1.2", "react": "^0.13.3", - "redux": "^0.12.0" + "redux": "^1.0.0-alpha", + "react-redux": "^1.0.0-alpha" }, "devDependencies": { "babel-core": "^5.5.8", diff --git a/package.json b/package.json index 1646effc1a..f68942eb55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redux", - "version": "0.12.0", + "version": "1.0.0-alpha", "description": "Atomic Flux with hot reloading", "main": "lib/index.js", "scripts": { @@ -44,9 +44,7 @@ "eslint-plugin-react": "^2.3.0", "expect": "^1.6.0", "istanbul": "^0.3.15", - "jsdom": "~5.4.3", "mocha": "^2.2.5", - "mocha-jsdom": "~0.4.0", "react": "^0.13.0", "react-hot-loader": "^1.2.7", "rimraf": "^2.3.4", diff --git a/scripts/browser b/scripts/browser index a714807862..22bad9a9fe 100755 --- a/scripts/browser +++ b/scripts/browser @@ -4,8 +4,5 @@ WEBPACK_CMD=node_modules/.bin/webpack mkdir -p dist -$WEBPACK_CMD src/umd.js dist/redux.js -NODE_ENV=production $WEBPACK_CMD src/umd.js dist/redux.min.js - -$WEBPACK_CMD src/umd-react.js dist/redux-react.js -NODE_ENV=production $WEBPACK_CMD src/umd-react.js dist/redux-react.min.js +$WEBPACK_CMD src/index.js dist/redux.js +NODE_ENV=production $WEBPACK_CMD src/index.js dist/redux.min.js diff --git a/scripts/build b/scripts/build index 8ae8463bad..50a3a47dcd 100755 --- a/scripts/build +++ b/scripts/build @@ -2,6 +2,3 @@ rm -rf lib `npm bin`/babel src --out-dir lib - -mv lib/entry-react.js ./react.js -mv lib/entry-react-native.js ./react-native.js diff --git a/src/components/createAll.js b/src/components/createAll.js deleted file mode 100644 index bd6383cccf..0000000000 --- a/src/components/createAll.js +++ /dev/null @@ -1,17 +0,0 @@ -import createProvider from './createProvider'; -import createProvideDecorator from './createProvideDecorator'; - -import createConnector from './createConnector'; -import createConnectDecorator from './createConnectDecorator'; - -export default function createAll(React) { - // Wrapper components - const Provider = createProvider(React); - const Connector = createConnector(React); - - // Higher-order components (decorators) - const provide = createProvideDecorator(React, Provider); - const connect = createConnectDecorator(React, Connector); - - return { Provider, Connector, provide, connect }; -} diff --git a/src/components/createConnectDecorator.js b/src/components/createConnectDecorator.js deleted file mode 100644 index a3196e1c16..0000000000 --- a/src/components/createConnectDecorator.js +++ /dev/null @@ -1,25 +0,0 @@ -import getDisplayName from '../utils/getDisplayName'; -import shallowEqualScalar from '../utils/shallowEqualScalar'; - -export default function createConnectDecorator(React, Connector) { - const { Component } = React; - - return function connect(select) { - return DecoratedComponent => class ConnectorDecorator extends Component { - static displayName = `Connector(${getDisplayName(DecoratedComponent)})`; - static DecoratedComponent = DecoratedComponent; - - shouldComponentUpdate(nextProps) { - return !shallowEqualScalar(this.props, nextProps); - } - - render() { - return ( - select(state, this.props)}> - {stuff => } - - ); - } - }; - }; -} diff --git a/src/components/createConnector.js b/src/components/createConnector.js deleted file mode 100644 index 8bfddd4da6..0000000000 --- a/src/components/createConnector.js +++ /dev/null @@ -1,89 +0,0 @@ -import createStoreShape from '../utils/createStoreShape'; -import identity from '../utils/identity'; -import shallowEqual from '../utils/shallowEqual'; -import isPlainObject from '../utils/isPlainObject'; -import invariant from 'invariant'; - -export default function createConnector(React) { - const { Component, PropTypes } = React; - const storeShape = createStoreShape(PropTypes); - - return class Connector extends Component { - static contextTypes = { - store: storeShape.isRequired - }; - - static propTypes = { - children: PropTypes.func.isRequired, - select: PropTypes.func.isRequired - }; - - static defaultProps = { - select: identity - }; - - shouldComponentUpdate(nextProps, nextState) { - return !this.isSliceEqual(this.state.slice, nextState.slice) || - !shallowEqual(this.props, nextProps); - } - - isSliceEqual(slice, nextSlice) { - const isRefEqual = slice === nextSlice; - if (isRefEqual) { - return true; - } else if (typeof slice !== 'object' || typeof nextSlice !== 'object') { - return isRefEqual; - } - return shallowEqual(slice, nextSlice); - } - - constructor(props, context) { - super(props, context); - this.state = this.selectState(props, context); - } - - componentDidMount() { - this.unsubscribe = this.context.store.subscribe(::this.handleChange); - this.handleChange(); - } - - componentWillReceiveProps(nextProps) { - if (nextProps.select !== this.props.select) { - // Force the state slice recalculation - this.handleChange(nextProps); - } - } - - componentWillUnmount() { - this.unsubscribe(); - } - - handleChange(props = this.props) { - const nextState = this.selectState(props, this.context); - if (!this.isSliceEqual(this.state.slice, nextState.slice)) { - this.setState(nextState); - } - } - - selectState(props, context) { - const state = context.store.getState(); - const slice = props.select(state); - - invariant( - isPlainObject(slice), - 'The return value of `select` prop must be an object. Instead received %s.', - slice - ); - - return { slice }; - } - - render() { - const { children } = this.props; - const { slice } = this.state; - const { store: { dispatch } } = this.context; - - return children({ dispatch, ...slice }); - } - }; -} diff --git a/src/components/createProvideDecorator.js b/src/components/createProvideDecorator.js deleted file mode 100644 index d181865a40..0000000000 --- a/src/components/createProvideDecorator.js +++ /dev/null @@ -1,20 +0,0 @@ -import getDisplayName from '../utils/getDisplayName'; - -export default function createProvideDecorator(React, Provider) { - const { Component } = React; - - return function provide(store) { - return DecoratedComponent => class ProviderDecorator extends Component { - static displayName = `Provider(${getDisplayName(DecoratedComponent)})`; - static DecoratedComponent = DecoratedComponent; - - render() { - return ( - - {() => } - - ); - } - }; - }; -} diff --git a/src/components/createProvider.js b/src/components/createProvider.js deleted file mode 100644 index 030c8e2ac7..0000000000 --- a/src/components/createProvider.js +++ /dev/null @@ -1,40 +0,0 @@ -import createStoreShape from '../utils/createStoreShape'; - -export default function createProvider(React) { - const { Component, PropTypes } = React; - const storeShape = createStoreShape(PropTypes); - - return class Provider extends Component { - static childContextTypes = { - store: storeShape.isRequired - }; - - static propTypes = { - children: PropTypes.func.isRequired - }; - - getChildContext() { - return { store: this.state.store }; - } - - constructor(props, context) { - super(props, context); - this.state = { store: props.store }; - } - - componentWillReceiveProps(nextProps) { - const { store } = this.state; - const { store: nextStore } = nextProps; - - if (store !== nextStore) { - const nextReducer = nextStore.getReducer(); - store.replaceReducer(nextReducer); - } - } - - render() { - const { children } = this.props; - return children(); - } - }; -} diff --git a/src/entry-react-native.js b/src/entry-react-native.js deleted file mode 100644 index 981975b461..0000000000 --- a/src/entry-react-native.js +++ /dev/null @@ -1 +0,0 @@ -export * from './lib/react-native'; diff --git a/src/entry-react.js b/src/entry-react.js deleted file mode 100644 index 241d66113b..0000000000 --- a/src/entry-react.js +++ /dev/null @@ -1 +0,0 @@ -export * from './lib/react'; diff --git a/src/react-native.js b/src/react-native.js deleted file mode 100644 index c6fc5363e0..0000000000 --- a/src/react-native.js +++ /dev/null @@ -1,4 +0,0 @@ -import React from 'react-native'; -import createAll from './components/createAll'; - -export const { Provider, Connector, provide, connect } = createAll(React); diff --git a/src/react.js b/src/react.js deleted file mode 100644 index a2058d695a..0000000000 --- a/src/react.js +++ /dev/null @@ -1,4 +0,0 @@ -import React from 'react'; -import createAll from './components/createAll'; - -export const { Provider, Connector, provide, connect } = createAll(React); diff --git a/src/umd-react.js b/src/umd-react.js deleted file mode 100644 index 88a5f4b408..0000000000 --- a/src/umd-react.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from './index'; -export * from './react'; diff --git a/src/umd.js b/src/umd.js deleted file mode 100644 index ea465c2a34..0000000000 --- a/src/umd.js +++ /dev/null @@ -1 +0,0 @@ -export * from './index'; diff --git a/src/utils/createStoreShape.js b/src/utils/createStoreShape.js deleted file mode 100644 index 851e7ce898..0000000000 --- a/src/utils/createStoreShape.js +++ /dev/null @@ -1,7 +0,0 @@ -export default function createStoreShape(PropTypes) { - return PropTypes.shape({ - subscribe: PropTypes.func.isRequired, - dispatch: PropTypes.func.isRequired, - getState: PropTypes.func.isRequired - }); -} diff --git a/src/utils/getDisplayName.js b/src/utils/getDisplayName.js deleted file mode 100644 index 512702c87a..0000000000 --- a/src/utils/getDisplayName.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function getDisplayName(Component) { - return Component.displayName || Component.name || 'Component'; -} diff --git a/src/utils/identity.js b/src/utils/identity.js deleted file mode 100644 index 8c690a8859..0000000000 --- a/src/utils/identity.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function identity(value) { - return value; -} diff --git a/src/utils/shallowEqual.js b/src/utils/shallowEqual.js deleted file mode 100644 index f82be71949..0000000000 --- a/src/utils/shallowEqual.js +++ /dev/null @@ -1,23 +0,0 @@ -export default function shallowEqual(objA, objB) { - if (objA === objB) { - return true; - } - - const keysA = Object.keys(objA); - const keysB = Object.keys(objB); - - if (keysA.length !== keysB.length) { - return false; - } - - // Test for A's keys different from B. - const hasOwn = Object.prototype.hasOwnProperty; - for (let i = 0; i < keysA.length; i++) { - if (!hasOwn.call(objB, keysA[i]) || - objA[keysA[i]] !== objB[keysA[i]]) { - return false; - } - } - - return true; -} diff --git a/src/utils/shallowEqualScalar.js b/src/utils/shallowEqualScalar.js deleted file mode 100644 index 2adb8ea85b..0000000000 --- a/src/utils/shallowEqualScalar.js +++ /dev/null @@ -1,34 +0,0 @@ -export default function shallowEqualScalar(objA, objB) { - if (objA === objB) { - return true; - } - - if (typeof objA !== 'object' || objA === null || - typeof objB !== 'object' || objB === null) { - return false; - } - - const keysA = Object.keys(objA); - const keysB = Object.keys(objB); - - if (keysA.length !== keysB.length) { - return false; - } - - // Test for A's keys different from B. - const hasOwn = Object.prototype.hasOwnProperty; - for (let i = 0; i < keysA.length; i++) { - if (!hasOwn.call(objB, keysA[i])) { - return false; - } - - const valA = objA[keysA[i]]; - const valB = objB[keysA[i]]; - - if (valA !== valB || typeof valA === 'object' || typeof valB === 'object') { - return false; - } - } - - return true; -} diff --git a/test/components/Connector.spec.js b/test/components/Connector.spec.js deleted file mode 100644 index bdc13b1c54..0000000000 --- a/test/components/Connector.spec.js +++ /dev/null @@ -1,295 +0,0 @@ -import expect from 'expect'; -import jsdomReact from './jsdomReact'; -import React, { PropTypes, Component } from 'react/addons'; -import { createStore } from '../../src'; -import { Connector } from '../../src/react'; - -const { TestUtils } = React.addons; - -describe('React', () => { - describe('Connector', () => { - jsdomReact(); - - // Mock minimal Provider interface - class Provider extends Component { - static childContextTypes = { - store: PropTypes.object.isRequired - } - - getChildContext() { - return { store: this.props.store }; - } - - render() { - return this.props.children(); - } - } - - function stringBuilder(prev = '', action) { - return action.type === 'APPEND' - ? prev + action.body - : prev; - } - - it('should receive the store in the context', () => { - const store = createStore({}); - - const tree = TestUtils.renderIntoDocument( - - {() => ( - - {() =>
} - - )} - - ); - - const connector = TestUtils.findRenderedComponentWithType(tree, Connector); - expect(connector.context.store).toBe(store); - }); - - it('should subscribe to the store changes', () => { - const store = createStore(stringBuilder); - - const tree = TestUtils.renderIntoDocument( - - {() => ( - ({ string })}> - {({ string }) =>
} - - )} - - ); - - const div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div'); - expect(div.props.string).toBe(''); - store.dispatch({ type: 'APPEND', body: 'a'}); - expect(div.props.string).toBe('a'); - store.dispatch({ type: 'APPEND', body: 'b'}); - expect(div.props.string).toBe('ab'); - }); - - it('should unsubscribe before unmounting', () => { - const store = createStore(stringBuilder); - const subscribe = store.subscribe; - - // Keep track of unsubscribe by wrapping subscribe() - const spy = expect.createSpy(() => {}); - store.subscribe = (listener) => { - const unsubscribe = subscribe(listener); - return () => { - spy(); - return unsubscribe(); - }; - }; - - const tree = TestUtils.renderIntoDocument( - - {() => ( - ({ string })}> - {({ string }) =>
} - - )} - - ); - - const connector = TestUtils.findRenderedComponentWithType(tree, Connector); - expect(spy.calls.length).toBe(0); - connector.componentWillUnmount(); - expect(spy.calls.length).toBe(1); - }); - - it('should shallowly compare the selected state to prevent unnecessary updates', () => { - const store = createStore(stringBuilder); - const spy = expect.createSpy(() => {}); - function render({ string }) { - spy(); - return
; - } - - const tree = TestUtils.renderIntoDocument( - - {() => ( - ({ string })}> - {render} - - )} - - ); - - const div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div'); - expect(spy.calls.length).toBe(1); - expect(div.props.string).toBe(''); - store.dispatch({ type: 'APPEND', body: 'a'}); - expect(spy.calls.length).toBe(2); - store.dispatch({ type: 'APPEND', body: 'b'}); - expect(spy.calls.length).toBe(3); - store.dispatch({ type: 'APPEND', body: ''}); - expect(spy.calls.length).toBe(3); - }); - - it('should recompute the state slice when the select prop changes', () => { - const store = createStore({ - a: () => 42, - b: () => 72 - }); - - function selectA(state) { - return { result: state.a }; - } - - function selectB(state) { - return { result: state.b }; - } - - function render({ result }) { - return
{result}
; - } - - class Container extends Component { - constructor() { - super(); - this.state = { select: selectA }; - } - - render() { - return ( - - {() => - - {render} - - } - - ); - } - } - - let tree = TestUtils.renderIntoDocument(); - let div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div'); - expect(div.props.children).toBe(42); - - tree.setState({ select: selectB }); - expect(div.props.children).toBe(72); - }); - - it('should pass dispatch() to the child function', () => { - const store = createStore({}); - - const tree = TestUtils.renderIntoDocument( - - {() => ( - - {({ dispatch }) =>
} - - )} - - ); - - const div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div'); - expect(div.props.dispatch).toBe(store.dispatch); - }); - - it('should throw an error if select returns anything but a plain object', () => { - const store = createStore({}); - - expect(() => { - TestUtils.renderIntoDocument( - - {() => ( - 1}> - {() =>
} - - )} - - ); - }).toThrow(/select/); - - expect(() => { - TestUtils.renderIntoDocument( - - {() => ( - 'hey'}> - {() =>
} - - )} - - ); - }).toThrow(/select/); - - function AwesomeMap() { } - - expect(() => { - TestUtils.renderIntoDocument( - - {() => ( - new AwesomeMap()}> - {() =>
} - - )} - - ); - }).toThrow(/select/); - }); - - it('should not setState when renderToString is called on the server', () => { - const { renderToString } = React; - const store = createStore(stringBuilder); - - class TestComp extends Component { - componentWillMount() { - store.dispatch({ - type: 'APPEND', - body: 'a' - }); - } - - render() { - return
{this.props.string}
; - } - } - - const el = ( - - {() => ( - ({ string })}> - {({ string }) => } - - )} - - ); - - expect(() => renderToString(el)).toNotThrow(); - }); - - it('should handle dispatch inside componentDidMount', () => { - const store = createStore(stringBuilder); - - class TestComp extends Component { - componentDidMount() { - store.dispatch({ - type: 'APPEND', - body: 'a' - }); - } - - render() { - return
{this.props.string}
; - } - } - - const tree = TestUtils.renderIntoDocument( - - {() => ( - ({ string })}> - {({ string }) => } - - )} - - ); - - const testComp = TestUtils.findRenderedComponentWithType(tree, TestComp); - expect(testComp.props.string).toBe('a'); - }); - }); -}); diff --git a/test/components/Provider.spec.js b/test/components/Provider.spec.js deleted file mode 100644 index 3e3b3c3308..0000000000 --- a/test/components/Provider.spec.js +++ /dev/null @@ -1,71 +0,0 @@ -import expect from 'expect'; -import jsdomReact from './jsdomReact'; -import React, { PropTypes, Component } from 'react/addons'; -import { createStore } from '../../src'; -import { Provider } from '../../src/react'; - -const { TestUtils } = React.addons; - -describe('React', () => { - describe('Provider', () => { - jsdomReact(); - - class Child extends Component { - static contextTypes = { - store: PropTypes.object.isRequired - } - - render() { - return
; - } - } - - it('should add the store to the child context', () => { - const store = createStore({}); - - const tree = TestUtils.renderIntoDocument( - - {() => } - - ); - - const child = TestUtils.findRenderedComponentWithType(tree, Child); - expect(child.context.store).toBe(store); - }); - - it('should replace just the reducer when receiving a new store in props', () => { - const store1 = createStore((state = 10) => state + 1); - const store2 = createStore((state = 10) => state * 2); - const spy = expect.createSpy(() => {}); - - class ProviderContainer extends Component { - state = { store: store1 }; - - render() { - return ( - - {() => } - - ); - } - } - - const container = TestUtils.renderIntoDocument(); - const child = TestUtils.findRenderedComponentWithType(container, Child); - expect(child.context.store.getState()).toEqual(11); - - child.context.store.subscribe(spy); - child.context.store.dispatch({}); - expect(spy.calls.length).toEqual(1); - expect(child.context.store.getState()).toEqual(12); - - container.setState({ store: store2 }); - expect(spy.calls.length).toEqual(2); - expect(child.context.store.getState()).toEqual(24); - - child.context.store.dispatch({}); - expect(spy.calls.length).toEqual(3); - expect(child.context.store.getState()).toEqual(48); - }); - }); -}); diff --git a/test/components/connect.spec.js b/test/components/connect.spec.js deleted file mode 100644 index 5b3fee90c2..0000000000 --- a/test/components/connect.spec.js +++ /dev/null @@ -1,154 +0,0 @@ -import expect from 'expect'; -import jsdomReact from './jsdomReact'; -import React, { PropTypes, Component } from 'react/addons'; -import { createStore } from '../../src'; -import { connect, Connector } from '../../src/react'; - -const { TestUtils } = React.addons; - -describe('React', () => { - describe('connect', () => { - jsdomReact(); - - // Mock minimal Provider interface - class Provider extends Component { - static childContextTypes = { - store: PropTypes.object.isRequired - } - - getChildContext() { - return { store: this.props.store }; - } - - render() { - return this.props.children(); - } - } - - it('should wrap the component into Provider', () => { - const store = createStore(() => ({ - foo: 'bar' - })); - - @connect(state => state) - class Container extends Component { - render() { - return
; - } - } - - const container = TestUtils.renderIntoDocument( - - {() => } - - ); - const div = TestUtils.findRenderedDOMComponentWithTag(container, 'div'); - expect(div.props.pass).toEqual('through'); - expect(div.props.foo).toEqual('bar'); - expect(() => - TestUtils.findRenderedComponentWithType(container, Connector) - ).toNotThrow(); - }); - - it('should handle additional prop changes in addition to slice', () => { - const store = createStore(() => ({ - foo: 'bar' - })); - - @connect(state => state) - class ConnectContainer extends Component { - render() { - return ( -
- ); - } - } - - class Container extends Component { - constructor() { - super(); - this.state = { - bar: { - baz: '' - } - }; - } - componentDidMount() { - - // Simulate deep object mutation - this.state.bar.baz = 'through'; - this.setState({ - bar: this.state.bar - }); - } - render() { - return ( - - {() => } - - ); - } - } - - const container = TestUtils.renderIntoDocument(); - const div = TestUtils.findRenderedDOMComponentWithTag(container, 'div'); - expect(div.props.foo).toEqual('bar'); - expect(div.props.pass).toEqual('through'); - }); - - it('should pass the only argument as the select prop down', () => { - const store = createStore(() => ({ - foo: 'baz', - bar: 'baz' - })); - - function select({ foo }) { - return { foo }; - } - - @connect(select) - class Container extends Component { - render() { - return
; - } - } - - const container = TestUtils.renderIntoDocument( - - {() => } - - ); - const connector = TestUtils.findRenderedComponentWithType(container, Connector); - expect(connector.props.select({ - foo: 5, - bar: 7 - })).toEqual({ - foo: 5 - }); - }); - - it('should set the displayName correctly', () => { - @connect(state => state) - class Container extends Component { - render() { - return
; - } - } - - expect(Container.displayName).toBe('Connector(Container)'); - }); - - it('should expose the wrapped component as DecoratedComponent', () => { - class Container extends Component { - render() { - return
; - } - } - - const decorator = connect(state => state); - const decorated = decorator(Container); - - expect(decorated.DecoratedComponent).toBe(Container); - }); - }); -}); diff --git a/test/components/jsdomReact.js b/test/components/jsdomReact.js deleted file mode 100644 index 0083824baf..0000000000 --- a/test/components/jsdomReact.js +++ /dev/null @@ -1,7 +0,0 @@ -import ExecutionEnvironment from 'react/lib/ExecutionEnvironment'; -import jsdom from 'mocha-jsdom'; - -export default function jsdomReact() { - jsdom(); - ExecutionEnvironment.canUseDOM = true; -} diff --git a/test/components/provide.spec.js b/test/components/provide.spec.js deleted file mode 100644 index babef47758..0000000000 --- a/test/components/provide.spec.js +++ /dev/null @@ -1,68 +0,0 @@ -import expect from 'expect'; -import jsdomReact from './jsdomReact'; -import React, { PropTypes, Component } from 'react/addons'; -import { createStore } from '../../src'; -import { provide, Provider } from '../../src/react'; - -const { TestUtils } = React.addons; - -describe('React', () => { - describe('provide', () => { - jsdomReact(); - - class Child extends Component { - static contextTypes = { - store: PropTypes.object.isRequired - } - - render() { - return
; - } - } - - it('should wrap the component into Provider', () => { - const store = createStore({}); - - @provide(store) - class Container extends Component { - render() { - return ; - } - } - - const container = TestUtils.renderIntoDocument( - - ); - const child = TestUtils.findRenderedComponentWithType(container, Child); - expect(child.props.pass).toEqual('through'); - expect(() => - TestUtils.findRenderedComponentWithType(container, Provider) - ).toNotThrow(); - expect(child.context.store).toBe(store); - }); - - it('sets the displayName correctly', () => { - @provide(createStore({})) - class Container extends Component { - render() { - return
; - } - } - - expect(Container.displayName).toBe('Provider(Container)'); - }); - - it('should expose the wrapped component as DecoratedComponent', () => { - class Container extends Component { - render() { - return
; - } - } - - const decorator = provide(state => state); - const decorated = decorator(Container); - - expect(decorated.DecoratedComponent).toBe(Container); - }); - }); -}); diff --git a/test/getDisplayName.spec.js b/test/getDisplayName.spec.js deleted file mode 100644 index a3a712d345..0000000000 --- a/test/getDisplayName.spec.js +++ /dev/null @@ -1,17 +0,0 @@ -import expect from 'expect'; -import { createClass, Component } from 'react'; -import getDisplayName from '../src/utils/getDisplayName'; - -describe('Utils', () => { - describe('getDisplayName', () => { - it('should extract the component class name', () => { - const names = [ - createClass({ displayName: 'Foo', render() {} }), - class Bar extends Component {}, - createClass({ render() {} }) - ].map(getDisplayName); - - expect(names).toEqual(['Foo', 'Bar', 'Component']); - }); - }); -}); diff --git a/test/utils/identity.spec.js b/test/utils/identity.spec.js deleted file mode 100644 index ef48e5593c..0000000000 --- a/test/utils/identity.spec.js +++ /dev/null @@ -1,11 +0,0 @@ -import expect from 'expect'; -import identity from '../../src/utils/identity'; - -describe('Utils', () => { - describe('identity', () => { - it('should return the first argument passed to it', () => { - const test = { a: 1 }; - expect(identity(test, 'test')).toBe(test); - }); - }); -}); diff --git a/test/utils/shallowEquality.spec.js b/test/utils/shallowEquality.spec.js deleted file mode 100644 index 7146185bfb..0000000000 --- a/test/utils/shallowEquality.spec.js +++ /dev/null @@ -1,133 +0,0 @@ -import expect from 'expect'; -import shallowEqualScalar from '../../src/utils/shallowEqualScalar'; -import shallowEqual from '../../src/utils/shallowEqual'; - -describe('Utils', () => { - // More info: https://github.com/gaearon/redux/pull/75#issuecomment-111635748 - describe('shallowEqualScalar', () => { - it('should return true if both arguments are the same object', () => { - const o = { a: 1, b: 2 }; - expect(shallowEqualScalar(o, o)).toBe(true); - }); - - it('should return false if either argument is null', () => { - expect(shallowEqualScalar(null, {})).toBe(false); - expect(shallowEqualScalar({}, null)).toBe(false); - }); - - it('should return true if arguments fields are equal', () => { - expect( - shallowEqualScalar( - { a: 1, b: 2, c: undefined }, - { a: 1, b: 2, c: undefined } - ) - ).toBe(true); - - expect( - shallowEqualScalar( - { a: 1, b: 2, c: 3 }, - { a: 1, b: 2, c: 3 } - ) - ).toBe(true); - }); - - it('should return false if first argument has too many keys', () => { - expect( - shallowEqualScalar( - { a: 1, b: 2, c: 3 }, - { a: 1, b: 2 } - ) - ).toBe(false); - }); - - it('should return false if second argument has too many keys', () => { - expect( - shallowEqualScalar( - { a: 1, b: 2 }, - { a: 1, b: 2, c: 3 } - ) - ).toBe(false); - }); - - it('should return false if arguments have keys dont have same value', () => { - expect( - shallowEqualScalar( - { a: 1, b: 2 }, - { a: 1, b: 3 } - ) - ).toBe(false); - }); - - it('should return false if arguments have field that are objects', () => { - const o = {}; - expect( - shallowEqualScalar( - { a: 1, b: 2, c: o }, - { a: 1, b: 2, c: o } - ) - ).toBe(false); - }); - - it('should return false if arguments have different keys', () => { - expect( - shallowEqualScalar( - { a: 1, b: 2, c: undefined }, - { a: 1, bb: 2, c: undefined } - ) - ).toBe(false); - }); - }); - - describe('shallowEqual', () => { - it('should return true if arguments fields are equal', () => { - expect( - shallowEqual( - { a: 1, b: 2, c: undefined }, - { a: 1, b: 2, c: undefined } - ) - ).toBe(true); - - expect( - shallowEqual( - { a: 1, b: 2, c: 3 }, - { a: 1, b: 2, c: 3 } - ) - ).toBe(true); - - const o = {}; - expect( - shallowEqual( - { a: 1, b: 2, c: o }, - { a: 1, b: 2, c: o } - ) - ).toBe(true); - }); - - it('should return false if first argument has too many keys', () => { - expect( - shallowEqual( - { a: 1, b: 2, c: 3 }, - { a: 1, b: 2 } - ) - ).toBe(false); - }); - - it('should return false if second argument has too many keys', () => { - expect( - shallowEqual( - { a: 1, b: 2 }, - { a: 1, b: 2, c: 3 } - ) - ).toBe(false); - }); - - it('should return false if arguments have different keys', () => { - expect( - shallowEqual( - { a: 1, b: 2, c: undefined }, - { a: 1, bb: 2, c: undefined } - ) - ).toBe(false); - }); - }); -}); diff --git a/webpack.config.js b/webpack.config.js index d7c5f5a61c..a1da852834 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,18 +20,7 @@ if (process.env.NODE_ENV === 'production') { ); } -var reactExternal = { - root: 'React', - commonjs2: 'react', - commonjs: 'react', - amd: 'react' -}; - module.exports = { - externals: { - 'react': reactExternal, - 'react-native': reactExternal - }, module: { loaders: [ { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ }