redux-form
Version:
A higher order component decorator for forms using Redux and React
1,655 lines (1,480 loc) • 77.6 kB
JavaScript
'use strict';
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _expect = require('expect');
var _expect2 = _interopRequireDefault(_expect);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require('react-redux');
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _reactAddonsTestUtils = require('react-addons-test-utils');
var _reactAddonsTestUtils2 = _interopRequireDefault(_reactAddonsTestUtils);
var _redux = require('redux');
var _reducer = require('../reducer');
var _reducer2 = _interopRequireDefault(_reducer);
var _createReduxForm = require('../createReduxForm');
var _createReduxForm2 = _interopRequireDefault(_createReduxForm);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(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) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint react/no-multi-comp:0 */
var createRestorableSpy = function createRestorableSpy(fn) {
return (0, _expect.createSpy)(fn, function restore() {
this.calls = [];
});
};
describe('createReduxForm', function () {
var reduxForm = (0, _createReduxForm2.default)(false, _react2.default, _reactRedux.connect);
var makeStore = function makeStore() {
return (0, _redux.createStore)((0, _redux.combineReducers)({
form: _reducer2.default
}));
};
it('should return a decorator function', function () {
(0, _expect2.default)(reduxForm).toBeA('function');
});
var Form = function (_Component) {
_inherits(Form, _Component);
function Form() {
_classCallCheck(this, Form);
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
}
Form.prototype.render = function render() {
return _react2.default.createElement('div', null);
};
return Form;
}(_react.Component);
var expectField = function expectField(_ref) {
var field = _ref.field;
var name = _ref.name;
var value = _ref.value;
var initial = _ref.initial;
var valid = _ref.valid;
var dirty = _ref.dirty;
var error = _ref.error;
var touched = _ref.touched;
var visited = _ref.visited;
var readonly = _ref.readonly;
(0, _expect2.default)(field).toBeA('object');
(0, _expect2.default)(field.name).toBe(name);
(0, _expect2.default)(field.value).toEqual(value);
if (readonly) {
(0, _expect2.default)(field.onBlur).toNotExist();
(0, _expect2.default)(field.onChange).toNotExist();
(0, _expect2.default)(field.onDragStart).toNotExist();
(0, _expect2.default)(field.onDrop).toNotExist();
(0, _expect2.default)(field.onFocus).toNotExist();
(0, _expect2.default)(field.onUpdate).toNotExist();
} else {
(0, _expect2.default)(field.onBlur).toBeA('function');
(0, _expect2.default)(field.onChange).toBeA('function');
(0, _expect2.default)(field.onDragStart).toBeA('function');
(0, _expect2.default)(field.onDrop).toBeA('function');
(0, _expect2.default)(field.onFocus).toBeA('function');
(0, _expect2.default)(field.onUpdate).toBeA('function');
}
(0, _expect2.default)(field.initialValue).toEqual(initial);
(0, _expect2.default)(field.defaultValue).toEqual(initial);
(0, _expect2.default)(field.defaultChecked).toBe(initial === true);
(0, _expect2.default)(field.valid).toBe(valid);
(0, _expect2.default)(field.invalid).toBe(!valid);
(0, _expect2.default)(field.dirty).toBe(dirty);
(0, _expect2.default)(field.pristine).toBe(!dirty);
(0, _expect2.default)(field.error).toEqual(error);
(0, _expect2.default)(field.touched).toBe(touched);
(0, _expect2.default)(field.visited).toBe(visited);
};
it('should render without error', function () {
var store = makeStore();
(0, _expect2.default)(function () {
var Decorated = reduxForm({
form: 'testForm',
fields: ['foo', 'bar']
})(Form);
_reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
}).toNotThrow();
});
it('should pass fields as props', function () {
var store = makeStore();
var Decorated = reduxForm({
form: 'testForm',
fields: ['foo', 'bar']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields).toBeA('object');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should initialize field values', function () {
var store = makeStore();
var Decorated = reduxForm({
form: 'testForm',
fields: ['foo', 'bar']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { foo: 'fooValue', bar: 'barValue' } })
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields).toBeA('object');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue',
initial: 'fooValue',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: 'barValue',
initial: 'barValue',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should set value and touch field on blur', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
stub.props.fields.foo.onBlur('fooValue');
(0, _expect2.default)(stub.props.fields).toBeA('object');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue',
initial: undefined,
valid: true,
dirty: true,
error: undefined,
touched: true,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should set value and NOT touch field on blur if touchOnBlur is disabled', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
touchOnBlur: false
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
stub.props.fields.foo.onBlur('fooValue');
(0, _expect2.default)(stub.props.fields).toBeA('object');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue',
initial: undefined,
valid: true,
dirty: true,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should set value and NOT touch field on change', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
stub.props.fields.foo.onChange('fooValue');
(0, _expect2.default)(stub.props.fields).toBeA('object');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue',
initial: undefined,
valid: true,
dirty: true,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should set value and touch field on change if touchOnChange is enabled', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
touchOnChange: true
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
stub.props.fields.foo.onChange('fooValue');
(0, _expect2.default)(stub.props.fields).toBeA('object');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue',
initial: undefined,
valid: true,
dirty: true,
error: undefined,
touched: true,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should set visited field on focus', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.active).toBe(undefined);
stub.props.fields.foo.onFocus();
(0, _expect2.default)(stub.props.active).toBe('foo');
(0, _expect2.default)(stub.props.fields).toBeA('object');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: true,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should set dirty when field changes', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { foo: 'fooValue', bar: 'barValue' } })
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue',
initial: 'fooValue',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
stub.props.fields.foo.onChange('fooValue!');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue!',
initial: 'fooValue',
valid: true,
dirty: true,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should set dirty when and array field changes', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['children[].name']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { children: [{ name: 'Tom' }, { name: 'Jerry' }] } })
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields.children).toBeA('array');
(0, _expect2.default)(stub.props.fields.children.length).toBe(2);
expectField({
field: stub.props.fields.children[0].name,
name: 'children[0].name',
value: 'Tom',
initial: 'Tom',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.children[1].name,
name: 'children[1].name',
value: 'Jerry',
initial: 'Jerry',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
stub.props.fields.children[0].name.onChange('Tim');
expectField({
field: stub.props.fields.children[0].name,
name: 'children[0].name',
value: 'Tim',
initial: 'Tom',
valid: true,
dirty: true,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.children[1].name,
name: 'children[1].name',
value: 'Jerry',
initial: 'Jerry',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
});
it('should trigger sync error on change that invalidates value', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
validate: function validate(values) {
var errors = {};
if (values.foo && values.foo.length > 8) {
errors.foo = 'Too long';
}
if (!values.bar) {
errors.bar = 'Required';
}
return errors;
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { foo: 'fooValue', bar: 'barValue' } })
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue',
initial: 'fooValue',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: 'barValue',
initial: 'barValue',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
(0, _expect2.default)(stub.props.valid).toBe(true);
(0, _expect2.default)(stub.props.invalid).toBe(false);
(0, _expect2.default)(stub.props.errors).toEqual({});
stub.props.fields.foo.onChange('fooValue!');
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: 'fooValue!',
initial: 'fooValue',
valid: false,
dirty: true,
error: 'Too long',
touched: false,
visited: false,
readonly: false
});
stub.props.fields.bar.onChange('');
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: '',
initial: 'barValue',
valid: false,
dirty: true,
error: 'Required',
touched: false,
visited: false,
readonly: false
});
(0, _expect2.default)(stub.props.valid).toBe(false);
(0, _expect2.default)(stub.props.invalid).toBe(true);
(0, _expect2.default)(stub.props.errors).toEqual({
foo: 'Too long',
bar: 'Required'
});
});
it('should trigger sync error on change that invalidates nested value', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo.bar'],
validate: function validate(values) {
var errors = {};
if (values.foo.bar && values.foo.bar.length > 8) {
errors.foo = { bar: 'Too long' };
}
return errors;
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { foo: { bar: 'fooBar' } } })
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
expectField({
field: stub.props.fields.foo.bar,
name: 'foo.bar',
value: 'fooBar',
initial: 'fooBar',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
(0, _expect2.default)(stub.props.valid).toBe(true);
(0, _expect2.default)(stub.props.invalid).toBe(false);
(0, _expect2.default)(stub.props.errors).toEqual({});
stub.props.fields.foo.bar.onChange('fooBarBaz');
expectField({
field: stub.props.fields.foo.bar,
name: 'foo.bar',
value: 'fooBarBaz',
initial: 'fooBar',
valid: false,
dirty: true,
error: 'Too long',
touched: false,
visited: false,
readonly: false
});
(0, _expect2.default)(stub.props.valid).toBe(false);
(0, _expect2.default)(stub.props.invalid).toBe(true);
(0, _expect2.default)(stub.props.errors).toEqual({
foo: {
bar: 'Too long'
}
});
});
it('should trigger sync error on change that invalidates array value', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo[]', 'bar[].name'],
validate: function validate(values) {
var errors = {};
if (values.foo && values.foo.length && values.foo[0] && values.foo[0].length > 8) {
errors.foo = ['Too long'];
}
if (values.bar && values.bar.length && values.bar[0] && values.bar[0].name === 'Ralphie') {
errors.bar = [{ name: 'You\'ll shoot your eye out, kid!' }];
}
return errors;
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { foo: ['fooBar'], bar: [{ name: '' }] } })
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
expectField({
field: stub.props.fields.foo[0],
name: 'foo[0]',
value: 'fooBar',
initial: 'fooBar',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
expectField({
field: stub.props.fields.bar[0].name,
name: 'bar[0].name',
value: '',
initial: '',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: false
});
(0, _expect2.default)(stub.props.valid).toBe(true);
(0, _expect2.default)(stub.props.invalid).toBe(false);
(0, _expect2.default)(stub.props.errors).toEqual({});
stub.props.fields.foo[0].onChange('fooBarBaz');
expectField({
field: stub.props.fields.foo[0],
name: 'foo[0]',
value: 'fooBarBaz',
initial: 'fooBar',
valid: false,
dirty: true,
error: 'Too long',
touched: false,
visited: false,
readonly: false
});
stub.props.fields.bar[0].name.onChange('Ralphie');
expectField({
field: stub.props.fields.bar[0].name,
name: 'bar[0].name',
value: 'Ralphie',
initial: '',
valid: false,
dirty: true,
error: 'You\'ll shoot your eye out, kid!',
touched: false,
visited: false,
readonly: false
});
(0, _expect2.default)(stub.props.valid).toBe(false);
(0, _expect2.default)(stub.props.invalid).toBe(true);
(0, _expect2.default)(stub.props.errors).toEqual({
foo: ['Too long'],
bar: [{ name: 'You\'ll shoot your eye out, kid!' }]
});
});
it('should call destroy on unmount', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar']
})(Form);
var div = document.createElement('div');
_reactDom2.default.render(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { foo: 'fooValue', bar: 'barValue' } })
), div);
var before = store.getState();
(0, _expect2.default)(before.form).toBeA('object');
(0, _expect2.default)(before.form[form]).toBeA('object');
(0, _expect2.default)(before.form[form].foo).toBeA('object');
(0, _expect2.default)(before.form[form].bar).toBeA('object');
_reactDom2.default.unmountComponentAtNode(div);
var after = store.getState();
(0, _expect2.default)(after.form).toBeA('object');
(0, _expect2.default)(after.form[form]).toNotExist();
});
it('should NOT call destroy on unmount if destroyOnUnmount is disabled', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
destroyOnUnmount: false
})(Form);
var div = document.createElement('div');
_reactDom2.default.render(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { initialValues: { foo: 'fooValue', bar: 'barValue' } })
), div);
var before = store.getState();
(0, _expect2.default)(before.form).toBeA('object');
(0, _expect2.default)(before.form[form]).toBeA('object');
(0, _expect2.default)(before.form[form].foo).toBeA('object');
(0, _expect2.default)(before.form[form].bar).toBeA('object');
_reactDom2.default.unmountComponentAtNode(div);
var after = store.getState();
(0, _expect2.default)(after.form).toBeA('object');
(0, _expect2.default)(after.form[form]).toBeA('object');
(0, _expect2.default)(after.form[form].foo).toBeA('object');
(0, _expect2.default)(after.form[form].bar).toBeA('object');
});
it('should hoist statics', function () {
var FormWithStatics = function (_Component2) {
_inherits(FormWithStatics, _Component2);
function FormWithStatics() {
_classCallCheck(this, FormWithStatics);
return _possibleConstructorReturn(this, _Component2.apply(this, arguments));
}
FormWithStatics.prototype.render = function render() {
return _react2.default.createElement('div', null);
};
return FormWithStatics;
}(_react.Component);
FormWithStatics.someStatic1 = 'cat';
FormWithStatics.someStatic2 = 42;
var Decorated = reduxForm({
form: 'testForm',
fields: ['foo', 'bar']
})(FormWithStatics);
(0, _expect2.default)(Decorated.someStatic1).toBe('cat');
(0, _expect2.default)(Decorated.someStatic2).toBe(42);
});
it('should not provide mutators when readonly', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
readonly: true
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
expectField({
field: stub.props.fields.foo,
name: 'foo',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: true
});
expectField({
field: stub.props.fields.bar,
name: 'bar',
value: undefined,
initial: undefined,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false,
readonly: true
});
});
it('should initialize an array field', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['children[].name'],
initialValues: {
children: [{ name: 'Tom' }, { name: 'Jerry' }]
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
expectField({
field: stub.props.fields.children[0].name,
name: 'children[0].name',
value: 'Tom',
initial: 'Tom',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.children[1].name,
name: 'children[1].name',
value: 'Jerry',
initial: 'Jerry',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
});
it('should call onSubmit prop', function (done) {
var submit = function submit(values) {
(0, _expect2.default)(values).toEqual({
foo: undefined,
bar: undefined
});
done();
};
var FormComponent = function (_Component3) {
_inherits(FormComponent, _Component3);
function FormComponent() {
_classCallCheck(this, FormComponent);
return _possibleConstructorReturn(this, _Component3.apply(this, arguments));
}
FormComponent.prototype.render = function render() {
return _react2.default.createElement('form', { onSubmit: this.props.handleSubmit });
};
return FormComponent;
}(_react.Component);
FormComponent.propTypes = {
handleSubmit: _react.PropTypes.func.isRequired
};
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
readonly: true
})(FormComponent);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { onSubmit: submit })
));
var formElement = _reactAddonsTestUtils2.default.findRenderedDOMComponentWithTag(dom, 'form');
_reactAddonsTestUtils2.default.Simulate.submit(formElement);
});
it('should call async onSubmit prop', function (done) {
var submit = function submit(values) {
(0, _expect2.default)(values).toEqual({
foo: undefined,
bar: undefined
});
return new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, 100);
}).then(done);
};
var FormComponent = function (_Component4) {
_inherits(FormComponent, _Component4);
function FormComponent() {
_classCallCheck(this, FormComponent);
return _possibleConstructorReturn(this, _Component4.apply(this, arguments));
}
FormComponent.prototype.render = function render() {
return _react2.default.createElement('form', { onSubmit: this.props.handleSubmit });
};
return FormComponent;
}(_react.Component);
FormComponent.propTypes = {
handleSubmit: _react.PropTypes.func.isRequired
};
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
readonly: true
})(FormComponent);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, { onSubmit: submit })
));
var formElement = _reactAddonsTestUtils2.default.findRenderedDOMComponentWithTag(dom, 'form');
_reactAddonsTestUtils2.default.Simulate.submit(formElement);
});
it('should NOT call async validation if form is pristine and initialized', function () {
var store = makeStore();
var form = 'testForm';
var errorValue = { foo: 'no bears allowed' };
var asyncValidate = (0, _expect.createSpy)().andReturn(Promise.reject(errorValue));
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
asyncValidate: asyncValidate,
asyncBlurFields: ['foo'],
initialValues: {
foo: 'dog',
bar: 'cat'
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
stub.props.fields.foo.onBlur('dog');
(0, _expect2.default)(asyncValidate).toNotHaveBeenCalled();
});
it('should call async validation if form is dirty and initialized', function () {
var store = makeStore();
var form = 'testForm';
var errorValue = { foo: 'no bears allowed' };
var asyncValidate = (0, _expect.createSpy)().andReturn(Promise.reject(errorValue));
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
asyncValidate: asyncValidate,
asyncBlurFields: ['foo'],
initialValues: {
foo: 'dog',
bar: 'cat'
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
stub.props.fields.foo.onBlur('bear');
(0, _expect2.default)(asyncValidate).toHaveBeenCalled();
});
it('should call async validation if form is pristine and NOT initialized', function () {
var store = makeStore();
var form = 'testForm';
var errorValue = { foo: 'no bears allowed' };
var asyncValidate = (0, _expect.createSpy)().andReturn(Promise.reject(errorValue));
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
asyncValidate: asyncValidate,
asyncBlurFields: ['foo']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
stub.props.fields.foo.onBlur();
(0, _expect2.default)(asyncValidate).toHaveBeenCalled();
});
it('should call async validation on submit even if pristine and initialized', function () {
var submit = (0, _expect.createSpy)();
var FormComponent = function (_Component5) {
_inherits(FormComponent, _Component5);
function FormComponent() {
_classCallCheck(this, FormComponent);
return _possibleConstructorReturn(this, _Component5.apply(this, arguments));
}
FormComponent.prototype.render = function render() {
return _react2.default.createElement('form', { onSubmit: this.props.handleSubmit(submit) });
};
return FormComponent;
}(_react.Component);
FormComponent.propTypes = {
handleSubmit: _react.PropTypes.func.isRequired
};
var store = makeStore();
var form = 'testForm';
var errorValue = { foo: 'no dogs allowed' };
var asyncValidate = (0, _expect.createSpy)().andReturn(Promise.reject(errorValue));
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
asyncValidate: asyncValidate,
asyncBlurFields: ['foo'],
initialValues: {
foo: 'dog',
bar: 'cat'
}
})(FormComponent);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var formElement = _reactAddonsTestUtils2.default.findRenderedDOMComponentWithTag(dom, 'form');
_reactAddonsTestUtils2.default.Simulate.submit(formElement);
(0, _expect2.default)(asyncValidate).toHaveBeenCalled();
(0, _expect2.default)(submit).toNotHaveBeenCalled();
});
it('should call submit function passed to handleSubmit', function (done) {
var submit = function submit(values) {
(0, _expect2.default)(values).toEqual({
foo: undefined,
bar: undefined
});
done();
};
var FormComponent = function (_Component6) {
_inherits(FormComponent, _Component6);
function FormComponent() {
_classCallCheck(this, FormComponent);
return _possibleConstructorReturn(this, _Component6.apply(this, arguments));
}
FormComponent.prototype.render = function render() {
return _react2.default.createElement('form', { onSubmit: this.props.handleSubmit(submit) });
};
return FormComponent;
}(_react.Component);
FormComponent.propTypes = {
handleSubmit: _react.PropTypes.func.isRequired
};
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
readonly: true
})(FormComponent);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var formElement = _reactAddonsTestUtils2.default.findRenderedDOMComponentWithTag(dom, 'form');
_reactAddonsTestUtils2.default.Simulate.submit(formElement);
});
it('should call submit function passed to async handleSubmit', function (done) {
var submit = function submit(values) {
(0, _expect2.default)(values).toEqual({
foo: undefined,
bar: undefined
});
return new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, 100);
}).then(done);
};
var FormComponent = function (_Component7) {
_inherits(FormComponent, _Component7);
function FormComponent() {
_classCallCheck(this, FormComponent);
return _possibleConstructorReturn(this, _Component7.apply(this, arguments));
}
FormComponent.prototype.render = function render() {
return _react2.default.createElement('form', { onSubmit: this.props.handleSubmit(submit) });
};
return FormComponent;
}(_react.Component);
FormComponent.propTypes = {
handleSubmit: _react.PropTypes.func.isRequired
};
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['foo', 'bar'],
readonly: true
})(FormComponent);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var formElement = _reactAddonsTestUtils2.default.findRenderedDOMComponentWithTag(dom, 'form');
_reactAddonsTestUtils2.default.Simulate.submit(formElement);
});
it('should initialize a non-array field with an array value and let it read it back', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['children'],
initialValues: {
children: [1, 2]
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
expectField({
field: stub.props.fields.children,
name: 'children',
value: [1, 2],
initial: [1, 2],
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
});
it('should initialize an array field with an array value', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['colors[]'],
initialValues: {
colors: ['red', 'blue']
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields.colors).toBeA('array');
(0, _expect2.default)(stub.props.fields.colors.length).toBe(2);
expectField({
field: stub.props.fields.colors[0],
name: 'colors[0]',
value: 'red',
initial: 'red',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.colors[1],
name: 'colors[1]',
value: 'blue',
initial: 'blue',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
});
it('should initialize a deep array field with values', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['users[].name', 'users[].age'],
initialValues: {
users: [{
name: 'Bob',
age: 27
}]
}
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields.users).toBeA('array');
(0, _expect2.default)(stub.props.fields.users.length).toBe(1);
(0, _expect2.default)(stub.props.fields.users[0]).toBeA('object');
expectField({
field: stub.props.fields.users[0].name,
name: 'users[0].name',
value: 'Bob',
initial: 'Bob',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.users[0].age,
name: 'users[0].age',
value: 27,
initial: 27,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
});
it('should add array values with defaults', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['users[].name', 'users[].age']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields.users).toBeA('array');
(0, _expect2.default)(stub.props.fields.users.length).toBe(0);
(0, _expect2.default)(stub.props.fields.users.addField).toBeA('function');
var before = stub.props.fields.users;
// add field
stub.props.fields.users.addField({ name: 'Bob', age: 27 });
// check field
(0, _expect2.default)(stub.props.fields.users.length).toBe(1);
(0, _expect2.default)(stub.props.fields.users[0]).toBeA('object');
expectField({
field: stub.props.fields.users[0].name,
name: 'users[0].name',
value: 'Bob',
initial: 'Bob',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.users[0].age,
name: 'users[0].age',
value: 27,
initial: 27,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
var after = stub.props.fields.users;
(0, _expect2.default)(after).toNotBe(before); // should be a new instance
// check state
(0, _expect2.default)(store.getState().form.testForm.users).toBeA('array');
(0, _expect2.default)(store.getState().form.testForm.users.length).toBe(1);
(0, _expect2.default)(store.getState().form.testForm.users[0].name).toEqual({
initial: 'Bob',
value: 'Bob'
});
(0, _expect2.default)(store.getState().form.testForm.users[0].age).toEqual({
initial: 27,
value: 27
});
});
// Test to demonstrate bug: https://github.com/erikras/redux-form/issues/630
it('should add array values when root is not an array', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['acknowledgements.items[].number', 'acknowledgements.items[].name', 'acknowledgements.show']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields.acknowledgements).toBeA('object');
(0, _expect2.default)(stub.props.fields.acknowledgements.items).toBeA('array');
(0, _expect2.default)(stub.props.fields.acknowledgements.items.length).toBe(0);
(0, _expect2.default)(stub.props.fields.acknowledgements.items.addField).toBeA('function');
// add field
stub.props.fields.acknowledgements.items.addField({
number: 1,
name: 'foo'
});
// check field
(0, _expect2.default)(stub.props.fields.acknowledgements.items.length).toBe(1);
(0, _expect2.default)(stub.props.fields.acknowledgements.items[0]).toBeA('object');
expectField({
field: stub.props.fields.acknowledgements.items[0].number,
name: 'acknowledgements.items[0].number',
value: 1,
initial: 1,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.acknowledgements.items[0].name,
name: 'acknowledgements.items[0].name',
value: 'foo',
initial: 'foo',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
});
// Test to demonstrate bug: https://github.com/erikras/redux-form/issues/468
it('should add array values with DEEP defaults', function () {
var store = makeStore();
var form = 'testForm';
var Decorated = reduxForm({
form: form,
fields: ['proposals[].arrival', 'proposals[].departure', 'proposals[].note', 'proposals[].rooms[].name', 'proposals[].rooms[].adults', 'proposals[].rooms[].children']
})(Form);
var dom = _reactAddonsTestUtils2.default.renderIntoDocument(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(Decorated, null)
));
var stub = _reactAddonsTestUtils2.default.findRenderedComponentWithType(dom, Form);
(0, _expect2.default)(stub.props.fields.proposals).toBeA('array');
(0, _expect2.default)(stub.props.fields.proposals.length).toBe(0);
(0, _expect2.default)(stub.props.fields.proposals.addField).toBeA('function');
// add field
var today = new Date();
stub.props.fields.proposals.addField({
arrival: today,
departure: today,
note: '',
rooms: [{
name: 'Room 1',
adults: 2,
children: 0
}]
});
stub.props.fields.proposals[0].rooms.addField({
name: 'Room 2',
adults: 0,
children: 2
});
// check field
(0, _expect2.default)(stub.props.fields.proposals.length).toBe(1);
(0, _expect2.default)(stub.props.fields.proposals[0]).toBeA('object');
expectField({
field: stub.props.fields.proposals[0].arrival,
name: 'proposals[0].arrival',
value: today,
initial: today,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].departure,
name: 'proposals[0].departure',
value: today,
initial: today,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].note,
name: 'proposals[0].note',
value: '',
initial: '',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].rooms[0].name,
name: 'proposals[0].rooms[0].name',
value: 'Room 1',
initial: 'Room 1',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].rooms[0].adults,
name: 'proposals[0].rooms[0].adults',
value: 2,
initial: 2,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].rooms[0].children,
name: 'proposals[0].rooms[0].children',
value: 0,
initial: 0,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].rooms[1].name,
name: 'proposals[0].rooms[1].name',
value: 'Room 2',
initial: 'Room 2',
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].rooms[1].adults,
name: 'proposals[0].rooms[1].adults',
value: 0,
initial: 0,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
expectField({
field: stub.props.fields.proposals[0].rooms[1].children,
name: 'proposals[0].rooms[1].children',
value: 2,
initial: 2,
valid: true,
dirty: false,
error: undefined,
touched: false,
visited: false
});
});
// Test to demonstrate https://github.com/erikras/redux-form/issues/612
//it('should work with a root-level array field', () => {
// const store = makeStore();
// const form = 'test