Files
4566704 a3d94c4b9f chore: 提交高层 xiaomi 封装库及示例
- 新增 xiaomi/examples/ 下 8 个示例程序(用户/家庭查询、设备列表、开关/灯光/空调控制、属性订阅、高级过滤分类、SPEC 解析)
- miot_client_sub.go: 重构 SubProp/SubEvent,使用 buildPropTopic/buildEventTopic 支持通配符订阅(siid/piid=0 → +),并修复锁顺序问题(将 RequestRefreshProp 移到 Lock 外)
- spec_parser.go: 新增 downloadSpecFile 方法,本地 SPEC 文件缺失时自动从 miot-spec.org 下载
- ARCH_PLAN.md: 架构设计从 Proposed 更新为 Accepted(v1.0→v1.1),补充设备分类/工厂/SPEC 映射等模块设计
- xiaomi/: 新增 miot 上层强类型封装模块,包含 Client 主入口、用户/家庭/设备 API、属性读写、动作调用、订阅通知,以及 devices/ 设备控制抽象(Switch/Light/AirConditioner/Fan/Cover/Humidifier/Vacuum/WaterHeater/Thermostat)和 specs/ SPEC 查询辅助
- 更多 xiaomi 示例(风扇/窗帘/传感器控制)
2026-06-29 08:51:21 +08:00

89 lines
2.0 KiB
Go

package xiaomi
import "testing"
func TestFilterByHome(t *testing.T) {
f := FilterByHome("home1")
if !f(&DeviceInfo{HomeID: "home1"}) {
t.Error("FilterByHome(home1) should match home1")
}
if f(&DeviceInfo{HomeID: "home2"}) {
t.Error("FilterByHome(home1) should not match home2")
}
if f(&DeviceInfo{HomeID: ""}) {
t.Error("FilterByHome(home1) should not match empty")
}
}
func TestFilterByRoom(t *testing.T) {
f := FilterByRoom("room1")
if !f(&DeviceInfo{RoomID: "room1"}) {
t.Error("FilterByRoom(room1) should match room1")
}
if f(&DeviceInfo{RoomID: "room2"}) {
t.Error("FilterByRoom(room1) should not match room2")
}
}
func TestFilterByOnline(t *testing.T) {
f := FilterByOnline()
if !f(&DeviceInfo{Online: true}) {
t.Error("FilterByOnline should match online=true")
}
if f(&DeviceInfo{Online: false}) {
t.Error("FilterByOnline should not match online=false")
}
}
func TestFilterByModel(t *testing.T) {
f := FilterByModel("xiaomi.light.v1")
if !f(&DeviceInfo{Model: "xiaomi.light.v1"}) {
t.Error("FilterByModel should match exact model")
}
if f(&DeviceInfo{Model: "xiaomi.light.v2"}) {
t.Error("FilterByModel should not match different model")
}
}
func TestDeviceFilterComposition(t *testing.T) {
tests := []struct {
name string
device *DeviceInfo
filters []DeviceFilter
want bool
}{
{
"all pass",
&DeviceInfo{HomeID: "home1", RoomID: "room1", Online: true},
[]DeviceFilter{FilterByHome("home1"), FilterByRoom("room1"), FilterByOnline()},
true,
},
{
"one fails",
&DeviceInfo{HomeID: "home1", RoomID: "room2", Online: true},
[]DeviceFilter{FilterByHome("home1"), FilterByRoom("room1"), FilterByOnline()},
false,
},
{
"no filters",
&DeviceInfo{HomeID: "home1"},
nil,
true, // empty filters = no-op
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ok := true
for _, f := range tt.filters {
if !f(tt.device) {
ok = false
break
}
}
if ok != tt.want {
t.Errorf("got %v, want %v", ok, tt.want)
}
})
}
}