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;