You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devices/sen6x/crc_test.go

212 lines
3.8 KiB
Go

// Copyright 2026 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package sen6x
import (
"bytes"
"testing"
)
func TestCRC8(t *testing.T) {
cases := []struct {
name string
b0 byte
b1 byte
want byte
}{
{
// From the datasheet: crc8(0xbeef) = 0x92
name: "datasheet example",
b0: 0xbe,
b1: 0xef,
want: 0x92,
},
{
// All zeros.
name: "zeros",
b0: 0x00,
b1: 0x00,
want: 0x81,
},
{
// All ones.
name: "ones",
b0: 0xff,
b1: 0xff,
want: 0xac,
},
{
// Single bit in b0.
name: "single bit b0",
b0: 0x01,
b1: 0x00,
want: 0x75,
},
{
// Single bit in b1.
name: "single bit b1",
b0: 0x00,
b1: 0x01,
want: 0xb0,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := crc8(tc.b0, tc.b1)
if got != tc.want {
t.Errorf("got %#02x, want %#02x", got, tc.want)
}
})
}
}
func TestValidateAndStripCRC(t *testing.T) {
cases := []struct {
name string
raw []byte
want []byte
wantErr bool
}{
{
name: "single word",
// 0xbeef with CRC 0x92 from datasheet example.
raw: []byte{0xbe, 0xef, 0x92},
want: []byte{0xbe, 0xef},
},
{
name: "two words",
raw: []byte{0xbe, 0xef, 0x92, 0x00, 0x00, 0x81},
want: []byte{0xbe, 0xef, 0x00, 0x00},
},
{
name: "wrong CRC on first word",
raw: []byte{0xbe, 0xef, 0x00},
wantErr: true,
},
{
name: "wrong CRC on second word",
raw: []byte{0xbe, 0xef, 0x92, 0x00, 0x00, 0x00},
wantErr: true,
},
{
name: "length not multiple of 3",
raw: []byte{0xbe, 0xef},
wantErr: true,
},
{
name: "empty input",
raw: []byte{},
want: []byte{},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got, err := validateAndStripCRC(tc.raw)
if err != nil && !tc.wantErr {
t.Fatalf("unexpected error: %v", err)
}
if err == nil && tc.wantErr {
t.Fatal("expected error, got nil")
}
if !tc.wantErr && !bytes.Equal(got, tc.want) {
t.Errorf("got %#v, want %#v", got, tc.want)
}
})
}
}
func TestPackWordsWithCRC(t *testing.T) {
cases := []struct {
name string
raw []uint16
want []byte
}{
{
name: "single word",
// 0xbeef with CRC of 0x92 from datasheet example.
raw: []uint16{0xbeef},
want: []byte{0xbe, 0xef, 0x92},
},
{
name: "two words",
raw: []uint16{0xbeef, 0x0000},
want: []byte{0xbe, 0xef, 0x92, 0x00, 0x00, 0x81},
},
{
name: "empty",
raw: []uint16{},
want: []byte{},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := packWordsWithCRC(tc.raw)
if !bytes.Equal(got, tc.want) {
t.Errorf("got %#v, want %#v", got, tc.want)
}
})
}
}
func TestPackBytesWithCRC(t *testing.T) {
cases := []struct {
name string
b []byte
want []byte
wantErr bool
}{
{
name: "single word",
// 0xbeef with CRC of 0x92 from datasheet example.
b: []byte{0xbe, 0xef},
want: []byte{0xbe, 0xef, 0x92},
},
{
name: "two words",
b: []byte{0xbe, 0xef, 0x00, 0x00},
want: []byte{0xbe, 0xef, 0x92, 0x00, 0x00, 0x81},
},
{
name: "empty",
b: []byte{},
want: []byte{},
},
{
name: "odd number of bytes",
b: []byte{0xbe},
wantErr: true,
},
{
name: "odd number of bytes, more than one",
b: []byte{0xbe, 0xef, 0x00},
wantErr: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got, err := packBytesWithCRC(tc.b)
if err != nil && !tc.wantErr {
t.Fatalf("unexpected error: %v", err)
}
if err == nil && tc.wantErr {
t.Fatal("expected error, got nil")
}
if !tc.wantErr && !bytes.Equal(got, tc.want) {
t.Errorf("got %#v, want %#v", got, tc.want)
}
})
}
}