From 85a66a3e70ceb9a18a9de143a8d762b783154cc0 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Wed, 10 Sep 2025 10:21:29 -0400 Subject: [PATCH] tape: Create test to ensure DecodeAnyInto can receive a pointer to any --- tape/dynamic_test.go | 162 ++++++++++++++++++------------------------- tape/misc_test.go | 75 ++++++++++++++++++++ 2 files changed, 143 insertions(+), 94 deletions(-) create mode 100644 tape/misc_test.go diff --git a/tape/dynamic_test.go b/tape/dynamic_test.go index 85b83d3..a0078ae 100644 --- a/tape/dynamic_test.go +++ b/tape/dynamic_test.go @@ -1,11 +1,56 @@ package tape -import "fmt" import "bytes" import "testing" import "reflect" import tu "git.tebibyte.media/sashakoshka/hopp/internal/testutil" +var samplePayloads = [][]byte { + /* int8 */ []byte { byte(LSI.WithCN(0)), 0x45 }, + /* int16 */ []byte { byte(LSI.WithCN(1)), 0x45, 0x67 }, + /* int32 */ []byte { byte(LSI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB }, + /* int64 */ []byte { byte(LSI.WithCN(7)), 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 }, + /* uint5 */ []byte { byte(SI.WithCN(12)) }, + /* uint8 */ []byte { byte(LI.WithCN(0)), 0x45 }, + /* uint16 */ []byte { byte(LI.WithCN(1)), 0x45, 0x67 }, + /* uint32 */ []byte { byte(LI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB }, + /* uint64 */ []byte { byte(LI.WithCN(7)), 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 }, + /* string */ []byte { byte(SBA.WithCN(7)), 'p', 'u', 'p', 'e', 'v', 'e', 'r' }, + /* []byte */ []byte { byte(SBA.WithCN(5)), 'b', 'l', 'a', 'r', 'g' }, + /* []string */ []byte { + byte(OTA.WithCN(0)), 2, byte(LBA.WithCN(0)), + 0x08, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, + 0x05, 0x11, 0x11, 0x11, 0x11, 0x11, + }, + /* map[uint16] any */ []byte { + byte(KTV.WithCN(0)), 2, + 0x02, 0x23, byte(LSI.WithCN(1)), 0x45, 0x67, + 0x02, 0x24, byte(LI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB, + }, +} + +var sampleValues = []any { + /* int8 */ int8(0x45), + /* int16 */ int16(0x4567), + /* int32 */ int32(0x456789AB), + /* int64 */ int64(0x456789ABCDEF0123), + /* uint5 */ uint8(12), + /* uint8 */ uint8(0x45), + /* uint16 */ uint16(0x4567), + /* uint32 */ uint32(0x456789AB), + /* uint64 */ uint64(0x456789ABCDEF0123), + /* string */ "pupever", + /* []byte */ "blarg", + /* []string */ []string { + "\x45\x67\x89\xAB\xCD\xEF\x01\x23", + "\x11\x11\x11\x11\x11", + }, + /* map[uint16] any */ map[uint16] any { + 0x0223: int16(0x4567), + 0x0224: uint32(0x456789AB), + }, +} + type userDefinedInteger int16 func TestEncodeAnyInt(test *testing.T) { @@ -87,31 +132,7 @@ func TestEncodeAnyTable(test *testing.T) { } func TestDecodeWrongType(test *testing.T) { - datas := [][]byte { - /* int8 */ []byte { byte(LSI.WithCN(0)), 0x45 }, - /* int16 */ []byte { byte(LSI.WithCN(1)), 0x45, 0x67 }, - /* int32 */ []byte { byte(LSI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB }, - /* int64 */ []byte { byte(LSI.WithCN(7)), 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 }, - /* uint5 */ []byte { byte(SI.WithCN(12)) }, - /* uint8 */ []byte { byte(LI.WithCN(0)), 0x45 }, - /* uint16 */ []byte { byte(LI.WithCN(1)), 0x45, 0x67 }, - /* uint32 */ []byte { byte(LI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB }, - /* uint64 */ []byte { byte(LI.WithCN(7)), 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 }, - /* string */ []byte { byte(SBA.WithCN(7)), 'p', 'u', 'p', 'e', 'v', 'e', 'r' }, - /* []byte */ []byte { byte(SBA.WithCN(5)), 'b', 'l', 'a', 'r', 'g' }, - /* []string */ []byte { - byte(OTA.WithCN(0)), 2, byte(LBA.WithCN(0)), - 0x08, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, - 0x05, 0x11, 0x11, 0x11, 0x11, 0x11, - }, - /* map[uint16] any */ []byte { - byte(KTV.WithCN(0)), 2, - 0x02, 0x23, byte(LSI.WithCN(1)), 0x45, 0x67, - 0x02, 0x23, byte(LI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB, - }, - } - - for index, data := range datas { + for index, data := range samplePayloads { test.Logf("data %2d %v [%s]", index, Tag(data[0]), tu.HexBytes(data[1:])) // integers should only assign to other integers if index > 8 { @@ -196,6 +217,27 @@ func TestEncodeDecodeAnyTable(test *testing.T) { if err != nil { test.Fatal(err) } } +func TestEncodeDecodeAnyDestination(test *testing.T) { + var destination any + for index, data := range samplePayloads { + tag := Tag(data[0]) + payload := data[1:] + test.Logf("data %2d %v [%s]", index, tag, tu.HexBytes(payload)) + n, err := DecodeAnyInto(NewDecoder(bytes.NewBuffer(payload)), &destination, tag) + if err != nil { test.Fatalf("error: %v | n: %d", err, n) } + got := destination + correct := sampleValues[index] + test.Log("got: ", tu.Describe(got)) + test.Log("correct:", tu.Describe(correct)) + if !reflect.DeepEqual(got, correct) { + test.Fatalf("values not equal") + } + if n != len(payload) { + test.Fatalf("n not equal: %d != %d", n, len(payload)) + } + } +} + func TestPeekSlice(test *testing.T) { buffer := bytes.NewBuffer([]byte { 2, byte(OTA.WithCN(3)), @@ -254,71 +296,3 @@ func TestPeekSliceOnce(test *testing.T) { test.Fatalf("wrong n: %d != %d", got, correct) } } - -func encAny(value any) ([]byte, Tag, int, error) { - tag, err := TagAny(value) - if err != nil { return nil, 0, 0, err } - buffer := bytes.Buffer { } - encoder := NewEncoder(&buffer) - n, err := EncodeAny(encoder, value, tag) - if err != nil { return nil, 0, n, err } - encoder.Flush() - return buffer.Bytes(), tag, n, nil -} - -func decAny(data []byte) (Tag, any, int, error) { - destination := map[uint16] any { } - tag, err := TagAny(destination) - if err != nil { return 0, nil, 0, err } - n, err := DecodeAnyInto(NewDecoder(bytes.NewBuffer(data)), &destination, tag) - if err != nil { return 0, nil, n, err } - return tag, destination, n, nil -} - -func testEncodeAny(test *testing.T, value any, correctTag Tag, correctBytes tu.Snake) error { - bytes, tag, n, err := encAny(value) - if err != nil { return err } - test.Log("n: ", n) - test.Log("tag: ", tag) - test.Log("got: ", tu.HexBytes(bytes)) - test.Log("correct:", correctBytes) - if tag != correctTag { - return fmt.Errorf("tag not equal: %v != %v", tag, correctTag) - } - if ok, n := correctBytes.Check(bytes); !ok { - return fmt.Errorf("bytes not equal at index %d", n) - } - if n != len(bytes) { - return fmt.Errorf("n not equal: %d != %d", n, len(bytes)) - } - return nil -} - -func testEncodeDecodeAny(test *testing.T, value, correctValue any) error { - if correctValue == nil { - correctValue = value - } - - test.Log("encoding...") - bytes, tag, n, err := encAny(value) - if err != nil { return err } - test.Log("n: ", n) - test.Log("tag:", tag) - test.Log("got:", tu.HexBytes(bytes)) - test.Log("decoding...", tag) - if n != len(bytes) { - return fmt.Errorf("n not equal: %d != %d", n, len(bytes)) - } - - _, decoded, n, err := decAny(bytes) - if err != nil { return err } - test.Log("got: ", tu.Describe(decoded)) - test.Log("correct:", tu.Describe(correctValue)) - if !reflect.DeepEqual(decoded, correctValue) { - return fmt.Errorf("values not equal") - } - if n != len(bytes) { - return fmt.Errorf("n not equal: %d != %d", n, len(bytes)) - } - return nil -} diff --git a/tape/misc_test.go b/tape/misc_test.go new file mode 100644 index 0000000..5151926 --- /dev/null +++ b/tape/misc_test.go @@ -0,0 +1,75 @@ +package tape + +import "fmt" +import "bytes" +import "testing" +import "reflect" +import tu "git.tebibyte.media/sashakoshka/hopp/internal/testutil" + +func encAny(value any) ([]byte, Tag, int, error) { + tag, err := TagAny(value) + if err != nil { return nil, 0, 0, err } + buffer := bytes.Buffer { } + encoder := NewEncoder(&buffer) + n, err := EncodeAny(encoder, value, tag) + if err != nil { return nil, 0, n, err } + encoder.Flush() + return buffer.Bytes(), tag, n, nil +} + +func decAny(data []byte) (Tag, any, int, error) { + destination := map[uint16] any { } + tag, err := TagAny(destination) + if err != nil { return 0, nil, 0, err } + n, err := DecodeAnyInto(NewDecoder(bytes.NewBuffer(data)), &destination, tag) + if err != nil { return 0, nil, n, err } + return tag, destination, n, nil +} + +func testEncodeAny(test *testing.T, value any, correctTag Tag, correctBytes tu.Snake) error { + bytes, tag, n, err := encAny(value) + if err != nil { return err } + test.Log("n: ", n) + test.Log("tag: ", tag) + test.Log("got: ", tu.HexBytes(bytes)) + test.Log("correct:", correctBytes) + if tag != correctTag { + return fmt.Errorf("tag not equal: %v != %v", tag, correctTag) + } + if ok, n := correctBytes.Check(bytes); !ok { + return fmt.Errorf("bytes not equal at index %d", n) + } + if n != len(bytes) { + return fmt.Errorf("n not equal: %d != %d", n, len(bytes)) + } + return nil +} + +func testEncodeDecodeAny(test *testing.T, value, correctValue any) error { + if correctValue == nil { + correctValue = value + } + + test.Log("encoding...") + bytes, tag, n, err := encAny(value) + if err != nil { return err } + test.Log("n: ", n) + test.Log("tag:", tag) + test.Log("got:", tu.HexBytes(bytes)) + test.Log("decoding...", tag) + if n != len(bytes) { + return fmt.Errorf("n not equal: %d != %d", n, len(bytes)) + } + + _, decoded, n, err := decAny(bytes) + if err != nil { return err } + test.Log("got: ", tu.Describe(decoded)) + test.Log("correct:", tu.Describe(correctValue)) + if !reflect.DeepEqual(decoded, correctValue) { + return fmt.Errorf("values not equal") + } + if n != len(bytes) { + return fmt.Errorf("n not equal: %d != %d", n, len(bytes)) + } + return nil +}