diff options
| author | Shulhan <ms@kilabit.info> | 2024-01-29 02:42:51 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2024-01-29 02:43:44 +0700 |
| commit | e33a335cd730748517b0bcde34c68e982205f5fa (patch) | |
| tree | e4d977b662412ff6dc0a0d883fa1849efc352bda | |
| parent | 137d8746c608a19c14f619fc796241d4c416e812 (diff) | |
| download | pakakeh.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".
| -rw-r--r-- | lib/test/mock/mock.go | 2 | ||||
| -rw-r--r-- | lib/test/mock/rand_reader.go | 51 | ||||
| -rw-r--r-- | lib/test/mock/rand_reader_example_test.go | 41 |
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 +} |
