Repository: icebob/fastest-validator
Pull request #45 (2018-11-09 16:50:03)

Add charset checker to string rules
This PR add the following checkers:
- **alpha** (Return true if the value is a string with only alphabetic characters)
```javascript
const schema = {
  x: {type: 'string', alpha: true}
}
```
- **numeric** (Return true if the value is a string with only numeric characters)
```javascript
const schema = {
  x: {type: 'string', numeric: true}
}
```

- **alphanum** (Return true if the value is a string with only alphanumeric characters)
```javascript
const schema = {
  x: {type: 'string', alphanum: true}
}
```

- **alphadash** (Return true if the value is a string with alphabetic characters and dashes)
```javascript
const schema = {
  x: {type: 'string', alphadash: true}
}
```


Patch:
diff --git a/lib/messages.js b/lib/messages.js
index a5b1ddc..cef228b 100644
--- a/lib/messages.js
+++ b/lib/messages.js
@@ -11,6 +11,10 @@ module.exports = {
 	stringPattern: "The '{field}' field fails to match the required pattern!",
 	stringContains: "The '{field}' field must contain the '{expected}' text!",
 	stringEnum: "The '{field}' field does not match any of the allowed values!",
+	stringNumeric: "The '{field}' field must be a numeric string",
+	stringAlpha: "The '{field}' field must be an alphabetic string",
+	stringAlphanum: "The '{field}' field must be an alphanumeric string",
+	stringAlphadash: "The '{field}' field must be an alphadash string",
 
 	number: "The '{field}' field must be a number!",
 	numberMin: "The '{field}' field must be greater than or equal to {expected}!",
diff --git a/lib/rules/string.js b/lib/rules/string.js
index 05a6b9c..2f3b5b2 100644
--- a/lib/rules/string.js
+++ b/lib/rules/string.js
@@ -1,17 +1,15 @@
 "use strict";
 
+const NUMERIC_PATTERN = /^-?[0-9]\d*(\.\d+)?$/;
+const ALPHA_PATTERN = /^[a-zA-Z]+$/;
+const ALPHANUM_PATTERN = /^[a-zA-Z0-9]+$/;
+const ALPHADASH_PATTERN = /^[a-zA-Z0-9_\-]+$/;
+
 module.exports = function checkString(value, schema) {
 	if (typeof value !== "string") {
 		return this.makeError("string");
 	}
 
-	/* TODO: charset
-	 	alpha: /^[a-zA-Z]+$/
-		alphaNum: /^[a-zA-Z0-9]+$/
-		alphaDash: /^[a-zA-Z0-9_\-]+$/
-
-	*/
-
 	const valueLength = value.length;
 
 	if (schema.empty === false && valueLength === 0) {
@@ -44,5 +42,21 @@ module.exports = function checkString(value, schema) {
 		return this.makeError("stringEnum", schema.enum);
 	}
 
+	if (schema.numeric === true && !NUMERIC_PATTERN.test(value) ) {
+		return this.makeError("stringNumeric", "A numeric string", value);
+	}
+
+	if(schema.alpha === true && !ALPHA_PATTERN.test(value)) {
+		return this.makeError("stringAlpha", "An alphabetic string", value);
+	}
+
+	if(schema.alphanum === true && !ALPHANUM_PATTERN.test(value)) {
+		return this.makeError("stringAlphanum", "An alphanumeric string", value);
+	}
+
+	if(schema.alphadash === true && !ALPHADASH_PATTERN.test(value)) {
+		return this.makeError("stringAlphadash", "An alphadash string", value);
+	}
+
 	return true;
 };
\ No newline at end of file


Test patch:
diff --git a/test/rules/string.spec.js b/test/rules/string.spec.js
index 140fdc5..12c700b 100644
--- a/test/rules/string.spec.js
+++ b/test/rules/string.spec.js
@@ -83,4 +83,56 @@ describe("Test checkString", () => {
 		expect(check("female", s)).toEqual(true);
 	});
 
+	it("check numeric string", () => {
+		const s = {type: "string", numeric: true};
+
+		expect(check("123.1s0", s)).toEqual({type: "stringNumeric", expected: "A numeric string", actual: "123.1s0"});
+		expect(check("x", s)).toEqual({type: "stringNumeric", expected: "A numeric string", actual: "x"});
+		expect(check("", s)).toEqual({type: "stringNumeric", expected: "A numeric string", actual: ""});
+		expect(check(" ", s)).toEqual({type: "stringNumeric", expected: "A numeric string", actual: " "});
+
+		expect(check("123", s)).toEqual(true);
+		expect(check("-123", s)).toEqual(true);
+		expect(check("123.10", s)).toEqual(true);
+		expect(check("-123.10", s)).toEqual(true);
+	});
+
+	it("check alphabetic string", () => {
+		const s = {type: "string", alpha: true};
+
+		expect(check("3312", s)).toEqual({type: "stringAlpha", expected: "An alphabetic string", actual: "3312"});
+		expect(check("h3ll0", s)).toEqual({type: "stringAlpha", expected: "An alphabetic string", actual: "h3ll0"});
+		expect(check("us3rnam3", s)).toEqual({type: "stringAlpha", expected: "An alphabetic string", actual: "us3rnam3"});
+
+		expect(check("username", s)).toEqual(true);
+		expect(check("hello", s)).toEqual(true);
+		expect(check("elliot", s)).toEqual(true);
+
+	});
+
+	it("check alphanumeric string", () => {
+		const s = {type: "string", alphanum: true};
+
+		expect(check("hello_world", s)).toEqual({type: "stringAlphanum", expected: "An alphanumeric string", actual: "hello_world"});
+		expect(check("print()", s)).toEqual({type: "stringAlphanum", expected: "An alphanumeric string", actual: "print()"});
+		expect(check("user.name", s)).toEqual({type: "stringAlphanum", expected: "An alphanumeric string", actual: "user.name"});
+
+		expect(check("p4ssword", s)).toEqual(true);
+		expect(check("anarchy77", s)).toEqual(true);
+	});
+
+	it("check alphadash string", () => {
+		const s = {type: "string", alphadash: true};
+
+		expect(check("hello world", s)).toEqual({type: "stringAlphadash", expected: "An alphadash string", actual: "hello world"});
+		expect(check("hello.world", s)).toEqual({type: "stringAlphadash", expected: "An alphadash string", actual: "hello.world"});
+		expect(check("spaced string", s)).toEqual({type: "stringAlphadash", expected: "An alphadash string", actual: "spaced string"});
+
+
+		expect(check("hello_world", s)).toEqual(true);
+		expect(check("dashed_string", s)).toEqual(true);
+
+	});
+
+
 });