aboutsummaryrefslogtreecommitdiff
path: root/lib/test
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-01-29 02:42:51 +0700
committerShulhan <ms@kilabit.info>2024-01-29 02:43:44 +0700
commite33a335cd730748517b0bcde34c68e982205f5fa (patch)
treee4d977b662412ff6dc0a0d883fa1849efc352bda /lib/test
parent137d8746c608a19c14f619fc796241d4c416e812 (diff)
downloadpakakeh.go-e33a335cd730748517b0bcde34c68e982205f5fa.tar.xz
test/mock: implement mock for crypto [rand.Reader]
The RandReader implement [io.Reader]. To provide predictable result, the RandReader is seeded with slice of bytes. A call to Read will fill the passed bytes with those seed. For example, given seed as "abc" (length is three), calling Read with bytes length five will return "abcab".
Diffstat (limited to 'lib/test')
-rw-r--r--lib/test/mock/mock.go2
-rw-r--r--lib/test/mock/rand_reader.go51
-rw-r--r--lib/test/mock/rand_reader_example_test.go41
3 files changed, 93 insertions, 1 deletions
diff --git a/lib/test/mock/mock.go b/lib/test/mock/mock.go
index 5ab5f924..23da6c21 100644
--- a/lib/test/mock/mock.go
+++ b/lib/test/mock/mock.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Package mock provide a mocking for standard input, standard output,
-// standard error, and io.ReadWriter.
+// standard error, io.ReadWriter, and [rand.Reader].
package mock
import (
diff --git a/lib/test/mock/rand_reader.go b/lib/test/mock/rand_reader.go
new file mode 100644
index 00000000..aebc3260
--- /dev/null
+++ b/lib/test/mock/rand_reader.go
@@ -0,0 +1,51 @@
+// Copyright 2024, Shulhan <ms@kilabit.info>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mock
+
+// RandReader implement [io.Reader] for mocking crypto [rand.Reader].
+// To provide predictable result, the RandReader is seeded with the same
+// slice of bytes.
+// A call to Read will fill the passed bytes with those seed.
+type RandReader struct {
+ seed []byte
+ counter int
+}
+
+// NewRandReader create new random reader using seed as generator.
+// The longer the seed, the longer the random values become unique.
+func NewRandReader(seed []byte) (r *RandReader) {
+ r = &RandReader{
+ seed: seed,
+ }
+ return r
+}
+
+// Read fill the raw bytes with seed.
+// If raw length larger than the seed, it will be filled with the same seed
+// until all bytes filled.
+//
+// For example, given seed as "abc" (length is three), and raw length is
+// five, then Read will return "abcab".
+func (rr *RandReader) Read(raw []byte) (n int, err error) {
+ var (
+ expn = len(raw)
+
+ nwrite int
+ )
+
+ for n < expn {
+ nwrite = copy(raw[n:], rr.seed[rr.counter:])
+ n += nwrite
+ }
+
+ // Increment the counter to make the seed start from next byte, so
+ // the next Read will return different result but still predictable.
+ rr.counter++
+ if rr.counter == len(rr.seed) {
+ rr.counter = 0
+ }
+
+ return n, nil
+}
diff --git a/lib/test/mock/rand_reader_example_test.go b/lib/test/mock/rand_reader_example_test.go
new file mode 100644
index 00000000..7aa1dd26
--- /dev/null
+++ b/lib/test/mock/rand_reader_example_test.go
@@ -0,0 +1,41 @@
+// Copyright 2024, Shulhan <ms@kilabit.info>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mock_test
+
+import (
+ "crypto/rand"
+ "fmt"
+ "log"
+
+ "github.com/shuLhan/share/lib/test/mock"
+)
+
+func ExampleRandReader() {
+ var (
+ seed = []byte(`123`)
+ rr = mock.NewRandReader(seed)
+ b = make([]byte, 8)
+
+ x int
+ n int
+ err error
+ )
+
+ rand.Reader = rr
+
+ for x = 0; x <= len(seed); x++ {
+ n, err = rand.Read(b)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(n, string(b))
+ }
+
+ // Output:
+ // 8 12312312
+ // 8 23232323
+ // 8 33333333
+ // 8 12312312
+}