From a1c3e1d69c9c27bc9eb4c336c9deabd315973276 Mon Sep 17 00:00:00 2001 From: Sepehr Date: Tue, 30 Apr 2024 23:16:21 +0200 Subject: [PATCH] Refactor name provider --- data/languages.json | 0 data/names.json | 106 ----------------------- data/paragraphs.json | 0 data/sentences.json | 0 generator.go | 3 + providers/name/name.go | 164 +++++++++++++++++++++++++----------- providers/name/name_test.go | 76 +++++++++++------ 7 files changed, 168 insertions(+), 181 deletions(-) delete mode 100644 data/languages.json delete mode 100644 data/names.json delete mode 100644 data/paragraphs.json delete mode 100644 data/sentences.json diff --git a/data/languages.json b/data/languages.json deleted file mode 100644 index e69de29..0000000 diff --git a/data/names.json b/data/names.json deleted file mode 100644 index af40441..0000000 --- a/data/names.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "firstNames": [ - "علی", - "مریم", - "حسن", - "زهرا", - "رضا", - "فاطمه", - "محمد", - "سارا", - "جواد", - "لیلا", - "امیر", - "نازنین", - "مجید", - "سمانه", - "کیان", - "نگین", - "شهاب", - "پریسا", - "مهدی", - "الهام", - "عرفان", - "تینا", - "بهنام", - "زینب", - "پویا", - "سپیده", - "کامران", - "ملیکا", - "یاسر", - "مینا", - "بهزاد", - "آناهیتا", - "فرشاد", - "مهسا", - "رامین", - "سحر", - "عباس", - "فریبا", - "هومن", - "آزاده", - "بهروز", - "سمیرا", - "سعید", - "شیرین", - "آرش", - "کتایون", - "فرید", - "هدیه", - "مانی", - "رویا" - ], - "lastNames": [ - "محمدی", - "هاشمی", - "سلطانی", - "احمدی", - "رضایی", - "کریمی", - "جعفری", - "حسینی", - "نجفی", - "شیرازی", - "فرزانه", - "علوی", - "رستمی", - "موسوی", - "کاشانی", - "تهرانی", - "صادقی", - "قاسمی", - "میرزایی", - "نوری", - "رحیمی", - "کوهی", - "شاهین", - "زارع", - "بهاری", - "عبدی", - "چراغی", - "امینی", - "پهلوان", - "تاج", - "داودی", - "صفری", - "باقری", - "زمانی", - "کوچکی", - "آقایی", - "مهدوی", - "جمشیدی", - "گلزار", - "پارسا", - "صمدی", - "شفیعی", - "مرادی", - "بابایی", - "حیدری", - "خانی", - "یزدانی", - "سلطانپور", - "فخری", - "ملکی" - ] -} diff --git a/data/paragraphs.json b/data/paragraphs.json deleted file mode 100644 index e69de29..0000000 diff --git a/data/sentences.json b/data/sentences.json deleted file mode 100644 index e69de29..0000000 diff --git a/generator.go b/generator.go index 00fd5e2..8d4919c 100644 --- a/generator.go +++ b/generator.go @@ -5,6 +5,7 @@ import ( "github.com/sepisoltani/persian-faker/providers/bill" "github.com/sepisoltani/persian-faker/providers/digit" "github.com/sepisoltani/persian-faker/providers/location" + "github.com/sepisoltani/persian-faker/providers/name" "github.com/sepisoltani/persian-faker/providers/phonenumber" ) @@ -15,6 +16,7 @@ type DataGenerator struct { Digit *digit.Digit PhoneNumber *phonenumber.PhoneNumber Location *location.Location + Name *name.Name } func NewDataGenerator() *DataGenerator { @@ -24,5 +26,6 @@ func NewDataGenerator() *DataGenerator { Digit: &digit.Digit{}, PhoneNumber: &phonenumber.PhoneNumber{}, Location: &location.Location{}, + Name: &name.Name{}, } } diff --git a/providers/name/name.go b/providers/name/name.go index a171394..0efb8d0 100644 --- a/providers/name/name.go +++ b/providers/name/name.go @@ -1,65 +1,131 @@ -package names +package name import ( - "encoding/json" "math/rand" - "os" - "path/filepath" + "time" ) -// NameData represents the structure for names data. -type NameData struct { - FirstNames []string `json:"firstNames"` - LastNames []string `json:"lastNames"` +var firstNames = []string{ + "علی", + "مریم", + "حسن", + "زهرا", + "رضا", + "فاطمه", + "محمد", + "سارا", + "جواد", + "لیلا", + "امیر", + "نازنین", + "مجید", + "سمانه", + "کیان", + "نگین", + "شهاب", + "پریسا", + "مهدی", + "الهام", + "عرفان", + "تینا", + "بهنام", + "زینب", + "پویا", + "سپیده", + "کامران", + "ملیکا", + "یاسر", + "مینا", + "بهزاد", + "آناهیتا", + "فرشاد", + "مهسا", + "رامین", + "سحر", + "عباس", + "فریبا", + "هومن", + "آزاده", + "بهروز", + "سمیرا", + "سعید", + "شیرین", + "آرش", + "کتایون", + "فرید", + "هدیه", + "مانی", + "رویا", } -// DataLoader is the interface for loading name data. -type DataLoader interface { - LoadData(path string) (NameData, error) +var lastNames = []string{ + "محمدی", + "هاشمی", + "سلطانی", + "احمدی", + "رضایی", + "کریمی", + "جعفری", + "حسینی", + "نجفی", + "شیرازی", + "فرزانه", + "علوی", + "رستمی", + "موسوی", + "کاشانی", + "تهرانی", + "صادقی", + "قاسمی", + "میرزایی", + "نوری", + "رحیمی", + "کوهی", + "شاهین", + "زارع", + "بهاری", + "عبدی", + "چراغی", + "امینی", + "پهلوان", + "تاج", + "داودی", + "صفری", + "باقری", + "زمانی", + "کوچکی", + "آقایی", + "مهدوی", + "جمشیدی", + "گلزار", + "پارسا", + "صمدی", + "شفیعی", + "مرادی", + "بابایی", + "حیدری", + "خانی", + "یزدانی", + "سلطانپور", + "فخری", + "ملکی", } +var rng = rand.New(rand.NewSource(time.Now().UnixNano())) -// FileDataLoader loads name data from a file. -type FileDataLoader struct{} - -func (fdl FileDataLoader) LoadData(path string) (NameData, error) { - var data NameData - file, err := os.ReadFile(path) - if err != nil { - return data, err - } - err = json.Unmarshal(file, &data) - return data, err -} - -// NameGenerator holds the loaded name data and the random generator. -type NameGenerator struct { - Data NameData - Rand *rand.Rand -} - -// NewNameGenerator creates a new NameGenerator with data loaded using the given DataLoader and random source. -func NewNameGenerator(loader DataLoader, seed int64) (*NameGenerator, error) { - dataPath := filepath.Join("data", "names.json") - data, err := loader.LoadData(dataPath) - if err != nil { - return nil, err - } - src := rand.NewSource(seed) - rng := rand.New(src) - return &NameGenerator{Data: data, Rand: rng}, nil +type Name struct { } -// RandomFirstName returns a random Persian first name. -func (ng *NameGenerator) RandomFirstName() string { - return ng.Data.FirstNames[ng.Rand.Intn(len(ng.Data.FirstNames))] +// GenerateFirstName returns a random Persian first name. +func (Name) GenerateFirstName() string { + return firstNames[rng.Intn(len(firstNames))] } -// RandomLastName returns a random Persian last name. -func (ng *NameGenerator) RandomLastName() string { - return ng.Data.LastNames[ng.Rand.Intn(len(ng.Data.LastNames))] +// GenerateLastName returns a random Persian last name. +func (Name) GenerateLastName() string { + return lastNames[rng.Intn(len(lastNames))] } -// RandomFullName returns a random Persian full name. -func (ng *NameGenerator) RandomFullName() string { - return ng.RandomFirstName() + " " + ng.RandomLastName() +// GenerateFullName returns a random Persian full name. +func (name Name) GenerateFullName() string { + return name.GenerateFirstName() + " " + name.GenerateLastName() } diff --git a/providers/name/name_test.go b/providers/name/name_test.go index 23bc387..36502db 100644 --- a/providers/name/name_test.go +++ b/providers/name/name_test.go @@ -1,40 +1,64 @@ -package names +package name import ( + "strings" "testing" ) -// MockDataLoader is a mock implementation of DataLoader for testing. -type MockDataLoader struct{} - -func (mdl MockDataLoader) LoadData(path string) (NameData, error) { - return NameData{ - FirstNames: []string{"Ali", "Reza"}, - LastNames: []string{"Kazemi", "Mousavi"}, - }, nil +func TestGenerateFirstName(t *testing.T) { + seen := make(map[string]bool) + for i := 0; i < 100; i++ { + n := &Name{} + name := n.GenerateFirstName() + if seen[name] { + continue + } + seen[name] = true + if !contains(firstNames, name) { + t.Errorf("GenerateFirstName returned an unexpected name: %s", name) + } + } + if len(seen) < 10 { // Check for some variability + t.Errorf("GenerateFirstName returned too few unique names, got: %d", len(seen)) + } } -// TestNameGenerator tests the functionality of NameGenerator. -func TestNameGenerator(t *testing.T) { - loader := MockDataLoader{} - seed := int64(1) // Fixed seed for reproducibility - ng, err := NewNameGenerator(loader, seed) - if err != nil { - t.Fatalf("Failed to create NameGenerator: %v", err) +// contains checks if a string is in a slice of strings +func contains(slice []string, item string) bool { + for _, a := range slice { + if a == item { + return true + } } + return false +} - firstName := ng.RandomFirstName() - if firstName != "Reza" { - t.Errorf("Expected 'Reza', got '%s'", firstName) +func TestGenerateLastName(t *testing.T) { + seen := make(map[string]bool) + for i := 0; i < 100; i++ { + n := &Name{} + name := n.GenerateLastName() + if seen[name] { + continue + } + seen[name] = true + if !contains(lastNames, name) { + t.Errorf("GenerateLastName returned an unexpected name: %s", name) + } } - - lastName := ng.RandomLastName() - if lastName != "Mousavi" { - t.Errorf("Expected 'Kazemi', got '%s'", lastName) + if len(seen) < 10 { // Check for some variability + t.Errorf("GenerateLastName returned too few unique names, got: %d", len(seen)) } +} - fullName := ng.RandomFullName() - if fullName != "Reza Mousavi" { - t.Errorf("Expected 'Reza Kazemi', got '%s'", fullName) +func TestGenerateFullName(t *testing.T) { + n := &Name{} + name := n.GenerateFullName() + parts := strings.Split(name, " ") + if len(parts) != 2 { + t.Errorf("GenerateFullName did not return a proper full name, got: %s", name) + } + if !contains(firstNames, parts[0]) || !contains(lastNames, parts[1]) { + t.Errorf("GenerateFullName returned an unexpected full name: %s", name) } }