feat: 初始化小米 IoT (MIoT) 智能家居 Go 库
- 实现 MIoT 客户端核心功能(MQTT 连接、设备管理、属性读写) - 支持云端 API 调用与局域网设备发现(mDNS) - 集成国际化(i18n)多语言支持 - 添加 MIoT 设备规约解析器(spec_parser) - 包含单元测试与使用示例
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user