package pwgen_test import ( "code.icb4dc0.de/prskr/go-pwgen" "errors" "testing" ) func FuzzDefaultGenerator_Generate(f *testing.F) { f.Add(uint(0), uint(2), uint(2), uint(2), uint(2)) f.Add(uint(5), uint(2), uint(2), uint(2), uint(2)) f.Add(uint(3), uint(2), uint(2), uint(2), uint(2)) f.Add(uint(3), uint(2), uint(2), uint(2), uint(0)) f.Add(uint(3), uint(2), uint(2), uint(2), uint(5)) f.Add(uint(10), uint(2), uint(2), uint(2), uint(5)) f.Fuzz(func(t *testing.T, letters, digits, uppercase, lowercase, specials uint) { password, err := pwgen.Default.Generate( pwgen.WithLetters(letters), pwgen.WithDigits(digits), pwgen.WithUppercase(uppercase), pwgen.WithLowercase(lowercase), pwgen.WithSpecials(specials), ) if err != nil { if errors.Is(err, pwgen.ErrLengthOverflow) { t.Logf("pwgen.ErrLengthOverflow") return } t.Fatal(err) } if matchesCriteria[rune]([]rune(password), containsDigit) < digits { t.Errorf("password %q does not contain %d digits", password, digits) } if matchesCriteria[rune]([]rune(password), containsLetter) < letters { t.Errorf("password %q does not contain %d letters", password, letters) } if matchesCriteria[rune]([]rune(password), containsUppercase) < uppercase { t.Errorf("password %q does not contain %d uppercase", password, uppercase) } if matchesCriteria[rune]([]rune(password), containsLowercase) < lowercase { t.Errorf("password %q does not contain %d lowercase", password, lowercase) } if matchesCriteria[rune]([]rune(password), containsSpecials) < specials { t.Errorf("password %q does not contain %d specials", password, specials) } }) } func matchesCriteria[T any](s []T, criteria func(T) bool) uint { var found uint for i := range s { if criteria(s[i]) { found += 1 } } return found } func containsLetter(r rune) bool { return r >= 'A' && r <= 'z' } func containsDigit(r rune) bool { return r >= '0' && r <= '9' } func containsSpecials(r rune) bool { for i := range pwgen.DefaultSpecialsAlphabet { if r == rune(pwgen.DefaultSpecialsAlphabet[i]) { return true } } return false } func containsLowercase(r rune) bool { return r >= 'a' && r <= 'z' } func containsUppercase(r rune) bool { return r >= 'A' && r <= 'Z' }