296 lines
12 KiB
Go
296 lines
12 KiB
Go
// Copyright 2024 Dolthub, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"math"
|
|
"sort"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestWriterReader tests that the writer can round-trip with the reader, preserving data while writing every data type.
|
|
func TestWriterReader(t *testing.T) {
|
|
writer := NewWriter(0)
|
|
writer.Bool(false)
|
|
writer.Bool(true)
|
|
writer.Int8(-128)
|
|
writer.Int8(-57)
|
|
writer.Int8(0)
|
|
writer.Int8(35)
|
|
writer.Int8(127)
|
|
writer.Int16(-32768)
|
|
writer.Int16(-25756)
|
|
writer.Int16(0)
|
|
writer.Int16(11527)
|
|
writer.Int16(32767)
|
|
writer.Int32(-2147483648)
|
|
writer.Int32(-4764286)
|
|
writer.Int32(0)
|
|
writer.Int32(17395298)
|
|
writer.Int32(2147483647)
|
|
writer.Int64(-9223372036854775808)
|
|
writer.Int64(-716243597812645)
|
|
writer.Int64(0)
|
|
writer.Int64(12784331275341)
|
|
writer.Int64(9223372036854775807)
|
|
writer.Uint8(0)
|
|
writer.Uint8(126)
|
|
writer.Uint8(255)
|
|
writer.Uint16(0)
|
|
writer.Uint16(8465)
|
|
writer.Uint16(65535)
|
|
writer.Uint32(0)
|
|
writer.Uint32(217357235)
|
|
writer.Uint32(4294967295)
|
|
writer.Uint64(0)
|
|
writer.Uint64(12465143251276)
|
|
writer.Uint64(18446744073709551615)
|
|
writer.Float32(-1716.5625)
|
|
writer.Float32(0)
|
|
writer.Float32(27465)
|
|
writer.Float64(-104451.625)
|
|
writer.Float64(0)
|
|
writer.Float64(26112.40625)
|
|
writer.VariableInt(-9223372036854775808)
|
|
writer.VariableInt(-716243597812645)
|
|
writer.VariableInt(0)
|
|
writer.VariableInt(12784331275341)
|
|
writer.VariableInt(9223372036854775807)
|
|
writer.VariableUint(0)
|
|
writer.VariableUint(12465143251276)
|
|
writer.VariableUint(18446744073709551615)
|
|
writer.String("")
|
|
writer.String("abc123")
|
|
writer.String("This is a full sentence. 素晴らしい")
|
|
writer.BoolSlice([]bool{true, false, false, true})
|
|
writer.Int8Slice([]int8{-128, -57, 0, 35, 127})
|
|
writer.Int16Slice([]int16{-32768, -25756, 0, 11527, 32767})
|
|
writer.Int32Slice([]int32{-2147483648, -4764286, 0, 17395298, 2147483647})
|
|
writer.Int64Slice([]int64{-9223372036854775808, -716243597812645, 0, 12784331275341, 9223372036854775807})
|
|
writer.Uint8Slice([]uint8{0, 126, 255})
|
|
writer.Uint16Slice([]uint16{0, 8465, 65535})
|
|
writer.Uint32Slice([]uint32{0, 217357235, 4294967295})
|
|
writer.Uint64Slice([]uint64{0, 12465143251276, 18446744073709551615})
|
|
writer.Float32Slice([]float32{-1716.5625, 0, 27465})
|
|
writer.Float64Slice([]float64{-104451.625, 0, 26112.40625})
|
|
writer.VariableIntSlice([]int64{-9223372036854775808, -716243597812645, 0, 12784331275341, 9223372036854775807})
|
|
writer.VariableUintSlice([]uint64{0, 12465143251276, 18446744073709551615})
|
|
writer.StringSlice([]string{"This", "is", "a", "string", "test."})
|
|
reader := NewReader(writer.Data())
|
|
require.Equal(t, false, reader.Bool())
|
|
require.Equal(t, true, reader.Bool())
|
|
require.Equal(t, int8(-128), reader.Int8())
|
|
require.Equal(t, int8(-57), reader.Int8())
|
|
require.Equal(t, int8(0), reader.Int8())
|
|
require.Equal(t, int8(35), reader.Int8())
|
|
require.Equal(t, int8(127), reader.Int8())
|
|
require.Equal(t, int16(-32768), reader.Int16())
|
|
require.Equal(t, int16(-25756), reader.Int16())
|
|
require.Equal(t, int16(0), reader.Int16())
|
|
require.Equal(t, int16(11527), reader.Int16())
|
|
require.Equal(t, int16(32767), reader.Int16())
|
|
require.Equal(t, int32(-2147483648), reader.Int32())
|
|
require.Equal(t, int32(-4764286), reader.Int32())
|
|
require.Equal(t, int32(0), reader.Int32())
|
|
require.Equal(t, int32(17395298), reader.Int32())
|
|
require.Equal(t, int32(2147483647), reader.Int32())
|
|
require.Equal(t, int64(-9223372036854775808), reader.Int64())
|
|
require.Equal(t, int64(-716243597812645), reader.Int64())
|
|
require.Equal(t, int64(0), reader.Int64())
|
|
require.Equal(t, int64(12784331275341), reader.Int64())
|
|
require.Equal(t, int64(9223372036854775807), reader.Int64())
|
|
require.Equal(t, uint8(0), reader.Uint8())
|
|
require.Equal(t, uint8(126), reader.Uint8())
|
|
require.Equal(t, uint8(255), reader.Uint8())
|
|
require.Equal(t, uint16(0), reader.Uint16())
|
|
require.Equal(t, uint16(8465), reader.Uint16())
|
|
require.Equal(t, uint16(65535), reader.Uint16())
|
|
require.Equal(t, uint32(0), reader.Uint32())
|
|
require.Equal(t, uint32(217357235), reader.Uint32())
|
|
require.Equal(t, uint32(4294967295), reader.Uint32())
|
|
require.Equal(t, uint64(0), reader.Uint64())
|
|
require.Equal(t, uint64(12465143251276), reader.Uint64())
|
|
require.Equal(t, uint64(18446744073709551615), reader.Uint64())
|
|
require.Equal(t, float32(-1716.5625), reader.Float32())
|
|
require.Equal(t, float32(0), reader.Float32())
|
|
require.Equal(t, float32(27465), reader.Float32())
|
|
require.Equal(t, float64(-104451.625), reader.Float64())
|
|
require.Equal(t, float64(0), reader.Float64())
|
|
require.Equal(t, float64(26112.40625), reader.Float64())
|
|
require.Equal(t, int64(-9223372036854775808), reader.VariableInt())
|
|
require.Equal(t, int64(-716243597812645), reader.VariableInt())
|
|
require.Equal(t, int64(0), reader.VariableInt())
|
|
require.Equal(t, int64(12784331275341), reader.VariableInt())
|
|
require.Equal(t, int64(9223372036854775807), reader.VariableInt())
|
|
require.Equal(t, uint64(0), reader.VariableUint())
|
|
require.Equal(t, uint64(12465143251276), reader.VariableUint())
|
|
require.Equal(t, uint64(18446744073709551615), reader.VariableUint())
|
|
require.Equal(t, "", reader.String())
|
|
require.Equal(t, "abc123", reader.String())
|
|
require.Equal(t, "This is a full sentence. 素晴らしい", reader.String())
|
|
require.Equal(t, []bool{true, false, false, true}, reader.BoolSlice())
|
|
require.Equal(t, []int8{-128, -57, 0, 35, 127}, reader.Int8Slice())
|
|
require.Equal(t, []int16{-32768, -25756, 0, 11527, 32767}, reader.Int16Slice())
|
|
require.Equal(t, []int32{-2147483648, -4764286, 0, 17395298, 2147483647}, reader.Int32Slice())
|
|
require.Equal(t, []int64{-9223372036854775808, -716243597812645, 0, 12784331275341, 9223372036854775807}, reader.Int64Slice())
|
|
require.Equal(t, []uint8{0, 126, 255}, reader.Uint8Slice())
|
|
require.Equal(t, []uint16{0, 8465, 65535}, reader.Uint16Slice())
|
|
require.Equal(t, []uint32{0, 217357235, 4294967295}, reader.Uint32Slice())
|
|
require.Equal(t, []uint64{0, 12465143251276, 18446744073709551615}, reader.Uint64Slice())
|
|
require.Equal(t, []float32{-1716.5625, 0, 27465}, reader.Float32Slice())
|
|
require.Equal(t, []float64{-104451.625, 0, 26112.40625}, reader.Float64Slice())
|
|
require.Equal(t, []int64{-9223372036854775808, -716243597812645, 0, 12784331275341, 9223372036854775807}, reader.VariableIntSlice())
|
|
require.Equal(t, []uint64{0, 12465143251276, 18446744073709551615}, reader.VariableUintSlice())
|
|
require.Equal(t, []string{"This", "is", "a", "string", "test."}, reader.StringSlice())
|
|
}
|
|
|
|
// TestWriterOrder ensures that some types that are traditionally not byte-comparable when serialized are
|
|
// byte-comparable using the writer.
|
|
func TestWriterOrder(t *testing.T) {
|
|
t.Run("int8", func(t *testing.T) {
|
|
var serializedData [][]byte
|
|
integers := []int8{8, -1, 99, 0, -45, -103, 4, 127, 1, 10, 0, -128, -33, 56}
|
|
for _, integer := range integers {
|
|
writer := NewWriter(1)
|
|
writer.Int8(integer)
|
|
serializedData = append(serializedData, writer.Data())
|
|
}
|
|
sort.Slice(integers, func(i, j int) bool {
|
|
return integers[i] < integers[j]
|
|
})
|
|
sort.Slice(serializedData, func(i, j int) bool {
|
|
return bytes.Compare(serializedData[i], serializedData[j]) == -1
|
|
})
|
|
deserializedIntegers := make([]int8, len(integers))
|
|
for i, data := range serializedData {
|
|
reader := NewReader(data)
|
|
deserializedIntegers[i] = reader.Int8()
|
|
}
|
|
require.Equal(t, integers, deserializedIntegers)
|
|
})
|
|
t.Run("int16", func(t *testing.T) {
|
|
var serializedData [][]byte
|
|
integers := []int16{8, -1, 999, 0, -455, -103, 4, 32767, 1, 100, 0, -32768, -33, 56}
|
|
for _, integer := range integers {
|
|
writer := NewWriter(2)
|
|
writer.Int16(integer)
|
|
serializedData = append(serializedData, writer.Data())
|
|
}
|
|
sort.Slice(integers, func(i, j int) bool {
|
|
return integers[i] < integers[j]
|
|
})
|
|
sort.Slice(serializedData, func(i, j int) bool {
|
|
return bytes.Compare(serializedData[i], serializedData[j]) == -1
|
|
})
|
|
deserializedIntegers := make([]int16, len(integers))
|
|
for i, data := range serializedData {
|
|
reader := NewReader(data)
|
|
deserializedIntegers[i] = reader.Int16()
|
|
}
|
|
require.Equal(t, integers, deserializedIntegers)
|
|
})
|
|
t.Run("int32", func(t *testing.T) {
|
|
var serializedData [][]byte
|
|
integers := []int32{8, -1, 999, 0, -4559775, -103, 4, 2147483647, 1, 100, 0, -2147483648, -33, 5667845}
|
|
for _, integer := range integers {
|
|
writer := NewWriter(4)
|
|
writer.Int32(integer)
|
|
serializedData = append(serializedData, writer.Data())
|
|
}
|
|
sort.Slice(integers, func(i, j int) bool {
|
|
return integers[i] < integers[j]
|
|
})
|
|
sort.Slice(serializedData, func(i, j int) bool {
|
|
return bytes.Compare(serializedData[i], serializedData[j]) == -1
|
|
})
|
|
deserializedIntegers := make([]int32, len(integers))
|
|
for i, data := range serializedData {
|
|
reader := NewReader(data)
|
|
deserializedIntegers[i] = reader.Int32()
|
|
}
|
|
require.Equal(t, integers, deserializedIntegers)
|
|
})
|
|
t.Run("int64", func(t *testing.T) {
|
|
var serializedData [][]byte
|
|
integers := []int64{8, -1, 999, 0, -4559775534255, -103, 4, 9223372036854775807, 1, 100, 0, -9223372036854775808, -33, 566782356235645}
|
|
for _, integer := range integers {
|
|
writer := NewWriter(8)
|
|
writer.Int64(integer)
|
|
serializedData = append(serializedData, writer.Data())
|
|
}
|
|
sort.Slice(integers, func(i, j int) bool {
|
|
return integers[i] < integers[j]
|
|
})
|
|
sort.Slice(serializedData, func(i, j int) bool {
|
|
return bytes.Compare(serializedData[i], serializedData[j]) == -1
|
|
})
|
|
deserializedIntegers := make([]int64, len(integers))
|
|
for i, data := range serializedData {
|
|
reader := NewReader(data)
|
|
deserializedIntegers[i] = reader.Int64()
|
|
}
|
|
require.Equal(t, integers, deserializedIntegers)
|
|
})
|
|
t.Run("float32", func(t *testing.T) {
|
|
var serializedData [][]byte
|
|
floats := []float32{8, -1.123479648834723, 999, 0, -4559775534255, -103.72453, 4, 3.40282347e+38,
|
|
9223372036854775807, 1, -3.40282347e+38, 100.1386723987453, 0, -9223372036854775808, -33,
|
|
float32(math.Inf(1)), float32(math.Inf(-1)), 566782356235645.1345}
|
|
for _, integer := range floats {
|
|
writer := NewWriter(4)
|
|
writer.Float32(integer)
|
|
serializedData = append(serializedData, writer.Data())
|
|
}
|
|
sort.Slice(floats, func(i, j int) bool {
|
|
return floats[i] < floats[j]
|
|
})
|
|
sort.Slice(serializedData, func(i, j int) bool {
|
|
return bytes.Compare(serializedData[i], serializedData[j]) == -1
|
|
})
|
|
deserializedFloats := make([]float32, len(floats))
|
|
for i, data := range serializedData {
|
|
reader := NewReader(data)
|
|
deserializedFloats[i] = reader.Float32()
|
|
}
|
|
require.Equal(t, floats, deserializedFloats)
|
|
})
|
|
t.Run("float64", func(t *testing.T) {
|
|
var serializedData [][]byte
|
|
floats := []float64{8, -1.123479648834723, 999, 0, -4559775534255, -103.72453, 4, 1.7976931348623157e+308,
|
|
9223372036854775807, 1, -1.7976931348623157e+308, 100.1386723987453, 0, -9223372036854775808, -33,
|
|
math.Inf(1), math.Inf(-1), 566782356235645.1345}
|
|
for _, integer := range floats {
|
|
writer := NewWriter(8)
|
|
writer.Float64(integer)
|
|
serializedData = append(serializedData, writer.Data())
|
|
}
|
|
sort.Slice(floats, func(i, j int) bool {
|
|
return floats[i] < floats[j]
|
|
})
|
|
sort.Slice(serializedData, func(i, j int) bool {
|
|
return bytes.Compare(serializedData[i], serializedData[j]) == -1
|
|
})
|
|
deserializedFloats := make([]float64, len(floats))
|
|
for i, data := range serializedData {
|
|
reader := NewReader(data)
|
|
deserializedFloats[i] = reader.Float64()
|
|
}
|
|
require.Equal(t, floats, deserializedFloats)
|
|
})
|
|
}
|