diff --git a/README.md b/README.md index 652a4ab..78b1cfe 100644 --- a/README.md +++ b/README.md @@ -38,33 +38,29 @@ Basic Usage Import the library into your project and start generating mocks: ```go -// specific -translations.SetLanguage("ptbr") - -addr, err := address.GenerateAddress() +// Create a Mocker instance for Portuguese +ptMocker, err := mocai.NewMocker("ptbr", true) if err != nil { - log.Println(err) + log.Fatal(err) } -addr.Street // returns street name -``` +// Access mock data +fmt.Printf("Address: %s\n", ptMocker.Address.Street) +fmt.Printf("Phone: %s\n", ptMocker.Phone.Number) -```go -// mocker -m, err := mocai.NewMocker("ptbr") +// For data in a different language, create a new instance +enMocker, err := mocai.NewMocker("en", true) if err != nil { - log.Println(err) + log.Fatal(err) } - -m.Address().Street // returns street name -m.Phone().Number // returns phone number ``` -### Examples -The ***examples*** folder contains samples of how to use the library, organized by approach: -- `specific/`: Examples using direct calls to each of Mocaí's mockable entities (e.g., phone.GeneratePhone, etc). +> **Important**: Each Mocker instance is immutable and contains data in the language specified at creation time. To get data in a different language, always create a new instance using NewMocker. + +### Examples +The ***examples*** folder contains samples of how to use the library: -- `mocker/`: Example using a main entry point `mocai.NewMocker("ptbr")` to generate mocks in a fluent and simplified way. +- `mocker/`: Example using a main entry point `mocai.NewMocker(lang string, isFormatted bool)` to generate mocks in a fluent and simplified way. To run an example, navigate to the desired directory and run: ``` diff --git a/docs/localization/pt/README-PT.md b/docs/localization/pt/README-PT.md index b4ed57c..1b12545 100644 --- a/docs/localization/pt/README-PT.md +++ b/docs/localization/pt/README-PT.md @@ -36,34 +36,29 @@ Uso Básico Importe a biblioteca em seu projeto e comece a gerar mocks: ```go -// specific -translations.SetLanguage("ptbr") - -addr, err := address.GenerateAddress() +// Cria uma instância do Mocker para português +ptMocker, err := mocai.NewMocker("ptbr", true) if err != nil { - log.Println(err) + log.Fatal(err) } -addr.Street // retorna o nome da rua -``` +// Acessa os dados mock +fmt.Printf("Endereço: %s\n", ptMocker.Address.Street) +fmt.Printf("Telefone: %s\n", ptMocker.Phone.Number) -```go -// mocker -m, err := mocai.NewMocker("ptbr") +// Para dados em outro idioma, crie uma nova instância +enMocker, err := mocai.NewMocker("en", true) if err != nil { - log.Println(err) + log.Fatal(err) } - -m.Address().Street // retorna o nome da rua -m.Phone().Number // retorna o número de telefone ``` -### Exemplos -O diretório ***examples*** contém exemplos de comoo usar a biblioteca, organizados por abordagem: +> **Importante**: Cada instância do Mocker é imutável e contém dados no idioma especificado no momento da criação. Para obter dados em um idioma diferente, sempre crie uma nova instância usando NewMocker. -- `specific/`: Exemplos usando as funções diretas de cada entidade mockável do Mocaí (`phone.GeneratePhone`, etc). +### Exemplos +O diretório ***examples*** contém exemplos de como usar a biblioteca: -- `mocker/`: Exemplo usando um ponto de entrada principal `mocai.NewMocker("ptbr")` para gerar mocks de maneira fluida e simplificada. +- `mocker/`: Exemplo usando um ponto de entrada principal `mocai.NewMocker(lang string, isFormatted bool)` para gerar mocks de maneira fluida e simplificada. Para executar um exemplo, acesse o diretório desejado e execute: ``` diff --git a/examples/mocker/main.go b/examples/mocker/main.go index fe087cb..054d970 100644 --- a/examples/mocker/main.go +++ b/examples/mocker/main.go @@ -15,21 +15,15 @@ func main() { // Initialize mocai and set a supported language // If the language is not available, the default language pt-BR will be set - m, err := mocai.NewMocker("ptbr") + m, err := mocai.NewMocker("ptbr", true) if err != nil { log.Println(err) } // Generate mock data // You can select which entity attributes to use // by accessing the entity and its fields - m.Person() // m.Person().Age, m.Person().CPF... - m.Address() // m.Address().City, m.Address().Number... - m.Phone() // m.Phone().AreaCode, m.Phone().Number - - // Printing mocks example - addr := m.Address() fmt.Printf("Address: %s, %d - %s, %s (%s) - %s\n", - addr.Street, addr.Number, addr.City, addr.State, addr.UF, addr.ZIP) + m.Address.Street, m.Address.Number, m.Address.City, m.Address.State, m.Address.UF, m.Address.ZIP) fmt.Println(cli.Footer) } diff --git a/examples/specific/main.go b/examples/specific/main.go deleted file mode 100644 index cb0501e..0000000 --- a/examples/specific/main.go +++ /dev/null @@ -1,96 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/brazzcore/mocai/internal/cli" - "github.com/brazzcore/mocai/pkg/mocai/entities/address" - "github.com/brazzcore/mocai/pkg/mocai/entities/certificate" - "github.com/brazzcore/mocai/pkg/mocai/entities/company" - "github.com/brazzcore/mocai/pkg/mocai/entities/national_id" - "github.com/brazzcore/mocai/pkg/mocai/entities/person" - "github.com/brazzcore/mocai/pkg/mocai/entities/phone" - "github.com/brazzcore/mocai/pkg/mocai/entities/vote_registration" - "github.com/brazzcore/mocai/pkg/mocai/translations" -) - -func main() { - // Set the language to pt-BR - translations.SetLanguage("ptbr") - - // Generate mock data - p, err := person.GeneratePerson() - if err != nil { - fmt.Print(err) - return - } - - addr, err := address.GenerateAddress() - if err != nil { - fmt.Print(err) - return - } - - ph, err := phone.GeneratePhone() - if err != nil { - fmt.Print(err) - return - } - - c, err := company.GenerateCompany(false) - if err != nil { - fmt.Print(err) - return - } - - cert, err := certificate.GenerateCertificate(false) - if err != nil { - fmt.Print(err) - return - } - - vr, err := vote_registration.GenerateVoteRegistration(false) - if err != nil { - fmt.Print(err) - return - } - - nid, err := national_id.GenerateNationalID(false) - if err != nil { - fmt.Print(err) - return - } - - fmt.Println(cli.HeaderMain) - fmt.Println(cli.SubHeader) - - fmt.Printf("Person: %s %s, %s, %d years old, CPF: %s\n", - p.FirstNameMale, p.LastName, *p.Gender, p.Age, p.CPF) - - fmt.Printf("RG: %s, State: %s, Issuing Body: %s\n", - nid.BrazilianRG.Number, nid.BrazilianRG.State, nid.BrazilianRG.IssuingBody) - - fmt.Printf("Birth Certificate: %s\n", - cert.BrazilianCertificates.BirthCertificate.CertificateNumber) - - fmt.Printf("Marriage Certificate: %s\n", - cert.BrazilianCertificates.MarriageCertificate.CertificateNumber) - - fmt.Printf("Death Certificate: %s\n", - cert.BrazilianCertificates.DeathCertificate.CertificateNumber) - - fmt.Printf("Company: %s, CNPJ: %s\n", - c.BrazilianCompany.CompanyName, c.BrazilianCompany.CNPJ) - - fmt.Printf("Address: %s, %d - %s, %s (%s) - %s\n", - addr.Street, addr.Number, addr.City, addr.State, addr.UF, addr.ZIP) - - fmt.Printf("Phone: (%s) %s\n", - ph.AreaCode, ph.Number) - - fmt.Printf("Voter Registration Card: Section: %s, Zone: %s, Registration: %s\n", - vr.BrazilianVoteRegistration.Section, vr.BrazilianVoteRegistration.Zone, - vr.BrazilianVoteRegistration.Number) - - fmt.Println(cli.Footer) -} diff --git a/pkg/mocai/entities/address/generator.go b/pkg/mocai/entities/address/generator.go index 118718f..011d5bb 100644 --- a/pkg/mocai/entities/address/generator.go +++ b/pkg/mocai/entities/address/generator.go @@ -23,9 +23,18 @@ type SlicesToCheck struct { err error } +// NewAddress creates and returns a new Address with randomly generated data. +func NewAddress() (*Address, error) { + addr, err := (&Address{}).generateAddress() + if err != nil { + return nil, err + } + return addr, nil +} + // GenerateAddress generates a mock address with random data. // It returns a pointer to an Address and an error if the generation fails. -func GenerateAddress() (*Address, error) { +func (a *Address) generateAddress() (*Address, error) { lang := translations.GetLanguage() // Get the list of streets, cities, states, and ZIP codes diff --git a/pkg/mocai/entities/certificate/countries/brazilian_certificates.go b/pkg/mocai/entities/certificate/countries/brazilian_certificates.go index 6b61c23..1b6279a 100644 --- a/pkg/mocai/entities/certificate/countries/brazilian_certificates.go +++ b/pkg/mocai/entities/certificate/countries/brazilian_certificates.go @@ -47,31 +47,31 @@ type DeathCertificate struct { // BrazilianCertificates represents all brazilian certificates type BrazilianCertificates struct { - BirthCertificate *BirthCertificate - MarriageCertificate *MarriageCertificate - DeathCertificate *DeathCertificate + BirthCertificate BirthCertificate + MarriageCertificate MarriageCertificate + DeathCertificate DeathCertificate } // GenerateBrazilianCertificates generates a valid brazilian certificates // If formatted is true, returns the number with separators (-) // Returns a pointer to BrazilianCertificates and error if any validation fails -func GenerateBrazilianCertificates(formatted bool) (*BrazilianCertificates, error) { +func GenerateBrazilianCertificates(formatted bool) (BrazilianCertificates, error) { createdBirthCertificate, err := generateBirthCertificate(formatted) if err != nil { - return nil, err + return BrazilianCertificates{}, err } createdMarriageCertificate, err := generateMarriageCertificate(formatted) if err != nil { - return nil, err + return BrazilianCertificates{}, err } createdDeathCertificate, err := generateDeathCertificate(formatted) if err != nil { - return nil, err + return BrazilianCertificates{}, err } - createdBrazilianCertificates := &BrazilianCertificates{ + createdBrazilianCertificates := BrazilianCertificates{ BirthCertificate: createdBirthCertificate, MarriageCertificate: createdMarriageCertificate, DeathCertificate: createdDeathCertificate, @@ -84,12 +84,12 @@ func GenerateBrazilianCertificates(formatted bool) (*BrazilianCertificates, erro // If formatted is true, returns the number with separators (-) // certificateType is the type of certificate [1 - for birth certificate, 2 - for marriage certificate, 3 - for death certificate] // Returns a pointer to BaseCertificate and error if any validation fails -func generateCertificate(formatted bool, certificateType int) (*BaseCertificate, error) { +func generateCertificate(formatted bool, certificateType int) (BaseCertificate, error) { // Registry Office // 1. Vital Records Office [6 digits] vitalRecordsOffice := generateRandomNumber(100000, 899999) if vitalRecordsOffice < 0 { - return nil, ErrInvalidVitalRecordsOffice + return BaseCertificate{}, ErrInvalidVitalRecordsOffice } // 2. Archive [2 digits] @@ -107,26 +107,26 @@ func generateCertificate(formatted bool, certificateType int) (*BaseCertificate, // 6. Book number [5 digits] bookNumber := generateRandomNumber(10000, 89999) if bookNumber < 0 { - return nil, ErrInvalidBookNumber + return BaseCertificate{}, ErrInvalidBookNumber } // 7. Page number [3 digits] pageNumber := generateRandomNumber(100, 899) if pageNumber < 0 { - return nil, ErrInvalidPageNumber + return BaseCertificate{}, ErrInvalidPageNumber } // 8. Term number [7 digits] termNumber := generateRandomNumber(1000000, 8999999) if termNumber < 0 { - return nil, ErrInvalidTermNumber + return BaseCertificate{}, ErrInvalidTermNumber } // Number without check digits [30 digits] numberWithoutCheckDigits := fmt.Sprintf("%06d%02d%02d%04d%d%05d%03d%07d", vitalRecordsOffice, archiveCode, serviceType, birthYear, certificateType, bookNumber, pageNumber, termNumber) if len(numberWithoutCheckDigits) != 30 { - return nil, ErrInvalidNumberWithoutCheckDigits + return BaseCertificate{}, ErrInvalidNumberWithoutCheckDigits } // 9. Check digits calculation [2 digits] @@ -139,10 +139,10 @@ func generateCertificate(formatted bool, certificateType int) (*BaseCertificate, } if certificateNumber == "" { - return nil, ErrInvalidCertificate + return BaseCertificate{}, ErrInvalidCertificate } - createdBaseCertificate := &BaseCertificate{ + createdBaseCertificate := BaseCertificate{ VitalRecordsOffice: vitalRecordsOffice, ArchiveCode: archiveCode, ServiceType: serviceType, @@ -159,42 +159,42 @@ func generateCertificate(formatted bool, certificateType int) (*BaseCertificate, } // generateBirthCertificate generates a valid Brazilian birth certificate -func generateBirthCertificate(formatted bool) (*BirthCertificate, error) { +func generateBirthCertificate(formatted bool) (BirthCertificate, error) { base, err := generateCertificate(formatted, brazilianBirthCertificateType) if err != nil { - return nil, err + return BirthCertificate{}, err } - createdBirthCertificate := &BirthCertificate{ - BaseCertificate: *base, + createdBirthCertificate := BirthCertificate{ + BaseCertificate: base, } return createdBirthCertificate, nil } // generateMarriageCertificate generates a valid Brazilian marriage certificate -func generateMarriageCertificate(formatted bool) (*MarriageCertificate, error) { +func generateMarriageCertificate(formatted bool) (MarriageCertificate, error) { base, err := generateCertificate(formatted, brazilianMarriageCertificateType) if err != nil { - return nil, err + return MarriageCertificate{}, err } - createdMarriageCertificate := &MarriageCertificate{ - BaseCertificate: *base, + createdMarriageCertificate := MarriageCertificate{ + BaseCertificate: base, } return createdMarriageCertificate, nil } // generateDeathCertificate generates a valid Brazilian death certificate -func generateDeathCertificate(formatted bool) (*DeathCertificate, error) { +func generateDeathCertificate(formatted bool) (DeathCertificate, error) { base, err := generateCertificate(formatted, brazilianDeathCertificateType) if err != nil { - return nil, err + return DeathCertificate{}, err } - createdDeathCertificate := &DeathCertificate{ - BaseCertificate: *base, + createdDeathCertificate := DeathCertificate{ + BaseCertificate: base, } return createdDeathCertificate, nil diff --git a/pkg/mocai/entities/certificate/generator.go b/pkg/mocai/entities/certificate/generator.go index 780a8b9..c48ac35 100644 --- a/pkg/mocai/entities/certificate/generator.go +++ b/pkg/mocai/entities/certificate/generator.go @@ -1,20 +1,30 @@ package certificate -import "github.com/brazzcore/mocai/pkg/mocai/entities/certificate/countries" +import ( + "github.com/brazzcore/mocai/pkg/mocai/entities/certificate/countries" +) // Certificate represents all certificates available type Certificate struct { - BrazilianCertificates *countries.BrazilianCertificates + BrazilianCertificates countries.BrazilianCertificates +} + +// NewCertificate creates a new Certificate with generated data. +func NewCertificate(isFormatted bool) (*Certificate, error) { + cert, err := (&Certificate{}).generateCertificate(isFormatted) + if err != nil { + return nil, err + } + return cert, nil } // GenerateCertificate generates all certificates available. // If formatted is true, returns the number with separators (-). // Returns a pointer to Certificate and error if any validation fails -func GenerateCertificate(formatted bool) (*Certificate, error) { +func (c *Certificate) generateCertificate(formatted bool) (*Certificate, error) { createdBrazilianCertificates, err := countries.GenerateBrazilianCertificates(formatted) if err != nil { return nil, err } - return &Certificate{BrazilianCertificates: createdBrazilianCertificates}, nil } diff --git a/pkg/mocai/entities/company/countries/brazilian_company.go b/pkg/mocai/entities/company/countries/brazilian_company.go index 4d23328..2461186 100644 --- a/pkg/mocai/entities/company/countries/brazilian_company.go +++ b/pkg/mocai/entities/company/countries/brazilian_company.go @@ -18,7 +18,7 @@ type BrazilianCompany struct { var rng = rand.New(rand.NewSource(time.Now().UnixNano())) -func GenerateBrazilianCompany(formatted bool) (*BrazilianCompany, error) { +func GenerateBrazilianCompany(formatted bool) (BrazilianCompany, error) { lang := translations.GetLanguage() // Get the list of company names @@ -26,7 +26,7 @@ func GenerateBrazilianCompany(formatted bool) (*BrazilianCompany, error) { // Validate data if len(companyNames) == 0 { - return nil, ErrNoCompanyNamesAvailable + return BrazilianCompany{}, ErrNoCompanyNamesAvailable } // Choose a random company name @@ -35,19 +35,19 @@ func GenerateBrazilianCompany(formatted bool) (*BrazilianCompany, error) { // Generate a random CNPJ without a mask cnpj, err := cnpj.GenerateCNPJ(formatted) if err != nil { - return nil, err + return BrazilianCompany{}, err } // Validate required fields if companyName == "" { - return nil, fmt.Errorf("%s: Company Name: %s", ErrGeneratingBrazilianCompany, companyName) + return BrazilianCompany{}, fmt.Errorf("%s: Company Name: %s", ErrGeneratingBrazilianCompany, companyName) } if cnpj == "" { - return nil, fmt.Errorf("%s: CNPJ is empty", ErrGeneratingCNPJ) + return BrazilianCompany{}, fmt.Errorf("%s: CNPJ is empty", ErrGeneratingCNPJ) } - createdCompany := &BrazilianCompany{ + createdCompany := BrazilianCompany{ CompanyName: companyName, CNPJ: cnpj, } diff --git a/pkg/mocai/entities/company/generator.go b/pkg/mocai/entities/company/generator.go index c94ab0f..2fb19ff 100644 --- a/pkg/mocai/entities/company/generator.go +++ b/pkg/mocai/entities/company/generator.go @@ -4,11 +4,20 @@ import "github.com/brazzcore/mocai/pkg/mocai/entities/company/countries" // Company represents a generic company. type Company struct { - BrazilianCompany *countries.BrazilianCompany + BrazilianCompany countries.BrazilianCompany +} + +// NewCompany creates a new Company with generated data. +func NewCompany(isFormatted bool) (*Company, error) { + comp, err := (&Company{}).generateCompany(isFormatted) + if err != nil { + return nil, err + } + return comp, nil } // GenerateCompany generates all companies available. -func GenerateCompany(formatted bool) (*Company, error) { +func (c *Company) generateCompany(formatted bool) (*Company, error) { createdCompanyBrazilian, err := countries.GenerateBrazilianCompany(formatted) if err != nil { return nil, err diff --git a/pkg/mocai/entities/cpf/generator.go b/pkg/mocai/entities/cpf/generator.go index 283b773..0fe9ba1 100644 --- a/pkg/mocai/entities/cpf/generator.go +++ b/pkg/mocai/entities/cpf/generator.go @@ -7,10 +7,23 @@ import ( "time" ) +type CPF struct { + Number string +} + +// NewCPF generates a new CPF number. +func NewCPF(isFormatted bool) (*CPF, error) { + cpf, err := (&CPF{}).generateCPF(isFormatted) + if err != nil { + return nil, err + } + return cpf, nil +} + // GenerateCPF generates a valid CPF number. // If formatted is true, the CPF will be returned in the format xxx.xxx.xxx-xx. // If formatted is false, the CPF will be returned as a plain string of 11 digits. -func GenerateCPF(formatted bool) (string, error) { +func (c *CPF) generateCPF(formatted bool) (*CPF, error) { // Create a local random generator with a unique seed src := rand.NewSource(time.Now().UnixNano()) r := rand.New(src) @@ -28,17 +41,17 @@ func GenerateCPF(formatted bool) (string, error) { digits = append(digits, calculateCheckDigit(digits, 11)) // Convert the digits to a string - cpf := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(digits)), ""), "[]") + cpfNumber := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(digits)), ""), "[]") // Format the CPF if requested if formatted { - if len(cpf) != 11 { - return "", ErrInvalidCPF + if len(cpfNumber) != 11 { + return nil, ErrInvalidCPF } - return cpf[:3] + "." + cpf[3:6] + "." + cpf[6:9] + "-" + cpf[9:], nil + return &CPF{Number: cpfNumber[:3] + "." + cpfNumber[3:6] + "." + cpfNumber[6:9] + "-" + cpfNumber[9:]}, nil } - return cpf, nil + return &CPF{Number: cpfNumber}, nil } // calculateCheckDigit calculates the check digit for a CPF. diff --git a/pkg/mocai/entities/gender/errors.go b/pkg/mocai/entities/gender/errors.go index ffed467..28e4f11 100644 --- a/pkg/mocai/entities/gender/errors.go +++ b/pkg/mocai/entities/gender/errors.go @@ -6,5 +6,6 @@ import "errors" // These errors represent specific failure scenarios and should be wrapped with additional // context when returned. var ( - ErrNoGenders = errors.New("no data available for genders") + ErrNoGenders = errors.New("no data available for genders") + ErrInvalidGender = errors.New("invalid gender") ) diff --git a/pkg/mocai/entities/gender/gender.go b/pkg/mocai/entities/gender/gender.go index 9b1b3c7..788bae1 100644 --- a/pkg/mocai/entities/gender/gender.go +++ b/pkg/mocai/entities/gender/gender.go @@ -6,28 +6,41 @@ import ( "github.com/brazzcore/mocai/pkg/mocai/translations" ) -// Gender represents a person's gender identity. -type Gender string +// Gender represents a person's gender. +type Gender struct { + Identity +} + +// Identity represents a person's gender identity. +type Identity string // Constants for different gender identities. const ( - Male Gender = "male" // Male gender identity - Female Gender = "female" // Female gender identity - NonBinary Gender = "non-binary" // Non-binary gender identity - GenderFluid Gender = "genderfluid" // Genderfluid identity - Agender Gender = "agender" // Agender identity - TwoSpirit Gender = "two-spirit" // Two-Spirit identity (used by some Indigenous peoples) - Other Gender = "other" // Other gender identity + Male Identity = "male" // Male gender identity + Female Identity = "female" // Female gender identity + NonBinary Identity = "non-binary" // Non-binary gender identity + GenderFluid Identity = "genderfluid" // Genderfluid identity + Agender Identity = "agender" // Agender identity + TwoSpirit Identity = "two-spirit" // Two-Spirit identity (used by some Indigenous peoples) + Other Identity = "other" // Other gender identity ) +// NewGender creates a new Gender instance with a randomly generated gender. +func NewGender() (*Gender, error) { + g, err := (&Gender{}).generateRandomGender() + if err != nil { + return nil, err + } + return g, nil +} + // GenerateRandomGender generates a random gender based on the current language. -func GenerateRandomGender() (*Gender, error) { +func (g *Gender) generateRandomGender() (*Gender, error) { lang := translations.GetLanguage() genderStr := translations.Get(lang, "gender") if genderStr == "" { return nil, fmt.Errorf("%s for: %s", ErrNoGenders, lang) } - - return (*Gender)(&genderStr), nil + return &Gender{Identity: Identity(genderStr)}, nil } diff --git a/pkg/mocai/entities/national_id/countries/errors.go b/pkg/mocai/entities/national_id/countries/errors.go deleted file mode 100644 index d50de61..0000000 --- a/pkg/mocai/entities/national_id/countries/errors.go +++ /dev/null @@ -1,8 +0,0 @@ -package countries - -import "errors" - -var ( - ErrGeneratingBrazilianNationalID = errors.New("error generating brazilian national id") - ErrToConvertDigit = errors.New("error converting digit") -) diff --git a/pkg/mocai/entities/national_id/generator.go b/pkg/mocai/entities/national_id/generator.go deleted file mode 100644 index 27d5fad..0000000 --- a/pkg/mocai/entities/national_id/generator.go +++ /dev/null @@ -1,19 +0,0 @@ -package national_id - -import "github.com/brazzcore/mocai/pkg/mocai/entities/national_id/countries" - -type NationalID struct { - BrazilianRG *countries.RG -} - -// GenerateNationalID generates a Brazilian national ID [RG]. -// If formatted is true, the Brazilian national ID will be returned in the format XX.XXX.XXX-X. -// if formatted is false, the Brazilian national ID will be returned as a plain string. -func GenerateNationalID(formatted bool) (*NationalID, error) { - rg, err := countries.GenerateBrazilianNationalID(formatted) - if err != nil { - return nil, err - } - - return &NationalID{BrazilianRG: rg}, nil -} diff --git a/pkg/mocai/entities/national_id/countries/brazilian_national_id.go b/pkg/mocai/entities/nationalid/countries/brazilian_national_id.go similarity index 86% rename from pkg/mocai/entities/national_id/countries/brazilian_national_id.go rename to pkg/mocai/entities/nationalid/countries/brazilian_national_id.go index b870614..443fd67 100644 --- a/pkg/mocai/entities/national_id/countries/brazilian_national_id.go +++ b/pkg/mocai/entities/nationalid/countries/brazilian_national_id.go @@ -15,17 +15,25 @@ type RG struct { IssuingBody string } +func NewRG(isFormatted bool) RG { + rg, err := (&RG{}).generateBrazilianNationalID(isFormatted) + if err != nil { + return RG{} + } + return rg +} + // GenerateBrazilianNationalID generates a valid Brazilian national ID [RG] for São Paulo. -func GenerateBrazilianNationalID(formatted bool) (*RG, error) { +func (r *RG) generateBrazilianNationalID(formatted bool) (RG, error) { rgNumber, err := calculateSPRGDigit() if err != nil { - return nil, err + return RG{}, err } if formatted { rgNumber = formatRG(rgNumber) } - return &RG{ + return RG{ Number: rgNumber, State: "SP", IssuingBody: "SSP - Secretaria de Seguranca Publica", diff --git a/pkg/mocai/entities/nationalid/countries/errors.go b/pkg/mocai/entities/nationalid/countries/errors.go new file mode 100644 index 0000000..4282562 --- /dev/null +++ b/pkg/mocai/entities/nationalid/countries/errors.go @@ -0,0 +1,7 @@ +package countries + +import "errors" + +var ( + ErrToConvertDigit = errors.New("error converting digit") +) diff --git a/pkg/mocai/entities/nationalid/generator.go b/pkg/mocai/entities/nationalid/generator.go new file mode 100644 index 0000000..597d12e --- /dev/null +++ b/pkg/mocai/entities/nationalid/generator.go @@ -0,0 +1,26 @@ +package nationalid + +import ( + "github.com/brazzcore/mocai/pkg/mocai/entities/nationalid/countries" +) + +type NationalID struct { + BrazilianRG countries.RG +} + +// NewNationalID creates a new NationalID entity with a generated Brazilian national ID [RG]. +func NewNationalID(isFormatted bool) (*NationalID, error) { + n, err := (&NationalID{}).generateNationalID(isFormatted) + if err != nil { + return nil, err + } + return n, nil +} + +// GenerateNationalID generates a Brazilian national ID [RG]. +// If formatted is true, the Brazilian national ID will be returned in the format XX.XXX.XXX-X. +// if formatted is false, the Brazilian national ID will be returned as a plain string. +func (n *NationalID) generateNationalID(formatted bool) (*NationalID, error) { + rg := countries.NewRG(formatted) + return &NationalID{BrazilianRG: rg}, nil +} diff --git a/pkg/mocai/entities/person/generator.go b/pkg/mocai/entities/person/generator.go index 5bd9b52..4073d89 100644 --- a/pkg/mocai/entities/person/generator.go +++ b/pkg/mocai/entities/person/generator.go @@ -17,12 +17,20 @@ type Person struct { LastName string Gender *gender.Gender Age int - CPF string + CPF *cpf.CPF +} + +func NewPerson(isFormatted bool) (*Person, error) { + p, err := (&Person{}).generatePerson(isFormatted) + if err != nil { + return nil, err + } + return p, nil } // GeneratePerson generates a mock person with random data. // It returns a pointer to a Person and an error if the generation fails. -func GeneratePerson() (*Person, error) { +func (p *Person) generatePerson(isFormatted bool) (*Person, error) { lang := translations.GetLanguage() // Get the list of first names and last names @@ -45,13 +53,13 @@ func GeneratePerson() (*Person, error) { lastName := lastNames[rand.Intn(len(lastNames))] // Generate a random gender - gender, err := gender.GenerateRandomGender() + gender, err := gender.NewGender() if err != nil { return nil, err } // Generate a random CPF without a mask - cpf, err := cpf.GenerateCPF(false) + cpf, err := cpf.NewCPF(isFormatted) if err != nil { return nil, err } @@ -67,7 +75,7 @@ func GeneratePerson() (*Person, error) { FirstNameFemale: firstNameFemale, LastName: lastName, Gender: gender, - Age: rand.Intn(80) + 18, + Age: rand.Intn(70) + 18, CPF: cpf, }, nil } diff --git a/pkg/mocai/entities/phone/generator.go b/pkg/mocai/entities/phone/generator.go index 9f801ab..7c75e48 100644 --- a/pkg/mocai/entities/phone/generator.go +++ b/pkg/mocai/entities/phone/generator.go @@ -14,9 +14,18 @@ type Phone struct { Number string } +// NewPhone creates a new Phone instance with generated data. +func NewPhone() (*Phone, error) { + phone, err := (&Phone{}).generatePhone() + if err != nil { + return nil, err + } + return phone, nil +} + // GeneratePhone generates a mock phone number with random data. // It returns a pointer to a Phone and an error if the generation fails. -func GeneratePhone() (*Phone, error) { +func (p *Phone) generatePhone() (*Phone, error) { lang := translations.GetLanguage() // Get the list of area codes diff --git a/pkg/mocai/entities/vote_registration/generator.go b/pkg/mocai/entities/vote_registration/generator.go deleted file mode 100644 index 6e6b5c5..0000000 --- a/pkg/mocai/entities/vote_registration/generator.go +++ /dev/null @@ -1,20 +0,0 @@ -package vote_registration - -import "github.com/brazzcore/mocai/pkg/mocai/entities/vote_registration/countries" - -// VoteRegistration represents a Brazilian vote registration. -type VoteRegistration struct { - BrazilianVoteRegistration *countries.BrazilianVoteRegistration -} - -// GenerateVoteRegistration generates a Brazilian vote registration. -// If formatted is true, the Brazilian vote registration will be returned in the format XXX XXX XXX. -// If formatted is false, the Brazilian vote registration will be returned as a plain string. -func GenerateVoteRegistration(formatted bool) (*VoteRegistration, error) { - brazilianVoteRegistration, err := countries.GenerateBrazilianVoteRegistration(formatted) - if err != nil { - return nil, err - } - - return &VoteRegistration{BrazilianVoteRegistration: brazilianVoteRegistration}, nil -} diff --git a/pkg/mocai/entities/vote_registration/countries/brazilian_vote_registration.go b/pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go similarity index 87% rename from pkg/mocai/entities/vote_registration/countries/brazilian_vote_registration.go rename to pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go index 84400ae..6bdbdd2 100644 --- a/pkg/mocai/entities/vote_registration/countries/brazilian_vote_registration.go +++ b/pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go @@ -18,10 +18,17 @@ type BrazilianVoteRegistration struct { Number string } +// NewBrazilianVoteRegistration generates a new Brazilian vote registration. +func NewBrazilianVoteRegistration(isFormatted bool) (*BrazilianVoteRegistration, error) { + bvr, err := (&BrazilianVoteRegistration{}).generateBrazilianVoteRegistration(isFormatted) + if err != nil { + return nil, err + } + return bvr, nil +} + // GenerateBrazilianVoteRegistration generates a valid Brazilian vote registration number. -// If formatted is true, the Brazilian vote registration number will be returned in the format XXX XXX XXX. -// If formatted is false, the Brazilian vote registration number will be returned as a plain string. -func GenerateBrazilianVoteRegistration(formatted bool) (*BrazilianVoteRegistration, error) { +func (b *BrazilianVoteRegistration) generateBrazilianVoteRegistration(formatted bool) (*BrazilianVoteRegistration, error) { section := randomInt3Digits() zone := randomInt3Digits() diff --git a/pkg/mocai/entities/vote_registration/countries/errors.go b/pkg/mocai/entities/voteregistration/countries/errors.go similarity index 100% rename from pkg/mocai/entities/vote_registration/countries/errors.go rename to pkg/mocai/entities/voteregistration/countries/errors.go diff --git a/pkg/mocai/entities/voteregistration/generator.go b/pkg/mocai/entities/voteregistration/generator.go new file mode 100644 index 0000000..5176d6b --- /dev/null +++ b/pkg/mocai/entities/voteregistration/generator.go @@ -0,0 +1,28 @@ +package voteregistration + +import "github.com/brazzcore/mocai/pkg/mocai/entities/voteregistration/countries" + +// VoteRegistration represents a Brazilian vote registration. +type VoteRegistration struct { + BrazilianVoteRegistration countries.BrazilianVoteRegistration +} + +// NewVoteRegistration generates a Brazilian vote registration. +func NewVoteRegistration(isFormatted bool) (*VoteRegistration, error) { + voteRegistration, err := (&VoteRegistration{}).generateVoteRegistration(isFormatted) + if err != nil { + return nil, err + } + return voteRegistration, nil +} + +// GenerateVoteRegistration generates a Brazilian vote registration. +// If formatted is true, the Brazilian vote registration will be returned in the format XXX XXX XXX. +// If formatted is false, the Brazilian vote registration will be returned as a plain string. +func (v *VoteRegistration) generateVoteRegistration(isFormatted bool) (*VoteRegistration, error) { + brazilianVoteRegistration, err := countries.NewBrazilianVoteRegistration(isFormatted) + if err != nil { + return nil, err + } + return &VoteRegistration{BrazilianVoteRegistration: *brazilianVoteRegistration}, nil +} diff --git a/pkg/mocai/mocker.go b/pkg/mocai/mocker.go index 101218d..15e16d9 100644 --- a/pkg/mocai/mocker.go +++ b/pkg/mocai/mocker.go @@ -5,81 +5,91 @@ import ( "github.com/brazzcore/mocai/pkg/mocai/entities/certificate" "github.com/brazzcore/mocai/pkg/mocai/entities/company" "github.com/brazzcore/mocai/pkg/mocai/entities/gender" - "github.com/brazzcore/mocai/pkg/mocai/entities/national_id" + "github.com/brazzcore/mocai/pkg/mocai/entities/nationalid" "github.com/brazzcore/mocai/pkg/mocai/entities/person" "github.com/brazzcore/mocai/pkg/mocai/entities/phone" - "github.com/brazzcore/mocai/pkg/mocai/entities/vote_registration" + "github.com/brazzcore/mocai/pkg/mocai/entities/voteregistration" "github.com/brazzcore/mocai/pkg/mocai/translations" ) -type Mocker struct{} +// Mocker represents an immutable collection of mock data in a specific language. +type Mocker struct { + Address *address.Address + Certificate *certificate.Certificate + Company *company.Company + Gender *gender.Gender + NationalID *nationalid.NationalID + Person *person.Person + Phone *phone.Phone + VoteRegistration *voteregistration.VoteRegistration + + formatted bool + lang string +} -func NewMocker(lang string) (*Mocker, error) { - err := translations.SetLanguage(lang) - if err != nil { +// NewMocker initializes a Mocai instance with the specified language and formatting options. +// All generated data will use the specified language. To get data in a different language, +// create a new Mocker instance. +func NewMocker(lang string, isFormatted bool) (*Mocker, error) { + if err := translations.SetLanguage(lang); err != nil { return nil, err } - return &Mocker{}, nil -} - -func (m *Mocker) SetLanguage(lang string) error { - err := translations.SetLanguage(lang) + address, err := address.NewAddress() if err != nil { - return err + return nil, err } - return err -} - -func (m *Mocker) GetLanguage() string { - return translations.GetLanguage() -} - -func (m *Mocker) Address() *address.Address { - a, _ := address.GenerateAddress() - - return a -} - -func (m *Mocker) Certificate() *certificate.Certificate { - c, _ := certificate.GenerateCertificate(false) - - return c -} - -func (m *Mocker) Company() *company.Company { - c, _ := company.GenerateCompany(false) - - return c -} - -func (m *Mocker) Gender() *gender.Gender { - g, _ := gender.GenerateRandomGender() + certificate, err := certificate.NewCertificate(isFormatted) + if err != nil { + return nil, err + } - return g -} + company, err := company.NewCompany(isFormatted) + if err != nil { + return nil, err + } -func (m *Mocker) NationalID() *national_id.NationalID { - n, _ := national_id.GenerateNationalID(false) + gender, err := gender.NewGender() + if err != nil { + return nil, err + } - return n -} + nationalID, err := nationalid.NewNationalID(isFormatted) + if err != nil { + return nil, err + } -func (m *Mocker) Person() *person.Person { - p, _ := person.GeneratePerson() + person, err := person.NewPerson(isFormatted) + if err != nil { + return nil, err + } - return p -} + phone, err := phone.NewPhone() + if err != nil { + return nil, err + } -func (m *Mocker) Phone() *phone.Phone { - p, _ := phone.GeneratePhone() + voteRegistration, err := voteregistration.NewVoteRegistration(isFormatted) + if err != nil { + return nil, err + } - return p + return &Mocker{ + Address: address, + Certificate: certificate, + Company: company, + Gender: gender, + NationalID: nationalID, + Person: person, + Phone: phone, + VoteRegistration: voteRegistration, + formatted: isFormatted, + lang: lang, + }, nil } -func (m *Mocker) VoteRegistration() *vote_registration.VoteRegistration { - v, _ := vote_registration.GenerateVoteRegistration(false) - - return v +// GetLanguage returns the language used to generate this Mocker's data +func (m *Mocker) GetLanguage() string { + return m.lang }