profile_board_test.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package main
  2. import (
  3. "encoding/json"
  4. "strings"
  5. "testing"
  6. )
  7. // A profile stores effect names, and names belong to a board, so a profile has
  8. // to say which board it came from. Otherwise a profile written for one keyboard
  9. // is applied to another without a word.
  10. func TestProfileCarriesTheBoardIdentity(t *testing.T) {
  11. p := &Profile{Name: "x", Board: &Board{VendorID: "0x36B0", ProductID: "0x309F"}}
  12. data, err := json.MarshalIndent(p, "", " ")
  13. if err != nil {
  14. t.Fatalf("marshal: %v", err)
  15. }
  16. if !strings.Contains(string(data), `"vendorId": "0x36B0"`) {
  17. t.Errorf("profile JSON = %s, want the vendor ID", data)
  18. }
  19. if !strings.Contains(string(data), `"productId": "0x309F"`) {
  20. t.Errorf("profile JSON = %s, want the product ID", data)
  21. }
  22. var back Profile
  23. if err := json.Unmarshal(data, &back); err != nil {
  24. t.Fatalf("unmarshal: %v", err)
  25. }
  26. if back.Board == nil || back.Board.ProductID != "0x309F" {
  27. t.Errorf("round trip = %+v, want the board back", back.Board)
  28. }
  29. }
  30. // A profile written before the field existed must still load, and must not be
  31. // reported as a mismatch.
  32. func TestProfileWithoutABoardStillLoads(t *testing.T) {
  33. var p Profile
  34. if err := json.Unmarshal([]byte(`{"name":"old","version":1,"zones":{}}`), &p); err != nil {
  35. t.Fatalf("unmarshal: %v", err)
  36. }
  37. if p.Board != nil {
  38. t.Errorf("Board = %+v, want nil for a profile that has none", p.Board)
  39. }
  40. if got := p.MatchesBoard(0x36B0, 0x309F); got != boardUnknown {
  41. t.Errorf("MatchesBoard() = %v, want %v for a profile with no board", got, boardUnknown)
  42. }
  43. }
  44. func TestProfileBoardComparison(t *testing.T) {
  45. same := &Profile{Board: &Board{VendorID: "0x36B0", ProductID: "0x309F"}}
  46. other := &Profile{Board: &Board{VendorID: "0x1111", ProductID: "0x2222"}}
  47. tests := []struct {
  48. name string
  49. profile *Profile
  50. vendorID, prodID uint16
  51. want boardMatch
  52. }{
  53. {"same board", same, 0x36B0, 0x309F, boardSame},
  54. {"other board", other, 0x36B0, 0x309F, boardOther},
  55. {"no board", &Profile{}, 0x36B0, 0x309F, boardUnknown},
  56. }
  57. for _, tt := range tests {
  58. t.Run(tt.name, func(t *testing.T) {
  59. if got := tt.profile.MatchesBoard(tt.vendorID, tt.prodID); got != tt.want {
  60. t.Errorf("MatchesBoard() = %v, want %v", got, tt.want)
  61. }
  62. })
  63. }
  64. }
  65. // The warning has to name both keyboards, or the user cannot tell which
  66. // profile is the wrong one.
  67. func TestBoardMismatchWarningNamesBothKeyboards(t *testing.T) {
  68. p := &Profile{
  69. Name: "paul",
  70. Board: &Board{VendorID: "0x1111", ProductID: "0x2222"},
  71. }
  72. msg := p.boardMismatchWarning(0x36B0, 0x309F)
  73. for _, want := range []string{"paul", "0x1111/0x2222", "0x36B0/0x309F"} {
  74. if !strings.Contains(msg, want) {
  75. t.Errorf("warning = %q, want it to name %q", msg, want)
  76. }
  77. }
  78. }
  79. func TestBoardIdentityIsShownNextToTheName(t *testing.T) {
  80. p := &Profile{Name: "paul", Board: &Board{VendorID: "0x36B0", ProductID: "0x309F"}}
  81. line := p.listLine()
  82. if !strings.HasPrefix(line, "paul") {
  83. t.Errorf("listLine() = %q, want it to start with the name", line)
  84. }
  85. if !strings.Contains(line, "0x36B0/0x309F") {
  86. t.Errorf("listLine() = %q, want the board", line)
  87. }
  88. }
  89. // A profile with no board must not claim to belong to one.
  90. func TestListLineWithoutABoardSaysNothingAboutIt(t *testing.T) {
  91. line := (&Profile{Name: "old"}).listLine()
  92. if strings.Contains(line, "0x") {
  93. t.Errorf("listLine() = %q, want no board for a profile that has none", line)
  94. }
  95. }