protocol_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package via
  2. import (
  3. "bytes"
  4. "testing"
  5. )
  6. type fakeTransport struct {
  7. reportIDs []byte
  8. reports [][]byte
  9. response []byte
  10. readCalls int
  11. }
  12. func (f *fakeTransport) SendReport(reportID byte, report []byte) (int, error) {
  13. f.reportIDs = append(f.reportIDs, reportID)
  14. f.reports = append(f.reports, bytes.Clone(report))
  15. return len(report), nil
  16. }
  17. func (f *fakeTransport) Read(buf []byte) (int, error) {
  18. f.readCalls++
  19. if len(f.response) > 0 {
  20. return copy(buf, f.response), nil
  21. }
  22. if len(f.reports) > 0 {
  23. return copy(buf, f.reports[len(f.reports)-1]), nil
  24. }
  25. return copy(buf, make([]byte, 32)), nil
  26. }
  27. func (f *fakeTransport) Close() error { return nil }
  28. func TestSetValueUsesQMKRGBLightPayload(t *testing.T) {
  29. transport := &fakeTransport{}
  30. protocol := Protocol{handle: transport}
  31. if err := protocol.SetValue(RGBLight, 0x02, 0x00); err != nil {
  32. t.Fatalf("SetValue() error = %v", err)
  33. }
  34. want := make([]byte, 32)
  35. want[0] = 0x07
  36. want[1] = 0x02
  37. want[2] = 0x02
  38. want[3] = 0x00
  39. if len(transport.reports) != 1 {
  40. t.Fatalf("SendReport() calls = %d, want 1", len(transport.reports))
  41. }
  42. if transport.reportIDs[0] != 0x00 {
  43. t.Errorf("report ID = 0x%02x, want 0x00", transport.reportIDs[0])
  44. }
  45. if !bytes.Equal(transport.reports[0], want) {
  46. t.Errorf("report = %v, want %v", transport.reports[0], want)
  47. }
  48. }
  49. func TestSetValueConsumesQMKResponse(t *testing.T) {
  50. response := make([]byte, 32)
  51. response[0] = 0x07
  52. response[1] = 0x02
  53. response[2] = 0x02
  54. response[3] = 0x00
  55. transport := &fakeTransport{response: response}
  56. protocol := Protocol{handle: transport}
  57. if err := protocol.SetValue(RGBLight, 0x02, 0x00); err != nil {
  58. t.Fatalf("SetValue() error = %v", err)
  59. }
  60. if transport.readCalls != 1 {
  61. t.Errorf("Read() calls = %d, want 1", transport.readCalls)
  62. }
  63. }
  64. func TestSetLightingColorUsesAllImpact80Channels(t *testing.T) {
  65. transport := &fakeTransport{}
  66. protocol := Protocol{handle: transport}
  67. if err := protocol.SetLightingColor(0x55, 0xff); err != nil {
  68. t.Fatalf("SetLightingColor() error = %v", err)
  69. }
  70. wantChannels := []byte{0x02, 0x03, 0x04}
  71. if len(transport.reports) != len(wantChannels) {
  72. t.Fatalf("SendReport() calls = %d, want %d", len(transport.reports), len(wantChannels))
  73. }
  74. for i, channel := range wantChannels {
  75. report := transport.reports[i]
  76. if report[0] != 0x07 || report[1] != channel || report[2] != 0x04 || report[3] != 0x55 || report[4] != 0xff {
  77. t.Errorf("color report %d = %v, want channel 0x%02x hue 0x55 saturation 0xff", i, report, channel)
  78. }
  79. }
  80. }
  81. func TestSetColorUsesQMKColorValue(t *testing.T) {
  82. transport := &fakeTransport{}
  83. protocol := Protocol{handle: transport}
  84. if err := protocol.SetColor(RGBLight, 0x2a, 0x80); err != nil {
  85. t.Fatalf("SetColor() error = %v", err)
  86. }
  87. want := make([]byte, 32)
  88. want[0] = 0x07
  89. want[1] = 0x02
  90. want[2] = 0x04
  91. want[3] = 0x2a
  92. want[4] = 0x80
  93. if !bytes.Equal(transport.reports[0], want) {
  94. t.Errorf("report = %v, want %v", transport.reports[0], want)
  95. }
  96. }
  97. func TestDisableLightingUsesAllImpact80Channels(t *testing.T) {
  98. transport := &fakeTransport{}
  99. protocol := Protocol{handle: transport}
  100. if err := protocol.DisableLighting(); err != nil {
  101. t.Fatalf("DisableLighting() error = %v", err)
  102. }
  103. if len(transport.reports) != 6 {
  104. t.Fatalf("SendReport() calls = %d, want 6", len(transport.reports))
  105. }
  106. wantChannels := []byte{0x02, 0x03, 0x04}
  107. for i, channel := range wantChannels {
  108. effect := transport.reports[i*2]
  109. brightness := transport.reports[i*2+1]
  110. if effect[1] != channel || effect[2] != 0x02 || effect[3] != 0x00 {
  111. t.Errorf("effect report %d = %v, want channel 0x%02x effect 0", i, effect, channel)
  112. }
  113. if brightness[1] != channel || brightness[2] != 0x01 || brightness[3] != 0x00 {
  114. t.Errorf("brightness report %d = %v, want channel 0x%02x brightness 0", i, brightness, channel)
  115. }
  116. }
  117. }
  118. func TestEnableLightingUsesAllImpact80Channels(t *testing.T) {
  119. transport := &fakeTransport{}
  120. protocol := Protocol{handle: transport}
  121. if err := protocol.EnableLighting(); err != nil {
  122. t.Fatalf("EnableLighting() error = %v", err)
  123. }
  124. if len(transport.reports) != 6 {
  125. t.Fatalf("SendReport() calls = %d, want 6", len(transport.reports))
  126. }
  127. wantChannels := []byte{0x02, 0x03, 0x04}
  128. wantEffects := []byte{0x04, 0x05, 0x04}
  129. for i, channel := range wantChannels {
  130. effect := transport.reports[i*2]
  131. brightness := transport.reports[i*2+1]
  132. if effect[1] != channel || effect[2] != 0x02 || effect[3] != wantEffects[i] {
  133. t.Errorf("effect report %d = %v, want channel 0x%02x effect %d", i, effect, channel, wantEffects[i])
  134. }
  135. if brightness[1] != channel || brightness[2] != 0x01 || brightness[3] != 160 {
  136. t.Errorf("brightness report %d = %v, want channel 0x%02x brightness 160", i, brightness, channel)
  137. }
  138. }
  139. }
  140. func TestGetValueReturnsQMKValueData(t *testing.T) {
  141. response := make([]byte, 32)
  142. response[0] = 0x08
  143. response[1] = 0x02
  144. response[2] = 0x01
  145. response[3] = 0xc8
  146. transport := &fakeTransport{response: response}
  147. protocol := Protocol{handle: transport}
  148. got, err := protocol.GetValue(RGBLight, 0x01)
  149. if err != nil {
  150. t.Fatalf("GetValue() error = %v", err)
  151. }
  152. if !bytes.Equal(got, []byte{0xc8}) {
  153. t.Errorf("GetValue() = %v, want [192]", got)
  154. }
  155. want := make([]byte, 32)
  156. want[0] = 0x08
  157. want[1] = 0x02
  158. want[2] = 0x01
  159. if !bytes.Equal(transport.reports[0], want) {
  160. t.Errorf("request = %v, want %v", transport.reports[0], want)
  161. }
  162. }
  163. func TestGetValueRejectsUnhandledResponse(t *testing.T) {
  164. response := make([]byte, 32)
  165. response[0] = 0xff
  166. protocol := Protocol{handle: &fakeTransport{response: response}}
  167. if _, err := protocol.GetValue(RGBLight, 0x01); err == nil {
  168. t.Fatal("GetValue() error = nil, want unhandled response error")
  169. }
  170. }
  171. func TestSetValueWritesEachImpact80EffectChannel(t *testing.T) {
  172. transport := &fakeTransport{}
  173. protocol := Protocol{handle: transport}
  174. cases := []struct {
  175. channel LEDType
  176. effect byte
  177. }{
  178. {RGBLight, 4},
  179. {RGBMatrix, 5},
  180. {SideLight, 4},
  181. }
  182. for _, tc := range cases {
  183. if err := protocol.SetValue(tc.channel, 0x02, tc.effect); err != nil {
  184. t.Fatalf("SetValue(%d) error = %v", tc.channel, err)
  185. }
  186. }
  187. if len(transport.reports) != len(cases) {
  188. t.Fatalf("SendReport() calls = %d, want %d", len(transport.reports), len(cases))
  189. }
  190. for i, tc := range cases {
  191. report := transport.reports[i]
  192. if report[0] != 0x07 || report[1] != byte(tc.channel) || report[2] != 0x02 || report[3] != tc.effect {
  193. t.Errorf("effect report %d = %v, want channel 0x%02x effect %d", i, report, tc.channel, tc.effect)
  194. }
  195. }
  196. }
  197. func TestGetValueReturnsTwoByteColor(t *testing.T) {
  198. response := make([]byte, 32)
  199. response[0] = 0x08
  200. response[1] = 0x03
  201. response[2] = 0x04
  202. response[3] = 0x2a
  203. response[4] = 0x80
  204. transport := &fakeTransport{response: response}
  205. protocol := Protocol{handle: transport}
  206. got, err := protocol.GetValue(RGBMatrix, 0x04)
  207. if err != nil {
  208. t.Fatalf("GetValue() error = %v", err)
  209. }
  210. if !bytes.Equal(got, []byte{0x2a, 0x80}) {
  211. t.Errorf("GetValue() = %v, want [42 128]", got)
  212. }
  213. want := make([]byte, 32)
  214. want[0] = 0x08
  215. want[1] = 0x03
  216. want[2] = 0x04
  217. if !bytes.Equal(transport.reports[0], want) {
  218. t.Errorf("request = %v, want %v", transport.reports[0], want)
  219. }
  220. }