Handle any value with tests

This commit is contained in:
christianalfoni 2015-03-28 23:12:23 +01:00
parent 703e879f75
commit dca9f78524
7 changed files with 539 additions and 81 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -26,7 +26,7 @@ describe('Element', function() {
});
it('should return true or false when calling hasValue() depending on value existance', function () {
it('should set back to pristine value when running reset', function () {
var reset = null;
var TestInput = React.createClass({
@ -48,8 +48,9 @@ describe('Element', function() {
);
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
TestUtils.Simulate.change(input, {target: {value: 'foobar'}});
reset();
expect(input.getDOMNode().value).toBe('');
expect(input.getDOMNode().value).toBe('foo');
});
@ -306,7 +307,7 @@ it('should allow an undefined value to be updated to a value', function (done) {
}, 0);
});
it('should be able to dynamically change validations', function (done) {
it('should be able to dynamically change validations', function (done) {
var isInvalid = false;
var TestInput = React.createClass({
@ -347,4 +348,32 @@ it('should be able to dynamically change validations', function (done) {
}, 0);
});
it('should be able to test a values validity', function () {
var isInvalid = false;
var TestInput = React.createClass({
mixins: [Formsy.Mixin],
render: function () {
return <input value={this.getValue()}/>
}
});
var TestForm = React.createClass({
render: function () {
return (
<Formsy.Form>
<TestInput name="A" validations="isEmail"/>
</Formsy.Form>
);
}
});
var form = TestUtils.renderIntoDocument(
<TestForm/>
);
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
expect(input.isValidValue('foo@bar.com')).toBe(true);
expect(input.isValidValue('foo@bar')).toBe(false);
});
});

View File

@ -438,6 +438,120 @@ describe('Formsy', function () {
});
it('should be possible to pass error state of elements by changing an errors attribute', function (done) {
var TestInput = React.createClass({
mixins: [Formsy.Mixin],
render: function () {
return <input value={this.getValue()}/>;
}
});
var TestForm = React.createClass({
getInitialState: function () {
return {
validationErrors: {
foo: 'bar'
}
};
},
onChange: function (values) {
if (values.foo) {
this.setState({
validationErrors: {}
});
} else {
this.setState({
validationErrors: {foo: 'bar'}
});
}
},
render: function () {
return (
<Formsy.Form onChange={this.onChange} validationErrors={this.state.validationErrors}>
<TestInput name="foo"/>
</Formsy.Form>);
}
});
var form = TestUtils.renderIntoDocument(
<TestForm/>
);
// Wait for update
setTimeout(function () {
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
expect(input.getErrorMessage()).toBe('bar');
input.setValue('gotValue');
// Wait for update
setTimeout(function () {
expect(input.getErrorMessage()).toBe(null);
done();
}, 0);
}, 0);
});
it('should trigger an onValidSubmit when submitting a valid form', function () {
var isCalled = false;
var TestInput = React.createClass({
mixins: [Formsy.Mixin],
render: function () {
return <input value={this.getValue()}/>;
}
});
var TestForm = React.createClass({
onValidSubmit: function () {
isCalled = true;
},
render: function () {
return (
<Formsy.Form onValidSubmit={this.onValidSubmit}>
<TestInput name="foo" validations="isEmail" value="foo@bar.com"/>
</Formsy.Form>);
}
});
var form = TestUtils.renderIntoDocument(
<TestForm/>
);
var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm);
TestUtils.Simulate.submit(TestForm.getDOMNode());
expect(isCalled).toBe(true);
});
it('should trigger an onInvalidSubmit when submitting an invalid form', function () {
var isCalled = false;
var TestInput = React.createClass({
mixins: [Formsy.Mixin],
render: function () {
return <input value={this.getValue()}/>;
}
});
var TestForm = React.createClass({
onInvalidSubmit: function () {
isCalled = true;
},
render: function () {
return (
<Formsy.Form onInvalidSubmit={this.onInvalidSubmit}>
<TestInput name="foo" validations="isEmail" value="foo@bar"/>
</Formsy.Form>);
}
});
var form = TestUtils.renderIntoDocument(
<TestForm/>
);
var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm);
TestUtils.Simulate.submit(TestForm.getDOMNode());
expect(isCalled).toBe(true);
});
});
describe("value === false", function() {

View File

@ -1,9 +1,11 @@
module.exports = {
getInitialState: function () {
var value = 'value' in this.props ? this.props.value : '';
return {
_value: this.props.value !== undefined ? this.props.value : '',
_value: value,
_isValid: true,
_isPristine: true
_isPristine: true,
_pristineValue: value
};
},
componentWillMount: function () {
@ -59,7 +61,8 @@ module.exports = {
// the value, set the value again running a validation
if (prevProps.validations !== this.props.validations || isValueChanged()) {
this.setValue(this.props.value === undefined ? '' : this.props.value);
var value = 'value' in this.props ? this.props.value : '';
this.setValue(value);
}
},
@ -91,7 +94,7 @@ module.exports = {
},
resetValue: function () {
this.setState({
_value: '',
_value: this.state._pristineValue,
_isPristine: true
}, function () {
this.props._validate(this);
@ -123,5 +126,8 @@ module.exports = {
},
showError: function () {
return !this.showRequired() && !this.state._isValid;
},
isValidValue: function (value) {
return this.props._isValidValue.call(null, this, value);
}
};

View File

@ -29,6 +29,8 @@ Formsy.Form = React.createClass({
onSuccess: function () {},
onError: function () {},
onSubmit: function () {},
onValidSubmit: function () {},
onInvalidSubmit: function () {},
onSubmitted: function () {},
onValid: function () {},
onInvalid: function () {},
@ -61,6 +63,10 @@ Formsy.Form = React.createClass({
this.registerInputs(this.props.children);
if (this.props.validationErrors) {
this.setInputValidationErrors(this.props.validationErrors);
}
var newInputKeys = Object.keys(this.inputs);
if (utils.arraysDiffer(inputKeys, newInputKeys)) {
this.validateForm();
@ -85,7 +91,9 @@ Formsy.Form = React.createClass({
// if wanting to reset the entire form to original state, the second param is a callback for this.
if (!this.props.url) {
this.updateModel();
this.props.onSubmit(this.mapModel(), this.resetModel, this.updateInputsWithError);
var model = this.mapModel();
this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);
this.state.isValid ? this.props.onValidSubmit(model, this.resetModel) : this.props.onInvalidSubmit(model, this.resetModel);
return;
}
@ -128,6 +136,17 @@ Formsy.Form = React.createClass({
this.validateForm();
},
setInputValidationErrors: function (errors) {
Object.keys(this.inputs).forEach(function (name, index) {
var component = this.inputs[name];
var args = [{
_isValid: !(name in errors),
_serverError: errors[name]
}];
component.setState.apply(component, args);
}.bind(this));
},
// Go through errors from server and grab the components
// stored in the inputs map. Change their state to invalid
// and set the serverError message
@ -167,6 +186,7 @@ Formsy.Form = React.createClass({
child.props._detachFromForm = this.detachFromForm;
child.props._validate = this.validate;
child.props._isFormDisabled = this.isFormDisabled;
child.props._isValidValue = this.runValidation;
}
if (child && child.props && child.props.children) {
@ -227,10 +247,14 @@ Formsy.Form = React.createClass({
},
runValidation: function (component) {
// Checks validation on current value or a passed value
runValidation: function (component, value) {
var isValid = true;
if (component._validations.length && (component.props.required || component.state._value !== '')) {
component._validations.split(',').forEach(function (validation) {
value = arguments.length === 2 ? value : component.state._value;
if (component._validations.length && (component.props.required || value !== '')) {
component._validations.split(/\,(?![^{\[]*[}\]])/g).forEach(function (validation) {
var args = validation.split(':');
var validateMethod = args.shift();
args = args.map(function (arg) {
@ -240,7 +264,7 @@ Formsy.Form = React.createClass({
return arg; // It is a string if it can not parse it
}
});
args = [component.state._value].concat(args);
args = [value].concat(args);
if (!validationRules[validateMethod]) {
throw new Error('Formsy does not have the validation rule: ' + validateMethod);
}

View File

@ -39,6 +39,6 @@ module.exports = {
return value == eql;
},
equalsField: function (value, field) {
return value === this[field];
return value == this[field];
}
};