348 lines
8.5 KiB
Go
348 lines
8.5 KiB
Go
package can
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"testing/quick"
|
|
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
func TestData_Bit(t *testing.T) {
|
|
for i, tt := range []struct {
|
|
data Data
|
|
bits []struct {
|
|
i uint8
|
|
bit bool
|
|
}
|
|
}{
|
|
{
|
|
data: Data{0x01, 0x23},
|
|
bits: []struct {
|
|
i uint8
|
|
bit bool
|
|
}{
|
|
// nibble 1: 0x1
|
|
{bit: true, i: 0},
|
|
{bit: false, i: 1},
|
|
{bit: false, i: 2},
|
|
{bit: false, i: 3},
|
|
// nibble 2: 0x0
|
|
{bit: false, i: 4},
|
|
{bit: false, i: 5},
|
|
{bit: false, i: 6},
|
|
{bit: false, i: 7},
|
|
// nibble 3: 0x3
|
|
{bit: true, i: 8},
|
|
{bit: true, i: 9},
|
|
{bit: false, i: 10},
|
|
{bit: false, i: 11},
|
|
// nibble 4: 0x2
|
|
{bit: false, i: 12},
|
|
{bit: true, i: 13},
|
|
{bit: false, i: 14},
|
|
{bit: false, i: 15},
|
|
},
|
|
},
|
|
} {
|
|
i, tt := i, tt
|
|
t.Run("Get", func(t *testing.T) {
|
|
i, tt := i, tt
|
|
for j, ttBit := range tt.bits {
|
|
j, ttBit := j, ttBit
|
|
t.Run(fmt.Sprintf("tt=%v,bit=%v", i, j), func(t *testing.T) {
|
|
bit := tt.data.Bit(ttBit.i)
|
|
assert.Equal(t, ttBit.bit, bit)
|
|
})
|
|
}
|
|
})
|
|
t.Run("Set", func(t *testing.T) {
|
|
i, tt := i, tt
|
|
t.Run(fmt.Sprintf("data=%v", i), func(t *testing.T) {
|
|
var data Data
|
|
for _, tBit := range tt.bits {
|
|
data.SetBit(tBit.i, tBit.bit)
|
|
}
|
|
assert.DeepEqual(t, tt.data, data)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestData_Property_SetGetBit(t *testing.T) {
|
|
f := func(_ Data, _ uint8, bit bool) bool {
|
|
return bit
|
|
}
|
|
g := func(data Data, i uint8, bit bool) bool {
|
|
i %= 64
|
|
data.SetBit(i, bit)
|
|
return data.Bit(i)
|
|
}
|
|
assert.NilError(t, quick.CheckEqual(f, g, nil))
|
|
}
|
|
|
|
func TestData_LittleEndian(t *testing.T) {
|
|
for i, tt := range []struct {
|
|
data Data
|
|
signals []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}
|
|
}{
|
|
{
|
|
data: Data{0x80, 0x01},
|
|
signals: []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}{
|
|
{start: 7, length: 2, unsigned: 0x3, signed: -1},
|
|
},
|
|
},
|
|
{
|
|
data: Data{0x01, 0x02, 0x03},
|
|
signals: []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}{
|
|
{start: 0, length: 24, unsigned: 0x030201, signed: 197121},
|
|
},
|
|
},
|
|
{
|
|
data: Data{0x40, 0x23, 0x01, 0x12},
|
|
signals: []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}{
|
|
{start: 24, length: 8, unsigned: 0x12, signed: 18},
|
|
{start: 8, length: 8, unsigned: 0x23, signed: 35},
|
|
{start: 4, length: 16, unsigned: 0x1234, signed: 4660},
|
|
},
|
|
},
|
|
} {
|
|
i, tt := i, tt
|
|
t.Run(fmt.Sprintf("UnsignedBits:%v", i), func(t *testing.T) {
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) {
|
|
actual := tt.data.UnsignedBitsLittleEndian(signal.start, signal.length)
|
|
assert.Equal(t, signal.unsigned, actual)
|
|
})
|
|
}
|
|
})
|
|
t.Run(fmt.Sprintf("SignedBits:%v", i), func(t *testing.T) {
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) {
|
|
actual := tt.data.SignedBitsLittleEndian(signal.start, signal.length)
|
|
assert.Equal(t, signal.signed, actual)
|
|
})
|
|
}
|
|
})
|
|
t.Run(fmt.Sprintf("SetUnsignedBits:%v", i), func(t *testing.T) {
|
|
var data Data
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) {
|
|
data.SetUnsignedBitsLittleEndian(signal.start, signal.length, signal.unsigned)
|
|
})
|
|
}
|
|
assert.DeepEqual(t, tt.data, data)
|
|
})
|
|
t.Run(fmt.Sprintf("SetSignedBits:%v", i), func(t *testing.T) {
|
|
var data Data
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) {
|
|
data.SetSignedBitsLittleEndian(signal.start, signal.length, signal.signed)
|
|
})
|
|
}
|
|
assert.DeepEqual(t, tt.data, data)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestData_BigEndian(t *testing.T) {
|
|
for i, tt := range []struct {
|
|
data Data
|
|
signals []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}
|
|
}{
|
|
{
|
|
data: Data{0x3f, 0xf7, 0x0d, 0xc4, 0x0c, 0x93, 0xff, 0xff},
|
|
signals: []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}{
|
|
{start: 7, length: 3, unsigned: 0x1, signed: 1},
|
|
{start: 4, length: 1, unsigned: 0x1, signed: -1},
|
|
{start: 55, length: 16, unsigned: 0xffff, signed: -1},
|
|
{start: 39, length: 16, unsigned: 0xc93, signed: 3219},
|
|
{start: 23, length: 16, unsigned: 0xdc4, signed: 3524},
|
|
{start: 3, length: 12, unsigned: 0xff7, signed: -9},
|
|
},
|
|
},
|
|
{
|
|
data: Data{0x3f, 0xe4, 0x0e, 0xb6, 0x0c, 0xba, 0x00, 0x05},
|
|
signals: []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}{
|
|
{start: 7, length: 3, unsigned: 0x1, signed: 1},
|
|
{start: 4, length: 1, unsigned: 0x1, signed: -1},
|
|
{start: 55, length: 16, unsigned: 0x5, signed: 5},
|
|
{start: 39, length: 16, unsigned: 0xcba, signed: 3258},
|
|
{start: 23, length: 16, unsigned: 0xeb6, signed: 3766},
|
|
{start: 3, length: 12, unsigned: 0xfe4, signed: -28},
|
|
},
|
|
},
|
|
{
|
|
data: Data{0x30, 0x53, 0x23, 0xe5, 0x0e, 0x11, 0xff, 0xff},
|
|
signals: []struct {
|
|
start uint8
|
|
length uint8
|
|
unsigned uint64
|
|
signed int64
|
|
}{
|
|
{start: 7, length: 3, unsigned: 0x1, signed: 1},
|
|
{start: 4, length: 1, unsigned: 0x1, signed: -1},
|
|
{start: 55, length: 16, unsigned: 0xffff, signed: -1},
|
|
{start: 39, length: 16, unsigned: 0xe11, signed: 3601},
|
|
{start: 23, length: 16, unsigned: 0x23e5, signed: 9189},
|
|
{start: 3, length: 12, unsigned: 0x53, signed: 83},
|
|
},
|
|
},
|
|
} {
|
|
i, tt := i, tt
|
|
t.Run(fmt.Sprintf("UnsignedBits:%v", i), func(t *testing.T) {
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) {
|
|
actual := tt.data.UnsignedBitsBigEndian(signal.start, signal.length)
|
|
assert.Equal(t, signal.unsigned, actual)
|
|
})
|
|
}
|
|
})
|
|
t.Run(fmt.Sprintf("SignedBits:%v", i), func(t *testing.T) {
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) {
|
|
actual := tt.data.SignedBitsBigEndian(signal.start, signal.length)
|
|
assert.Equal(t, signal.signed, actual)
|
|
})
|
|
}
|
|
})
|
|
t.Run(fmt.Sprintf("SetUnsignedBits:%v", i), func(t *testing.T) {
|
|
var data Data
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) {
|
|
data.SetUnsignedBitsBigEndian(signal.start, signal.length, signal.unsigned)
|
|
})
|
|
}
|
|
assert.DeepEqual(t, tt.data, data)
|
|
})
|
|
t.Run(fmt.Sprintf("SetSignedBits:%v", i), func(t *testing.T) {
|
|
var data Data
|
|
for j, signal := range tt.signals {
|
|
j, signal := j, signal
|
|
t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) {
|
|
data.SetSignedBitsBigEndian(signal.start, signal.length, signal.signed)
|
|
})
|
|
}
|
|
assert.DeepEqual(t, tt.data, data)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestInvertEndian_Property_Idempotent(t *testing.T) {
|
|
for i := uint8(0); i < 64; i++ {
|
|
assert.Equal(t, i, invertEndian(invertEndian(i)))
|
|
}
|
|
}
|
|
|
|
func TestPackUnpackBigEndian(t *testing.T) {
|
|
f := func(data Data) Data {
|
|
return data
|
|
}
|
|
g := func(data Data) Data {
|
|
data.UnpackBigEndian(data.PackBigEndian())
|
|
return data
|
|
}
|
|
assert.NilError(t, quick.CheckEqual(f, g, nil))
|
|
}
|
|
|
|
func TestPackUnpackLittleEndian(t *testing.T) {
|
|
f := func(data Data) Data {
|
|
return data
|
|
}
|
|
g := func(data Data) Data {
|
|
data.UnpackLittleEndian(data.PackLittleEndian())
|
|
return data
|
|
}
|
|
assert.NilError(t, quick.CheckEqual(f, g, nil))
|
|
}
|
|
|
|
func TestData_CheckBitRange(t *testing.T) {
|
|
// example case that big-endian signals and little-endian signals use different indexing
|
|
assert.NilError(t, CheckBitRangeBigEndian(8, 55, 16))
|
|
assert.ErrorContains(t, CheckBitRangeLittleEndian(8, 55, 16), "bit range out of bounds")
|
|
}
|
|
|
|
func BenchmarkData_UnpackLittleEndian(b *testing.B) {
|
|
var data Data
|
|
for i := 0; i < b.N; i++ {
|
|
data.UnpackLittleEndian(0)
|
|
}
|
|
}
|
|
|
|
func BenchmarkData_UnpackBigEndian(b *testing.B) {
|
|
var data Data
|
|
for i := 0; i < b.N; i++ {
|
|
data.UnpackBigEndian(0)
|
|
}
|
|
}
|
|
|
|
func BenchmarkData_PackBigEndian(b *testing.B) {
|
|
var data Data
|
|
for i := 0; i < b.N; i++ {
|
|
_ = data.PackBigEndian()
|
|
}
|
|
}
|
|
|
|
func BenchmarkData_PackLittleEndian(b *testing.B) {
|
|
var data Data
|
|
for i := 0; i < b.N; i++ {
|
|
_ = data.PackLittleEndian()
|
|
}
|
|
}
|
|
|
|
func BenchmarkData_UnsignedBitsBigEndian(b *testing.B) {
|
|
var data Data
|
|
for i := 0; i < b.N; i++ {
|
|
_ = data.UnsignedBitsBigEndian(0, 16)
|
|
}
|
|
}
|
|
|
|
func BenchmarkData_UnsignedBitsLittleEndian(b *testing.B) {
|
|
var data Data
|
|
for i := 0; i < b.N; i++ {
|
|
_ = data.UnsignedBitsLittleEndian(0, 16)
|
|
}
|
|
}
|