Files
OpsLog/internal/steppir/steppir_test.go
T

85 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package steppir
import (
"encoding/binary"
"testing"
)
// The exact bytes are the correctness checksum. If buildSet ever drifts from the
// three-source-agreed layout, this fails — a wrong packet is a silently mistuned
// antenna, far worse than a compile error.
func TestBuildSetLayout(t *testing.T) {
// 14.074 MHz, normal, set-freq. freq/10 = 1_407_400 = 0x00 0x15 0x79 0xA8.
pkt := buildSet(14_074_000, DirNormal, '1')
want := []byte{'@', 'A', 0x00, 0x15, 0x79, 0xA8, 0x00, 0x00, '1', 0x00, 0x0D}
if len(pkt) != 11 {
t.Fatalf("packet is %d bytes, want 11", len(pkt))
}
for i := range want {
if pkt[i] != want[i] {
t.Fatalf("byte %d = 0x%02X, want 0x%02X\n got %X\nwant %X", i, pkt[i], want[i], pkt, want)
}
}
// Frequency must round-trip: bytes [2:6] × 10 = Hz.
if got := int(binary.BigEndian.Uint32(pkt[2:6])) * 10; got != 14_074_000 {
t.Fatalf("freq round-trip = %d, want 14074000", got)
}
}
func TestBuildSetDirectionAndCommand(t *testing.T) {
cases := []struct {
dir int
cmd byte
wantDir byte
wantCmd byte
}{
{DirNormal, '1', 0x00, '1'},
{Dir180, '1', 0x40, '1'},
{DirBi, '1', 0x80, '1'},
{DirNormal, 'S', 0x00, 'S'}, // retract / home
{DirNormal, 'R', 0x00, 'R'}, // autotrack on
}
for _, c := range cases {
pkt := buildSet(21_000_000, c.dir, c.cmd)
if pkt[7] != c.wantDir {
t.Errorf("dir %d → byte 0x%02X, want 0x%02X", c.dir, pkt[7], c.wantDir)
}
if pkt[8] != c.wantCmd {
t.Errorf("cmd %q → byte 0x%02X, want 0x%02X", c.cmd, pkt[8], c.wantCmd)
}
}
}
// parseStatus decodes what the controller sends back — the inverse of buildSet's
// frequency field, plus the direction nibble.
func TestParseStatus(t *testing.T) {
frame := []byte{0x00, 0x00, 0x00, 0x15, 0x79, 0xA8, 0x01, 0x40, '1', '2', 0x0D}
st, err := parseStatus(frame)
if err != nil {
t.Fatal(err)
}
if st.Frequency != 14074 {
t.Errorf("freq = %d kHz, want 14074", st.Frequency)
}
if st.Direction != Dir180 {
t.Errorf("direction = %d, want %d (180°)", st.Direction, Dir180)
}
if st.MotorsMoving != 0 { // 0x01 is the always-set bit, not motion
t.Errorf("moving = %d, want 0 (only the always-on bit set)", st.MotorsMoving)
}
// Motors busy: a bit beyond 0x01 is set.
frame[6] = 0x07
st, _ = parseStatus(frame)
if st.MotorsMoving == 0 {
t.Error("active-motors 0x07 should read as moving")
}
// 0xFF is "command received", not motion.
frame[6] = 0xFF
st, _ = parseStatus(frame)
if st.MotorsMoving != 0 {
t.Error("active-motors 0xFF (command received) must not read as moving")
}
}