package devices import ( "testing" "xiaomihome/xiaomi" ) func TestToInt(t *testing.T) { tests := []struct { name string value interface{} want int }{ {"float64", float64(42), 42}, {"int", int(42), 42}, {"int64", int64(42), 42}, {"uint8", uint8(100), 100}, {"uint16", uint16(1000), 1000}, {"nil", nil, 0}, {"string", "hello", 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := toInt(tt.value) if got != tt.want { t.Errorf("toInt(%v) = %d, want %d", tt.value, got, tt.want) } }) } } func TestToFloat(t *testing.T) { tests := []struct { name string value interface{} want float64 }{ {"float64", float64(26.5), 26.5}, {"float32", float32(30.0), 30.0}, {"int", int(25), 25.0}, {"int64", int64(20), 20.0}, {"string", "26.5", 0.0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := toFloat(tt.value) if got != tt.want { t.Errorf("toFloat(%v) = %f, want %f", tt.value, got, tt.want) } }) } } func TestAirConditionerModeConstants(t *testing.T) { if ACModeCool != "cool" || ACModeHeat != "heat" || ACModeDry != "dry" || ACModeAuto != "auto" { t.Error("AC mode constants mismatch") } } func TestFanSpeedConstants(t *testing.T) { if ACFanLow != "low" || ACFanAuto != "auto" { t.Error("Fan speed constants mismatch") } } func TestSwingModeConstants(t *testing.T) { if ACSwingOff != "off" || ACSwingVertical != "vertical" { t.Error("Swing mode constants mismatch") } } func TestMatchURN(t *testing.T) { tests := []struct { name string urn string types []string want bool }{ { "air-conditioner", "urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c1:1", []string{"air-conditioner"}, true, }, { "light", "urn:miot-spec-v2:device:light:0000A001:philips-bulb:1", []string{"light"}, true, }, { "switch outlet", "urn:miot-spec-v2:device:outlet:0000A002:xiaomi-plug:1", []string{"switch", "outlet"}, true, }, { "fan", "urn:miot-spec-v2:device:fan:0000A003:xiaomi-fan:1", []string{"fan"}, true, }, { "curtain", "urn:miot-spec-v2:device:curtain:0000A005:aqara-c1:1", []string{"curtain"}, true, }, { "humidifier", "urn:miot-spec-v2:device:humidifier:0000A006:xiaomi-h1:1", []string{"humidifier"}, true, }, { "vacuum", "urn:miot-spec-v2:device:vacuum:0000A007:roborock-s5:1", []string{"vacuum"}, true, }, { "water-heater", "urn:miot-spec-v2:device:water-heater:0000A008:xiaomi-wh1:1", []string{"water-heater"}, true, }, { "heater thermostat", "urn:miot-spec-v2:device:heater:0000A009:xiaomi-h1:1", []string{"heater"}, true, }, { "tofan-wk01 not fan", // "tofan" 含 "fan" 子串,不得误匹配 fan 系列 "urn:miot-spec-v2:device:thermostat:0000A031:tofan-wk01:1:0000C822", []string{"fan", "ceiling-fan", "ventilator", "air-fresh", "air-purifier"}, false, }, { "tofan-wk01 thermostat", "urn:miot-spec-v2:device:thermostat:0000A031:tofan-wk01:1:0000C822", []string{"heater", "electric-blanket", "thermostat"}, true, }, { "no match", "urn:miot-spec-v2:device:unknown:0000A099:test:1", []string{"air-conditioner", "light", "switch"}, false, }, { "empty URN", "", []string{"light"}, false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := matchURN(tt.urn, tt.types...) if got != tt.want { t.Errorf("matchURN(%q, %v) = %v, want %v", tt.urn, tt.types, got, tt.want) } }) } } func TestFactoryNilClientPanic(t *testing.T) { // Create with a nil client should panic (calling methods on nil client) // This is a documentation test noting expected behavior t.Skip("requires real or mock client") } func TestCreateNilInfo(t *testing.T) { client := &xiaomi.Client{} result, err := Create(client, nil) if result != nil { t.Errorf("expected nil result, got %v", result) } if err == nil { t.Error("expected error for nil info") } } func TestServiceShortName(t *testing.T) { cases := []struct { urn string want string }{ {"urn:miot-spec-v2:service:thermostat:0000784A:tofan-wk01:1", "thermostat"}, {"urn:miot-spec-v2:service:air-conditioner:0000780F:tofan-wk01:1", "air-conditioner"}, {"urn:tofan-spec:service:adv-setting:00007801:tofan-wk01:1", "adv-setting"}, {"urn:miot-spec-v2:property:on:00000006:tofan-wk01:1", "urn:miot-spec-v2:property:on:00000006:tofan-wk01:1"}, } for _, c := range cases { if got := serviceShortName(c.urn); got != c.want { t.Errorf("serviceShortName(%q) = %q, want %q", c.urn, got, c.want) } } }