Files
4566704 3a44cb9e6a feat: 初始化小米 IoT (MIoT) 智能家居 Go 库
- 实现 MIoT 客户端核心功能(MQTT 连接、设备管理、属性读写)
- 支持云端 API 调用与局域网设备发现(mDNS)
- 集成国际化(i18n)多语言支持
- 添加 MIoT 设备规约解析器(spec_parser)
- 包含单元测试与使用示例
2026-06-28 22:05:49 +08:00

167 lines
3.8 KiB
Go

// Package miot provides white-box tests for miot_lan.go LAN device control.
package miot
import "testing"
func TestLanDeviceState_String(t *testing.T) {
tests := []struct {
state LanDeviceState
want string
}{
{LanDeviceFresh, "fresh"},
{LanDevicePing1, "ping1"},
{LanDevicePing2, "ping2"},
{LanDevicePing3, "ping3"},
{LanDeviceDead, "dead"},
{LanDeviceState(99), "unknown"},
}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
if got := tt.state.String(); got != tt.want {
t.Errorf("LanDeviceState(%d).String() = %q, want %q", tt.state, got, tt.want)
}
})
}
}
func TestHexDecode_Valid(t *testing.T) {
data, err := hexDecode("abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789")
if err != nil {
t.Fatalf("hexDecode failed: %v", err)
}
if len(data) != 32 {
t.Errorf("hexDecode len = %d, want 32", len(data))
}
}
func TestHexDecode_InvalidChar(t *testing.T) {
_, err := hexDecode("ghij")
if err == nil {
t.Error("hexDecode with invalid chars should error")
}
}
func TestHexDecode_Empty(t *testing.T) {
data, err := hexDecode("")
if err != nil {
t.Fatalf("hexDecode empty: %v", err)
}
if len(data) != 0 {
t.Errorf("len = %d, want 0", len(data))
}
}
func TestMd5Sum_KnownValue(t *testing.T) {
result := md5Sum([]byte("hello"))
if len(result) != 16 {
t.Errorf("md5Sum len = %d, want 16", len(result))
}
result2 := md5Sum([]byte("hello"))
if result != result2 {
t.Error("md5Sum should be deterministic")
}
}
func TestMd5Sum_DifferentInput(t *testing.T) {
r1 := md5Sum([]byte("hello"))
r2 := md5Sum([]byte("world"))
if r1 == r2 {
t.Error("different inputs should produce different hashes")
}
}
func TestMinFloat(t *testing.T) {
if minFloat(1.0, 2.0) != 1.0 {
t.Error("minFloat(1, 2) should be 1")
}
if minFloat(2.0, 1.0) != 1.0 {
t.Error("minFloat(2, 1) should be 1")
}
if minFloat(5.5, 5.5) != 5.5 {
t.Error("minFloat(5.5, 5.5) should be 5.5")
}
}
func TestToInt_Helper(t *testing.T) {
tests := []struct {
input interface{}
wantVal int
wantOk bool
}{
{float64(42), 42, true},
{int(100), 100, true},
{int64(200), 200, true},
{"not a number", 0, false},
{nil, 0, false},
{true, 0, false},
}
for _, tt := range tests {
got, ok := toInt(tt.input)
if got != tt.wantVal || ok != tt.wantOk {
t.Errorf("toInt(%v) = (%d, %v), want (%d, %v)", tt.input, got, ok, tt.wantVal, tt.wantOk)
}
}
}
func TestIsNumeric(t *testing.T) {
tests := []struct {
input string
want bool
}{
{"12345", true}, {"0", true}, {"000", true},
{"123abc", false}, {"abc", false},
{"", false}, {"12.34", false},
}
for _, tt := range tests {
got := isNumeric(tt.input)
if got != tt.want {
t.Errorf("isNumeric(%q) = %v, want %v", tt.input, got, tt.want)
}
}
}
func TestTrimNull(t *testing.T) {
tests := []struct {
input, want []byte
}{
{[]byte("hello\x00"), []byte("hello")},
{[]byte("hello\x00\x00"), []byte("hello")},
{[]byte("hello"), []byte("hello")},
{[]byte{0, 0}, []byte{}},
{[]byte{}, []byte{}},
}
for _, tt := range tests {
got := trimNull(tt.input)
if string(got) != string(tt.want) {
t.Errorf("trimNull(%v) = %v, want %v", tt.input, got, tt.want)
}
}
}
func TestMustParseUint64(t *testing.T) {
if mustParseUint64("1234567890") != 1234567890 {
t.Error("mustParseUint64('1234567890') wrong")
}
if mustParseUint64("0") != 0 {
t.Error("mustParseUint64('0') should be 0")
}
}
func TestLanDeviceState_IotaValues(t *testing.T) {
if int(LanDeviceFresh) != 0 {
t.Errorf("LanDeviceFresh = %d, want 0", LanDeviceFresh)
}
if int(LanDeviceDead) != 4 {
t.Errorf("LanDeviceDead = %d, want 4", LanDeviceDead)
}
}
func TestLanProtocolConstants(t *testing.T) {
if otHeader != 0x2131 {
t.Errorf("otHeader = %#x, want 0x2131", otHeader)
}
if otPort != 54321 {
t.Errorf("otPort = %d, want 54321", otPort)
}
}