149 lines
3.1 KiB
Go
149 lines
3.1 KiB
Go
package basic
|
|
|
|
import "testing"
|
|
|
|
func TestNormalizeName(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
// Basic capitalization
|
|
{"JOHN", "John"},
|
|
{"doe", "Doe"},
|
|
{"jOhN", "jOhN"}, // mixed case — trust user input
|
|
|
|
// O' prefix
|
|
{"O'BRIAN", "O'Brian"},
|
|
{"o'connor", "O'Connor"},
|
|
{"O'NEIL", "O'Neil"},
|
|
|
|
// Mc prefix
|
|
{"MCDONALD", "McDonald"},
|
|
{"mcdonald", "McDonald"},
|
|
{"MCBRIDE", "McBride"},
|
|
|
|
// Mac prefix (len >= 5 to avoid false positives)
|
|
{"MACARTHUR", "MacArthur"},
|
|
{"macarthur", "MacArthur"},
|
|
{"MACDONALD", "MacDonald"},
|
|
|
|
// Mac prefix - short words should NOT get Mac treatment
|
|
{"MACK", "Mack"},
|
|
{"macy", "Macy"},
|
|
{"mace", "Mace"},
|
|
{"mach", "Mach"},
|
|
|
|
// Hyphenated names
|
|
{"SMITH-JONES", "Smith-Jones"},
|
|
{"smith-jones", "Smith-Jones"},
|
|
{"O'BRIEN-MCDONALD", "O'Brien-McDonald"},
|
|
|
|
// Roman numerals and suffixes
|
|
{"iii", "III"},
|
|
{"III", "III"},
|
|
{"iv", "IV"},
|
|
{"jr", "Jr."},
|
|
{"sr", "Sr."},
|
|
{"ii", "II"},
|
|
|
|
// Compound surnames (De, Di, La, Le, Lo, Du)
|
|
{"DESANTIS", "DeSantis"},
|
|
{"devries", "DeVries"},
|
|
{"DEMARCO", "DeMarco"},
|
|
{"DIMAGGIO", "DiMaggio"},
|
|
{"dicaprio", "DiCaprio"},
|
|
{"LASALLE", "LaSalle"},
|
|
{"lafleur", "LaFleur"},
|
|
{"LEBLANC", "LeBlanc"},
|
|
{"lebron", "LeBron"},
|
|
{"LOPRESTI", "LoPresti"},
|
|
{"DUBOIS", "DuBois"},
|
|
{"dupont", "DuPont"},
|
|
|
|
// Compound surname prefixes should NOT affect regular names
|
|
{"DEAN", "Dean"},
|
|
{"DENNIS", "Dennis"},
|
|
{"DIANA", "Diana"},
|
|
{"LAURA", "Laura"},
|
|
{"LEON", "Leon"},
|
|
|
|
// Multi-word last names
|
|
{"DE LA CRUZ", "De La Cruz"},
|
|
{"VAN DER BERG", "Van Der Berg"},
|
|
|
|
// Whitespace handling
|
|
{" JOHN ", "John"},
|
|
{"", ""},
|
|
{" ", ""},
|
|
|
|
// Mixed case — skip normalization, trust user input
|
|
{"John", "John"},
|
|
{"Smith", "Smith"},
|
|
{"DeSantis", "DeSantis"},
|
|
{"DiCaprio", "DiCaprio"},
|
|
{"O'Brien", "O'Brien"},
|
|
{"LeBron", "LeBron"},
|
|
{"MacArthur", "MacArthur"},
|
|
{"McDonald", "McDonald"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
result := NormalizeName(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("NormalizeName(%q) = %q, want %q", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNameContainsProfanity(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected bool
|
|
}{
|
|
// Should flag
|
|
{"fuck", true},
|
|
{"FUCK", true},
|
|
{"Shit", true},
|
|
{"ass", true},
|
|
|
|
// Should NOT flag — profane substrings inside real names
|
|
{"Massimo", false},
|
|
{"Dickens", false},
|
|
{"Cockburn", false},
|
|
{"Draper", false},
|
|
{"Ashton", false},
|
|
{"Cassidy", false},
|
|
|
|
// Normal names
|
|
{"John", false},
|
|
{"Smith", false},
|
|
{"O'Brien", false},
|
|
|
|
// Profanity in hyphenated or multi-word name
|
|
{"Fuck-Face", true},
|
|
|
|
// Leet speak
|
|
{"b1tch", true},
|
|
{"a$$", true},
|
|
{"sh!t", true},
|
|
{"fvck", false}, // not in leet map, won't match
|
|
{"f4g", true},
|
|
{"4ss", true},
|
|
{"pu$$y", true},
|
|
|
|
// Empty
|
|
{"", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
result := NameContainsProfanity(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("NameContainsProfanity(%q) = %v, want %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|