Skip to content

Commit

Permalink
minor boundaries to logic and better tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jedib0t committed Apr 18, 2024
1 parent 4df9462 commit 83c3198
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 28 deletions.
26 changes: 17 additions & 9 deletions password/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,24 @@ func (g *generator) Generate() string {
defer g.pool.Put(password)

idx := 0
fillPassword := func(count int, runes []rune) {
for ; count > 0 && idx < len(password); count-- {
fillPassword := func(runes []rune, count int) {
for ; idx < len(password) && count > 0; count-- {
password[idx] = runes[g.rng.IntN(len(runes))]
idx++
}
}
fillPassword(g.minLowerCase, g.charsetCaseLower)
fillPassword(g.minUpperCase, g.charsetCaseUpper)
fillPassword(g.numSymbolsToGenerate(), g.charsetSymbols)
fillPassword(len(password)-idx, g.charsetNonSymbols)
if g.minLowerCase > 0 {
fillPassword(g.charsetCaseLower, g.minLowerCase)
}
if g.minUpperCase > 0 {
fillPassword(g.charsetCaseUpper, g.minUpperCase)
}
if numSymbols := g.numSymbolsToGenerate(); numSymbols > 0 {
fillPassword(g.charsetSymbols, numSymbols)
}
if remainingChars := len(password) - idx; remainingChars > 0 {
fillPassword(g.charsetNonSymbols, remainingChars)
}

// shuffle it all
g.rng.Shuffle(len(password), func(i, j int) {
Expand Down Expand Up @@ -119,15 +127,15 @@ func (g *generator) sanitize() (Generator, error) {
if g.minUpperCase > g.numChars {
return nil, ErrMinUpperCaseTooLong
}
if g.minSymbols > 0 && len(g.charsetSymbols) == 0 {
return nil, ErrNoSymbolsInCharset
}
if g.minSymbols > g.numChars {
return nil, ErrMinSymbolsTooLong
}
if g.minLowerCase+g.minUpperCase+g.minSymbols > g.numChars {
return nil, ErrRequirementsNotMet
}
if g.minSymbols > 0 && len(g.charsetSymbols) == 0 {
return nil, ErrNoSymbolsInCharset
}
return g, nil
}

Expand Down
38 changes: 19 additions & 19 deletions password/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package password

import (
"fmt"
"strings"
"slices"
"testing"
"unicode"

Expand Down Expand Up @@ -42,19 +42,19 @@ func TestGenerator_Generate(t *testing.T) {
"uCFmDFDAoLZY",
"pMgNoVa9z5Vv",
}
sb := strings.Builder{}
var actualPasswords []string
for idx := 0; idx < 100; idx++ {
password := g.Generate()
assert.NotEmpty(t, password)
if idx < len(expectedPasswords) {
actualPasswords = append(actualPasswords, password)
assert.Equal(t, expectedPasswords[idx], password)
if expectedPasswords[idx] != password {
sb.WriteString(fmt.Sprintf("%#v,\n", password))
}
}
}
if sb.Len() > 0 {
fmt.Println(sb.String())
if !slices.Equal(expectedPasswords, actualPasswords) {
for _, pw := range actualPasswords {
fmt.Printf("%#v,\n", pw)
}
}
}

Expand All @@ -81,15 +81,13 @@ func TestGenerator_Generate_WithAMixOfEverything(t *testing.T) {
"bVrPjBRC<bqy",
"f?orrWDzVYjx",
}
sb := strings.Builder{}
var actualPasswords []string
for idx := 0; idx < 100; idx++ {
password := g.Generate()
assert.NotEmpty(t, password)
if idx < len(expectedPasswords) {
actualPasswords = append(actualPasswords, password)
assert.Equal(t, expectedPasswords[idx], password)
if expectedPasswords[idx] != password {
sb.WriteString(fmt.Sprintf("%#v,\n", password))
}
}

numLowerCase := len(filterRunes([]rune(password), unicode.IsLower))
Expand All @@ -99,8 +97,10 @@ func TestGenerator_Generate_WithAMixOfEverything(t *testing.T) {
numSymbols := len(filterRunes([]rune(password), Symbols.Contains))
assert.True(t, numSymbols == 1, password)
}
if sb.Len() > 0 {
fmt.Println(sb.String())
if !slices.Equal(expectedPasswords, actualPasswords) {
for _, pw := range actualPasswords {
fmt.Printf("%#v,\n", pw)
}
}
}

Expand All @@ -126,22 +126,22 @@ func TestGenerator_Generate_WithSymbols(t *testing.T) {
"-e3a6cda4#!1",
"162e6bb#ee53",
}
sb := strings.Builder{}
var actualPasswords []string
for idx := 0; idx < 100; idx++ {
password := g.Generate()
assert.NotEmpty(t, password)
if idx < len(expectedPasswords) {
actualPasswords = append(actualPasswords, password)
assert.Equal(t, expectedPasswords[idx], password)
if expectedPasswords[idx] != password {
sb.WriteString(fmt.Sprintf("%#v,\n", password))
}
}

numSymbols := getNumSymbols(password)
assert.True(t, numSymbols >= 0 && numSymbols <= 3, password)
}
if sb.Len() > 0 {
fmt.Println(sb.String())
if !slices.Equal(expectedPasswords, actualPasswords) {
for _, pw := range actualPasswords {
fmt.Printf("%#v,\n", pw)
}
}
})

Expand Down

0 comments on commit 83c3198

Please sign in to comment.