92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
|
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'
|
||
|
}
|