From 3c610289d44cb2f7fab5822b60961e466c6c5c14 Mon Sep 17 00:00:00 2001 From: Alan Lira Date: Sun, 22 Sep 2019 11:10:34 -0300 Subject: [PATCH] Develop (#14) * perf: decrease tests on phone validation (#12) * perf: decrease tests on phone validation * Refactor way to customize Validators * Change way to handle custom validation options * Update appveyor.yml * upgrade packages --- Readme.md | 2 + appveyor.yml | 2 +- global.json | 2 +- src/Flunt.Br/Document/Phone.cs | 206 ------------------ .../BankContractExtensions.cs | 4 +- .../PersonContractExtensions.cs | 6 +- .../Extensions/PhoneContractExtensions.cs | 39 ++++ .../StreetContractExtensions.cs | 4 +- src/Flunt.Br/Flunt.Br.csproj | 2 +- .../Validation/PhoneContractExtensions.cs | 33 --- src/Flunt.Br/{Document => Validations}/Cep.cs | 11 +- .../{Document => Validations}/Cnpj.cs | 5 +- src/Flunt.Br/{Document => Validations}/Cpf.cs | 21 +- .../{Document => Validations}/CreditCard.cs | 46 ++-- .../Interfaces/IValidate.cs} | 2 +- .../Validations/PhoneValidations/Phone.cs | 83 +++++++ .../PhoneValidationOptions.cs | 12 + .../VoterDocument.cs | 16 +- tests/Flunt.Br.Tests/BankContractTest.cs | 2 +- tests/Flunt.Br.Tests/Flunt.Br.Tests.csproj | 8 +- tests/Flunt.Br.Tests/PersonContractTest.cs | 4 +- tests/Flunt.Br.Tests/PhoneContractTest.cs | 98 +++++++-- tests/Flunt.Br.Tests/StreetContractTest.cs | 2 +- 23 files changed, 271 insertions(+), 339 deletions(-) delete mode 100644 src/Flunt.Br/Document/Phone.cs rename src/Flunt.Br/{Validation => Extensions}/BankContractExtensions.cs (87%) rename src/Flunt.Br/{Validation => Extensions}/PersonContractExtensions.cs (95%) create mode 100644 src/Flunt.Br/Extensions/PhoneContractExtensions.cs rename src/Flunt.Br/{Validation => Extensions}/StreetContractExtensions.cs (87%) delete mode 100644 src/Flunt.Br/Validation/PhoneContractExtensions.cs rename src/Flunt.Br/{Document => Validations}/Cep.cs (52%) rename src/Flunt.Br/{Document => Validations}/Cnpj.cs (94%) rename src/Flunt.Br/{Document => Validations}/Cpf.cs (64%) rename src/Flunt.Br/{Document => Validations}/CreditCard.cs (71%) rename src/Flunt.Br/{Document/interfaces/Validate.cs => Validations/Interfaces/IValidate.cs} (68%) create mode 100644 src/Flunt.Br/Validations/PhoneValidations/Phone.cs create mode 100644 src/Flunt.Br/Validations/PhoneValidations/PhoneValidationOptions.cs rename src/Flunt.Br/{Document => Validations}/VoterDocument.cs (90%) diff --git a/Readme.md b/Readme.md index 30bb5fa..5416baa 100644 --- a/Readme.md +++ b/Readme.md @@ -39,6 +39,7 @@ This lib enables in your validation contracts this methods: .IsCnpj(company.document, "Document", "Invalid document") .IsPhone(company.phone, "Phone", "Invalid phone") .IsCellPhone(person.cellphone, "Phone", "Invalid cellphone") + .IsNewFormatCellPhone(person.cellphone, "Phone", "Invalid cellphone") .IsCep(company.Cep, "Cep", "Invalid Cep") ``` @@ -52,6 +53,7 @@ Essa biblioteca possibilita esses métodos em seus Validation Contracts: .IsCnpj(empresa.documento, "Documento", "Documento inválido") .IsPhone(empresa.telefone, "Telefone", "Telefone inválido") .IsCellPhone(pessoa.telefone, "Telefone", "Telefone inválido") + .IsNewFormatCellPhone(pessoa.telefone, "Telefone", "Telefone inválido") .IsCep(company.Cep, "Cep", "Cep Inválido"); ``` diff --git a/appveyor.yml b/appveyor.yml index 64ad200..eedfd1f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ version: 1.0.{build} -image: Visual Studio 2017 Preview +image: Ubuntu1804 dotnet_csproj: patch: true file: '**\*.csproj' diff --git a/global.json b/global.json index 005601e..5db2779 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "projects": [ "src", "test" ], "sdk": { - "version": "2.2.102" + "version": "2.2.401" } } \ No newline at end of file diff --git a/src/Flunt.Br/Document/Phone.cs b/src/Flunt.Br/Document/Phone.cs deleted file mode 100644 index c175845..0000000 --- a/src/Flunt.Br/Document/Phone.cs +++ /dev/null @@ -1,206 +0,0 @@ -using System.Text.RegularExpressions; -using Flunt.Br.Document.interfaces; -using System.Collections.Generic; -using System.Linq; - -namespace Flunt.Br.Document -{ - internal class Phone : IValidate - { - - public Phone() - { - this.format = null; - } - public Phone(string numberFormat) - { - var regex = new Regex(@"[0-9]+"); - var phonePattern = Regex.Replace(numberFormat, @"[0-9,?]+", m => { - var optionalsCount = m.Value.Split(new char[] { '?' }).Length - 1; - var stringRegex = ""; - if(optionalsCount != 0) - { - stringRegex += (m.Length - optionalsCount); - stringRegex += ","; - stringRegex += (optionalsCount + (m.Length - optionalsCount)); - } - else - { - stringRegex = m.Length.ToString(); - } - return $@"\d{{{stringRegex}}}"; - }); - phonePattern = @"^" + Regex.Replace(phonePattern, @"(?:(?(1)(?!))(\+)|(?(2)(?!))(\()|(?(3)(?!))(\)))+", m => $@"\{m.Value}").Replace("-", @"\-").Replace(" ", @"\s") + "$"; - this.format = new Regex(phonePattern); - } - - public bool Validate(string value) - { - if (this.format != null) - { - return this.format.IsMatch(value); - } - else - { - foreach (var regex in this.ListPhoneValidFormat) - { - if (regex.IsMatch(value)) return true; - } - return false; - } - } - - private IReadOnlyCollection ListPhoneValidFormat - { - get - { - return new List - { - //(99) 9999-9999 - new Regex(@"^\(\d{2}\)\s\d{4}\-\d{4}"), - //(99) 99999-9999 - new Regex(@"^\(\d{2}\)\s\d{5}-\d{4}$"), - //(99)9999-9999 - new Regex(@"^\(\d{2}\)\d{4}-\d{4}$"), - //(99)99999-9999 - new Regex(@"^\(\d{2}\)\d{5}-\d{4}$"), - //999999-9999 - new Regex(@"^\d{6}\-\d{4}$"), - //9999999-9999 - new Regex(@"^\d{7}\-\d{4}$"), - //99999999999 - new Regex(@"^\d{11}$"), - //9999999999 - new Regex(@"^\d{10}$"), - //99 99999 9999 - new Regex(@"^\d{2}\s\d{5}\s\d{4}$"), - //99 9999 9999 - new Regex(@"^\d{2}\s\d{4}\s\d{4}$"), - //55(99) 9999-9999 - new Regex(@"^\d{2}\(\d{2}\)\s\d{4}\-\d{4}$"), - //55(99) 99999-9999 - new Regex(@"^\d{2}\(\d{2}\)\s\d{5}\-\d{4}$"), - //55(99)99999-9999 - new Regex(@"^\d{2}\(\d{2}\)\d{5}\-\d{4}$"), - //55(99)9999-9999 - new Regex(@"^\d{2}\(\d{2}\)\d{4}\-\d{4}$"), - //55999999-9999 - new Regex(@"^\d{2}\d{2}\d{4}\-\d{4}$"), - //5599 99999 9999 - new Regex(@"^\d{4}\s\d{5}\s\d{4}$"), - //5599 9999 9999 - new Regex(@"^\d{4}\s\d{4}\s\d{4}$"), - //5599 9999 9999 - new Regex(@"^\d{4}\s\d{4}\s\d{4}$"), - //55 (99) 9999-9999 - new Regex(@"^\d{2}\s\(\d{2}\)\s\d{4}\-\d{4}$"), - //55 (99) 9999 9999 - new Regex(@"^\d{2}\s\(\d{2}\)\s\d{4}\s\d{4}$"), - //55 (99) 99999-9999 - new Regex(@"^\d{2}\s\(\d{2}\)\s\d{5}\-\d{4}$"), - //55 (99) 999999999 - new Regex(@"^\d{2}\s\(\d{2}\)\s\d{5}\d{4}$"), - //55 (99)999999999 - new Regex(@"^\d{2}\s\(\d{2}\)\d{5}\d{4}$"), - //55 (99)99999999 - new Regex(@"^\d{2}\s\(\d{2}\)\d{4}\d{4}$"), - //55 (99)99999-9999 - new Regex(@"^\d{2}\s\(\d{2}\)\d{5}\-\d{4}$"), - //55 (99)9999-9999 - new Regex(@"^\d{2}\s\(\d{2}\)\d{4}\-\d{4}$"), - //55 999999-9999 - new Regex(@"^\d{2}\s\d{2}\d{5}\-\d{4}$"), - //55 9999999-9999 - new Regex(@"^\d{2}\s\d{2}\d{5}\-\d{4}$"), - //55 9999999 9999 - new Regex(@"^\d{2}\s\d{2}\d{5}\s\d{4}$"), - //55 999999-9999 - new Regex(@"^\d{2}\s\d{2}\d{4}\-\d{4}$"), - //55 999999 9999 - new Regex(@"^\d{2}\s\d{2}\d{4}\s\d{4}$"), - //55 9999999999 - new Regex(@"^\d{2}\s\d{2}\d{4}\d{4}$"), - //55 9999999999 - new Regex(@"^\d{2}\s\d{2}\d{4}\d{4}$"), - //559999999999 - new Regex(@"^\d{2}\d{2}\d{4}\d{4}$"), - //559999999999 - new Regex(@"^\d{2}\d{2}\d{4}\d{4}$"), - //559999999-9999 - new Regex(@"^\d{2}\d{2}\d{5}\-\d{4}$"), - //5599999999999 - new Regex(@"^\d{2}\d{2}\d{5}\d{4}$"), - //559999999999 - new Regex(@"^\d{2}\d{2}\d{4}\d{4}$"), - //55 99999999999 - new Regex(@"^\d{2}\s\d{2}\d{5}\d{4}$"), - //55 99 9999 9999 - new Regex(@"^\d{2}\s\d{2}\s\d{4}\s\d{4}$"), - //55 99 99999 9999 - new Regex(@"^\d{2}\s\d{2}\s\d{5}\s\d{4}$"), - //+55(99) 9999-9999 - new Regex(@"^\+\d{2}\(\d{2}\)\s\d{4}\-\d{4}$"), - //+55(99) 99999-9999 - new Regex(@"^\+\d{2}\(\d{2}\)\s\d{5}\-\d{4}$"), - //+55(99)99999-9999 - new Regex(@"^\+\d{2}\(\d{2}\)\d{5}\-\d{4}$"), - //+55(99)9999-9999 - new Regex(@"^\+\d{2}\(\d{2}\)\d{4}\-\d{4}$"), - //+55999999-9999 - new Regex(@"^\+\d{2}\d{2}\d{4}\-\d{4}$"), - //+559999999-9999 - new Regex(@"^\+\d{2}\d{2}\d{5}\-\d{4}$"), - //+5599 99999 9999 - new Regex(@"^\+\d{4}\s\d{5}\s\d{4}$"), - //+5599 9999 9999 - new Regex(@"^\+\d{4}\s\d{4}\s\d{4}$"), - //+5599 9999 9999 - new Regex(@"^\+\d{4}\s\d{4}\s\d{4}$"), - //+55 (99) 9999-9999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\s\d{4}\-\d{4}$"), - //+55 (99) 9999 9999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\s\d{4}\s\d{4}$"), - //+55 (99) 999999999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\s\d{5}\d{4}$"), - //+55 (99)999999999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\d{5}\d{4}$"), - //+55 (99)99999999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\d{4}\d{4}$"), - //+55 (99)99999-9999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\d{5}\-\d{4}$"), - //+55 (99)9999-9999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\d{4}\-\d{4}$"), - //+55 999999-9999 - new Regex(@"^\+\d{2}\s\d{2}\d{5}\-\d{4}$"), - //+55 9999999-9999 - new Regex(@"^\+\d{2}\s\d{2}\d{5}\-\d{4}$"), - //+55 9999999 9999 - new Regex(@"^\+\d{2}\s\d{2}\d{5}\s\d{4}$"), - //+55 999999-9999 - new Regex(@"^\+\d{2}\s\d{2}\d{4}\-\d{4}$"), - //+55 999999 9999 - new Regex(@"^\+\d{2}\s\d{2}\d{4}\s\d{4}$"), - //+55 9999999999 - new Regex(@"^\+\d{2}\s\d{2}\d{4}\d{4}$"), - //+55 9999999999 - new Regex(@"^\+\d{2}\s\d{2}\d{4}\d{4}$"), - //+559999999999 - new Regex(@"^\+\d{2}\d{2}\d{4}\d{4}$"), - //+559999999999 - new Regex(@"^\+\d{2}\d{2}\d{4}\d{4}$"), - //+55 99999999999 - new Regex(@"^\+\d{2}\s\d{2}\d{5}\d{4}$"), - //+55 99 99999 9999 - new Regex(@"^\+\d{2}\s\d{2}\s\d{5}\s\d{4}$"), - //+55 99 9999 9999 - new Regex(@"^\+\d{2}\s\d{2}\s\d{4}\s\d{4}$"), - //+55 (99) 99999-9999 - new Regex(@"^\+\d{2}\s\(\d{2}\)\s\d{5}\-\d{4}$"), - }; - } - - } - - private Regex format { get; set; } - } -} \ No newline at end of file diff --git a/src/Flunt.Br/Validation/BankContractExtensions.cs b/src/Flunt.Br/Extensions/BankContractExtensions.cs similarity index 87% rename from src/Flunt.Br/Validation/BankContractExtensions.cs rename to src/Flunt.Br/Extensions/BankContractExtensions.cs index cc6f198..501c3cb 100644 --- a/src/Flunt.Br/Validation/BankContractExtensions.cs +++ b/src/Flunt.Br/Extensions/BankContractExtensions.cs @@ -1,7 +1,7 @@ -using Flunt.Br.Document; +using Flunt.Br.Validations; using Flunt.Validations; -namespace Flunt.Br.Validation +namespace Flunt.Br.Extensions { public static partial class ContractExtensions { diff --git a/src/Flunt.Br/Validation/PersonContractExtensions.cs b/src/Flunt.Br/Extensions/PersonContractExtensions.cs similarity index 95% rename from src/Flunt.Br/Validation/PersonContractExtensions.cs rename to src/Flunt.Br/Extensions/PersonContractExtensions.cs index 2c73fa4..fc92947 100644 --- a/src/Flunt.Br/Validation/PersonContractExtensions.cs +++ b/src/Flunt.Br/Extensions/PersonContractExtensions.cs @@ -1,8 +1,8 @@ -using System; -using Flunt.Br.Document; +using Flunt.Br.Validations; using Flunt.Validations; +using System; -namespace Flunt.Br.Validation +namespace Flunt.Br.Extensions { public static partial class ContractExtensions { diff --git a/src/Flunt.Br/Extensions/PhoneContractExtensions.cs b/src/Flunt.Br/Extensions/PhoneContractExtensions.cs new file mode 100644 index 0000000..66a19f2 --- /dev/null +++ b/src/Flunt.Br/Extensions/PhoneContractExtensions.cs @@ -0,0 +1,39 @@ +using Flunt.Br.Validations.PhoneValidations; +using Flunt.Validations; + +namespace Flunt.Br.Extensions +{ + public static partial class ContractExtensions + { + public static Contract IsPhone(this Contract contract, string value, string property, string message) + { + if (string.IsNullOrEmpty(value) || !new Phone().Validate(value)) + contract.AddNotification(property, message); + return contract; + } + + public static Contract IsPhone(this Contract contract, string value, string numberFormat, string property, string message, bool strictNineDigit = false) + { + var result = new Phone(new PhoneValidationOptions { Format = numberFormat, StrictNineDigit = strictNineDigit }).Validate(value); + if (string.IsNullOrEmpty(value) || !result) + contract.AddNotification(property, message); + return contract; + } + + public static Contract IsCellPhone(this Contract contract, string value, string property, string message, bool strictNineDigit = false) + { + var result = new Phone(new PhoneValidationOptions { StrictNineDigit = strictNineDigit, CellPhonesOnly = true }).Validate(value); + if (string.IsNullOrEmpty(value) || !result) + contract.AddNotification(property, message); + return contract; + } + + public static Contract IsNewFormatCellPhone(this Contract contract, string value, string property, string message) + { + var result = new Phone(new PhoneValidationOptions { StrictNineDigit = true, CellPhonesOnly = true }).Validate(value); + if (string.IsNullOrEmpty(value) || !result) + contract.AddNotification(property, message); + return contract; + } + } +} \ No newline at end of file diff --git a/src/Flunt.Br/Validation/StreetContractExtensions.cs b/src/Flunt.Br/Extensions/StreetContractExtensions.cs similarity index 87% rename from src/Flunt.Br/Validation/StreetContractExtensions.cs rename to src/Flunt.Br/Extensions/StreetContractExtensions.cs index 2570907..28cebdb 100644 --- a/src/Flunt.Br/Validation/StreetContractExtensions.cs +++ b/src/Flunt.Br/Extensions/StreetContractExtensions.cs @@ -1,7 +1,7 @@ -using Flunt.Br.Document; +using Flunt.Br.Validations; using Flunt.Validations; -namespace Flunt.Br.Validation +namespace Flunt.Br.Extensions { public static partial class ContractExtensions { diff --git a/src/Flunt.Br/Flunt.Br.csproj b/src/Flunt.Br/Flunt.Br.csproj index 1b51932..1451e49 100644 --- a/src/Flunt.Br/Flunt.Br.csproj +++ b/src/Flunt.Br/Flunt.Br.csproj @@ -14,6 +14,6 @@ Validation;Flunt.Br;Flunt;Cnpj;Cpf;Telefone;Cep - + \ No newline at end of file diff --git a/src/Flunt.Br/Validation/PhoneContractExtensions.cs b/src/Flunt.Br/Validation/PhoneContractExtensions.cs deleted file mode 100644 index ad0f6cb..0000000 --- a/src/Flunt.Br/Validation/PhoneContractExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Flunt.Br.Document; -using Flunt.Validations; - -namespace Flunt.Br.Validation -{ - public static partial class ContractExtensions - { - public static Contract IsPhone(this Contract contract, string value, string property, string message) - { - if (string.IsNullOrEmpty(value) || !new Phone().Validate(value)) - contract.AddNotification(property, message); - return contract; - } - - public static Contract IsPhone(this Contract contract, string value, string numberFormat, string property, string message) - { - if (string.IsNullOrEmpty(value) || !new Phone(numberFormat).Validate(value)) - contract.AddNotification(property, message); - return contract; - } - - - public static Contract IsCellPhone(this Contract contract, string value, string property, string message) - { - if (string.IsNullOrEmpty(value) || !new Phone("(99) ?9999-9999").Validate(value)) - if (string.IsNullOrEmpty(value) || !new Phone("(99)?9999-9999").Validate(value)) - contract.AddNotification(property, message); - - return contract; - } - - } -} \ No newline at end of file diff --git a/src/Flunt.Br/Document/Cep.cs b/src/Flunt.Br/Validations/Cep.cs similarity index 52% rename from src/Flunt.Br/Document/Cep.cs rename to src/Flunt.Br/Validations/Cep.cs index 89abcc0..140ad08 100644 --- a/src/Flunt.Br/Document/Cep.cs +++ b/src/Flunt.Br/Validations/Cep.cs @@ -1,16 +1,17 @@ +using Flunt.Br.Document.Interfaces; using System.Text.RegularExpressions; -using Flunt.Br.Document.interfaces; -namespace Flunt.Br.Document +namespace Flunt.Br.Validations { internal class Cep : IValidate { public bool Validate(string value) { - if (value.IndexOf("-") > 0) + if (value.IndexOf("-") > 0) + { return new Regex(@"^\d{5}-\d{3}$", RegexOptions.Singleline).Match(value).Success; - else - return new Regex(@"^\d{8}$", RegexOptions.Singleline).Match(value).Success; + } + return new Regex(@"^\d{8}$", RegexOptions.Singleline).Match(value).Success; } } } \ No newline at end of file diff --git a/src/Flunt.Br/Document/Cnpj.cs b/src/Flunt.Br/Validations/Cnpj.cs similarity index 94% rename from src/Flunt.Br/Document/Cnpj.cs rename to src/Flunt.Br/Validations/Cnpj.cs index ae9c5b8..b0928fc 100644 --- a/src/Flunt.Br/Document/Cnpj.cs +++ b/src/Flunt.Br/Validations/Cnpj.cs @@ -1,7 +1,6 @@ -using Flunt.Br.Document.interfaces; -using System; +using Flunt.Br.Document.Interfaces; -namespace Flunt.Br.Document +namespace Flunt.Br.Validations { internal class Cnpj : IValidate { diff --git a/src/Flunt.Br/Document/Cpf.cs b/src/Flunt.Br/Validations/Cpf.cs similarity index 64% rename from src/Flunt.Br/Document/Cpf.cs rename to src/Flunt.Br/Validations/Cpf.cs index 95e0a56..b315955 100644 --- a/src/Flunt.Br/Document/Cpf.cs +++ b/src/Flunt.Br/Validations/Cpf.cs @@ -1,13 +1,13 @@ -using Flunt.Br.Document.interfaces; +using Flunt.Br.Document.Interfaces; -namespace Flunt.Br.Document +namespace Flunt.Br.Validations { internal class Cpf : IValidate { public bool Validate(string value) { - int[] multiplicador1 = new int[9] { 10, 9, 8, 7, 6, 5, 4, 3, 2 }; - int[] multiplicador2 = new int[10] { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2 }; + var multiplicador1 = new int[9] { 10, 9, 8, 7, 6, 5, 4, 3, 2 }; + var multiplicador2 = new int[10] { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2 }; string tempCpf; string digito; int soma; @@ -22,21 +22,16 @@ public bool Validate(string value) for (int i = 0; i < 9; i++) soma += int.Parse(tempCpf[i].ToString()) * multiplicador1[i]; resto = soma % 11; - if (resto < 2) - resto = 0; - else - resto = 11 - resto; + resto = resto < 2 ? 0 : 11 - resto; digito = resto.ToString(); tempCpf = tempCpf + digito; soma = 0; + for (int i = 0; i < 10; i++) soma += int.Parse(tempCpf[i].ToString()) * multiplicador2[i]; resto = soma % 11; - if (resto < 2) - resto = 0; - else - resto = 11 - resto; - digito = digito + resto.ToString(); + resto = resto < 2 ? 0 : 11 - resto; + digito = digito + resto; return value.EndsWith(digito); } } diff --git a/src/Flunt.Br/Document/CreditCard.cs b/src/Flunt.Br/Validations/CreditCard.cs similarity index 71% rename from src/Flunt.Br/Document/CreditCard.cs rename to src/Flunt.Br/Validations/CreditCard.cs index a75f9bc..557f43b 100644 --- a/src/Flunt.Br/Document/CreditCard.cs +++ b/src/Flunt.Br/Validations/CreditCard.cs @@ -1,17 +1,34 @@ -using Flunt.Br.Document.interfaces; +using Flunt.Br.Document.Interfaces; using System.Linq; using System.Text.RegularExpressions; -namespace Flunt.Br.Document +namespace Flunt.Br.Validations { internal class CreditCard : IValidate { + private static bool IsValidLuhnn(string val) + { + var valSum = 0; + var currentProcNum = 0; + + for (int i = val.Length - 1; i >= 0; i--) + { + if (!int.TryParse(val.Substring(i, 1), out int currentDigit)) + return false; + + currentProcNum = currentDigit << (1 + i & 1); + valSum += (currentProcNum > 9 ? currentProcNum - 9 : currentProcNum); + } + + return (valSum > 0 && valSum % 10 == 0); + } + public bool Validate(string value) { value = new Regex(@"['\""&,\\]|\s{2,}").Replace(value, "").Trim(); if (!new Regex(@"[0-9]+").IsMatch(value)) return false; - - if (value.All(char.IsDigit) == false) + + if (!value.All(char.IsDigit)) { return false; } @@ -19,27 +36,8 @@ public bool Validate(string value) { return false; } - - return IsValidLuhnn(value); - } - - private bool IsValidLuhnn(string val) - { - int currentDigit; - int valSum = 0; - int currentProcNum = 0; - - for (int i = val.Length - 1; i >= 0; i--) - { - if (!int.TryParse(val.Substring(i, 1), out currentDigit)) - return false; - currentProcNum = currentDigit << (1 + i & 1); - valSum += (currentProcNum > 9 ? currentProcNum - 9 : currentProcNum); - - } - - return (valSum > 0 && valSum % 10 == 0); + return IsValidLuhnn(value); } } } \ No newline at end of file diff --git a/src/Flunt.Br/Document/interfaces/Validate.cs b/src/Flunt.Br/Validations/Interfaces/IValidate.cs similarity index 68% rename from src/Flunt.Br/Document/interfaces/Validate.cs rename to src/Flunt.Br/Validations/Interfaces/IValidate.cs index f62f22d..85adfd2 100644 --- a/src/Flunt.Br/Document/interfaces/Validate.cs +++ b/src/Flunt.Br/Validations/Interfaces/IValidate.cs @@ -1,4 +1,4 @@ -namespace Flunt.Br.Document.interfaces +namespace Flunt.Br.Document.Interfaces { internal interface IValidate { diff --git a/src/Flunt.Br/Validations/PhoneValidations/Phone.cs b/src/Flunt.Br/Validations/PhoneValidations/Phone.cs new file mode 100644 index 0000000..66ae667 --- /dev/null +++ b/src/Flunt.Br/Validations/PhoneValidations/Phone.cs @@ -0,0 +1,83 @@ +using Flunt.Br.Document.Interfaces; +using System.Text.RegularExpressions; + +namespace Flunt.Br.Validations.PhoneValidations +{ + internal class Phone : IValidate + { + private readonly PhoneValidationOptions _validationOptions; + + private static readonly Regex _defaultFormat = new Regex(@"^(?:(?:\+?55)?[ .-]*\(?0?[1-9][0-9]\)?)[ .-]?(?:(?:(?:9[ .-]*)?[0-9]{4})[ .-]*[0-9]{4})$"); + + public Phone(PhoneValidationOptions validationOptions) + { + _validationOptions = validationOptions; + } + + public Phone() + { + _validationOptions = new PhoneValidationOptions(); + } + + public bool Validate(string value) + { + if (string.IsNullOrEmpty(value)) + { + return false; + } + + Regex formatToApply; + if (_validationOptions.Format != null) + { + formatToApply = HandleCustomFormat(_validationOptions.Format); + + return formatToApply.IsMatch(value); + } + + formatToApply = SetFormatBaseOnOptions(_validationOptions); + return formatToApply.IsMatch(value); + } + + private static Regex HandleCustomFormat(string customFormat) + { + var regex = new Regex(@"[0-9]+"); + var phonePattern = Regex.Replace(customFormat, @"[0-9,?]+", m => { + var optionalsCount = m.Value.Split(new char[] { '?' }).Length - 1; + var stringRegex = ""; + if (optionalsCount != 0) + { + stringRegex += (m.Length - optionalsCount); + stringRegex += ","; + stringRegex += (optionalsCount + (m.Length - optionalsCount)); + } + else + { + stringRegex = m.Length.ToString(); + } + return $@"\d{{{stringRegex}}}"; + }); + phonePattern = @"^" + Regex.Replace(phonePattern, @"(?:(?(1)(?!))(\+)|(?(2)(?!))(\()|(?(3)(?!))(\)))+", m => $@"\{m.Value}").Replace("-", @"\-").Replace(" ", @"\s") + "$"; + return new Regex(phonePattern); + } + + private static Regex SetFormatBaseOnOptions(PhoneValidationOptions phoneOptions) + { + if (phoneOptions.CellPhonesOnly && phoneOptions.StrictNineDigit) + { + return new Regex(@"^(?:(?:\+?55)?[ .-]*\(?0?[1-9][0-9]\)?)[ .-]?(?:(?:(?:9[ .-]*)[0-9]{4})[ .-]*[0-9]{4})$"); + } + + if (phoneOptions.CellPhonesOnly && !phoneOptions.StrictNineDigit) + { + return new Regex(@"^(?:(?:\+?55)?[ .-]*\(?0?[1-9][0-9]\)?)[ .-]?(?:(?:(?:9[ .-]*)[0-9]{4}|[8-9][0-9]{3})[ .-]*[0-9]{4})$"); + } + + if (!phoneOptions.CellPhonesOnly && phoneOptions.StrictNineDigit) + { + return new Regex(@"^(?:(?:\+?55)?[ .-]*\(?0?[1-9][0-9]\)?)[ .-]?(?:(?:9[ .-]*[0-9]{4}|[1-7][0-9]{3})[ .-]*[0-9]{4})$"); + } + + return _defaultFormat; + } + } +} \ No newline at end of file diff --git a/src/Flunt.Br/Validations/PhoneValidations/PhoneValidationOptions.cs b/src/Flunt.Br/Validations/PhoneValidations/PhoneValidationOptions.cs new file mode 100644 index 0000000..a60a9f6 --- /dev/null +++ b/src/Flunt.Br/Validations/PhoneValidations/PhoneValidationOptions.cs @@ -0,0 +1,12 @@ +using Flunt.Br.Document.Interfaces; +using System.Text.RegularExpressions; + +namespace Flunt.Br.Validations.PhoneValidations +{ + internal class PhoneValidationOptions + { + public bool StrictNineDigit { get; set; } + public bool CellPhonesOnly { get; set; } + public string Format { get; set; } + } +} diff --git a/src/Flunt.Br/Document/VoterDocument.cs b/src/Flunt.Br/Validations/VoterDocument.cs similarity index 90% rename from src/Flunt.Br/Document/VoterDocument.cs rename to src/Flunt.Br/Validations/VoterDocument.cs index fa42fe1..408ede8 100644 --- a/src/Flunt.Br/Document/VoterDocument.cs +++ b/src/Flunt.Br/Validations/VoterDocument.cs @@ -1,9 +1,7 @@ -using System; +using Flunt.Br.Document.Interfaces; using System.Text.RegularExpressions; -using Flunt.Br.Document.interfaces; -using System.Collections.Generic; -namespace Flunt.Br.Document +namespace Flunt.Br.Validations { internal class VoterDocument : IValidate { @@ -68,17 +66,9 @@ public bool Validate(string value) { return true; } - else - { - return false; - } - - } - else - { return false; } - + return false; } } } \ No newline at end of file diff --git a/tests/Flunt.Br.Tests/BankContractTest.cs b/tests/Flunt.Br.Tests/BankContractTest.cs index f94f8fc..2702f8f 100644 --- a/tests/Flunt.Br.Tests/BankContractTest.cs +++ b/tests/Flunt.Br.Tests/BankContractTest.cs @@ -1,4 +1,4 @@ -using Flunt.Br.Validation; +using Flunt.Br.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Flunt.Validations; diff --git a/tests/Flunt.Br.Tests/Flunt.Br.Tests.csproj b/tests/Flunt.Br.Tests/Flunt.Br.Tests.csproj index d48c2d3..e1b3faa 100644 --- a/tests/Flunt.Br.Tests/Flunt.Br.Tests.csproj +++ b/tests/Flunt.Br.Tests/Flunt.Br.Tests.csproj @@ -5,10 +5,10 @@ false - - - - + + + + diff --git a/tests/Flunt.Br.Tests/PersonContractTest.cs b/tests/Flunt.Br.Tests/PersonContractTest.cs index 9799d00..65b8a50 100644 --- a/tests/Flunt.Br.Tests/PersonContractTest.cs +++ b/tests/Flunt.Br.Tests/PersonContractTest.cs @@ -1,6 +1,6 @@ -using Flunt.Br.Validation; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Flunt.Br.Extensions; using Flunt.Validations; +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Flunt.Br.Tests { diff --git a/tests/Flunt.Br.Tests/PhoneContractTest.cs b/tests/Flunt.Br.Tests/PhoneContractTest.cs index ad430bf..5cc59b1 100644 --- a/tests/Flunt.Br.Tests/PhoneContractTest.cs +++ b/tests/Flunt.Br.Tests/PhoneContractTest.cs @@ -1,4 +1,4 @@ -using Flunt.Br.Validation; +using Flunt.Br.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Flunt.Validations; @@ -16,8 +16,8 @@ public class PhoneContractTest [DataRow("(99)9956999-9999")] [DataRow("59-9999")] [DataRow("999-9999")] - [DataRow("9995996666399999")] [DataRow("999999999")] + [DataRow("9995996666399999")] [DataRow("99 922999 9963699")] [DataRow("99 9994599 922999")] [DataRow("55(99) 9999-992299")] @@ -59,46 +59,65 @@ public void IsPhone_Invalid(string value) } [TestMethod] - [DataRow("(99) 9999-9999")] + [DataRow("(99) 3999-9999")] [DataRow("(99) 99999-9999")] - [DataRow("(99)9999-9999")] [DataRow("(99)99999-9999")] - [DataRow("999999-9999")] + [DataRow("993999-9999")] [DataRow("9999999-9999")] - [DataRow("9999999999")] + [DataRow("9939999999")] [DataRow("99999999999")] - [DataRow("99 9999 9999")] + [DataRow("99 3999 9999")] [DataRow("99 99999 9999")] - [DataRow("55(99) 9999-9999")] + [DataRow("55(99) 3999-9999")] [DataRow("55(99) 99999-9999")] - [DataRow("55(99)9999-9999")] + [DataRow("55(99)3999-9999")] [DataRow("55(99)99999-9999")] - [DataRow("55999999-9999")] + [DataRow("55993999-9999")] [DataRow("559999999-9999")] - [DataRow("559999999999")] + [DataRow("559939999999")] [DataRow("5599999999999")] - [DataRow("5599 9999 9999")] + [DataRow("5599 3999 9999")] [DataRow("5599 99999 9999")] - [DataRow("55 (99) 9999-9999")] + [DataRow("55 (99) 3999-9999")] [DataRow("55 (99) 99999-9999")] - [DataRow("55 (99)9999-9999")] + [DataRow("55 (99)3999-9999")] [DataRow("55 (99)99999-9999")] - [DataRow("55 999999-9999")] + [DataRow("55 993999-9999")] [DataRow("55 9999999-9999")] - [DataRow("55 9999999999")] + [DataRow("55 9939999999")] [DataRow("55 99999999999")] - [DataRow("55 99 9999 9999")] + [DataRow("55 99 3999 9999")] [DataRow("55 99 99999 9999")] - [DataRow("+55 (99) 9999-9999")] + [DataRow("+55 (99) 3999-9999")] [DataRow("+55 (99) 99999-9999")] - [DataRow("+55 (99)9999-9999")] + [DataRow("+55 (99)3999-9999")] [DataRow("+55 (99)99999-9999")] - [DataRow("+55 999999-9999")] + [DataRow("+55 993999-9999")] [DataRow("+55 9999999-9999")] - [DataRow("+55 9999999999")] + [DataRow("+55 9939999999")] [DataRow("+55 99999999999")] - [DataRow("+55 99 9999 9999")] + [DataRow("+55 99 3999 9999")] [DataRow("+55 99 99999 9999")] + [DataRow("(99) 9999-9999")] + [DataRow("999999-9999")] + [DataRow("9999999999")] + [DataRow("99 9999 9999")] + [DataRow("55(99) 9999-9999")] + [DataRow("55(99)9999-9999")] + [DataRow("55999999-9999")] + [DataRow("559999999999")] + [DataRow("5599 9999 9999")] + [DataRow("55 (99) 9999-9999")] + [DataRow("55 (99)9999-9999")] + [DataRow("(99)9999-9999")] + [DataRow("55 999999-9999")] + [DataRow("55 9999999999")] + [DataRow("55 99 9999 9999")] + [DataRow("+55 (99) 9999-9999")] + [DataRow("+55 (99)9999-9999")] + [DataRow("+55 999999-9999")] + [DataRow("+55 9999999999")] + [DataRow("+55 99 9999 9999")] public void IsPhone_Valid(string value) { var right = new Contract() @@ -108,7 +127,7 @@ public void IsPhone_Valid(string value) [TestMethod] [DataRow("(99) 9999-9999", "(99) ?9999-9999")] - [DataRow("(99) 99999-9999", "(99) ?9999-9999")] + [DataRow("(99) 99999-9999", "(99) ?9999-9999")] [DataRow("(99) 9999-9999", "(99) 9999-9999")] [DataRow("(99) 99999-9999", "(99) 99999-9999")] [DataRow("(99)9999-9999", "(99)9999-9999")] @@ -207,6 +226,8 @@ public void IsPhoneFormat_Invalid(string value, string formatNumber) [TestMethod] [DataRow("456456444456")] + [DataRow("(45)3333-3333")] + [DataRow("(99) 8 9999-9999")] [DataRow(null)] public void IsCellPhone_Invalid(string value) { @@ -216,12 +237,43 @@ public void IsCellPhone_Invalid(string value) [TestMethod] [DataRow("(45)99999-9999")] + [DataRow("+55(99)99999-9999")] + [DataRow("+55(99)9-9999-9999")] + [DataRow("+55 (99) 9999-9999")] + [DataRow("+55 (99) 9999-9999")] + public void IsCellPhone_Valid(string value) { var right = new Contract().IsCellPhone(value, "cellphone", "Invalid cellphone"); Assert.IsTrue(right.Valid); } + [TestMethod] + [DataRow("4599999999")] + [DataRow("+55(99)9999-9999")] + [DataRow("+55(99)9999-9999")] + [DataRow("+55 (99) 9999-9999")] + [DataRow("+55 (99) 9999-9999")] + [DataRow("+55 (99) 3333-4444")] + + public void IsNewCellPhone_Invalid(string value) + { + var wrong = new Contract().IsNewFormatCellPhone(value, "cellphone", "Invalid cellphone"); + Assert.IsFalse(wrong.Valid); + } + + [TestMethod] + [DataRow("45999999999")] + [DataRow("+55(99)99999-9999")] + [DataRow("+55(99)9.9999-9999")] + [DataRow("+55 (99) 9-9999-9999")] + [DataRow("+55 (99) 9 9999-9999")] + + public void IsNewCellPhone_Valid(string value) + { + var right = new Contract().IsNewFormatCellPhone(value, "cellphone", "Invalid cellphone"); + Assert.IsTrue(right.Valid); + } } } \ No newline at end of file diff --git a/tests/Flunt.Br.Tests/StreetContractTest.cs b/tests/Flunt.Br.Tests/StreetContractTest.cs index ca186b3..3ff8534 100644 --- a/tests/Flunt.Br.Tests/StreetContractTest.cs +++ b/tests/Flunt.Br.Tests/StreetContractTest.cs @@ -1,4 +1,4 @@ -using Flunt.Br.Validation; +using Flunt.Br.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Flunt.Validations;