From 25fe1ec5635fd476f91b3a7f437f9807b98031c5 Mon Sep 17 00:00:00 2001 From: Adrien Mulattieri Date: Thu, 4 Aug 2022 20:30:07 +0200 Subject: [PATCH] feat: Random utils functions --- random/random.go | 47 ++++++++++++++++++++++ random/random_test.go | 91 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 random/random.go create mode 100644 random/random_test.go diff --git a/random/random.go b/random/random.go new file mode 100644 index 00000000..b7dd847e --- /dev/null +++ b/random/random.go @@ -0,0 +1,47 @@ +package random + +import ( + "fmt" + "math/rand" + "strings" +) + +const NumericRunes = "0123456789" +const LowerAlphaRunes = "abcdefghijklmnopqrstuvwxyz" +const UpperAlphaRunes = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +const AlphaRunes = UpperAlphaRunes + LowerAlphaRunes + +// Return a random string made up of characters passed +func Runes(prefix string, length int, runes ...string) string { + chars := strings.Join(runes, "") + var bytes = make([]byte, length) + rand.Read(bytes) + for i, b := range bytes { + bytes[i] = chars[b%byte(len(chars))] + } + return prefix + string(bytes) +} + +// Return a random string of alpha characters +func Alpha(prefix string, length int) string { + return Runes(prefix, length, AlphaRunes) +} + +// Return a random string of alpha and numeric characters +func String(prefix string, length int) string { + return Runes(prefix, length, AlphaRunes, NumericRunes) +} + +// Given a list of strings, return one of the strings randomly +func Item(items ...string) string { + var bytes = make([]byte, 1) + rand.Read(bytes) + return items[bytes[0]%byte(len(items))] +} + +// Return a random domain name in the form "randomAlpha.net" +func DomainName() string { + return fmt.Sprintf("%s.%s", + Alpha("", 14), + Item("net", "com", "org", "io", "gov")) +} diff --git a/random/random_test.go b/random/random_test.go new file mode 100644 index 00000000..0c3063af --- /dev/null +++ b/random/random_test.go @@ -0,0 +1,91 @@ +package random + +import ( + "fmt" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestString(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + for _, tc := range []struct { + msg string + prefix string + length int + contains string + expectedLength int + }{{ + msg: "only made of alpha and numeric characters", + prefix: "", + length: 10, + contains: AlphaRunes + NumericRunes, + expectedLength: 10, + }, { + msg: "with prefix and add to length", + prefix: "abc", + length: 5, + contains: AlphaRunes + NumericRunes, + expectedLength: 5 + 3, // = len("abc") + }} { + t.Run(tc.msg, func(t *testing.T) { + res := String(tc.prefix, tc.length) + assert.Equal(t, tc.expectedLength, len(res)) + assert.Contains(t, res, tc.prefix) + for _, ch := range res { + assert.Contains(t, tc.contains, fmt.Sprintf("%c", ch)) + } + }) + } +} + +func TestAlpha(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + for _, tc := range []struct { + msg string + prefix string + length int + contains string + expectedLength int + }{{ + msg: "only made of alpha characters", + prefix: "", + length: 10, + contains: AlphaRunes, + expectedLength: 10, + }, { + msg: "with prefix and add to length", + prefix: "abc", + length: 5, + contains: AlphaRunes, + expectedLength: 5 + 3, // = len("abc") + }} { + t.Run(tc.msg, func(t *testing.T) { + res := Alpha(tc.prefix, tc.length) + assert.Equal(t, tc.expectedLength, len(res)) + assert.Contains(t, res, tc.prefix) + for _, ch := range res { + assert.Contains(t, tc.contains, fmt.Sprintf("%c", ch)) + } + }) + } +} + +func TestItem(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + for _, tc := range []struct { + msg string + items []string + expected string + }{{ + msg: "one of the given list", + items: []string{"com", "net", "org"}, + }} { + t.Run(tc.msg, func(t *testing.T) { + res := Item(tc.items...) + assert.Contains(t, tc.items, res) + }) + } +}