diff --git a/API.md b/API.md index 1a31266..44e2f2e 100644 --- a/API.md +++ b/API.md @@ -659,18 +659,36 @@ Returns true if the value is the boolean true ``` Returns true if the value is the boolean false -**isNumeric** -```html - -``` -Returns true if string only contains numbers - **isAlpha** ```html ``` Returns true if string is only letters +**isNumeric** +```html + +``` +Returns true if string only contains numbers. Examples: 42; -3.14 + +**isAlphanumeric** +```html + +``` +Returns true if string only contains letters or numbers + +**isInt** +```html + +``` +Returns true if string represents integer value. Examples: 42; -12; 0 + +**isFloat** +```html + +``` +Returns true if string represents float value. Examples: 42; -3.14; 1e3 + **isWords** ```html diff --git a/specs/Rules-isAlpha-spec.js b/specs/Rules-isAlpha-spec.js index 5d795d7..c851430 100644 --- a/specs/Rules-isAlpha-spec.js +++ b/specs/Rules-isAlpha-spec.js @@ -47,7 +47,7 @@ describe('Rules: isAlpha', function () { it('should pass with a string is only latin letters', pass('myValue')); - it('should fail with a string with numbers', fail('myValue 42')); + it('should fail with a string with numbers', fail('myValue42')); it('should pass with an undefined', pass(undefined)); diff --git a/specs/Rules-isAlphanumeric-spec.js b/specs/Rules-isAlphanumeric-spec.js new file mode 100644 index 0000000..b7a6bc9 --- /dev/null +++ b/specs/Rules-isAlphanumeric-spec.js @@ -0,0 +1,62 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isAlphanumeric', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with a string is only latin letters', pass('myValue')); + + it('should pass with a string with numbers', pass('myValue42')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with an empty string', pass('')); + + it('should pass with a number', pass(42)); + + it('should fail with a non alpha and number symbols', fail('!@#$%^&*()')); + +}); diff --git a/specs/Rules-isFloat-spec.js b/specs/Rules-isFloat-spec.js new file mode 100644 index 0000000..138c68c --- /dev/null +++ b/specs/Rules-isFloat-spec.js @@ -0,0 +1,68 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isFloat', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with an empty string', pass('')); + + it('should fail with an unempty string', fail('myValue')); + + it('should pass with a number as string', pass('+42')); + + it('should fail with a number as string with not digits', fail('42 as an answer')); + + it('should pass with an int', pass(42)); + + it('should pass with a float', pass(Math.PI)); + + it('should pass with a float in science notation', pass('-1e3')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with a zero', pass(0)); + +}); diff --git a/specs/Rules-isInt-spec.js b/specs/Rules-isInt-spec.js new file mode 100644 index 0000000..17cf42c --- /dev/null +++ b/specs/Rules-isInt-spec.js @@ -0,0 +1,68 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isInt', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with an empty string', pass('')); + + it('should fail with an unempty string', fail('myValue')); + + it('should pass with a number as string', pass('+42')); + + it('should fail with a number as string with not digits', fail('42 as an answer')); + + it('should pass with an int', pass(42)); + + it('should fail with a float', fail(Math.PI)); + + it('should fail with a float in science notation', fail('-1e3')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with a zero', pass(0)); + +}); diff --git a/specs/Rules-isNumeric-spec.js b/specs/Rules-isNumeric-spec.js index f7b1938..94bd4f0 100644 --- a/specs/Rules-isNumeric-spec.js +++ b/specs/Rules-isNumeric-spec.js @@ -57,6 +57,8 @@ describe('Rules: isNumeric', function () { it('should pass with a float', pass(Math.PI)); + it('should fail with a float in science notation', fail('-1e3')); + it('should pass with an undefined', pass(undefined)); it('should pass with a null', pass(null)); diff --git a/src/validationRules.js b/src/validationRules.js index 9b5f527..f6c0e95 100644 --- a/src/validationRules.js +++ b/src/validationRules.js @@ -38,16 +38,25 @@ var validations = { if (typeof value === 'number') { return true; } - return validations.matchRegexp(values, value, /^[-+]?(\d*[.])?\d+$/); + return validations.matchRegexp(values, value, /^[-+]?(?:\d*[.])?\d+$/); }, isAlpha: function (values, value) { - return validations.matchRegexp(values, value, /^[a-zA-Z]+$/); + return validations.matchRegexp(values, value, /^[A-Z]+$/i); + }, + isAlphanumeric: function (values, value) { + return validations.matchRegexp(values, value, /^[0-9A-Z]+$/i); + }, + isInt: function (values, value) { + return validations.matchRegexp(values, value, /^(?:[-+]?(?:0|[1-9]\d*))$/); + }, + isFloat: function (values, value) { + return validations.matchRegexp(values, value, /^(?:[-+]?(?:\d+))?(?:\.\d*)?(?:[eE][\+\-]?(?:\d+))?$/); }, isWords: function (values, value) { - return validations.matchRegexp(values, value, /^[a-zA-Z\s]+$/); + return validations.matchRegexp(values, value, /^[A-Z\s]+$/i); }, isSpecialWords: function (values, value) { - return validations.matchRegexp(values, value, /^[a-zA-Z\s\u00C0-\u017F]+$/); + return validations.matchRegexp(values, value, /^[A-Z\s\u00C0-\u017F]+$/i); }, isLength: function (values, value, length) { return !isExisty(value) || isEmpty(value) || value.length === length;