diff --git a/release/formsy-react.js b/release/formsy-react.js index 49ff2ae..0910aa9 100644 --- a/release/formsy-react.js +++ b/release/formsy-react.js @@ -1,2 +1,712 @@ -!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i(require("react")):"function"==typeof define&&define.amd?define(["react"],i):"object"==typeof exports?exports.Formsy=i(require("react")):t.Formsy=i(t.react)}(this,function(t){return function(t){function i(r){if(e[r])return e[r].exports;var n=e[r]={exports:{},id:r,loaded:!1};return t[r].call(n.exports,n,n.exports,i),n.loaded=!0,n.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){(function(i){"use strict";var r=i.React||e(4),n={},s=e(3),o=e(1),u=e(2),a={};n.Mixin=u,n.defaults=function(t){a=t},n.addValidationRule=function(t,i){s[t]=i},n.Form=r.createClass({displayName:"Form",getInitialState:function(){return{isValid:!0,isSubmitting:!1,canChange:!1}},getDefaultProps:function(){return{onSuccess:function(){},onError:function(){},onSubmit:function(){},onValidSubmit:function(){},onInvalidSubmit:function(){},onSubmitted:function(){},onValid:function(){},onInvalid:function(){},onChange:function(){},validationErrors:null}},componentWillMount:function(){this.inputs={},this.model={}},componentDidMount:function(){this.validateForm()},componentWillUpdate:function(){var t=Object.keys(this.inputs);setTimeout(function(){if(this.isMounted()){this.props.validationErrors&&this.setInputValidationErrors(this.props.validationErrors);var i=Object.keys(this.inputs);o.arraysDiffer(t,i)&&this.validateForm()}}.bind(this),0)},reset:function(){this.setFormPristine(!0),this.resetModel()},submit:function(t){t&&t.preventDefault(),this.setFormPristine(!1),this.updateModel();var i=this.mapModel();this.props.onSubmit(i,this.resetModel,this.updateInputsWithError),this.state.isValid?this.props.onValidSubmit(i,this.resetModel,this.updateInputsWithError):this.props.onInvalidSubmit(i,this.resetModel,this.updateInputsWithError)},mapModel:function(){return this.props.mapping?this.props.mapping(this.model):this.model},updateModel:function(){Object.keys(this.inputs).forEach(function(t){var i=this.inputs[t];this.model[t]=i.state._value}.bind(this))},resetModel:function(){Object.keys(this.inputs).forEach(function(t){this.inputs[t].resetValue()}.bind(this)),this.validateForm()},setInputValidationErrors:function(t){Object.keys(this.inputs).forEach(function(i,e){var r=this.inputs[i],n=[{_isValid:!(i in t),_validationError:t[i]}];r.setState.apply(r,n)}.bind(this))},updateInputsWithError:function(t){Object.keys(t).forEach(function(i,e){var r=this.inputs[i];if(!r)throw new Error("You are trying to update an input that does not exists. Verify errors object with input names. "+JSON.stringify(t));var n=[{_isValid:!1,_externalError:t[i]}];r.setState.apply(r,n)}.bind(this))},traverseChildrenAndRegisterInputs:function(t){return"object"!=typeof t||null===t?t:r.Children.map(t,function(t){return"object"!=typeof t||null===t?t:t.props&&t.props.name?r.cloneElement(t,{_attachToForm:this.attachToForm,_detachFromForm:this.detachFromForm,_validate:this.validate,_isFormDisabled:this.isFormDisabled,_isValidValue:function(t,i){return this.runValidation(t,i).isValid}.bind(this)},t.props&&t.props.children):r.cloneElement(t,{},this.traverseChildrenAndRegisterInputs(t.props&&t.props.children))},this)},isFormDisabled:function(){return this.props.disabled},getCurrentValues:function(){return Object.keys(this.inputs).reduce(function(t,i){var e=this.inputs[i];return t[i]=e.state._value,t}.bind(this),{})},setFormPristine:function(t){var i=this.inputs,e=Object.keys(i);this.setState({_formSubmitted:!t}),e.forEach(function(e,r){var n=i[e];n.setState({_formSubmitted:!t,_isPristine:t})}.bind(this))},validate:function(t){this.state.canChange&&this.props.onChange(this.getCurrentValues());var i=this.runValidation(t);t.setState({_isValid:i.isValid,_isRequired:i.isRequired,_validationError:i.error,_externalError:null},this.validateForm)},runValidation:function(t,i){var e=this.getCurrentValues(),r=t.props.validationErrors,n=t.props.validationError;i=2===arguments.length?i:t.state._value;var s=this.runRules(i,e,t._validations),o=this.runRules(i,e,t._requiredValidations);"function"==typeof t.validate&&(s.failed=t.validate()?[]:["failed"]);var u=Object.keys(t._requiredValidations).length?!!o.success.length:!1,a=!(s.failed.length||this.props.validationErrors&&this.props.validationErrors[t.props.name]);return{isRequired:u,isValid:u?!1:a,error:function(){return a&&!u?"":s.errors.length?s.errors[0]:this.props.validationErrors&&this.props.validationErrors[t.props.name]?this.props.validationErrors[t.props.name]:u?r[o.success[0]]||null:a?void 0:r[s.failed[0]]||n}.call(this)}},runRules:function(t,i,e){var r={errors:[],failed:[],success:[]};return Object.keys(e).length&&Object.keys(e).forEach(function(n){if(s[n]&&"function"==typeof e[n])throw new Error("Formsy does not allow you to override default validations: "+n);if(!s[n]&&"function"!=typeof e[n])throw new Error("Formsy does not have the validation rule: "+n);if("function"==typeof e[n]){var o=e[n](i,t);return void("string"==typeof o?(r.errors.push(o),r.failed.push(n)):o||r.failed.push(n))}if("function"!=typeof e[n]){var o=s[n](i,t,e[n]);return void("string"==typeof o?(r.errors.push(o),r.failed.push(n)):o?r.success.push(n):r.failed.push(n))}return r.success.push(n)}),r},validateForm:function(){var t=!0,i=this.inputs,e=Object.keys(i),r=function(){e.forEach(function(e){i[e].state._isValid||(t=!1)}.bind(this)),this.setState({isValid:t}),t?this.props.onValid():this.props.onInvalid(),this.setState({canChange:!0})}.bind(this);e.forEach(function(t,n){var s=i[t],o=this.runValidation(s);o.isValid&&s.state._externalError&&(o.isValid=!1),s.setState({_isValid:o.isValid,_isRequired:o.isRequired,_validationError:o.error,_externalError:!o.isValid&&s.state._externalError?s.state._externalError:null},n===e.length-1?r:null)}.bind(this)),!e.length&&this.isMounted()&&this.setState({canChange:!0})},attachToForm:function(t){this.inputs[t.props.name]=t,this.model[t.props.name]=t.state._value,this.validate(t)},detachFromForm:function(t){delete this.inputs[t.props.name],delete this.model[t.props.name]},render:function(){return r.DOM.form({onSubmit:this.submit,className:this.props.className},this.traverseChildrenAndRegisterInputs(this.props.children))}}),i.exports||i.module||i.define&&i.define.amd||(i.Formsy=n),t.exports=n}).call(i,function(){return this}())},function(t,i,e){"use strict";t.exports={arraysDiffer:function(t,i){var e=!1;return t.length!==i.length?e=!0:t.forEach(function(t,r){this.isSame(t,i[r])||(e=!0)},this),e},objectsDiffer:function(t,i){var e=!1;return Object.keys(t).length!==Object.keys(i).length?e=!0:Object.keys(t).forEach(function(r){this.isSame(t[r],i[r])||(e=!0)},this),e},isSame:function(t,i){return t!==i?!1:Array.isArray(t)?!this.arraysDiffer(t,i):"object"==typeof t&&null!==t?!this.objectsDiffer(t,i):!0}}},function(t,i,e){"use strict";var r=e(1),n=function(t){return"string"==typeof t?t.split(/\,(?![^{\[]*[}\]])/g).reduce(function(t,i){var e=i.split(":"),r=e.shift();if(e=e.map(function(t){try{return JSON.parse(t)}catch(i){return t}}),e.length>1)throw new Error("Formsy does not support multiple args on string validations. Use object format of validations instead.");return t[r]=e.length?e[0]:!0,t},{}):t||{}};t.exports={getInitialState:function(){return{_value:this.props.value,_isRequired:!1,_isValid:!0,_isPristine:!0,_pristineValue:this.props.value,_validationError:"",_externalError:null,_formSubmitted:!1}},getDefaultProps:function(){return{validationError:"",validationErrors:{}}},componentWillMount:function(){var t=function(){this.setValidations(this.props.validations,this.props.required),this.props._attachToForm(this)}.bind(this);if(!this.props.name)throw new Error("Form Input requires a name property when used");return this.props._attachToForm?void t():setTimeout(function(){if(this.isMounted()){if(!this.props._attachToForm)throw new Error("Form Mixin requires component to be nested in a Form");t()}}.bind(this),0)},componentWillReceiveProps:function(t){this.setValidations(t.validations,t.required)},componentDidUpdate:function(t,i){var e=function(){return!r.isSame(this.props.value,t.value)&&r.isSame(this.state._value,t.value)}.bind(this);e()&&this.setValue(this.props.value)},componentWillUnmount:function(){this.props._detachFromForm(this)},setValidations:function(t,i){this._validations=n(t)||{},this._requiredValidations=i===!0?{isDefaultRequiredValue:!0}:n(i)},setValue:function(t){this.setState({_value:t,_isPristine:!1},function(){this.props._validate(this)}.bind(this))},resetValue:function(){this.setState({_value:this.state._pristineValue,_isPristine:!0},function(){this.props._validate(this)})},getValue:function(){return this.state._value},hasValue:function(){return""!==this.state._value},getErrorMessage:function(){return!this.isValid()||this.showRequired()?this.state._externalError||this.state._validationError:null},isFormDisabled:function(){return this.props._isFormDisabled()},isValid:function(){return this.state._isValid},isPristine:function(){return this.state._isPristine},isFormSubmitted:function(){return this.state._formSubmitted},isRequired:function(){return!!this.props.required},showRequired:function(){return this.state._isRequired},showError:function(){return!this.showRequired()&&!this.isValid()},isValidValue:function(t){return this.props._isValidValue.call(null,this,t)}}},function(t,i,e){"use strict";t.exports={isDefaultRequiredValue:function(t,i){return void 0===i||""===i},hasValue:function(t,i){return!!i},matchRegexp:function(t,i,e){return!!i&&!!i.match(e)},isUndefined:function(t,i){return void 0===i},isEmptyString:function(t,i){return""===i},isEmail:function(t,i){return!i||i.match(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i)},isTrue:function(t,i){return i===!0},isFalse:function(t,i){return i===!1},isNumeric:function(t,i){if(!i)return!1;if("number"==typeof i)return!0;var e=i.match(/[-+]?(\d*[.])?\d+/);return e?e[0]==i:!1},isAlpha:function(t,i){return i&&/^[a-zA-Z]+$/.test(i)},isWords:function(t,i){return i&&/^[a-zA-Z\s]+$/.test(i)},isSpecialWords:function(t,i){return!i||i.match(/^[a-zA-Z\s\u00C0-\u017F]+$/)},isLength:function(t,i,e){return i&&i.length===e},equals:function(t,i,e){return i==e},equalsField:function(t,i,e){return i==t[e]},maxLength:function(t,i,e){return i&&i.length&&i.length<=e},minLength:function(t,i,e){return i&&i.length&&i.length>=e}}},function(i,e,r){i.exports=t}])}); -//# sourceMappingURL=formsy-react.js.map \ No newline at end of file +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1) { + throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.'); + } + + validations[validateMethod] = args.length ? args[0] : true; + return validations; + }, {}); + + } + + return validations || {}; +}; + +module.exports = { + getInitialState: function () { + return { + _value: this.props.value, + _isRequired: false, + _isValid: true, + _isPristine: true, + _pristineValue: this.props.value, + _validationError: '', + _externalError: null, + _formSubmitted: false + }; + }, + getDefaultProps: function () { + return { + validationError: '', + validationErrors: {} + }; + }, + + componentWillMount: function () { + var configure = function () { + this.setValidations(this.props.validations, this.props.required); + this.props._attachToForm(this); + }.bind(this); + + if (!this.props.name) { + throw new Error('Form Input requires a name property when used'); + } + + if (!this.props._attachToForm) { + return setTimeout(function () { + if (!this.isMounted()) return; + if (!this.props._attachToForm) { + throw new Error('Form Mixin requires component to be nested in a Form'); + } + configure(); + }.bind(this), 0); + } + configure(); + }, + + // We have to make the validate method is kept when new props are added + componentWillReceiveProps: function (nextProps) { + this.setValidations(nextProps.validations, nextProps.required); + }, + + componentDidUpdate: function (prevProps, prevState) { + + var isValueChanged = function () { + + return !utils.isSame(this.props.value, prevProps.value) && utils.isSame(this.state._value, prevProps.value); + + }.bind(this); + + // If validations has changed or something outside changes + // the value, set the value again running a validation + if (isValueChanged()) { + this.setValue(this.props.value); + } + }, + + // Detach it when component unmounts + componentWillUnmount: function () { + this.props._detachFromForm(this); + }, + + setValidations: function (validations, required) { + + // Add validations to the store itself as the props object can not be modified + this._validations = convertValidationsToObject(validations) || {}; + this._requiredValidations = required === true ? {isDefaultRequiredValue: true} : convertValidationsToObject(required); + + }, + + // We validate after the value has been set + setValue: function (value) { + this.setState({ + _value: value, + _isPristine: false + }, function () { + this.props._validate(this); + }.bind(this)); + }, + resetValue: function () { + this.setState({ + _value: this.state._pristineValue, + _isPristine: true + }, function () { + this.props._validate(this); + }); + }, + getValue: function () { + return this.state._value; + }, + hasValue: function () { + return this.state._value !== ''; + }, + getErrorMessage: function () { + return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError) : null; + }, + isFormDisabled: function () { + return this.props._isFormDisabled(); + }, + isValid: function () { + return this.state._isValid; + }, + isPristine: function () { + return this.state._isPristine; + }, + isFormSubmitted: function () { + return this.state._formSubmitted; + }, + isRequired: function () { + return !!this.props.required; + }, + showRequired: function () { + return this.state._isRequired; + }, + showError: function () { + return !this.showRequired() && !this.isValid(); + }, + isValidValue: function (value) { + return this.props._isValidValue.call(null, this, value); + } +}; + + + +},{"./utils.js":3}],3:[function(require,module,exports){ +module.exports = { + arraysDiffer: function (a, b) { + var isDifferent = false; + if (a.length !== b.length) { + isDifferent = true; + } else { + a.forEach(function (item, index) { + if (!this.isSame(item, b[index])) { + isDifferent = true; + } + }, this); + } + return isDifferent; + }, + objectsDiffer: function (a, b) { + var isDifferent = false; + if (Object.keys(a).length !== Object.keys(b).length) { + isDifferent = true; + } else { + Object.keys(a).forEach(function (key) { + if (!this.isSame(a[key], b[key])) { + isDifferent = true; + } + }, this); + } + return isDifferent; + }, + isSame: function (a, b) { + + if (a !== b) { + return false; + } + + if (Array.isArray(a)) { + return !this.arraysDiffer(a, b); + } else if (typeof a === 'object' && a !== null) { + return !this.objectsDiffer(a, b); + } + + return true; + } +}; + + + +},{}],4:[function(require,module,exports){ +var isExisty = function (value) { + return value !== null && value !== undefined; +}; + +var validations = { + isDefaultRequiredValue: function (values, value) { + return value === undefined || value === ''; + }, + hasValue: function (values, value) { + return !!value; + }, + matchRegexp: function (values, value, regexp) { + return isExisty(value) && regexp.test(value); + }, + isUndefined: function (values, value) { + return value === undefined; + }, + isEmptyString: function (values, value) { + return value === ''; + }, + isEmail: function (values, value) { + return validations.matchRegexp(values, value, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i); + }, + isTrue: function (values, value) { + return value === true; + }, + isFalse: function (values, value) { + return value === false; + }, + isNumeric: function (values, value) { + if (!isExisty(value)) { + return false; + } + if (typeof value === 'number') { + return true; + } else { + var matchResults = value.match(/[-+]?(\d*[.])?\d+/); + if (!!matchResults) { + return matchResults[0] == value; + } else { + return false; + } + } + }, + isAlpha: function (values, value) { + return value && /^[a-zA-Z]+$/.test(value); + }, + isWords: function (values, value) { + return value && /^[a-zA-Z\s]+$/.test(value); + }, + isSpecialWords: function (values, value) { + return !value || /^[a-zA-Z\s\u00C0-\u017F]+$/.test(value); + }, + isLength: function (values, value, length) { + return isExisty(value) && value.length === length; + }, + equals: function (values, value, eql) { + return value == eql; + }, + equalsField: function (values, value, field) { + return value == values[field]; + }, + maxLength: function (values, value, length) { + return isExisty(value) && value.length <= length; + }, + minLength: function (values, value, length) { + return isExisty(value) && value.length >= length; + } +}; + +module.exports = validations; + + + +},{}]},{},[1]); diff --git a/release/formsy-react.min.js b/release/formsy-react.min.js new file mode 100644 index 0000000..26f2276 --- /dev/null +++ b/release/formsy-react.min.js @@ -0,0 +1 @@ +!function t(i,e,r){function n(o,u){if(!e[o]){if(!i[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(s)return s(o,!0);var l=new Error("Cannot find module '"+o+"'");throw l.code="MODULE_NOT_FOUND",l}var d=e[o]={exports:{}};i[o][0].call(d.exports,function(t){var e=i[o][1][t];return n(e?e:t)},d,d.exports,t,i,e,r)}return e[o].exports}for(var s="function"==typeof require&&require,o=0;o1)throw new Error("Formsy does not support multiple args on string validations. Use object format of validations instead.");return t[r]=e.length?e[0]:!0,t},{}):t||{}};i.exports={getInitialState:function(){return{_value:this.props.value,_isRequired:!1,_isValid:!0,_isPristine:!0,_pristineValue:this.props.value,_validationError:"",_externalError:null,_formSubmitted:!1}},getDefaultProps:function(){return{validationError:"",validationErrors:{}}},componentWillMount:function(){var t=function(){this.setValidations(this.props.validations,this.props.required),this.props._attachToForm(this)}.bind(this);if(!this.props.name)throw new Error("Form Input requires a name property when used");return this.props._attachToForm?(t(),void 0):setTimeout(function(){if(this.isMounted()){if(!this.props._attachToForm)throw new Error("Form Mixin requires component to be nested in a Form");t()}}.bind(this),0)},componentWillReceiveProps:function(t){this.setValidations(t.validations,t.required)},componentDidUpdate:function(t){var i=function(){return!e.isSame(this.props.value,t.value)&&e.isSame(this.state._value,t.value)}.bind(this);i()&&this.setValue(this.props.value)},componentWillUnmount:function(){this.props._detachFromForm(this)},setValidations:function(t,i){this._validations=r(t)||{},this._requiredValidations=i===!0?{isDefaultRequiredValue:!0}:r(i)},setValue:function(t){this.setState({_value:t,_isPristine:!1},function(){this.props._validate(this)}.bind(this))},resetValue:function(){this.setState({_value:this.state._pristineValue,_isPristine:!0},function(){this.props._validate(this)})},getValue:function(){return this.state._value},hasValue:function(){return""!==this.state._value},getErrorMessage:function(){return!this.isValid()||this.showRequired()?this.state._externalError||this.state._validationError:null},isFormDisabled:function(){return this.props._isFormDisabled()},isValid:function(){return this.state._isValid},isPristine:function(){return this.state._isPristine},isFormSubmitted:function(){return this.state._formSubmitted},isRequired:function(){return!!this.props.required},showRequired:function(){return this.state._isRequired},showError:function(){return!this.showRequired()&&!this.isValid()},isValidValue:function(t){return this.props._isValidValue.call(null,this,t)}}},{"./utils.js":3}],3:[function(t,i){i.exports={arraysDiffer:function(t,i){var e=!1;return t.length!==i.length?e=!0:t.forEach(function(t,r){this.isSame(t,i[r])||(e=!0)},this),e},objectsDiffer:function(t,i){var e=!1;return Object.keys(t).length!==Object.keys(i).length?e=!0:Object.keys(t).forEach(function(r){this.isSame(t[r],i[r])||(e=!0)},this),e},isSame:function(t,i){return t!==i?!1:Array.isArray(t)?!this.arraysDiffer(t,i):"object"==typeof t&&null!==t?!this.objectsDiffer(t,i):!0}}},{}],4:[function(t,i){var e=function(t){return null!==t&&void 0!==t},r={isDefaultRequiredValue:function(t,i){return void 0===i||""===i},hasValue:function(t,i){return!!i},matchRegexp:function(t,i,r){return e(i)&&r.test(i)},isUndefined:function(t,i){return void 0===i},isEmptyString:function(t,i){return""===i},isEmail:function(t,i){return r.matchRegexp(t,i,/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i)},isTrue:function(t,i){return i===!0},isFalse:function(t,i){return i===!1},isNumeric:function(t,i){if(!e(i))return!1;if("number"==typeof i)return!0;var r=i.match(/[-+]?(\d*[.])?\d+/);return r?r[0]==i:!1},isAlpha:function(t,i){return i&&/^[a-zA-Z]+$/.test(i)},isWords:function(t,i){return i&&/^[a-zA-Z\s]+$/.test(i)},isSpecialWords:function(t,i){return!i||/^[a-zA-Z\s\u00C0-\u017F]+$/.test(i)},isLength:function(t,i,r){return e(i)&&i.length===r},equals:function(t,i,e){return i==e},equalsField:function(t,i,e){return i==t[e]},maxLength:function(t,i,r){return e(i)&&i.length<=r},minLength:function(t,i,r){return e(i)&&i.length>=r}};i.exports=r},{}]},{},[1]); \ No newline at end of file diff --git a/specs/Rules-equals-spec.jsx b/specs/Rules-equals-spec.jsx index e689a84..d4ae10e 100644 --- a/specs/Rules-equals-spec.jsx +++ b/specs/Rules-equals-spec.jsx @@ -35,18 +35,6 @@ describe('Rules: equals', function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: undefined}}); - expect(isValid).not.toHaveBeenCalled(); - }); - - it('should fail with null', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: null}}); - expect(isValid).not.toHaveBeenCalled(); - }); - it('should fail when the value is not equal', function () { expect(isValid).not.toHaveBeenCalled(); TestUtils.Simulate.change(input, {target: {value: 'foo'}}); @@ -59,4 +47,22 @@ describe('Rules: equals', function() { expect(isValid).toHaveBeenCalled(); }); + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 42}}); + expect(isValid).not.toHaveBeenCalled(); + }); + }); diff --git a/specs/Rules-hasValue-spec.jsx b/specs/Rules-hasValue-spec.jsx index 7fde21e..ff4967a 100644 --- a/specs/Rules-hasValue-spec.jsx +++ b/specs/Rules-hasValue-spec.jsx @@ -35,22 +35,44 @@ describe('Rules: hasValue', function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: undefined}}); - expect(isValid).not.toHaveBeenCalled(); - }); - - it('should fail with null', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: null}}); - expect(isValid).not.toHaveBeenCalled(); - }); - it('should pass with a string', function () { expect(isValid).not.toHaveBeenCalled(); TestUtils.Simulate.change(input, {target: {value: 'myValue'}}); expect(isValid).toHaveBeenCalled(); }); + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should pass with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 42}}); + expect(isValid).toHaveBeenCalled(); + }); + +/* ToDo: + + it('should pass with an empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should pass with a zero', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 0}}); + expect(isValid).toHaveBeenCalled(); + }); + +*/ + }); diff --git a/specs/Rules-isAlpha-spec.jsx b/specs/Rules-isAlpha-spec.jsx index 8e0e57c..0ef8c75 100644 --- a/specs/Rules-isAlpha-spec.jsx +++ b/specs/Rules-isAlpha-spec.jsx @@ -35,13 +35,25 @@ describe('Rules: isAlpha', function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { + it('should pass with a string is only latin letters', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'myValue'}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should fail with a string with numbers', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'myValue 42'}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with an undefined', function () { expect(isValid).not.toHaveBeenCalled(); TestUtils.Simulate.change(input, {target: {value: undefined}}); expect(isValid).not.toHaveBeenCalled(); }); - it('should fail with null', function () { + it('should fail with a null', function () { expect(isValid).not.toHaveBeenCalled(); TestUtils.Simulate.change(input, {target: {value: null}}); expect(isValid).not.toHaveBeenCalled(); @@ -49,14 +61,14 @@ describe('Rules: isAlpha', function() { it('should fail with a number', function () { expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 123}}); + TestUtils.Simulate.change(input, {target: {value: 42}}); expect(isValid).not.toHaveBeenCalled(); }); - it('should pass with a string', function () { + it('should fail with an empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 'myValue'}}); - expect(isValid).toHaveBeenCalled(); }); }); diff --git a/specs/Rules-isEmail-spec.jsx b/specs/Rules-isEmail-spec.jsx index 4b94387..14fa3c4 100644 --- a/specs/Rules-isEmail-spec.jsx +++ b/specs/Rules-isEmail-spec.jsx @@ -47,4 +47,28 @@ describe('Rules: isEmail', function() { expect(isValid).toHaveBeenCalled(); }); + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 42}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with an empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); + expect(isValid).not.toHaveBeenCalled(); + }); + }); diff --git a/specs/Rules-isEmptyString-spec.jsx b/specs/Rules-isEmptyString-spec.jsx new file mode 100644 index 0000000..20d6370 --- /dev/null +++ b/specs/Rules-isEmptyString-spec.jsx @@ -0,0 +1,74 @@ +var React = require('react/addons'); +var TestUtils = React.addons.TestUtils; +var Formsy = require('./../src/main.js'); + +describe('Rules: isEmptyString', function() { + var TestInput, isValid, form, input; + + beforeEach(function() { + isValid = jasmine.createSpy('valid'); + + TestInput = React.createClass({ + mixins: [Formsy.Mixin], + updateValue: function (event) { + this.setValue(event.target.value); + }, + render: function () { + if (this.isValid()) { + isValid(); + } + return + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(function() { + TestInput = isValid = isInvalid = form = null; + }); + + it('should fail with non-empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'asd'}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should pass with an empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should fail with a undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 123}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a zero', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 0}}); + expect(isValid).not.toHaveBeenCalled(); + }); + +}); diff --git a/specs/Rules-isLength-spec.jsx b/specs/Rules-isLength-spec.jsx index 7efdb2f..c398726 100644 --- a/specs/Rules-isLength-spec.jsx +++ b/specs/Rules-isLength-spec.jsx @@ -20,55 +20,104 @@ describe('Rules: isLength', function() { return } }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - }); afterEach(function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: undefined}}); - expect(isValid).not.toHaveBeenCalled(); + describe('isLength:3', function() { + + beforeEach(function() { + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + }); + + it('should fail with a string too small', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'hi'}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a string too long', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'foo bar'}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should pass with the right length', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'sup'}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 123}}); + expect(isValid).not.toHaveBeenCalled(); + }); + }); - it('should fail with null', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: null}}); - expect(isValid).not.toHaveBeenCalled(); - }); + describe('isLength:0', function() { - it('should fail with a number', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 123}}); - expect(isValid).not.toHaveBeenCalled(); - }); + beforeEach(function() { + form = TestUtils.renderIntoDocument( + + + + ); - it('should fail with a string too small', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: "hi"}}); - expect(isValid).not.toHaveBeenCalled(); - }); + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + }); - it('should fail with a string too long', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: "foo bar"}}); - expect(isValid).not.toHaveBeenCalled(); - }); + it('should fail with a string too long', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'foo bar'}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should pass with empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should fail with undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 123}}); + expect(isValid).not.toHaveBeenCalled(); + }); - it('should pass with the right length', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 'sup'}}); - expect(isValid).toHaveBeenCalled(); }); }); diff --git a/specs/Rules-isNumeric-spec.jsx b/specs/Rules-isNumeric-spec.jsx index ed135ee..8cb2285 100644 --- a/specs/Rules-isNumeric-spec.jsx +++ b/specs/Rules-isNumeric-spec.jsx @@ -35,18 +35,6 @@ describe('Rules: isNumeric', function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: undefined}}); - expect(isValid).not.toHaveBeenCalled(); - }); - - it('should fail with null', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: null}}); - expect(isValid).not.toHaveBeenCalled(); - }); - it('should fail with a string', function () { expect(isValid).not.toHaveBeenCalled(); TestUtils.Simulate.change(input, {target: {value: 'myValue'}}); @@ -55,19 +43,37 @@ describe('Rules: isNumeric', function() { it('should pass with a number as string', function () { expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: '123'}}); + TestUtils.Simulate.change(input, {target: {value: '42'}}); expect(isValid).toHaveBeenCalled(); }); it('should pass with an int', function () { expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 123}}); + TestUtils.Simulate.change(input, {target: {value: 42}}); expect(isValid).toHaveBeenCalled(); }); it('should pass with a float', function () { expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 1.23}}); + TestUtils.Simulate.change(input, {target: {value: Math.PI}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should pass with a zero', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 0}}); expect(isValid).toHaveBeenCalled(); }); diff --git a/specs/Rules-isWords-spec.jsx b/specs/Rules-isWords-spec.jsx index 539d7f2..59576ce 100644 --- a/specs/Rules-isWords-spec.jsx +++ b/specs/Rules-isWords-spec.jsx @@ -35,24 +35,6 @@ describe('Rules: isWords', function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: undefined}}); - expect(isValid).not.toHaveBeenCalled(); - }); - - it('should fail with null', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: null}}); - expect(isValid).not.toHaveBeenCalled(); - }); - - it('should fail with a number', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 123}}); - expect(isValid).not.toHaveBeenCalled(); - }); - it('should pass with a 1 word', function () { expect(isValid).not.toHaveBeenCalled(); TestUtils.Simulate.change(input, {target: {value: 'sup'}}); @@ -65,4 +47,28 @@ describe('Rules: isWords', function() { expect(isValid).toHaveBeenCalled(); }); + it('should fail with a string with numbers', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'myValue 42'}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 42}}); + expect(isValid).not.toHaveBeenCalled(); + }); + }); diff --git a/specs/Rules-maxLength-spec.jsx b/specs/Rules-maxLength-spec.jsx index df3f1c3..4232ca5 100644 --- a/specs/Rules-maxLength-spec.jsx +++ b/specs/Rules-maxLength-spec.jsx @@ -35,24 +35,6 @@ describe('Rules: maxLength', function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: undefined}}); - expect(isValid).not.toHaveBeenCalled(); - }); - - it('should fail with null', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: null}}); - expect(isValid).not.toHaveBeenCalled(); - }); - - it('should fail with a number', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 123}}); - expect(isValid).not.toHaveBeenCalled(); - }); - it('should pass when a string\'s length is smaller', function () { expect(isValid).not.toHaveBeenCalled(); TestUtils.Simulate.change(input, {target: {value: 'hi'}}); @@ -71,4 +53,28 @@ describe('Rules: maxLength', function() { expect(isValid).not.toHaveBeenCalled(); }); + it('should pass with an empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); + expect(isValid).toHaveBeenCalled(); + }) + + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 123}}); + expect(isValid).not.toHaveBeenCalled(); + }); + }); diff --git a/specs/Rules-minLength-spec.jsx b/specs/Rules-minLength-spec.jsx index 6d5ef5f..ba0360d 100644 --- a/specs/Rules-minLength-spec.jsx +++ b/specs/Rules-minLength-spec.jsx @@ -20,55 +20,110 @@ describe('Rules: minLength', function() { return } }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - }); afterEach(function() { TestInput = isValid = isInvalid = form = null; }); - it('should fail with undefined', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: undefined}}); - expect(isValid).not.toHaveBeenCalled(); + describe('minLength:3', function() { + + beforeEach(function() { + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + }); + + it('should fail when a string\'s length is smaller', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'hi'}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should pass when a string\'s length is equal', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'bar'}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should pass when a string\'s length is bigger', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'myValue'}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should fail with an empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); + expect(isValid).not.toHaveBeenCalled(); + }) + + it('should fail with an undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 123}}); + expect(isValid).not.toHaveBeenCalled(); + }); + }); - it('should fail with null', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: null}}); - expect(isValid).not.toHaveBeenCalled(); - }); + describe('minLength:0', function() { - it('should fail with a number', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 123}}); - expect(isValid).not.toHaveBeenCalled(); - }); + beforeEach(function() { + form = TestUtils.renderIntoDocument( + + + + ); - it('should fail when a string\'s length is smaller', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 'hi'}}); - expect(isValid).not.toHaveBeenCalled(); - }); + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + }); - it('should pass when a string\'s length is equal', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 'bar'}}); - expect(isValid).toHaveBeenCalled(); - }); + it('should pass when a string\'s length is bigger', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 'myValue'}}); + expect(isValid).toHaveBeenCalled(); + }); + + it('should pass with empty string', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: ''}}); + expect(isValid).toHaveBeenCalled(); + }) + + it('should fail with undefined', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: undefined}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with null', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: null}}); + expect(isValid).not.toHaveBeenCalled(); + }); + + it('should fail with a number', function () { + expect(isValid).not.toHaveBeenCalled(); + TestUtils.Simulate.change(input, {target: {value: 123}}); + expect(isValid).not.toHaveBeenCalled(); + }); - it('should pass when a string\'s length is bigger', function () { - expect(isValid).not.toHaveBeenCalled(); - TestUtils.Simulate.change(input, {target: {value: 'myValue'}}); - expect(isValid).toHaveBeenCalled(); }); }); diff --git a/src/validationRules.js b/src/validationRules.js index 0d30179..6634310 100644 --- a/src/validationRules.js +++ b/src/validationRules.js @@ -1,4 +1,8 @@ -module.exports = { +var isExisty = function (value) { + return value !== null && value !== undefined; +}; + +var validations = { isDefaultRequiredValue: function (values, value) { return value === undefined || value === ''; }, @@ -6,7 +10,7 @@ module.exports = { return !!value; }, matchRegexp: function (values, value, regexp) { - return !!value && !!value.match(regexp); + return isExisty(value) && regexp.test(value); }, isUndefined: function (values, value) { return value === undefined; @@ -15,7 +19,7 @@ module.exports = { return value === ''; }, isEmail: function (values, value) { - return !value || value.match(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i); + return validations.matchRegexp(values, value, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i); }, isTrue: function (values, value) { return value === true; @@ -24,7 +28,7 @@ module.exports = { return value === false; }, isNumeric: function (values, value) { - if (!value) { + if (!isExisty(value)) { return false; } if (typeof value === 'number') { @@ -45,10 +49,10 @@ module.exports = { return value && /^[a-zA-Z\s]+$/.test(value); }, isSpecialWords: function (values, value) { - return !value || value.match(/^[a-zA-Z\s\u00C0-\u017F]+$/); + return !value || /^[a-zA-Z\s\u00C0-\u017F]+$/.test(value); }, isLength: function (values, value, length) { - return value && value.length === length; + return isExisty(value) && value.length === length; }, equals: function (values, value, eql) { return value == eql; @@ -57,9 +61,11 @@ module.exports = { return value == values[field]; }, maxLength: function (values, value, length) { - return value && value.length && value.length <= length; + return isExisty(value) && value.length <= length; }, minLength: function (values, value, length) { - return value && value.length && value.length >= length; + return isExisty(value) && value.length >= length; } }; + +module.exports = validations;