299 lines
8.3 KiB
Go
299 lines
8.3 KiB
Go
package tape
|
|
|
|
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) {
|
|
err := testEncodeAny(test, uint8(0xCA), LI.WithCN(0), tu.S(0xCA))
|
|
if err != nil { test.Fatal(err) }
|
|
err = testEncodeAny(test, 400, LSI.WithCN(3), tu.S(
|
|
0, 0, 0x1, 0x90,
|
|
))
|
|
if err != nil { test.Fatal(err) }
|
|
}
|
|
|
|
func TestEncodeAnyTable(test *testing.T) {
|
|
err := testEncodeAny(test, map[uint16] any {
|
|
0xF3B9: 1,
|
|
0x0102: 2,
|
|
0x0000: "hi!",
|
|
0xFFFF: []uint16 { 0xBEE5, 0x7777 },
|
|
0x1234: [][]uint16 { []uint16 { 0x5 }, []uint16 { 0x17, 0xAAAA} },
|
|
0x2345: [][]int16 { []int16 { 0x5 }, []int16 { 0x17, -0xAAA } },
|
|
0x3456: userDefinedInteger(0x3921),
|
|
0x1F1F: float32(67.26),
|
|
0x0F0F: float64(5.3),
|
|
}, KTV.WithCN(0), tu.S(9).AddVar(
|
|
[]byte {
|
|
0xF3, 0xB9,
|
|
byte(LSI.WithCN(3)),
|
|
0, 0, 0, 1,
|
|
},
|
|
[]byte {
|
|
0x01, 0x02,
|
|
byte(LSI.WithCN(3)),
|
|
0, 0, 0, 2,
|
|
},
|
|
[]byte {
|
|
0, 0,
|
|
byte(SBA.WithCN(3)),
|
|
'h', 'i', '!',
|
|
},
|
|
[]byte {
|
|
0xFF, 0xFF,
|
|
byte(OTA.WithCN(0)), 2, byte(LI.WithCN(1)),
|
|
0xBE, 0xE5, 0x77, 0x77,
|
|
},
|
|
[]byte {
|
|
0x12, 0x34,
|
|
byte(OTA.WithCN(0)), 2, byte(OTA.WithCN(0)),
|
|
1, byte(LI.WithCN(1)),
|
|
0, 0x5,
|
|
2, byte(LI.WithCN(1)),
|
|
0, 0x17,
|
|
0xAA, 0xAA,
|
|
},
|
|
[]byte {
|
|
0x23, 0x45,
|
|
byte(OTA.WithCN(0)), 2, byte(OTA.WithCN(0)),
|
|
1, byte(LSI.WithCN(1)),
|
|
0, 0x5,
|
|
2, byte(LSI.WithCN(1)),
|
|
0, 0x17,
|
|
0xF5, 0x56,
|
|
},
|
|
[]byte {
|
|
0x34, 0x56,
|
|
byte(LSI.WithCN(1)),
|
|
0x39, 0x21,
|
|
},
|
|
[]byte {
|
|
0x1F, 0x1F,
|
|
byte(FP.WithCN(3)),
|
|
0x42, 0x86, 0x85, 0x1F,
|
|
},
|
|
[]byte {
|
|
0x0F, 0x0F,
|
|
byte(FP.WithCN(7)),
|
|
0x40, 0x15, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
|
|
},
|
|
))
|
|
if err != nil { test.Fatal(err) }
|
|
}
|
|
|
|
func TestDecodeWrongType(test *testing.T) {
|
|
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 {
|
|
cas := func(destination any) {
|
|
n, err := DecodeAnyInto(NewDecoder(bytes.NewBuffer(data[1:])), destination, Tag(data[0]))
|
|
if err != nil { test.Fatalf("error: %v | n: %d", err, n) }
|
|
reflectValue := reflect.ValueOf(destination).Elem()
|
|
if reflectValue.CanInt() {
|
|
if reflectValue.Int() != 0 {
|
|
test.Fatalf("destination not zero: %v", reflectValue.Elem().Interface())
|
|
}
|
|
} else {
|
|
if reflectValue.Uint() != 0 {
|
|
test.Fatalf("destination not zero: %v", reflectValue.Elem().Interface())
|
|
}
|
|
}
|
|
if n != len(data) - 1 {
|
|
test.Fatalf("n not equal: %d != %d", n, len(data) - 1)
|
|
}
|
|
}
|
|
test.Log("- int8")
|
|
{ var dest int8; cas(&dest) }
|
|
test.Log("- int16")
|
|
{ var dest int16; cas(&dest) }
|
|
test.Log("- int32")
|
|
{ var dest int32; cas(&dest) }
|
|
test.Log("- int64")
|
|
{ var dest int64; cas(&dest) }
|
|
test.Log("- uint8")
|
|
{ var dest uint8; cas(&dest) }
|
|
test.Log("- uint16")
|
|
{ var dest uint16; cas(&dest) }
|
|
test.Log("- uint32")
|
|
{ var dest uint32; cas(&dest) }
|
|
test.Log("- uint64")
|
|
{ var dest uint64; cas(&dest) }
|
|
}
|
|
arrayCase := func(destination any) {
|
|
n, err := DecodeAnyInto(NewDecoder(bytes.NewBuffer(data[1:])), destination, Tag(data[0]))
|
|
if err != nil { test.Fatalf("error: %v | n: %d", err, n) }
|
|
reflectDestination := reflect.ValueOf(destination)
|
|
reflectValue := reflectDestination.Elem()
|
|
if reflectValue.Len() != 0 {
|
|
test.Fatalf("len(destination) not zero: %v", reflectValue.Interface())
|
|
}
|
|
if n != len(data) - 1 {
|
|
test.Fatalf("n not equal: %d != %d", n, len(data) - 1)
|
|
}
|
|
}
|
|
// SBA/LBA types should only assign to other SBA/LBA types
|
|
if index != 9 && index != 10 {
|
|
test.Log("- string")
|
|
{ var dest string; arrayCase(&dest) }
|
|
test.Log("- []byte")
|
|
{ var dest []byte; arrayCase(&dest) }
|
|
}
|
|
// arrays should only assign to other arrays
|
|
if index != 11 {
|
|
test.Log("- []string")
|
|
{ var dest []string; arrayCase(&dest) }
|
|
}
|
|
// tables should only assign to other tables
|
|
if index != 12 {
|
|
test.Log("- map[uint16] any")
|
|
{ var dest = map[uint16] any { }; arrayCase(&dest) }
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEncodeDecodeAnyTable(test *testing.T) {
|
|
err := testEncodeDecodeAny(test, map[uint16] any {
|
|
0xF3B9: uint32(1),
|
|
0x0102: uint32(2),
|
|
0x0103: int64(23432),
|
|
0x0104: int64(-88777),
|
|
0x0000: []byte("hi!"),
|
|
0xFFFF: []uint16 { 0xBEE5, 0x7777 },
|
|
0x1234: [][]uint16 { []uint16 { 0x5 }, []uint16 { 0x17, 0xAAAA} },
|
|
0x1F1F: float32(67.26),
|
|
0x0F0F: float64(5.3),
|
|
}, nil)
|
|
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)),
|
|
0, 0, 0, 1, byte(LI.WithCN(1)),
|
|
0, 0x5,
|
|
2, byte(LI.WithCN(1)),
|
|
0, 0x17,
|
|
0xAA, 0xAA,
|
|
})
|
|
decoder := NewDecoder(buffer)
|
|
|
|
elem, dimension, err := peekSlice(decoder, OTA.WithCN(0))
|
|
if err != nil { test.Fatal(err) }
|
|
if elem != LI.WithCN(1) {
|
|
test.Fatalf("wrong element tag: %v %02X", elem, byte(elem))
|
|
}
|
|
if got, correct := dimension, 2; got != correct {
|
|
test.Fatalf("wrong dimension: %d != %d", got, correct)
|
|
}
|
|
}
|
|
|
|
func TestPeekSliceOnce(test *testing.T) {
|
|
buffer := bytes.NewBuffer([]byte {
|
|
2, byte(OTA.WithCN(3)),
|
|
0, 0, 0, 1, byte(LI.WithCN(1)),
|
|
0, 0x5,
|
|
2, byte(LI.WithCN(1)),
|
|
0, 0x17,
|
|
0xAA, 0xAA,
|
|
})
|
|
decoder := NewDecoder(buffer)
|
|
|
|
test.Log("--- stage 1")
|
|
elem, populated, n, err := peekSliceOnce(decoder, OTA.WithCN(0), 0)
|
|
if err != nil { test.Fatal(err) }
|
|
if elem != OTA.WithCN(3) {
|
|
test.Fatal("wrong element tag:", elem)
|
|
}
|
|
if !populated {
|
|
test.Fatal("wrong populated:", populated)
|
|
}
|
|
if got, correct := n, 2; got != correct {
|
|
test.Fatalf("wrong n: %d != %d", got, correct)
|
|
}
|
|
|
|
test.Log("--- stage 2")
|
|
elem, populated, n, err = peekSliceOnce(decoder, elem, n)
|
|
if err != nil { test.Fatal(err) }
|
|
if elem != LI.WithCN(1) {
|
|
test.Fatal("wrong element tag:", elem)
|
|
}
|
|
if !populated {
|
|
test.Fatal("wrong populated:", populated)
|
|
}
|
|
if got, correct := n, 7; got != correct {
|
|
test.Fatalf("wrong n: %d != %d", got, correct)
|
|
}
|
|
}
|