--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "crypto/rand"
+ "encoding/hex"
+ "io"
+ "reflect"
+ "slices"
+ "strings"
+ "testing"
+ "testing/quick"
+)
+
+func TestBinaryEmpty(t *testing.T) {
+ object := []byte{}
+ hexstring := mustHexDec("80")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if !bytes.Equal(decoded.([]byte), object) {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestBinary1234(t *testing.T) {
+ object := []byte{0x01, 0x02, 0x03, 0x04}
+ hexstring := mustHexDec("8401020304")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if !bytes.Equal(decoded.([]byte), object) {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestBinaryLen62(t *testing.T) {
+ object := bytes.Repeat([]byte{'a'}, 62)
+ hexstring := mustHexDec("BD01" + strings.Repeat("61", 62))
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if !bytes.Equal(decoded.([]byte), object) {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestBinaryLen318(t *testing.T) {
+ object := bytes.Repeat([]byte{'a'}, 318)
+ hexstring := mustHexDec("BE0001" + strings.Repeat("61", 318))
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if !bytes.Equal(decoded.([]byte), object) {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestBinaryLen65853(t *testing.T) {
+ object := bytes.Repeat([]byte{'a'}, 65853)
+ hexstring := mustHexDec("BF0000000000000000" + strings.Repeat("61", 65853))
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if !bytes.Equal(decoded.([]byte), object) {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestBinaryThrowsWhenNotEnoughData(t *testing.T) {
+ hexstring := mustHexDec("84010203")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestBinaryThrowsWhenNotEnoughDataForLength8(t *testing.T) {
+ hexstring := mustHexDec("BD01" + strings.Repeat("61", 61))
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestBinaryThrowsWhenNotEnoughDataForLength16(t *testing.T) {
+ hexstring := mustHexDec("BE0001" + strings.Repeat("61", 317))
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestBinaryThrowsWhenNotEnoughDataForLength64(t *testing.T) {
+ hexstring := mustHexDec("BF0000000000000000" + strings.Repeat("61", 65852))
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestBinSymmetric(t *testing.T) {
+ f := func(x uint8) bool {
+ str := make([]byte, x)
+ rand.Read(str)
+ encoded, err := EncodeBuf(str, nil)
+ if err != nil {
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ return false
+ }
+ if !slices.Equal(str, decoded.([]byte)) {
+ t.Logf("Expected <%s, %d>", reflect.TypeOf(str), str)
+ t.Logf("Instead <%s, %d>", reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
--- /dev/null
+// GoKEKS -- Go KEKS codec implementation
+// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, version 3 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package keks
+
+import (
+ "bytes"
+ "encoding/hex"
+ "io"
+ "reflect"
+ "testing"
+ "testing/quick"
+)
+
+func TestMultipleOfChunkLen(t *testing.T) {
+ object := BlobChunked{
+ Chunks: []string{"test", "data"},
+ ChunkLen: 4,
+ }
+ hexstring := mustHexDec("0B00000000000000038474657374846461746180")
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ udecoded, success := decoded.(BlobChunked)
+ if !success {
+ t.Errorf("failed to cast")
+ }
+ if object.ChunkLen != udecoded.ChunkLen {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ }
+ for i := range len(object.Chunks) {
+ if object.Chunks[i] != udecoded.Chunks[i] {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ }
+ }
+}
+
+func TestLargerOfChunkLen(t *testing.T) {
+ object := BlobChunked{
+ Chunks: []string{"test", "data", "2"},
+ ChunkLen: 4,
+ }
+ hexstring := mustHexDec("0B0000000000000003847465737484646174618132")
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ udecoded, success := decoded.(BlobChunked)
+ if !success {
+ t.Errorf("failed to cast")
+ }
+ if object.ChunkLen != udecoded.ChunkLen {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ }
+ for i := range len(object.Chunks) {
+ if object.Chunks[i] != udecoded.Chunks[i] {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ }
+ }
+}
+
+func TestEmpty(t *testing.T) {
+ object := BlobChunked{
+ Chunks: []string{},
+ ChunkLen: 4,
+ }
+ hexstring := mustHexDec("0B000000000000000380")
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ udecoded, success := decoded.(BlobChunked)
+ if !success {
+ t.Errorf("failed to cast")
+ }
+ if object.ChunkLen != udecoded.ChunkLen {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ }
+ for i := range len(object.Chunks) {
+ if object.Chunks[i] != udecoded.Chunks[i] {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ }
+ }
+}
+
+func TestBlobSymmetric(t *testing.T) {
+ f := func(ChunkLen uint8, ChunkNum uint8) bool {
+ if uint16(ChunkLen)*uint16(ChunkNum) > 2000 {
+ return true
+ }
+ chunks := make([]string, ChunkNum)
+ for i := range ChunkNum {
+ chunks[i] = RandStringBytes(int(ChunkLen))
+ }
+ object := BlobChunked{
+ Chunks: chunks,
+ ChunkLen: int64(ChunkLen),
+ }
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ return false
+ }
+ decoded, err := NewDecoderFromBytes(encoded, nil).Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(BlobChunked)
+ if !success {
+ t.Errorf("failed to cast")
+ return false
+ }
+ if object.ChunkLen != udecoded.ChunkLen {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ for i := range len(object.Chunks) {
+ if object.Chunks[i] != udecoded.Chunks[i] {
+ t.Errorf("expected <%s, %v>", reflect.TypeOf(object), object)
+ t.Errorf("instead <%s, %v>", reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestBlobThrowsWhenNotEnoughData(t *testing.T) {
+ hexstring := mustHexDec("0B00000000000000038474657374846461")
+ _, err := NewDecoderFromBytes(hexstring, nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %s", err)
+ }
+}
+
+func TestBlobThrowsWhenNotEnoughDataForLength(t *testing.T) {
+ hexstring := mustHexDec("0B00000000")
+ _, err := NewDecoderFromBytes(hexstring, nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %s", err)
+ }
+}
+
+func TestBlobThrowsWhenWrongTerminatorLength(t *testing.T) {
+ hexstring := mustHexDec("0B0000000000000003847465737484646174618A7465726D696E61746F72")
+ _, err := NewDecoderFromBytes(hexstring, nil).Decode()
+ if err != ErrBlobBadChunkLen {
+ t.Errorf("expected ErrBlobBadChunkLen, got %s", err)
+ }
+}
+
+func TestBlobThrowsWhenWrongTerminatorTag(t *testing.T) {
+ hexstring := mustHexDec("0B00000000000000038474657374846461746104746861742077617320612077726F6E6720746167")
+ _, err := NewDecoderFromBytes(hexstring, nil).Decode()
+ if err != ErrBlobBadAtom {
+ t.Errorf("expected ErrBlobBadChunkLen, got %s", err)
+ }
+}
\ No newline at end of file
--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "encoding/hex"
+ "reflect"
+ "testing"
+)
+
+func TestTrue(t *testing.T) {
+ object := true
+ hexstring := mustHexDec("03")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value true", reflect.TypeOf(object))
+ t.Logf("got type %s, value %t", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestFalse(t *testing.T) {
+ object := false
+ hexstring := mustHexDec("02")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value true", reflect.TypeOf(object))
+ t.Logf("got type %s, value %t", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
--- /dev/null
+// GoKEKS -- Go KEKS codec implementation
+// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, version 3 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package keks
+
+import (
+ "bytes"
+ "io"
+ "reflect"
+ "testing"
+)
+
+func TestThrowsWhenEncodingFloat(t *testing.T) {
+ _, err := EncodeBuf(1.5, nil)
+ if err == nil {
+ t.Errorf("expected Error, got nil")
+ }
+}
+
+func TestLoadsFloat16(t *testing.T) {
+ decoded, err := NewDecoderFromBytes(append([]byte{0x10}, bytes.Repeat([]byte{0x11}, 2)...), nil).Decode()
+ object := Raw(append([]byte{0x10}, bytes.Repeat([]byte{0x11}, 2)...))
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ udecoded, success := decoded.(Raw)
+ if !success {
+ t.Errorf("expected Raw, got %v", reflect.TypeOf(decoded))
+ }
+ if !bytes.Equal(object, udecoded) {
+ t.Errorf("expected %v, got %v", object, decoded)
+ }
+}
+
+func TestLoadsFloat32(t *testing.T) {
+ decoded, err := NewDecoderFromBytes(append([]byte{0x11}, bytes.Repeat([]byte{0x11}, 4)...), nil).Decode()
+ object := Raw(append([]byte{0x11}, bytes.Repeat([]byte{0x11}, 4)...))
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ udecoded, success := decoded.(Raw)
+ if !success {
+ t.Errorf("expected Raw, got %v", reflect.TypeOf(decoded))
+ }
+ if !bytes.Equal(object, udecoded) {
+ t.Errorf("expected %v, got %v", object, decoded)
+ }
+}
+
+func TestLoadsFloat64(t *testing.T) {
+ decoded, err := NewDecoderFromBytes(append([]byte{0x12}, bytes.Repeat([]byte{0x11}, 8)...), nil).Decode()
+ object := Raw(append([]byte{0x12}, bytes.Repeat([]byte{0x11}, 8)...))
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ udecoded, success := decoded.(Raw)
+ if !success {
+ t.Errorf("expected Raw, got %v", reflect.TypeOf(decoded))
+ }
+ if !bytes.Equal(object, udecoded) {
+ t.Errorf("expected %v, got %v", object, decoded)
+ }
+}
+
+func TestLoadsFloat128(t *testing.T) {
+ decoded, err := NewDecoderFromBytes(append([]byte{0x13}, bytes.Repeat([]byte{0x11}, 16)...), nil).Decode()
+ object := Raw(append([]byte{0x13}, bytes.Repeat([]byte{0x11}, 16)...))
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ udecoded, success := decoded.(Raw)
+ if !success {
+ t.Errorf("expected Raw, got %v", reflect.TypeOf(decoded))
+ }
+ if !bytes.Equal(object, udecoded) {
+ t.Errorf("expected %v, got %v", object, decoded)
+ }
+}
+
+func TestLoadsFloat256(t *testing.T) {
+ decoded, err := NewDecoderFromBytes(append([]byte{0x14}, bytes.Repeat([]byte{0x11}, 32)...), nil).Decode()
+ object := Raw(append([]byte{0x14}, bytes.Repeat([]byte{0x11}, 32)...))
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ udecoded, success := decoded.(Raw)
+ if !success {
+ t.Errorf("expected Raw, got %v", reflect.TypeOf(decoded))
+ }
+ if !bytes.Equal(object, udecoded) {
+ t.Errorf("expected %v, got %v", object, decoded)
+ }
+}
+
+func TestThrowhsWhenNotEnoughDataForFloat256(t *testing.T) {
+ _, err := NewDecoderFromBytes(append([]byte{0x14}, bytes.Repeat([]byte{0x11}, 32-1)...), nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %s", err)
+ }
+}
+
+func TestThrowhsWhenNotEnoughDataForFloat128(t *testing.T) {
+ _, err := NewDecoderFromBytes(append([]byte{0x13}, bytes.Repeat([]byte{0x11}, 16-1)...), nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %s", err)
+ }
+}
+
+func TestThrowhsWhenNotEnoughDataForFloat64(t *testing.T) {
+ _, err := NewDecoderFromBytes(append([]byte{0x12}, bytes.Repeat([]byte{0x11}, 8-1)...), nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %s", err)
+ }
+}
+
+func TestThrowhsWhenNotEnoughDataForFloat32(t *testing.T) {
+ _, err := NewDecoderFromBytes(append([]byte{0x11}, bytes.Repeat([]byte{0x11}, 4-1)...), nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %s", err)
+ }
+}
+
+func TestThrowhsWhenNotEnoughDataForFloat16(t *testing.T) {
+ _, err := NewDecoderFromBytes(append([]byte{0x10}, bytes.Repeat([]byte{0x11}, 2-1)...), nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %s", err)
+ }
+}
--- /dev/null
+package keks
+
+import (
+ "io"
+ "testing"
+)
+
+func TestThrowsWhenUnknownTag(t *testing.T) {
+ hexstring := []byte{0x05}
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != ErrUnknownType {
+ t.Errorf("expected ErrUnknownType, got %v", err)
+ }
+}
+
+func TestThrowsWhenEmptyData(t *testing.T) {
+ hexstring := []byte{}
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestLonelyEOC(t *testing.T) {
+ hexstring := []byte{0x00}
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != ErrUnexpectedEOC {
+ t.Errorf("expected ErrUnexpectedEOC, got %v", err)
+ }
+}
\ No newline at end of file
--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "encoding/hex"
+ "io"
+ "math/big"
+ "reflect"
+ "testing"
+ "testing/quick"
+)
+
+func mustHexDec(s string) []byte {
+ b, err := hex.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+func TestZero(t *testing.T) {
+ object := uint64(0)
+ hexstring := mustHexDec("0C80")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestOne(t *testing.T) {
+ object := uint64(1)
+ hexstring := mustHexDec("0C8101")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestNegativeOne(t *testing.T) {
+ object := int64(-1)
+ hexstring := mustHexDec("0D80")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func Test1s63(t *testing.T) {
+ object := big.NewInt(0).SetBytes(mustHexDec("800000000000000000"))
+ hexstring := mustHexDec("0C89800000000000000000")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded.(*big.Int).Cmp(object) != 0 {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func Test1s64(t *testing.T) {
+ object := big.NewInt(1).SetBytes(mustHexDec("010000000000000000"))
+ hexstring := mustHexDec("0C89010000000000000000")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded.(*big.Int).Cmp(object) != 0 {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func Test1s130(t *testing.T) {
+ object := big.NewInt(1).SetBytes(mustHexDec("0400000000000000000000000000000000"))
+ hexstring := mustHexDec("0C910400000000000000000000000000000000")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded.(*big.Int).Cmp(object) != 0 {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestM1s63(t *testing.T) {
+ object := big.NewInt(0).SetBytes(mustHexDec("00800000000000000000"))
+ object = object.Neg(object)
+ hexstring := mustHexDec("0D897FFFFFFFFFFFFFFFFF")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded.(*big.Int).Cmp(object) != 0 {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestM1s64(t *testing.T) {
+ object := big.NewInt(0).SetBytes(mustHexDec("010000000000000000"))
+ object = object.Neg(object)
+ hexstring := mustHexDec("0D88FFFFFFFFFFFFFFFF")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded.(*big.Int).Cmp(object) != 0 {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestM1s130(t *testing.T) {
+ object := big.NewInt(1).SetBytes(mustHexDec("0100000000000000000000000000000000"))
+ object = object.Neg(object)
+ hexstring := mustHexDec("0D90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded.(*big.Int).Cmp(object) != 0 {
+ t.Logf("expected type %s, value %d", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %d", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestDecodeNotEnoughData(t *testing.T) {
+ _, err := NewDecoderFromBytes(mustHexDec("0C830102"), nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected error, got %v", err)
+ }
+ _, err = NewDecoderFromBytes(mustHexDec("0C8301"), nil).Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected error, got %v", err)
+ }
+}
+
+func TestThrowsWhenUnminimalInt(t *testing.T) {
+ encoded := mustHexDec("0C81007B")
+ _, err := NewDecoderFromBytes(encoded, nil).Decode()
+ if err != ErrIntNonMinimal {
+ t.Errorf("expected ErrIntNonMinimal, got %v", err)
+ }
+}
+
+func TestThrowsWhenNonBinInInt(t *testing.T) {
+ encoded := mustHexDec("0C017B")
+ _, err := NewDecoderFromBytes(encoded, nil).Decode()
+ if err != ErrBadInt {
+ t.Errorf("expected ErrBadInt, got %v", err)
+ }
+}
+func TestTemp(t *testing.T) {
+ object, suc := big.NewInt(1).SetString("-400000000000000000090009090909090909000000000000", 10)
+ t.Log(object)
+ if !suc {
+ t.Errorf("expected ErrBadInt, got %v", suc)
+ }
+}
+
+func TestUInt64Symmetric(t *testing.T) {
+ f := func(x uint64) bool {
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ if x != decoded {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestUInt32Symmetric(t *testing.T) {
+ f := func(x uint32) bool {
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(uint64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != uint32(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+func TestUInt16Symmetric(t *testing.T) {
+ f := func(x uint16) bool {
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(uint64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != uint16(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+func TestUInt8Symmetric(t *testing.T) {
+ f := func(x uint8) bool {
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(uint64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != uint8(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestPlusInt32Symmetric(t *testing.T) {
+ f := func(x int32) bool {
+ if x == -1<<31 {
+ return true
+ }
+ if x < 0 {
+ x = -x
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(uint64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int32(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestMinusInt32Symmetric(t *testing.T) {
+ f := func(x int32) bool {
+ if x > 0 {
+ x = -x
+ }
+ if x == 0 {
+ return true
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(int64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int32(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestPlusInt16Symmetric(t *testing.T) {
+ f := func(x int16) bool {
+ if x == -1<<15 {
+ return true
+ }
+ if x < 0 {
+ x = -x
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(uint64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int16(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestMinusInt16Symmetric(t *testing.T) {
+ f := func(x int16) bool {
+ if x > 0 {
+ x = -x
+ }
+ if x == 0 {
+ return true
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(int64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int16(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestPlusInt8Symmetric(t *testing.T) {
+ f := func(x int8) bool {
+ if x == -1<<7 {
+ return true
+ }
+ if x < 0 {
+ x = -x
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(uint64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int8(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestMinusInt8Symmetric(t *testing.T) {
+ f := func(x int8) bool {
+ if x > 0 {
+ x = -x
+ }
+ if x == 0 {
+ return true
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(int64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int8(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestPlusInt64Symmetric(t *testing.T) {
+ f := func(x int64) bool {
+ if x < 0 {
+ x = -x
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(uint64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int64(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestMinusInt64Symmetric(t *testing.T) {
+ f := func(x int64) bool {
+ if x > 0 {
+ x = -x
+ }
+ if x == 0 {
+ return true
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+
+ }
+ udecoded, success := decoded.(int64)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ if x != int64(udecoded) {
+ t.Logf("Expected <%s, %d>, got <%s, %d>", reflect.TypeOf(x), x, reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "encoding/hex"
+ "io"
+ "reflect"
+ "slices"
+ "testing"
+ "testing/quick"
+)
+
+func TestListEmpty(t *testing.T) {
+ object := []any{}
+ hexstring := []byte("\x08\x00")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ udecoded, success := decoded.([]any)
+ if !success {
+ t.Errorf("failed to cast")
+ }
+ if !slices.Equal(object, udecoded) {
+ t.Logf("expected type %s, value true", reflect.TypeOf(object))
+ t.Logf("got type %s, value %t", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestThrowsWhenNoEOC(t *testing.T) {
+ hexstring := []byte("\x08")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestListIntSymmetric(t *testing.T) {
+ f := func(x []uint64) bool {
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ return false
+ }
+ udecoded, success := decoded.([]any)
+ if !success {
+
+ t.Errorf("failed to cast")
+ }
+ for i := range x {
+ if x[i] != udecoded[i] {
+ t.Logf("Expected <%s, %d>", reflect.TypeOf(x), x)
+ t.Logf("Instead <%s, %d>", reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "encoding/hex"
+ "maps"
+ "reflect"
+ "testing"
+ "testing/quick"
+)
+
+func TestEmptyMap(t *testing.T) {
+ hexstring := []byte("\x09\x00")
+ object := make(map[string]any)
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ udecoded, success := decoded.(map[string]any)
+ if !success {
+ t.Errorf("failed to cast")
+ }
+ if !maps.Equal(object, udecoded) {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Fail()
+ }
+}
+
+func TestThrowsWhenNonStringKey(t *testing.T) {
+ object := make(map[any]any)
+ object[1] = "a"
+ hexstring := []byte("\x09\x0C\x80\xC6value2\x00")
+ _, err := EncodeBuf(object, nil)
+ if err != ErrMapBadKey {
+ t.Errorf("expected ErrMapBadKey during encode, got %v", err)
+ }
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err = decoder.Decode()
+ if err != ErrMapBadKey {
+ t.Errorf("expected ErrMapBadKey during decode, got %v", err)
+ }
+}
+
+func TestThrowsWhenUnexpectedEOC(t *testing.T) {
+ hexstring := []byte("\x09\xC4key1\x00\x00")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != ErrUnexpectedEOC {
+ t.Errorf("expected ErrUnexpectedEOC during decode, got %v", err)
+ }
+}
+
+func TestThrowsWhenEmptyStringKey(t *testing.T) {
+ object := make(map[any]any)
+ object[""] = "a"
+ hexstring := []byte("\x09\xC0\x0C\x81\x01\xC4key1\xC6value1\x00")
+ _, err := EncodeBuf(object, nil)
+ if err != ErrMapBadKey {
+ t.Errorf("expected ErrMapBadKey during encode, got %v", err)
+ }
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err = decoder.Decode()
+ if err != ErrMapBadKey {
+ t.Errorf("expected ErrMapBadKey during decode, got %v", err)
+ }
+}
+
+func TestThrowsWhenUnsortedKeys(t *testing.T) {
+ hexstring := []byte("\x09\xC4key2\xC6value2\xC4key1\xC6value1\x00")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != ErrMapUnordered {
+ t.Errorf("expected ErrMapUnordered during decode, got %v", err)
+ }
+}
+
+func TestMapIntSymmetric(t *testing.T) {
+ f := func(x map[string]uint64) bool {
+ delete(x, "")
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(map[string]any)
+ if !success {
+ t.Logf("failed to cast")
+ return false
+ }
+ for k := range x {
+ if x[k] != udecoded[k] {
+ t.Logf("expected <%s, %v>", reflect.TypeOf(x), x)
+ t.Logf("instead <%s, %v>", reflect.TypeOf(udecoded), udecoded)
+ return false
+ }
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "encoding/hex"
+ "io"
+ "math/rand"
+ "reflect"
+ "strings"
+ "testing"
+ "testing/quick"
+)
+
+func TestEmptyString(t *testing.T) {
+ object := ""
+ hexstring := mustHexDec("C0")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestStringLen62(t *testing.T) {
+ object := strings.Repeat("a", 62)
+ hexstring := mustHexDec(
+ strings.Join([]string{"FD01", strings.Repeat("61", 62)}, ""),
+ )
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestStringLen318(t *testing.T) {
+ object := strings.Repeat("a", 318)
+ hexstring := mustHexDec(
+ strings.Join([]string{"FE0001", strings.Repeat("61", 318)}, ""),
+ )
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected hexstring %s, got %s", hex.EncodeToString(hexstring), hex.EncodeToString(encoded))
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestStringLen65853(t *testing.T) {
+ object := strings.Repeat("a", 65853)
+ hexstring := mustHexDec(
+ strings.Join([]string{"FF0000000000000000", strings.Repeat("61", 65853)}, ""),
+ )
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ encoded, err := EncodeBuf(object, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if !bytes.Equal(encoded, hexstring) {
+ t.Logf("expected hexstring to begin with %s, got %s", hex.EncodeToString(hexstring)[:40], hex.EncodeToString(encoded)[:40])
+ t.Fail()
+ }
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %s", err)
+ }
+ if decoded != object {
+ t.Logf("expected type %s, value %s", reflect.TypeOf(object), object)
+ t.Logf("got type %s, value %s", reflect.TypeOf(decoded), decoded)
+ t.Error()
+ }
+}
+
+func TestThrowsWhenNullByteInUTF8(t *testing.T) {
+ hexstring := []byte("\xC5he\x00\x01\x02")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != ErrBadUTF8 {
+ t.Errorf("expected ErrBadUTF8, got %v", err)
+ }
+}
+
+func TestOkWhenNullByteInUTF8AndUTF8CheckDisabled(t *testing.T) {
+ hexstring := []byte("\xC5he\xe2\x82\x28")
+ decoder := NewDecoderFromBytes(hexstring, &DecodeOpts{DisableUTF8Check: true})
+ _, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+}
+
+func TestThrowsWhenInvalid2BytesInUTF8(t *testing.T) {
+ hexstring := []byte("\xC5he\xc3\x28o")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != ErrBadUTF8 {
+ t.Errorf("expected ErrBadUTF8, got %v", err)
+ }
+}
+
+func TestOkWhenInvalid2BytesUTF8AndUTF8CheckDisabled(t *testing.T) {
+ hexstring := []byte("\xC5he\xc3\x28o")
+ decoder := NewDecoderFromBytes(hexstring, &DecodeOpts{DisableUTF8Check: true})
+ _, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+}
+
+func TestThrowsWhenInvalidUTF3Bytes(t *testing.T) {
+ hexstring := []byte("\xC5he\xe2\x82\x28")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != ErrBadUTF8 {
+ t.Errorf("expected ErrBadUTF8, got %v", err)
+ }
+}
+
+func TestOkWhenInvalid3BytesUTF8AndUTF8CheckDisabled(t *testing.T) {
+ hexstring := []byte("\xC5he\xe2\x82\x28")
+ decoder := NewDecoderFromBytes(hexstring, &DecodeOpts{DisableUTF8Check: true})
+ _, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+}
+
+func TestThrowsWhenNotEnoughData(t *testing.T) {
+ hexstring := []byte("\xC5he")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestThrowsWhenNotEnoughDataForLength8(t *testing.T) {
+ hexstring := []byte("\xC5he")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestThrowsWhenNotEnoughDataForLength16(t *testing.T) {
+ hexstring := []byte("\xC5he")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestThrowsWhenNotEnoughDataForLength64(t *testing.T) {
+ hexstring := []byte("\xC5he")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+func RandStringBytes(n int) string {
+ b := make([]byte, n)
+ for i := range b {
+ b[i] = letterBytes[rand.Intn(len(letterBytes))]
+ }
+ return string(b)
+}
+
+func TestThrowsWhenStringTooLong(t *testing.T) {
+ f := func(x uint8, y uint8) bool {
+ if (y == x) || (y == 0) || (x == 0) {
+ return true
+ }
+ if y > x {
+ z := x
+ x = y
+ y = z
+ }
+ str := RandStringBytes(int(x))
+ encoded, _ := EncodeBuf(str, nil)
+ decoder := NewDecoderFromBytes(encoded, &DecodeOpts{MaxStrLen: int64(x - y)})
+ _, err := decoder.Decode()
+ if err != ErrLenTooBig {
+ t.Logf("expected ErrLenTooBig, got %v", err)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestStringSymmetric(t *testing.T) {
+ f := func(x uint8) bool {
+ str := RandStringBytes(int(x))
+ encoded, err := EncodeBuf(str, nil)
+ if err != nil {
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ return false
+ }
+ if str != decoded.(string) {
+ t.Logf("Expected <%s, %s>", reflect.TypeOf(str), str)
+ t.Logf("Instead <%s, %s>", reflect.TypeOf(decoded), decoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "testing"
+ "testing/quick"
+ "time"
+)
+
+func TestLargeNumberOfSeconds(t *testing.T) {
+ hexstring := mustHexDec("187000000065195F65")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ t.Log(decoded)
+}
+
+func TestThrowsWhenMsbIsSet(t *testing.T) {
+ hexstring := mustHexDec("188000000065195F65")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err == nil {
+ t.Errorf("expected 'reserved TAI64 value is in use', got %v", err)
+ }
+}
+
+func TestThrowsWhenTooManyNanosecs(t *testing.T) {
+ hexstring := bytes.Join([][]byte{mustHexDec("194000000065195F65"), []byte(";\x9a\xca\x00")}, nil)
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err == nil {
+ t.Errorf("expected 'too many nanoseconds', got %v", err)
+ }
+}
+
+func TestThrowsWhenZeroNanoseconds(t *testing.T) {
+ hexstring := mustHexDec("19400000000000000000000000")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err == nil {
+ t.Errorf("expected 'non-minimal TAI64N', got %v", err)
+ }
+}
+
+func TestThrowsWhenTooManyAttoseconds(t *testing.T) {
+ hexstring := mustHexDec("1A4000000065195F65075BCA00A75BCA00")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err == nil {
+ t.Errorf("expected 'too many attoseconds', got %v", err)
+ }
+}
+
+func TestThrowsWhenZeroAttoseconds(t *testing.T) {
+ hexstring := mustHexDec("1A40000000000000000000000000000000")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err == nil {
+ t.Errorf("expected 'non-minimal TAI64NA', got %v", err)
+ }
+}
+
+func TestZeroNanosecondsOkForTAI64NA(t *testing.T) {
+ hexstring := mustHexDec("1A40000000000000000000000000000001")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("expected no error, got %v", err)
+ }
+}
+
+func TestThrowsWhenMsbIsSetForTAI64NA(t *testing.T) {
+ hexstring := bytes.Join([][]byte{mustHexDec("1A8000000065195F65"), mustHexDec("00010000"), mustHexDec("00010000")}, nil)
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ _, err := decoder.Decode()
+ if err == nil {
+ t.Errorf("expected 'reserved TAI64 value is in use', got %v", err)
+ }
+}
+
+func Test19700101(t *testing.T) {
+ hexstring := mustHexDec("18400000000000000A")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ expected := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
+ decodedTime := decoded.(time.Time)
+ if !decodedTime.Equal(expected) {
+ t.Errorf("expected %v, got %v", expected, decoded)
+ }
+}
+
+func Test19920602(t *testing.T) {
+ hexstring := mustHexDec("18400000002A2B2C2D")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ decodedTime := decoded.(time.Time)
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ expected := time.Date(1992, 6, 2, 8, 6, 43, 0, time.UTC)
+ if !decodedTime.Equal(expected) {
+ t.Errorf("expected %v, got %v", expected, decoded)
+ }
+}
+
+func Test19971003(t *testing.T) {
+ hexstring := mustHexDec("184000000034353637")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ decodedTime := decoded.(time.Time)
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ expected := time.Date(1997, 10, 3, 18, 14, 48, 0, time.UTC)
+ if !decodedTime.Equal(expected) {
+ t.Errorf("expected %v, got %v", expected, decoded)
+ }
+}
+
+func Test20161231(t *testing.T) {
+ hexstring := mustHexDec("1840000000586846A3")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ decodedTime := decoded.(time.Time)
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ expected := time.Date(2016, 12, 31, 23, 59, 59, 0, time.UTC)
+ if !decodedTime.Equal(expected) {
+ t.Errorf("expected %v, got %v", expected, decoded)
+ }
+}
+
+func Test20170101(t *testing.T) {
+ hexstring := mustHexDec("1840000000586846A5")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ decodedTime := decoded.(time.Time)
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ expected := time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC)
+ if !decodedTime.Equal(expected) {
+ t.Errorf("expected %v, got %v", expected, decoded)
+ }
+}
+
+func Test20241120(t *testing.T) {
+ hexstring := mustHexDec("1940000000673DD3E136F11FE0")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ decodedTime := decoded.(time.Time)
+ if err != nil {
+ t.Errorf("error during decode: %v", err)
+ }
+ expected := time.Date(2024, 11, 20, 12, 19, 8, 921772000, time.UTC)
+ if !decodedTime.Equal(expected) {
+ t.Errorf("expected %v, got %v", expected, decoded)
+ }
+}
+
+func TestTaiSymmetric(t *testing.T) {
+ f := func(a int64, b int64) bool {
+ x := time.Unix(a, b)
+ if a > 1<<62-1 {
+ return true
+ }
+ if a < -1<<62 {
+ return true
+ }
+ encoded, err := EncodeBuf(x, nil)
+ if err != nil {
+ t.Logf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Logf("error during decode: %s", err)
+ return false
+ }
+ udecoded, success := decoded.(time.Time)
+ if !success {
+ return false
+ }
+ return x.Equal(udecoded)
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
--- /dev/null
+package keks
+
+import (
+ "bytes"
+ "reflect"
+ "testing"
+ "testing/quick"
+
+ "github.com/google/uuid"
+)
+
+func TestUUIDEncodeDecode(t *testing.T) {
+ object, _ := uuid.Parse("12345678-1234-5678-1234-567812345678")
+ hexstring := mustHexDec("0412345678123456781234567812345678")
+ decoder := NewDecoderFromBytes(hexstring, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if decoded != object {
+ t.Errorf("expected %v, got %v", object, decoded)
+ }
+ encoded, err := EncodeBuf(hexstring, nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ }
+ if bytes.Equal(encoded, hexstring) {
+ t.Errorf("expected %v, got %v", hexstring, encoded)
+ }
+}
+
+func TestUUIDSymmetric(t *testing.T) {
+ f := func(x uuid.UUID) bool {
+ encoded, err := EncodeBuf(x[:], nil)
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ return false
+ }
+ decoder := NewDecoderFromBytes(encoded, nil)
+ decoded, err := decoder.Decode()
+ if err != nil {
+ t.Errorf("error during encode: %s", err)
+ return false
+ }
+ decodedBytes, success := decoded.([]byte)
+ if !success {
+ t.Errorf("failed to cast to []byte")
+ return false
+ }
+ udecoded, err := uuid.FromBytes(decodedBytes)
+ if err != nil {
+ t.Errorf("failed to cast to uuid")
+ return false
+ }
+ if x != udecoded {
+ t.Logf("expected <%s, %d>", reflect.TypeOf(x), x)
+ t.Logf("instead <%s, %d>", reflect.TypeOf(udecoded), udecoded)
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}