commands_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package rgb
  2. import (
  3. "errors"
  4. "reflect"
  5. "testing"
  6. intrgb "github.com/wobkey/rgb/internal/rgb"
  7. "github.com/wobkey/rgb/internal/via"
  8. )
  9. type commandReport struct {
  10. channel via.LEDType
  11. param uint8
  12. value uint8
  13. hue uint8
  14. saturation uint8
  15. }
  16. type fakeZoneProtocol struct {
  17. reports []commandReport
  18. failAt int
  19. }
  20. func (f *fakeZoneProtocol) SetValue(channel via.LEDType, param, value uint8) error {
  21. if f.failAt >= 0 && f.failAt == len(f.reports) {
  22. return errors.New("write failed")
  23. }
  24. f.reports = append(f.reports, commandReport{
  25. channel: channel,
  26. param: param,
  27. value: value,
  28. })
  29. return nil
  30. }
  31. func (f *fakeZoneProtocol) SetColor(channel via.LEDType, hue, saturation uint8) error {
  32. if f.failAt >= 0 && f.failAt == len(f.reports) {
  33. return errors.New("write failed")
  34. }
  35. f.reports = append(f.reports, commandReport{
  36. channel: channel,
  37. param: 4,
  38. hue: hue,
  39. saturation: saturation,
  40. })
  41. return nil
  42. }
  43. func TestSelectedChannelOperations(t *testing.T) {
  44. defaultZones := []intrgb.Zone{intrgb.ZoneLogo, intrgb.ZoneBacklight, intrgb.ZoneSide}
  45. sideZones := []intrgb.Zone{intrgb.ZoneSide}
  46. operations := []struct {
  47. name string
  48. zones []intrgb.Zone
  49. sideZones []intrgb.Zone
  50. run func(zoneProtocol, []intrgb.Zone) error
  51. want []commandReport
  52. wantSide []commandReport
  53. }{
  54. {
  55. name: "brightness",
  56. zones: defaultZones,
  57. sideZones: sideZones,
  58. run: func(protocol zoneProtocol, zones []intrgb.Zone) error {
  59. return setBrightnessOnZones(protocol, zones, 160)
  60. },
  61. want: []commandReport{
  62. {channel: 2, param: 1, value: 160},
  63. {channel: 3, param: 1, value: 160},
  64. {channel: 4, param: 1, value: 160},
  65. },
  66. wantSide: []commandReport{{channel: 4, param: 1, value: 160}},
  67. },
  68. {
  69. name: "speed",
  70. zones: defaultZones,
  71. sideZones: sideZones,
  72. run: func(protocol zoneProtocol, zones []intrgb.Zone) error {
  73. return setSpeedOnZones(protocol, zones, 2)
  74. },
  75. want: []commandReport{
  76. {channel: 2, param: 3, value: 2},
  77. {channel: 3, param: 3, value: 2},
  78. {channel: 4, param: 3, value: 2},
  79. },
  80. wantSide: []commandReport{{channel: 4, param: 3, value: 2}},
  81. },
  82. {
  83. name: "color",
  84. zones: defaultZones,
  85. sideZones: sideZones,
  86. run: func(protocol zoneProtocol, zones []intrgb.Zone) error {
  87. return setColorOnZones(protocol, zones, 85, 255)
  88. },
  89. want: []commandReport{
  90. {channel: 2, param: 4, hue: 85, saturation: 255},
  91. {channel: 3, param: 4, hue: 85, saturation: 255},
  92. {channel: 4, param: 4, hue: 85, saturation: 255},
  93. },
  94. wantSide: []commandReport{{channel: 4, param: 4, hue: 85, saturation: 255}},
  95. },
  96. {
  97. name: "disable",
  98. zones: defaultZones,
  99. sideZones: sideZones,
  100. run: disableLightingOnZones,
  101. want: []commandReport{
  102. {channel: 2, param: 2, value: 0},
  103. {channel: 2, param: 1, value: 0},
  104. {channel: 3, param: 2, value: 0},
  105. {channel: 3, param: 1, value: 0},
  106. {channel: 4, param: 2, value: 0},
  107. {channel: 4, param: 1, value: 0},
  108. },
  109. wantSide: []commandReport{
  110. {channel: 4, param: 2, value: 0},
  111. {channel: 4, param: 1, value: 0},
  112. },
  113. },
  114. {
  115. name: "enable",
  116. zones: defaultZones,
  117. sideZones: sideZones,
  118. run: enableLightingOnZones,
  119. want: []commandReport{
  120. {channel: 2, param: 2, value: 4},
  121. {channel: 2, param: 1, value: 160},
  122. {channel: 3, param: 2, value: 5},
  123. {channel: 3, param: 1, value: 160},
  124. {channel: 4, param: 2, value: 4},
  125. {channel: 4, param: 1, value: 160},
  126. },
  127. wantSide: []commandReport{
  128. {channel: 4, param: 2, value: 4},
  129. {channel: 4, param: 1, value: 160},
  130. },
  131. },
  132. {
  133. name: "mode",
  134. zones: defaultZones,
  135. sideZones: sideZones,
  136. run: func(protocol zoneProtocol, zones []intrgb.Zone) error {
  137. return setModeOnZones(protocol, zones, 17)
  138. },
  139. want: []commandReport{
  140. {channel: 2, param: 2, value: 17},
  141. {channel: 3, param: 2, value: 17},
  142. {channel: 4, param: 2, value: 17},
  143. },
  144. wantSide: []commandReport{{channel: 4, param: 2, value: 17}},
  145. },
  146. }
  147. for _, tc := range operations {
  148. t.Run(tc.name+"/default", func(t *testing.T) {
  149. protocol := &fakeZoneProtocol{failAt: -1}
  150. if err := tc.run(protocol, tc.zones); err != nil {
  151. t.Fatalf("operation error = %v", err)
  152. }
  153. if !reflect.DeepEqual(protocol.reports, tc.want) {
  154. t.Errorf("reports = %v, want %v", protocol.reports, tc.want)
  155. }
  156. })
  157. t.Run(tc.name+"/side", func(t *testing.T) {
  158. protocol := &fakeZoneProtocol{failAt: -1}
  159. if err := tc.run(protocol, tc.sideZones); err != nil {
  160. t.Fatalf("operation error = %v", err)
  161. }
  162. if !reflect.DeepEqual(protocol.reports, tc.wantSide) {
  163. t.Errorf("reports = %v, want %v", protocol.reports, tc.wantSide)
  164. }
  165. })
  166. }
  167. }
  168. func TestSelectedChannelStopsOnFirstError(t *testing.T) {
  169. protocol := &fakeZoneProtocol{failAt: 1}
  170. err := setBrightnessOnZones(protocol, intrgb.AllZones(), 160)
  171. if err == nil {
  172. t.Fatal("setBrightnessOnZones() expected error, got nil")
  173. }
  174. if len(protocol.reports) != 1 {
  175. t.Errorf("reports = %v, want one report before failure", protocol.reports)
  176. }
  177. }