Files
xiaomihome/xiaomi/errors_test.go
T
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

82 lines
1.9 KiB
Go

package xiaomi
import (
"errors"
"testing"
)
func TestSentinelErrors(t *testing.T) {
tests := []struct {
name string
err error
}{
{"ErrNotSupported", ErrNotSupported},
{"ErrDeviceNotFound", ErrDeviceNotFound},
{"ErrHomeNotFound", ErrHomeNotFound},
{"ErrRoomNotFound", ErrRoomNotFound},
{"ErrDeviceOffline", ErrDeviceOffline},
{"ErrNoSPEC", ErrNoSPEC},
{"ErrInvalidProp", ErrInvalidProp},
{"ErrNotInitialized", ErrNotInitialized},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.err == nil {
t.Errorf("%s sentinel error is nil", tt.name)
}
})
}
}
func TestClientError(t *testing.T) {
t.Run("with DID", func(t *testing.T) {
ce := &ClientError{Op: "GetProp", DID: "abc123", Err: ErrDeviceOffline}
expected := `xiaomi: GetProp device=abc123: xiaomi: device is offline`
if ce.Error() != expected {
t.Errorf("Error() = %q, want %q", ce.Error(), expected)
}
})
t.Run("without DID", func(t *testing.T) {
ce := &ClientError{Op: "GetHomeList", Err: ErrHomeNotFound}
expected := `xiaomi: GetHomeList: xiaomi: home not found`
if ce.Error() != expected {
t.Errorf("Error() = %q, want %q", ce.Error(), expected)
}
})
}
func TestWrapErr(t *testing.T) {
t.Run("wraps error", func(t *testing.T) {
err := wrapErr("SetProp", "did1", ErrDeviceOffline)
if err == nil {
t.Fatal("expected non-nil error")
}
ce, ok := err.(*ClientError)
if !ok {
t.Fatalf("expected *ClientError, got %T", err)
}
if ce.Op != "SetProp" {
t.Errorf("Op = %q, want SetProp", ce.Op)
}
if ce.DID != "did1" {
t.Errorf("DID = %q, want did1", ce.DID)
}
})
t.Run("nil returns nil", func(t *testing.T) {
err := wrapErr("op", "did", nil)
if err != nil {
t.Errorf("expected nil, got %v", err)
}
})
}
func TestClientErrorUnwrap(t *testing.T) {
inner := errors.New("inner error")
ce := &ClientError{Op: "test", Err: inner}
if !errors.Is(ce, inner) {
t.Error("errors.Is(ce, inner) should be true")
}
}