'use strict';
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj['default'] : obj; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
var _fluxMixin = require('../fluxMixin');
var fluxMixin = _interopRequire(_fluxMixin);
var _Flummox$Store$Actions = require('../../Flux');
var _addContext = require('./addContext');
var addContext = _interopRequire(_addContext);
var _sinon = require('sinon');
var sinon = _interopRequire(_sinon);
var _React = require('react/addons');
var React = _interopRequire(_React);
var PropTypes = React.PropTypes;
var TestUtils = React.addons.TestUtils;
describe('fluxMixin', function () {
var TestActions = (function (_Actions) {
function TestActions() {
_classCallCheck(this, TestActions);
if (_Actions != null) {
_Actions.apply(this, arguments);
}
}
_inherits(TestActions, _Actions);
TestActions.prototype.getSomething = function getSomething(something) {
return something;
};
return TestActions;
})(_Flummox$Store$Actions.Actions);
var TestStore = (function (_Store) {
function TestStore(flux) {
_classCallCheck(this, TestStore);
_Store.call(this);
var testActions = flux.getActions('test');
this.register(testActions.getSomething, this.handleGetSomething);
this.state = {
something: null
};
}
_inherits(TestStore, _Store);
TestStore.prototype.handleGetSomething = function handleGetSomething(something) {
this.setState({ something: something });
};
return TestStore;
})(_Flummox$Store$Actions.Store);
var Flux = (function (_Flummox) {
function Flux() {
_classCallCheck(this, Flux);
_Flummox.call(this);
this.createActions('test', TestActions);
this.createStore('test', TestStore, this);
this.createStore('test2', TestStore, this);
}
_inherits(Flux, _Flummox);
return Flux;
})(_Flummox$Store$Actions.Flummox);
var ComponentWithFluxMixin = React.createClass({
displayName: 'ComponentWithFluxMixin',
mixins: [fluxMixin()],
render: function render() {
return null;
}
});
it('gets flux from either props or context', function () {
var flux = new Flux();
var contextComponent = undefined,
propsComponent = undefined;
var ContextComponent = addContext(ComponentWithFluxMixin, { flux: flux }, { flux: React.PropTypes.instanceOf(_Flummox$Store$Actions.Flummox) });
var tree = TestUtils.renderIntoDocument(React.createElement(ContextComponent, null));
contextComponent = TestUtils.findRenderedComponentWithType(tree, ComponentWithFluxMixin);
propsComponent = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { flux: flux }));
expect(contextComponent.flux).to.be.an['instanceof'](_Flummox$Store$Actions.Flummox);
expect(propsComponent.flux).to.be.an['instanceof'](_Flummox$Store$Actions.Flummox);
});
it('exposes flux as context', function () {
var flux = new Flux();
var ChildComponent = React.createClass({
displayName: 'ChildComponent',
contextTypes: {
flux: PropTypes.instanceOf(_Flummox$Store$Actions.Flummox) },
render: function render() {
return React.createElement('div', null);
}
});
var Component = React.createClass({
displayName: 'Component',
mixins: [fluxMixin()],
render: function render() {
return React.createElement(
'div',
null,
React.createElement(ChildComponent, { key: 'test' })
);
}
});
var tree = TestUtils.renderIntoDocument(React.createElement(Component, { flux: flux }));
var childComponent = TestUtils.findRenderedComponentWithType(tree, ChildComponent);
expect(childComponent.context.flux).to.equal(flux);
});
it('throws error if neither props or context is set', function () {
var flux = new Flux();
expect(TestUtils.renderIntoDocument.bind(null, React.createElement(ComponentWithFluxMixin, null))).to['throw']('fluxMixin: Could not find Flux instance. Ensure that your component ' + 'has either `this.context.flux` or `this.props.flux`.');
});
it('ignores change event after unmounted', function () {
var flux = new Flux();
flux.getActions('test').getSomething('foo');
var getterMap = {
test: function test(store) {
return { something: store.state.something };
}
};
var Component = React.createClass({
displayName: 'Component',
mixins: [fluxMixin(getterMap)],
render: function render() {
return null;
}
});
var container = document.createElement('div');
var component = React.render(React.createElement(Component, { flux: flux }), container);
var listener = flux.getStore('test').listeners('change')[0];
React.unmountComponentAtNode(container);
flux.getActions('test').getSomething('bar');
listener();
expect(component.state.something).to.equal('foo');
});
it('uses #connectToStores() to get initial state', function () {
var flux = new Flux();
flux.getActions('test').getSomething('foobar');
var getterMap = {
test: function test(store) {
return {
something: store.state.something,
custom: true };
} };
var mixin = fluxMixin(getterMap);
var connectToStores = sinon.spy(mixin, 'connectToStores');
var Component = React.createClass({
displayName: 'Component',
mixins: [mixin],
getInitialState: function getInitialState() {
return {
foobar: 'baz' };
},
render: function render() {
return null;
}
});
var component = TestUtils.renderIntoDocument(React.createElement(Component, { key: 'test', flux: flux }));
expect(connectToStores.calledOnce).to.be['true'];
expect(connectToStores.firstCall.args[0]).to.equal(getterMap);
expect(flux.getStore('test').listeners('change')).to.have.length(1);
expect(component.state).to.deep.equal({
something: 'foobar',
custom: true,
foobar: 'baz' });
});
describe('#connectToStores', function () {
it('returns initial state', function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
var initialState = component.connectToStores('test');
expect(initialState).to.deep.equal({
something: null });
});
it('merges store state with component state on change', function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
component.setState({ otherThing: 'barbaz' });
component.connectToStores('test');
flux.getActions('test').getSomething('foobar');
expect(component.state).to.deep.equal({
something: 'foobar',
otherThing: 'barbaz' });
});
it('uses custom state getter, if given', function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux, bar: 'baz' }));
component.setState({ otherThing: 'barbaz' });
component.connectToStores('test', function (store, props) {
return {
something: store.state.something,
barbaz: 'bar' + props.bar };
});
flux.getActions('test').getSomething('foobar');
expect(component.state).to.deep.equal({
something: 'foobar',
otherThing: 'barbaz',
barbaz: 'barbaz' });
});
it('syncs with store after prop change', function () {
var flux = new Flux();
var Component = React.createClass({
displayName: 'Component',
mixins: [fluxMixin({
test: function test(store, props) {
return {
foo: 'foo is ' + props.foo };
} })],
render: function render() {
return null;
}
});
var component = TestUtils.renderIntoDocument(React.createElement(Component, { key: 'test', flux: flux, foo: 'bar' }));
expect(component.state.foo).to.equal('foo is bar');
component.setProps({ foo: 'baz' });
expect(component.state.foo).to.equal('foo is baz');
});
it('accepts object of keys to state getters', function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
component.setState({ otherThing: 'barbaz' });
component.connectToStores({
test: function test(store) {
return {
something: store.state.something,
custom: true };
} });
flux.getActions('test').getSomething('foobar');
expect(component.state).to.deep.equal({
something: 'foobar',
otherThing: 'barbaz',
custom: true });
});
it('calls default state getter once with array of stores', function () {
var flux = new Flux();
flux.getStore('test2').setState({ otherThing: 'barbaz' });
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
component.connectToStores(['test', 'test2']);
flux.getActions('test').getSomething('foobar');
expect(component.state).to.deep.equal({
something: 'foobar',
otherThing: 'barbaz'
});
});
it('calls custom state getter once with array of stores', function () {
var flux = new Flux();
var testStore = flux.getStore('test');
var test2Store = flux.getStore('test2');
testStore._testId = 'test';
test2Store._testId = 'test2';
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
var stateGetter = sinon.stub().returns({ foo: 'bar' });
var state = component.connectToStores(['test', 'test2'], stateGetter);
expect(stateGetter.calledOnce).to.be['true'];
expect(stateGetter.firstCall.args[0][0]._testId).to.equal('test');
expect(stateGetter.firstCall.args[0][1]._testId).to.equal('test2');
expect(state).to.deep.equal({
foo: 'bar'
});
});
it('uses default getter if null is passed as getter', function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
component.setState({ otherThing: 'barbaz' });
component.connectToStores('test', null);
flux.getActions('test').getSomething('foobar');
expect(component.state).to.deep.equal({
something: 'foobar',
otherThing: 'barbaz' });
});
it('removes listener before unmounting', function () {
var flux = new Flux();
var div = document.createElement('div');
var component = React.render(React.createElement(ComponentWithFluxMixin, { flux: flux }), div);
var store = flux.getStore('test');
component.connectToStores('test');
expect(store.listeners('change').length).to.equal(1);
React.unmountComponentAtNode(div);
expect(store.listeners('change').length).to.equal(0);
});
});
describe('#getStoreState', function () {
it('gets combined state of connected stores', function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: 'test', flux: flux }));
component.connectToStores({
test: function test(store) {
return {
foo: 'bar' };
},
test2: function test2(store) {
return {
bar: 'baz'
};
}
});
component.setState({ baz: 'foo' });
expect(component.getStoreState()).to.deep.equal({
foo: 'bar',
bar: 'baz'
});
});
});
});