package via import ( "bytes" "testing" ) type fakeTransport struct { reportIDs []byte reports [][]byte response []byte readCalls int } func (f *fakeTransport) SendReport(reportID byte, report []byte) (int, error) { f.reportIDs = append(f.reportIDs, reportID) f.reports = append(f.reports, bytes.Clone(report)) return len(report), nil } func (f *fakeTransport) Read(buf []byte) (int, error) { f.readCalls++ if len(f.response) > 0 { return copy(buf, f.response), nil } if len(f.reports) > 0 { return copy(buf, f.reports[len(f.reports)-1]), nil } return copy(buf, make([]byte, 32)), nil } func (f *fakeTransport) Close() error { return nil } func TestSetValueUsesQMKRGBLightPayload(t *testing.T) { transport := &fakeTransport{} protocol := Protocol{handle: transport} if err := protocol.SetValue(RGBLight, 0x02, 0x00); err != nil { t.Fatalf("SetValue() error = %v", err) } want := make([]byte, 32) want[0] = 0x07 want[1] = 0x02 want[2] = 0x02 want[3] = 0x00 if len(transport.reports) != 1 { t.Fatalf("SendReport() calls = %d, want 1", len(transport.reports)) } if transport.reportIDs[0] != 0x00 { t.Errorf("report ID = 0x%02x, want 0x00", transport.reportIDs[0]) } if !bytes.Equal(transport.reports[0], want) { t.Errorf("report = %v, want %v", transport.reports[0], want) } } func TestSetValueConsumesQMKResponse(t *testing.T) { response := make([]byte, 32) response[0] = 0x07 response[1] = 0x02 response[2] = 0x02 response[3] = 0x00 transport := &fakeTransport{response: response} protocol := Protocol{handle: transport} if err := protocol.SetValue(RGBLight, 0x02, 0x00); err != nil { t.Fatalf("SetValue() error = %v", err) } if transport.readCalls != 1 { t.Errorf("Read() calls = %d, want 1", transport.readCalls) } } func TestSetColorUsesQMKColorValue(t *testing.T) { transport := &fakeTransport{} protocol := Protocol{handle: transport} if err := protocol.SetColor(RGBLight, 0x2a, 0x80); err != nil { t.Fatalf("SetColor() error = %v", err) } want := make([]byte, 32) want[0] = 0x07 want[1] = 0x02 want[2] = 0x04 want[3] = 0x2a want[4] = 0x80 if !bytes.Equal(transport.reports[0], want) { t.Errorf("report = %v, want %v", transport.reports[0], want) } } func TestDisableLightingUsesAllImpact80Channels(t *testing.T) { transport := &fakeTransport{} protocol := Protocol{handle: transport} if err := protocol.DisableLighting(); err != nil { t.Fatalf("DisableLighting() error = %v", err) } if len(transport.reports) != 6 { t.Fatalf("SendReport() calls = %d, want 6", len(transport.reports)) } wantChannels := []byte{0x02, 0x03, 0x04} for i, channel := range wantChannels { effect := transport.reports[i*2] brightness := transport.reports[i*2+1] if effect[1] != channel || effect[2] != 0x02 || effect[3] != 0x00 { t.Errorf("effect report %d = %v, want channel 0x%02x effect 0", i, effect, channel) } if brightness[1] != channel || brightness[2] != 0x01 || brightness[3] != 0x00 { t.Errorf("brightness report %d = %v, want channel 0x%02x brightness 0", i, brightness, channel) } } } func TestEnableLightingUsesAllImpact80Channels(t *testing.T) { transport := &fakeTransport{} protocol := Protocol{handle: transport} if err := protocol.EnableLighting(); err != nil { t.Fatalf("EnableLighting() error = %v", err) } if len(transport.reports) != 6 { t.Fatalf("SendReport() calls = %d, want 6", len(transport.reports)) } wantChannels := []byte{0x02, 0x03, 0x04} for i, channel := range wantChannels { effect := transport.reports[i*2] brightness := transport.reports[i*2+1] if effect[1] != channel || effect[2] != 0x02 || effect[3] != 0x01 { t.Errorf("effect report %d = %v, want channel 0x%02x effect 1", i, effect, channel) } if brightness[1] != channel || brightness[2] != 0x01 || brightness[3] != 160 { t.Errorf("brightness report %d = %v, want channel 0x%02x brightness 160", i, brightness, channel) } } } func TestGetValueReturnsQMKValueData(t *testing.T) { response := make([]byte, 32) response[0] = 0x08 response[1] = 0x02 response[2] = 0x01 response[3] = 0xc8 transport := &fakeTransport{response: response} protocol := Protocol{handle: transport} got, err := protocol.GetValue(RGBLight, 0x01) if err != nil { t.Fatalf("GetValue() error = %v", err) } if !bytes.Equal(got, []byte{0xc8}) { t.Errorf("GetValue() = %v, want [192]", got) } want := make([]byte, 32) want[0] = 0x08 want[1] = 0x02 want[2] = 0x01 if !bytes.Equal(transport.reports[0], want) { t.Errorf("request = %v, want %v", transport.reports[0], want) } } func TestGetValueRejectsUnhandledResponse(t *testing.T) { response := make([]byte, 32) response[0] = 0xff protocol := Protocol{handle: &fakeTransport{response: response}} if _, err := protocol.GetValue(RGBLight, 0x01); err == nil { t.Fatal("GetValue() error = nil, want unhandled response error") } }