From 4e483e44b70df5b65ef15aab3547bf698235b128 Mon Sep 17 00:00:00 2001 From: Tiago Palte Date: Tue, 2 Jan 2024 21:47:02 -0300 Subject: [PATCH] Implements phone validator --- README.md | 5 +-- phone.go | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++ phone_test.go | 67 ++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 phone.go create mode 100644 phone_test.go diff --git a/README.md b/README.md index dd8c1f4..b9de597 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ portuguese. BR Doc é um pacote para validação, tanto do formato quanto dos dígitos, de documentos brasileiros, como CPF, CNPJ, CEP, CNH, PIS/PASEP, RENAVAM, placa -veicular e RG (só SP e RJ). +veicular e RG (só SP e RJ), telefone e celular. Aceito PRs de todas as formas. Está permitido escrever em português, também. :) @@ -33,6 +33,7 @@ Principais funções: - `func IsMercosulPlate(doc string) bool` - `func IsCNS(doc string) bool` - `func IsRG(doc string, uf FederativeUnit) bool` +- `func IsPhone(phone string) (isValid bool, uf FederativeUnit)` ## Coisas a fazer @@ -43,6 +44,7 @@ Principais funções: - [x] validação de RENAVAM (obrigado @leogregianin!) - [x] validação de placa veicular - [x] validação de CNS (obrigado @renatosuero!) +- [x] validação de telefone e celular (obrigado @tiagompalte!) - [ ] validação de RG - [x] SP (obrigado @robas!) - [x] RJ (obrigado @robas!) @@ -59,7 +61,6 @@ submitted for inclusion in the work by you shall be in the public domain, without any additional terms or conditions. [1]: ./LICENSE - [badge-1-img]: https://img.shields.io/github/license/paemuri/brdoc?style=flat-square [badge-1-link]: https://github.com/paemuri/brdoc/blob/master/LICENSE [badge-2-img]: https://img.shields.io/badge/go.dev-reference-007d9c?style=flat-square&logo=go&logoColor=white diff --git a/phone.go b/phone.go new file mode 100644 index 0000000..ee3d621 --- /dev/null +++ b/phone.go @@ -0,0 +1,99 @@ +package brdoc + +import "regexp" + +var cellPhoneRegexp = regexp.MustCompile(`^(?:(?:\+|00)?(55)\s?)?(?:\(?([1-9][0-9])\)?\s?)(?:((?:9\s?\d|[6789]{1})\d{3})(?:(\-|\s|\.))?(\d{4}))$`) +var residencialPhoneRegexp = regexp.MustCompile(`^(?:(?:\+|00)?(55)\s?)?(?:\(?([1-9][0-9])\)?\s?)(?:((?:\s?\d|[2345]{1})\d{3})(?:(\-|\s|\.))?(\d{4}))$`) + +var mapDDD = map[string]FederativeUnit{ + "61": DF, + "62": GO, + "64": GO, + "65": MT, + "66": MT, + "67": MS, + "82": AL, + "71": BA, + "73": BA, + "74": BA, + "75": BA, + "77": BA, + "85": CE, + "88": CE, + "98": MA, + "99": MA, + "83": PB, + "81": PE, + "87": PE, + "86": PI, + "89": PI, + "84": RN, + "79": SE, + "68": AC, + "96": AP, + "92": AM, + "97": AM, + "91": PA, + "93": PA, + "94": PA, + "69": RO, + "95": RR, + "63": TO, + "27": ES, + "28": ES, + "31": MG, + "32": MG, + "33": MG, + "34": MG, + "35": MG, + "37": MG, + "38": MG, + "21": RJ, + "22": RJ, + "24": RJ, + "11": SP, + "12": SP, + "13": SP, + "14": SP, + "15": SP, + "16": SP, + "17": SP, + "18": SP, + "19": SP, + "41": PR, + "42": PR, + "43": PR, + "44": PR, + "45": PR, + "46": PR, + "51": RS, + "53": RS, + "54": RS, + "55": RS, + "47": SC, + "48": SC, + "49": SC, +} + +// IsPhone verifies if `phone` is a phone number valid and return UF from DDD. +func IsPhone(phone string) (isValid bool, uf FederativeUnit) { + if !cellPhoneRegexp.MatchString(phone) && !residencialPhoneRegexp.MatchString(phone) { + isValid = false + return + } + + cellPhoneGroups := cellPhoneRegexp.FindStringSubmatch(phone) + residencialPhoneGroups := residencialPhoneRegexp.FindStringSubmatch(phone) + var groups []string + + if cellPhoneGroups == nil { + groups = residencialPhoneGroups + } else { + groups = cellPhoneGroups + } + + groupDDD := 2 + uf, isValid = mapDDD[groups[groupDDD]] + + return +} diff --git a/phone_test.go b/phone_test.go new file mode 100644 index 0000000..71e09c7 --- /dev/null +++ b/phone_test.go @@ -0,0 +1,67 @@ +package brdoc + +import "testing" + +func TestIsPhone(t *testing.T) { + t.Parallel() + + for i, tc := range []struct { + name string + expectedValid bool + expectedUf FederativeUnit + v string + }{ + {"Valid_ShouldReturnTrueUfSP", true, SP, "+55(11)999999999"}, + {"Valid_ShouldReturnTrueUfSP", true, SP, "55(11)999999999"}, + {"Valid_ShouldReturnTrueUfPR", true, PR, "(41)999999999"}, + {"Valid_ShouldReturnTrueUfDF", true, DF, "(61)32222222"}, + {"Valid_ShouldReturnTrueUfAC", true, AC, "(68) 99988-1234"}, + {"Valid_ShouldReturnTrueUfPE", true, PE, "8198988888"}, + {"Valid_ShouldReturnTrueUfPE", true, PE, "558198988888"}, + {"Valid_ShouldReturnFalseUfAC", true, SP, "12 9999-9999"}, + {"InvalidDDI_ShouldReturnFalseUfAC", false, AC, "+01(11)999999999"}, + {"InvalidDDD_ShouldReturnFalseUfAC_1", false, AC, "(01)999999999"}, + {"InvalidDDD_ShouldReturnFalseUfAC_2", false, AC, "55(01)999999999"}, + {"InvalidPattern_ShouldReturnFalseUfAC_1", true, SP, "11 9999 9999"}, + {"InvalidPattern_ShouldReturnFalseUfAC_2", true, SP, "11 9 9999 9999"}, + {"InvalidPattern_ShouldReturnFalseUfAC_3", false, AC, "11.99999.9999"}, + {"InvalidPattern_ShouldReturnFalseUfAC_4", false, AC, "11 99999/9999"}, + {"InvalidPattern_ShouldReturnFalseUfAC_5", false, AC, "(11)9999999-99"}, + {"Teste_novo_1", true, SP, "+55 (11) 3340-2800"}, + {"Teste_novo_2", true, SP, "+55 (12) 3340 2801"}, + {"Teste_novo_3", true, SP, "+55 (13) 33402802"}, + {"Teste_novo_4", true, SP, "+55 (14)3340-2803"}, + {"Teste_novo_5", true, SP, "+55 (15)33402804"}, + {"Teste_novo_6", true, SP, "+55 (16)3340 2805"}, + {"Teste_novo_7", true, SP, "+55 (17) 9 6340-2806"}, + {"Teste_novo_8", true, SP, "+55 (18) 9 6340 2807"}, + {"Teste_novo_9", true, SP, "+55 (19) 9 63402808"}, + {"Teste_novo_10", true, RJ, "+55 (21)9 7340-2809"}, + {"Teste_novo_11", true, RJ, "+55 (22)9 73402810"}, + {"Teste_novo_12", true, RJ, "+55 (24)9 7340 2811"}, + {"Teste_novo_13", true, ES, "+55 (27) 98340-2812"}, + {"Teste_novo_14", true, ES, "+55 (28) 98340 2813"}, + {"Teste_novo_15", true, MG, "+55 (31) 983402814"}, + {"Teste_novo_16", true, MG, "+55 (32)99340-2815"}, + {"Teste_novo_17", true, MG, "+55 (33)993402816"}, + {"Teste_novo_18", true, MG, "+55 (34)99340 2817"}, + {"Teste_novo_19", true, MG, "+55 35 3340-2818"}, + {"Teste_novo_20", true, MG, "+55 37 33402819"}, + {"Teste_novo_21", true, MG, "+55 38 3340 2820"}, + {"Teste_novo_22", true, PR, "+55 41 9 6340-2821"}, + {"Teste_novo_23", true, PR, "+55 42 9 63402822"}, + {"Teste_novo_24", true, PR, "+55 43 9 6340 2823"}, + {"Teste_novo_25", true, PR, "+55 44 97340-2824"}, + {"Teste_novo_26", true, PR, "+55 45 973402825"}, + {"Teste_novo_27", true, PR, "+55 46 97340 2826"}, + } { + tC := tc + t.Run(testName(i, tC.name), func(t *testing.T) { + t.Parallel() + t.Helper() + isValid, uf := IsPhone(tC.v) + assertEqual(t, tC.expectedValid, isValid) + assertEqual(t, tC.expectedUf, uf) + }) + } +}