keyboard_info_test.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "strings"
  7. "testing"
  8. intdevice "netdome.biz/paul/qmk-rgb/internal/device"
  9. )
  10. type deviceInfoOutput struct {
  11. Devices []keyboardLine `json:"devices"`
  12. Total int `json:"total"`
  13. }
  14. func stubDiscovery(t *testing.T, devices []intdevice.Device) {
  15. t.Helper()
  16. orig := discoverAll
  17. discoverAll = func() ([]intdevice.Device, error) { return devices, nil }
  18. t.Cleanup(func() { discoverAll = orig })
  19. }
  20. // runRealKeyboardInfo executes the shipped command so a re-added
  21. // human-readable banner is caught, not just changes inside a helper.
  22. func runRealKeyboardInfo(t *testing.T) (stdout, stderr string, err error) {
  23. t.Helper()
  24. var out, errOut bytes.Buffer
  25. origOut, origErr := keyboardInfoCmd.OutOrStdout(), keyboardInfoCmd.ErrOrStderr()
  26. keyboardInfoCmd.SetOut(&out)
  27. keyboardInfoCmd.SetErr(&errOut)
  28. t.Cleanup(func() {
  29. keyboardInfoCmd.SetOut(origOut)
  30. keyboardInfoCmd.SetErr(origErr)
  31. })
  32. err = keyboardInfoCmd.RunE(keyboardInfoCmd, nil)
  33. return out.String(), errOut.String(), err
  34. }
  35. func TestKeyboardInfoWritesOnlyJSON(t *testing.T) {
  36. withJSON(t)
  37. stubDiscovery(t, []intdevice.Device{
  38. {Index: 1, Path: "/dev/hidraw7", VendorID: 0x36b0, ProductID: 0x309f, Name: "Impact 80"},
  39. })
  40. stdout, stderr, err := runRealKeyboardInfo(t)
  41. if err != nil {
  42. t.Fatalf("keyboard info returned error: %v", err)
  43. }
  44. if stderr != "" {
  45. t.Errorf("keyboard info wrote %q to stderr, want no human-readable banner next to the JSON", stderr)
  46. }
  47. var got deviceInfoOutput
  48. if err := json.Unmarshal([]byte(stdout), &got); err != nil {
  49. t.Fatalf("stdout is not valid JSON: %v (output %q)", err, stdout)
  50. }
  51. if got.Total != 1 {
  52. t.Errorf("total = %d, want 1", got.Total)
  53. }
  54. if len(got.Devices) != 1 {
  55. t.Fatalf("devices = %d entries, want 1", len(got.Devices))
  56. }
  57. if got.Devices[0].Index != 1 {
  58. t.Errorf("devices[0].index = %d, want 1", got.Devices[0].Index)
  59. }
  60. if got.Devices[0].Path != "/dev/hidraw7" {
  61. t.Errorf("devices[0].path = %q, want %q", got.Devices[0].Path, "/dev/hidraw7")
  62. }
  63. }
  64. func TestKeyboardInfoEmitsIndentedJSON(t *testing.T) {
  65. withJSON(t)
  66. stubDiscovery(t, []intdevice.Device{
  67. {Index: 1, Path: "/dev/hidraw7", Name: "Impact 80"},
  68. })
  69. stdout, _, err := runRealKeyboardInfo(t)
  70. if err != nil {
  71. t.Fatalf("keyboard info returned error: %v", err)
  72. }
  73. if !strings.Contains(stdout, "\n \"devices\": [") {
  74. t.Errorf("stdout = %q, want two-space indented JSON like the other commands emit", stdout)
  75. }
  76. if !strings.HasSuffix(stdout, "\n") {
  77. t.Errorf("stdout = %q, want a trailing newline", stdout)
  78. }
  79. }
  80. func TestKeyboardInfoEmitsEmptyArrayNotNull(t *testing.T) {
  81. withJSON(t)
  82. stubDiscovery(t, nil)
  83. stdout, _, err := runRealKeyboardInfo(t)
  84. if err != nil {
  85. t.Fatalf("keyboard info returned error: %v", err)
  86. }
  87. if !strings.Contains(stdout, `"devices": []`) {
  88. t.Errorf("stdout = %q, want an empty array so consumers can iterate unconditionally", stdout)
  89. }
  90. }
  91. func TestKeyboardInfoPropagatesDiscoveryError(t *testing.T) {
  92. orig := discoverAll
  93. discoverAll = func() ([]intdevice.Device, error) { return nil, errStub }
  94. t.Cleanup(func() { discoverAll = orig })
  95. _, _, err := runRealKeyboardInfo(t)
  96. if err == nil {
  97. t.Fatal("keyboard info expected discovery error, got nil")
  98. }
  99. if !strings.Contains(err.Error(), "enumerate") {
  100. t.Errorf("error = %v, want it to wrap the discovery failure", err)
  101. }
  102. }
  103. var errStub = errors.New("enumerate: stub failure")