Added emaiul test

This commit is contained in:
Sebastian Seedorf
2020-05-27 12:52:25 +02:00
parent d0cea00ff4
commit 9a46e52f93
3 changed files with 110 additions and 27 deletions

2
mod.ts
View File

@@ -6,7 +6,7 @@ export {
Validatable, Validatable,
ArraySymbol, ArraySymbol,
} from "./Validator.ts"; } from "./Validator.ts";
export { isString } from "./validators/string.ts"; export { isString, isUrl, isEmail } from "./validators/string.ts";
export { isNumber, isInteger } from "./validators/number.ts"; export { isNumber, isInteger } from "./validators/number.ts";
export { isArray } from "./validators/array.ts"; export { isArray } from "./validators/array.ts";
export { or } from "./validators/logic.ts"; export { or } from "./validators/logic.ts";

View File

@@ -1,4 +1,4 @@
import { isString, isURL } from "./string.ts"; import { isString, isUrl, isEmail } from "./string.ts";
import { validate } from "../mod.ts"; import { validate } from "../mod.ts";
import { import {
assertEquals, assertEquals,
@@ -35,20 +35,24 @@ Deno.test("isString (no match)", async () => {
} }
}); });
Deno.test("isURL (match)", async () => { Deno.test("isUrl (match)", async () => {
const values = [ const values = [
"http://google.com", "http://google.com",
"http://10.1.1.1", "http://10.1.1.1",
"http://10.1.1.254", "http://10.1.1.254",
"http://223.255.255.254", "http://223.255.255.254",
" data:,Hello World!" " data:,Hello World!",
]; ];
for (const value of values) { for (const value of values) {
assertEquals(await validate(value, isURL({allowLocal: true, allowDataUrl: true})), [], value); assertEquals(
await validate(value, isUrl({ allowLocal: true, allowDataUrl: true })),
[],
"" + value,
);
} }
}); });
Deno.test("isURL (no match)", async () => { Deno.test("isUrl (no match)", async () => {
const values = [ const values = [
"invalid", "invalid",
"http://0.0.0.0", "http://0.0.0.0",
@@ -56,9 +60,67 @@ Deno.test("isURL (no match)", async () => {
"http://10.1.1.255", "http://10.1.1.255",
"http://224.1.1.1", "http://224.1.1.1",
"http://1.1.1.1.1", "http://1.1.1.1.1",
" data:,Hello World!" " data:,Hello World!",
]; ];
for (const value of values) { for (const value of values) {
assertNotEquals(await validate(value, isURL({allowLocal: true})), [], value); assertNotEquals(
await validate(value, isUrl({ allowLocal: true })),
[],
"" + value,
);
}
});
Deno.test("isEmail (match)", async () => {
const values = [
"email@example.com",
"firstname.lastname@example.com",
"email@subdomain.example.com",
"firstname+lastname@example.com",
"email@123.123.123.123",
"email@[123.123.123.123]",
"1234567890@example.com",
"234567890@example.com",
"email@example-one.com",
"_______@example.com",
"email@example.name",
"email@example.museum",
"email@example.co.jp",
"firstname-lastname@example.com",
];
for (const value of values) {
assertEquals(
await validate(value, isEmail()),
[],
"" + value,
);
}
});
Deno.test("isEmail (no match)", async () => {
const values = [
"",
1,
"foo§@bar.baz",
"#@%^%#$@#$@#.com",
"@example.com",
"Joe Smith <email@example.com>",
"email.example.com",
"email@example@example.com",
".email@example.com",
"email.@example.com",
"email..email@example.com",
"あいうえお@example.com",
"email@example.com (Joe Smith)",
"email@example",
"email@-example.com",
"email@example..com",
"Abc..123@example.com",
];
for (const value of values) {
assertNotEquals(
await validate(value, isEmail()),
[],
"" + value,
);
} }
}); });

View File

@@ -21,7 +21,7 @@ export function isString(): Validator {
* *
* @param param Options * @param param Options
*/ */
export function isURL( export function isUrl(
{ {
protocols = ["http", "https"], protocols = ["http", "https"],
allowDataUrl = false, allowDataUrl = false,
@@ -31,7 +31,7 @@ export function isURL(
allowDomain = true, allowDomain = true,
allowBasicAuth = false, allowBasicAuth = false,
allowPort = true, allowPort = true,
allowRecourcePath = true allowRecourcePath = true,
}: { }: {
protocols?: string[] | null; protocols?: string[] | null;
allowDataUrl?: boolean; allowDataUrl?: boolean;
@@ -45,19 +45,18 @@ export function isURL(
} = {}, } = {},
): Validator { ): Validator {
return { return {
type: "isURL", type: "isUrl",
extends: [isString()], extends: [isString()],
check: (value: any) => { check: (value: any) => {
if (value === null || value === undefined) return; if (value === null || value === undefined) return;
if (allowUrl) { if (allowUrl) {
let regex = "^"; let regex = "^";
// protocol identifier (optional) // protocol identifier (optional)
// short syntax // still required // short syntax // still required
if (protocols) { if (protocols) {
regex += `(?:(?:(?:${protocols.join("|")}):)?\\/\\/)` regex += `(?:(?:(?:${protocols.join("|")}):)?\\/\\/)`;
} else { } else {
regex += `(?:(?:(?:[a-z]+):)?\/\/)` regex += `(?:(?:(?:[a-z]+):)?\/\/)`;
} }
// user:pass BasicAuth (optional) // user:pass BasicAuth (optional)
if (allowBasicAuth) { if (allowBasicAuth) {
@@ -71,8 +70,8 @@ export function isURL(
} }
if (allowIp) { if (allowIp) {
regex += "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + regex += "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))"; "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))";
} }
if (allowIp || allowDomain) { if (allowIp || allowDomain) {
regex += "|"; // [hostname] ip end / domain start regex += "|"; // [hostname] ip end / domain start
@@ -81,25 +80,24 @@ export function isURL(
// host & domain names, may end with dot // host & domain names, may end with dot
// can be replaced by a shortest alternative // can be replaced by a shortest alternative
// (?![-_])(?:[-\\w\\u00a1-\\uffff]{0,63}[^-_]\\.)+ // (?![-_])(?:[-\\w\\u00a1-\\uffff]{0,63}[^-_]\\.)+
regex += regex += "(?:" +
"(?:" + "(?:" +
"(?:" + "[a-z0-9\\u00a1-\\uffff]" +
"[a-z0-9\\u00a1-\\uffff]" + "[a-z0-9\\u00a1-\\uffff_-]{0,62}" +
"[a-z0-9\\u00a1-\\uffff_-]{0,62}" + ")?" +
")?" + "[a-z0-9\\u00a1-\\uffff]\\." +
"[a-z0-9\\u00a1-\\uffff]\\." +
")+" + ")+" +
// TLD identifier name, may end with dot // TLD identifier name, may end with dot
"(?:[a-z\\u00a1-\\uffff]{2,}\\.?)" "(?:[a-z\\u00a1-\\uffff]{2,}\\.?)";
} }
regex += ")"; // [hostname] end regex += ")"; // [hostname] end
if (allowPort) { if (allowPort) {
// port number (optional) // port number (optional)
regex += "(?::\\d{2,5})?" regex += "(?::\\d{2,5})?";
} }
if (allowRecourcePath) { if (allowRecourcePath) {
// resource path (optional) // resource path (optional)
regex += "(?:[/?#]\\S*)?" regex += "(?:[/?#]\\S*)?";
} }
regex += "$"; regex += "$";
if (value.match(new RegExp(regex, "i"))) { if (value.match(new RegExp(regex, "i"))) {
@@ -107,15 +105,38 @@ export function isURL(
} }
} }
if (allowDataUrl) { if (allowDataUrl) {
const regex = /^\s*data:([a-z]+\/[a-z]+(;[a-z\-]+\=[a-z\-]+)?)?(;base64)?,[a-z0-9\!\$\&\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i; const regex =
/^\s*data:([a-z]+\/[a-z]+(;[a-z\-]+\=[a-z\-]+)?)?(;base64)?,[a-z0-9\!\$\&\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i;
if (value.match(regex)) { if (value.match(regex)) {
return; return;
} }
} }
return { }; return {};
}, },
message: (value: any, args?: Args) => { message: (value: any, args?: Args) => {
return `This value is not a valid URL.`; return `This value is not a valid URL.`;
}, },
}; };
} }
/**
* https://stackoverflow.com/questions/201323/how-to-validate-an-email-address-using-a-regular-expression
*/
export function isEmail(): Validator {
return {
type: "isEmail",
extends: [isString()],
check: (value: any) => {
if (value === null || value === undefined) return;
const regex =
/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i;
if (value.match(regex)) {
return;
}
return {};
},
message: (value: any, args?: Args) => {
return `This value has to be an email address.`;
},
};
}