mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-31 23:41:22 +00:00
211 lines
8.0 KiB
Go
211 lines
8.0 KiB
Go
package ssz
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
type decodeTest struct {
|
|
input string
|
|
ptr interface{}
|
|
value interface{}
|
|
error string
|
|
}
|
|
|
|
// Notice: spaces in the input string will be ignored.
|
|
var decodeTests = []decodeTest{
|
|
// bool
|
|
{input: "00", ptr: new(bool), value: false},
|
|
{input: "01", ptr: new(bool), value: true},
|
|
|
|
// uint8
|
|
{input: "00", ptr: new(uint8), value: uint8(0)},
|
|
{input: "01", ptr: new(uint8), value: uint8(1)},
|
|
{input: "10", ptr: new(uint8), value: uint8(16)},
|
|
{input: "80", ptr: new(uint8), value: uint8(128)},
|
|
{input: "FF", ptr: new(uint8), value: uint8(255)},
|
|
|
|
// uint16
|
|
{input: "0000", ptr: new(uint16), value: uint16(0)},
|
|
{input: "0001", ptr: new(uint16), value: uint16(1)},
|
|
{input: "0010", ptr: new(uint16), value: uint16(16)},
|
|
{input: "0080", ptr: new(uint16), value: uint16(128)},
|
|
{input: "00FF", ptr: new(uint16), value: uint16(255)},
|
|
{input: "FFFF", ptr: new(uint16), value: uint16(65535)},
|
|
|
|
// uint32
|
|
{input: "00000000", ptr: new(uint32), value: uint32(0)},
|
|
{input: "00000001", ptr: new(uint32), value: uint32(1)},
|
|
{input: "00000010", ptr: new(uint32), value: uint32(16)},
|
|
{input: "00000080", ptr: new(uint32), value: uint32(128)},
|
|
{input: "000000FF", ptr: new(uint32), value: uint32(255)},
|
|
{input: "0000FFFF", ptr: new(uint32), value: uint32(65535)},
|
|
{input: "FFFFFFFF", ptr: new(uint32), value: uint32(4294967295)},
|
|
|
|
// uint64
|
|
{input: "0000000000000000", ptr: new(uint64), value: uint64(0)},
|
|
{input: "0000000000000001", ptr: new(uint64), value: uint64(1)},
|
|
{input: "0000000000000010", ptr: new(uint64), value: uint64(16)},
|
|
{input: "0000000000000080", ptr: new(uint64), value: uint64(128)},
|
|
{input: "00000000000000FF", ptr: new(uint64), value: uint64(255)},
|
|
{input: "000000000000FFFF", ptr: new(uint64), value: uint64(65535)},
|
|
{input: "00000000FFFFFFFF", ptr: new(uint64), value: uint64(4294967295)},
|
|
{input: "FFFFFFFFFFFFFFFF", ptr: new(uint64), value: uint64(18446744073709551615)},
|
|
|
|
// bytes
|
|
{input: "00000000", ptr: new([]byte), value: []byte{}},
|
|
{input: "0000000101", ptr: new([]byte), value: []byte{1}},
|
|
{input: "00000006 010203040506", ptr: new([]byte), value: []byte{1, 2, 3, 4, 5, 6}},
|
|
|
|
// slice
|
|
{input: "00000000", ptr: new([]uint16), value: []uint16(nil)},
|
|
{input: "00000004 0001 0002", ptr: new([]uint16), value: []uint16{1, 2}},
|
|
{input: "00000018 00000008 0001 0002 0003 0004 00000008 0005 0006 0007 0008", ptr: new([][]uint16),
|
|
value: [][]uint16{
|
|
{1, 2, 3, 4},
|
|
{5, 6, 7, 8},
|
|
},
|
|
},
|
|
|
|
// array
|
|
{input: "00000001 01", ptr: new([1]byte), value: [1]byte{1}},
|
|
{input: "00000006 010203040506", ptr: new([6]byte), value: [6]byte{1, 2, 3, 4, 5, 6}},
|
|
{input: "00000002 0001", ptr: new([1]uint16), value: [1]uint16{1}},
|
|
{input: "00000004 0001 0002", ptr: new([2]uint16), value: [2]uint16{1, 2}},
|
|
{input: "00000018 00000008 0001 0002 0003 0004 00000008 0005 0006 0007 0008", ptr: new([2][4]uint16),
|
|
value: [2][4]uint16{
|
|
{1, 2, 3, 4},
|
|
{5, 6, 7, 8},
|
|
},
|
|
},
|
|
|
|
// struct
|
|
{input: "00000003 00 0000", ptr: new(simpleStruct), value: simpleStruct{}},
|
|
{input: "00000003 0002 01", ptr: new(simpleStruct), value: simpleStruct{B: 2, A: 1}},
|
|
{input: "00000007 03 00000002 0006", ptr: new(outerStruct),
|
|
value: outerStruct{
|
|
V: 3,
|
|
SubV: innerStruct{6},
|
|
}},
|
|
|
|
// slice + struct
|
|
{input: "00000012 0000000E 00000003 000201 00000003 000403", ptr: new(arrayStruct),
|
|
value: arrayStruct{
|
|
V: []simpleStruct{
|
|
{B: 2, A: 1},
|
|
{B: 4, A: 3},
|
|
},
|
|
}},
|
|
{input: "00000016 00000007 03 00000002 0006 00000007 05 00000002 0007", ptr: new([]outerStruct),
|
|
value: []outerStruct{
|
|
{V: 3, SubV: innerStruct{V: 6}},
|
|
{V: 5, SubV: innerStruct{V: 7}},
|
|
}},
|
|
|
|
// pointer
|
|
{input: "00000003 0002 01", ptr: new(*simpleStruct), value: &simpleStruct{B: 2, A: 1}},
|
|
{input: "00000008 00000003 0002 01 03", ptr: new(pointerStruct),
|
|
value: pointerStruct{P: &simpleStruct{B: 2, A: 1}, V: 3}},
|
|
{input: "00000008 00000003 0002 01 03", ptr: new(*pointerStruct),
|
|
value: &pointerStruct{P: &simpleStruct{B: 2, A: 1}, V: 3}},
|
|
{input: "00000004 01020304", ptr: new(*[]uint8), value: &[]uint8{1, 2, 3, 4}},
|
|
{input: "00000010 0000000000000001 0000000000000002", ptr: new(*[]uint64), value: &[]uint64{1, 2}},
|
|
{input: "0000000E 00000003 0002 01 00000003 0004 03", ptr: new([]*simpleStruct),
|
|
value: []*simpleStruct{
|
|
{B: 2, A: 1},
|
|
{B: 4, A: 3},
|
|
},
|
|
},
|
|
{input: "0000000E 00000003 0002 01 00000003 0004 03", ptr: new([2]*simpleStruct),
|
|
value: [2]*simpleStruct{
|
|
{B: 2, A: 1},
|
|
{B: 4, A: 3},
|
|
},
|
|
},
|
|
{input: "00000018 00000008 00000003 0002 01 00 00000008 00000003 0004 03 01", ptr: new([]*pointerStruct),
|
|
value: []*pointerStruct{
|
|
{P: &simpleStruct{B: 2, A: 1}, V: 0},
|
|
{P: &simpleStruct{B: 4, A: 3}, V: 1},
|
|
},
|
|
},
|
|
|
|
// error: nil target
|
|
{input: "00", ptr: nil, value: nil, error: "decode error: cannot decode into nil for output type <nil>"},
|
|
|
|
// error: non-pointer target
|
|
{input: "00", ptr: uint8(0), error: "decode error: can only decode into pointer target for output type uint8"},
|
|
|
|
// error: unsupported type
|
|
{input: "00", ptr: new(string), error: "decode error: type string is not serializable for output type string"},
|
|
|
|
// error: bool: wrong input value
|
|
{input: "02", ptr: new(bool), error: "decode error: expect 0 or 1 for decoding bool but got 2 for output type bool"},
|
|
|
|
// error: uint16: wrong header
|
|
{input: "00", ptr: new(uint16), error: "decode error: can only read 1 bytes while expected to read 2 bytes for output type uint16"},
|
|
|
|
// error: bytes: wrong input
|
|
{input: "00000001", ptr: new([]byte), error: "decode error: can only read 0 bytes while expected to read 1 bytes for output type []uint8"},
|
|
|
|
// error: slice: wrong header
|
|
{input: "000001", ptr: new([]uint16), error: "decode error: failed to decode header of slice: can only read 3 bytes while expected to read 4 bytes for output type []uint16"},
|
|
|
|
// error: slice: wrong input
|
|
{input: "00000001", ptr: new([]uint16), error: "decode error: failed to decode element of slice: can only read 0 bytes while expected to read 2 bytes for output type []uint16"},
|
|
|
|
// error: byte array: wrong input
|
|
{input: "00000001 01", ptr: new([2]byte), error: "decode error: input byte array size (1) isn't euqal to output array size (2) for output type [2]uint8"},
|
|
|
|
// error: array: input too short
|
|
{input: "00000002 0001", ptr: new([2]uint16), error: "decode error: input is too short for output type [2]uint16"},
|
|
|
|
// error: array: input too long
|
|
{input: "00000004 0001 0002", ptr: new([1]uint16), error: "decode error: input is too long for output type [1]uint16"},
|
|
|
|
// error: struct: wrong header
|
|
{input: "000001", ptr: new(simpleStruct), error: "decode error: failed to decode header of struct: can only read 3 bytes while expected to read 4 bytes for output type ssz.simpleStruct"},
|
|
|
|
// error: struct: wrong input
|
|
{input: "00000003 01 02", ptr: new(simpleStruct), error: "decode error: failed to decode field of slice: can only read 0 bytes while expected to read 1 bytes for output type ssz.simpleStruct"},
|
|
}
|
|
|
|
func runTests(t *testing.T, decode func([]byte, interface{}) error) {
|
|
for i, test := range decodeTests {
|
|
input, err := hex.DecodeString(stripSpace(test.input))
|
|
if err != nil {
|
|
t.Errorf("test %d: invalid hex input %q", i, test.input)
|
|
continue
|
|
}
|
|
err = decode(input, test.ptr)
|
|
// Check unexpected error
|
|
if test.error == "" && err != nil {
|
|
t.Errorf("test %d: unexpected decode error: %v\ndecoding into %T\ninput %q",
|
|
i, err, test.ptr, test.input)
|
|
continue
|
|
}
|
|
// Check expected error
|
|
if test.error != "" && fmt.Sprint(err) != test.error {
|
|
t.Errorf("test %d: decode error mismatch\ngot %v\nwant %v\ndecoding into %T\ninput %q",
|
|
i, err, test.error, test.ptr, test.input)
|
|
continue
|
|
}
|
|
// Check expected output
|
|
if err == nil {
|
|
output := reflect.ValueOf(test.ptr).Elem().Interface()
|
|
if !reflect.DeepEqual(output, test.value) {
|
|
t.Errorf("test %d: value mismatch\ngot %#v\nwant %#v\ndecoding into %T\ninput %q",
|
|
i, output, test.value, test.ptr, test.input)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDecodeWithByteReader(t *testing.T) {
|
|
runTests(t, func(input []byte, into interface{}) error {
|
|
return Decode(bytes.NewReader(input), into)
|
|
})
|
|
}
|