effect_verify_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. // 46 is the board's highest ID and is named, so an index above it is what is
  69. // left uncatalogued.
  70. func TestSetEffectVerifiedNamesUncataloguedEffect(t *testing.T) {
  71. proto := &verifyingProtocol{applied: map[via.Channel]uint8{via.ChannelRgbMatrix: 99}}
  72. targets := []intrgb.EffectTarget{{Channel: via.ChannelRgbMatrix, ID: 99}}
  73. results, err := setEffectVerified(proto, targets, impact80Display(), impact80Catalog(t))
  74. if err != nil {
  75. t.Fatalf("setEffectVerified() error = %v", err)
  76. }
  77. if got := results[0].AppliedName; got != "unknown" {
  78. t.Errorf("results[0].AppliedName = %q, want %q", got, "unknown")
  79. }
  80. }
  81. func TestSetEffectVerifiedPropagatesReadError(t *testing.T) {
  82. proto := &verifyingProtocol{getErr: errors.New("read timeout")}
  83. targets := []intrgb.EffectTarget{{Channel: via.ChannelRgblight, ID: 1}}
  84. if _, err := setEffectVerified(proto, targets, impact80Display(), impact80Catalog(t)); err == nil {
  85. t.Fatal("setEffectVerified() expected read error, got nil")
  86. }
  87. }
  88. // A keyboard that ignored the set must not be reported as having taken the
  89. // effect.
  90. func TestEffectCommandReportsHeldEffect(t *testing.T) {
  91. t.Cleanup(vendoredDefinitions(t))
  92. proto := &verifyingProtocol{applied: map[via.Channel]uint8{via.ChannelRgblight: 1}}
  93. stdout, _, err := executeEffectCommand(t, proto, "logo", "none")
  94. if err != nil {
  95. t.Fatalf("effect returned error: %v", err)
  96. }
  97. if strings.Contains(stdout, `Effect set to "none"`) {
  98. t.Errorf("stdout = %q, want no success claim for an effect the keyboard kept", stdout)
  99. }
  100. for _, want := range []string{"logo", "wave", "none"} {
  101. if !strings.Contains(stdout, want) {
  102. t.Errorf("stdout = %q, want it to name %q", stdout, want)
  103. }
  104. }
  105. }
  106. func TestEffectCommandStaysQuietWhenApplied(t *testing.T) {
  107. t.Cleanup(vendoredDefinitions(t))
  108. proto := &verifyingProtocol{
  109. applied: map[via.Channel]uint8{
  110. via.ChannelRgblight: 1,
  111. via.ChannelRgbMatrix: 28,
  112. via.ChannelAudio: 1,
  113. },
  114. }
  115. stdout, _, err := executeEffectCommand(t, proto, "", "wave")
  116. if err != nil {
  117. t.Fatalf("effect returned error: %v", err)
  118. }
  119. if got, want := stdout, "Effect set to \"wave\"\n"; got != want {
  120. t.Errorf("stdout = %q, want %q", got, want)
  121. }
  122. }