io: implement generic array (de-)serialization

It is done through reflection and panics
in every unexpected situation.
This commit is contained in:
Evgenii Stratonikov 2019-11-13 10:36:29 +03:00
parent 61fdd5cde5
commit ad9091d13d
10 changed files with 164 additions and 96 deletions

View file

@ -5,6 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// mocks io.Reader and io.Writer, always fails to Write() or Read().
@ -191,3 +192,83 @@ func TestWriteVarUint100000000000(t *testing.T) {
assert.Nil(t, br.Err)
assert.Equal(t, val, res)
}
type testSerializable uint16
// EncodeBinary implements io.Serializable interface.
func (t testSerializable) EncodeBinary(w *BinWriter) {
w.WriteLE(t)
}
// DecodeBinary implements io.Serializable interface.
func (t *testSerializable) DecodeBinary(r *BinReader) {
r.ReadLE(t)
}
func TestBinWriter_WriteArray(t *testing.T) {
var arr [3]testSerializable
for i := range arr {
arr[i] = testSerializable(i)
}
expected := []byte{3, 0, 0, 1, 0, 2, 0}
w := NewBufBinWriter()
w.WriteArray(arr)
require.NoError(t, w.Err)
require.Equal(t, expected, w.Bytes())
w.Reset()
w.WriteArray(arr[:])
require.NoError(t, w.Err)
require.Equal(t, expected, w.Bytes())
arrS := make([]Serializable, len(arr))
for i := range arrS {
arrS[i] = &arr[i]
}
w.Reset()
w.WriteArray(arr)
require.NoError(t, w.Err)
require.Equal(t, expected, w.Bytes())
w.Reset()
require.Panics(t, func() { w.WriteArray(1) })
w.Reset()
w.Err = errors.New("error")
w.WriteArray(arr[:])
require.Error(t, w.Err)
require.Equal(t, w.Bytes(), []byte(nil))
w.Reset()
w.Err = errors.New("error")
require.Panics(t, func() { w.WriteArray([]int{}) })
w.Reset()
w.Err = errors.New("error")
require.Panics(t, func() { w.WriteArray(make(chan testSerializable)) })
}
func TestBinReader_ReadArray(t *testing.T) {
data := []byte{3, 0, 0, 1, 0, 2, 0}
r := NewBinReaderFromBuf(data)
result := r.ReadArray(testSerializable(0))
elems := []testSerializable{0, 1, 2}
require.Equal(t, []*testSerializable{&elems[0], &elems[1], &elems[2]}, result)
r = NewBinReaderFromBuf(data)
r.Err = errors.New("error")
result = r.ReadArray(testSerializable(0))
require.Error(t, r.Err)
require.Equal(t, ([]*testSerializable)(nil), result)
r = NewBinReaderFromBuf([]byte{0})
result = r.ReadArray(testSerializable(0))
require.NoError(t, r.Err)
require.Equal(t, []*testSerializable{}, result)
r = NewBinReaderFromBuf([]byte{0})
require.Panics(t, func() { r.ReadArray(0) })
}