profile_load_test.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package main
  2. import (
  3. "bytes"
  4. "testing"
  5. intrgb "netdome.biz/paul/qmk-rgb/internal/rgb"
  6. )
  7. // README.md: "With `--zone`, commands target exactly the selected channel."
  8. // A profile key names a channel, so a load applies only the keys that resolve to
  9. // a selected channel. The keys themselves are resolved by resolveZoneName, which
  10. // channels_test.go covers; what matters here is that a key is never applied to a
  11. // channel it does not name.
  12. func TestLoadAppliesOnlyTheKeysTheSelectionNames(t *testing.T) {
  13. dir := t.TempDir()
  14. profile := Profile{
  15. Name: "three",
  16. Version: 1,
  17. Zones: map[string]*ZoneSettings{
  18. "logo": {Enabled: true, Effect: "light", Brightness: 100, Speed: 1, Color: "00ff"},
  19. "backlight": {Enabled: true, Effect: "solid_color", Brightness: 100, Speed: 1, Color: "00ff"},
  20. "side": {Enabled: true, Effect: "wave", Brightness: 100, Speed: 1, Color: "00ff"},
  21. },
  22. }
  23. originalDir := profilesDir
  24. t.Cleanup(func() { profilesDir = originalDir })
  25. profilesDir = dir
  26. if err := profile.Save(); err != nil {
  27. t.Fatalf("save profile: %v", err)
  28. }
  29. tests := []struct {
  30. name string
  31. zoneFlag string
  32. wantApplied int
  33. }{
  34. {"no flag applies all three", "", 3},
  35. {"logo applies one", "logo", 1},
  36. {"backlight applies one", "backlight", 1},
  37. {"side applies one", "side", 1},
  38. }
  39. for _, tt := range tests {
  40. t.Run(tt.name, func(t *testing.T) {
  41. proto := &verifyingProtocol{}
  42. restore := stubTargetForProfileTest(t, proto, tt.zoneFlag, impact80Display())
  43. defer restore()
  44. cmd := NewProfileLoadCmd()
  45. cmd.SetOut(&bytes.Buffer{})
  46. cmd.SetErr(&bytes.Buffer{})
  47. cmd.SetArgs([]string{"three"})
  48. if err := cmd.Execute(); err != nil {
  49. t.Fatalf("load returned error: %v", err)
  50. }
  51. if got := effectWrites(proto); got != tt.wantApplied {
  52. t.Errorf("effect writes = %d, want %d", got, tt.wantApplied)
  53. }
  54. })
  55. }
  56. }
  57. // effectWrites counts the effect writes, one per applied channel.
  58. func effectWrites(proto *verifyingProtocol) int {
  59. count := 0
  60. for _, r := range proto.reports {
  61. if r.param == uint8(intrgb.EffectID) {
  62. count++
  63. }
  64. }
  65. return count
  66. }
  67. // A key the selection leaves out is the user's own choice, and saying the
  68. // keyboard lacks it is false. Only a key that resolves to a channel the
  69. // keyboard does not have is reported.
  70. func TestLoadIsQuietAboutAKeyTheSelectionExcludes(t *testing.T) {
  71. dir := t.TempDir()
  72. originalDir := profilesDir
  73. t.Cleanup(func() { profilesDir = originalDir })
  74. profilesDir = dir
  75. profile := Profile{
  76. Name: "three",
  77. Version: 1,
  78. Zones: map[string]*ZoneSettings{
  79. "logo": {Enabled: true, Effect: "light", Brightness: 100, Speed: 1, Color: "00ff"},
  80. "backlight": {Enabled: true, Effect: "solid_color", Brightness: 100, Speed: 1, Color: "00ff"},
  81. },
  82. }
  83. if err := profile.Save(); err != nil {
  84. t.Fatalf("save profile: %v", err)
  85. }
  86. proto := &verifyingProtocol{}
  87. t.Cleanup(stubTargetForProfileTest(t, proto, "logo", impact80Display()))
  88. var stderr bytes.Buffer
  89. cmd := NewProfileLoadCmd()
  90. cmd.SetOut(&bytes.Buffer{})
  91. cmd.SetErr(&stderr)
  92. cmd.SetArgs([]string{"three"})
  93. if err := cmd.Execute(); err != nil {
  94. t.Fatalf("load returned error: %v", err)
  95. }
  96. if stderr.Len() != 0 {
  97. t.Errorf("stderr = %q, want nothing for a channel the selection excluded", stderr.String())
  98. }
  99. if got := effectWrites(proto); got != 1 {
  100. t.Errorf("effect writes = %d, want 1", got)
  101. }
  102. }