effect_verify_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package main
  2. import (
  3. "errors"
  4. "strings"
  5. "testing"
  6. intrgb "netdome.biz/paul/qmk-rgb/internal/rgb"
  7. "netdome.biz/paul/qmk-rgb/internal/via"
  8. )
  9. // The Impact 80's logo and side channels do not accept effect ID 0: the
  10. // firmware reads it as "switch the lighting off" and leaves the mode register
  11. // on its previous value. A set of "none" therefore leaves the effect running
  12. // while the command reports success, which is the contradiction this read-back
  13. // exists to prevent.
  14. func TestSetEffectVerifiedReportsHeldEffect(t *testing.T) {
  15. proto := &verifyingProtocol{applied: map[via.Channel]uint8{via.ChannelRgblight: 1}}
  16. targets := []intrgb.EffectTarget{{Channel: via.ChannelRgblight, ID: 0}}
  17. results, err := setEffectVerified(proto, targets, impact80Display(), impact80Catalog(t))
  18. if err != nil {
  19. t.Fatalf("setEffectVerified() error = %v", err)
  20. }
  21. if len(results) != 1 {
  22. t.Fatalf("results = %d entries, want 1", len(results))
  23. }
  24. got := results[0]
  25. if got.Name != "logo" {
  26. t.Errorf("results[0].Name = %q, want %q", got.Name, "logo")
  27. }
  28. if got.RequestedID != 0 || got.RequestedName != "none" {
  29. t.Errorf("results[0].Requested = %d/%q, want 0/%q", got.RequestedID, got.RequestedName, "none")
  30. }
  31. if got.AppliedID != 1 || got.AppliedName != "wave" {
  32. t.Errorf("results[0].Applied = %d/%q, want 1/%q", got.AppliedID, got.AppliedName, "wave")
  33. }
  34. if !got.Mismatch() {
  35. t.Error("results[0].Mismatch() = false, want true (keyboard kept effect 1)")
  36. }
  37. }
  38. func TestSetEffectVerifiedMatchesWhenApplied(t *testing.T) {
  39. proto := &verifyingProtocol{
  40. applied: map[via.Channel]uint8{
  41. via.ChannelRgblight: 1,
  42. via.ChannelRgbMatrix: 28,
  43. via.ChannelAudio: 1,
  44. },
  45. }
  46. // "wave" is a different ID on every channel of this board, so the
  47. // read-back has to compare per channel, not one value for all.
  48. targets := []intrgb.EffectTarget{
  49. {Channel: via.ChannelRgblight, ID: 1},
  50. {Channel: via.ChannelRgbMatrix, ID: 28},
  51. {Channel: via.ChannelAudio, ID: 1},
  52. }
  53. results, err := setEffectVerified(proto, targets, impact80Display(), impact80Catalog(t))
  54. if err != nil {
  55. t.Fatalf("setEffectVerified() error = %v", err)
  56. }
  57. if proto.getCalls != 3 {
  58. t.Errorf("GetValue calls = %d, want 3", proto.getCalls)
  59. }
  60. for _, r := range results {
  61. if r.Mismatch() {
  62. t.Errorf("%s: Mismatch() = true, want false (requested %d, board holds %d)", r.Name, r.RequestedID, r.AppliedID)
  63. }
  64. }
  65. }
  66. // An effect the catalog does not name must be reported as unknown rather than
  67. // dropped, so a set to a raw index the catalog does not cover stays visible.
  68. func TestSetEffectVerifiedNamesUncataloguedEffect(t *testing.T) {
  69. proto := &verifyingProtocol{applied: map[via.Channel]uint8{via.ChannelRgbMatrix: 46}}
  70. targets := []intrgb.EffectTarget{{Channel: via.ChannelRgbMatrix, ID: 46}}
  71. results, err := setEffectVerified(proto, targets, impact80Display(), impact80Catalog(t))
  72. if err != nil {
  73. t.Fatalf("setEffectVerified() error = %v", err)
  74. }
  75. if got := results[0].AppliedName; got != "unknown" {
  76. t.Errorf("results[0].AppliedName = %q, want %q", got, "unknown")
  77. }
  78. }
  79. func TestSetEffectVerifiedPropagatesReadError(t *testing.T) {
  80. proto := &verifyingProtocol{getErr: errors.New("read timeout")}
  81. targets := []intrgb.EffectTarget{{Channel: via.ChannelRgblight, ID: 1}}
  82. if _, err := setEffectVerified(proto, targets, impact80Display(), impact80Catalog(t)); err == nil {
  83. t.Fatal("setEffectVerified() expected read error, got nil")
  84. }
  85. }
  86. // A keyboard that ignored the set must not be reported as having taken the
  87. // effect.
  88. func TestEffectCommandReportsHeldEffect(t *testing.T) {
  89. proto := &verifyingProtocol{applied: map[via.Channel]uint8{via.ChannelRgblight: 1}}
  90. stdout, _, err := executeEffectCommand(t, proto, "logo", "none")
  91. if err != nil {
  92. t.Fatalf("effect returned error: %v", err)
  93. }
  94. if strings.Contains(stdout, `Effect set to "none"`) {
  95. t.Errorf("stdout = %q, want no success claim for an effect the keyboard kept", stdout)
  96. }
  97. for _, want := range []string{"logo", "wave", "none"} {
  98. if !strings.Contains(stdout, want) {
  99. t.Errorf("stdout = %q, want it to name %q", stdout, want)
  100. }
  101. }
  102. }
  103. func TestEffectCommandStaysQuietWhenApplied(t *testing.T) {
  104. proto := &verifyingProtocol{
  105. applied: map[via.Channel]uint8{
  106. via.ChannelRgblight: 1,
  107. via.ChannelRgbMatrix: 28,
  108. via.ChannelAudio: 1,
  109. },
  110. }
  111. stdout, _, err := executeEffectCommand(t, proto, "", "wave")
  112. if err != nil {
  113. t.Fatalf("effect returned error: %v", err)
  114. }
  115. if got, want := stdout, "Effect set to \"wave\"\n"; got != want {
  116. t.Errorf("stdout = %q, want %q", got, want)
  117. }
  118. }