Skip to content

Commit

Permalink
create a test harness for HamDeck
Browse files Browse the repository at this point in the history
  • Loading branch information
ftl committed Dec 6, 2023
1 parent 693cf73 commit 15071ff
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 2 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ require (
github.com/jfreymuth/pulse v0.1.0
github.com/muesli/streamdeck v0.4.0
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
golang.org/x/image v0.14.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/karalabe/hid v1.0.1-0.20190806082151-9c14560f9ee8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
Expand Down Expand Up @@ -76,6 +76,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
151 changes: 151 additions & 0 deletions pkg/hamdeck/hamdeck_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package hamdeck

import (
"image"
"io"
"os"
"path/filepath"
"sync"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestHamDeckRoundtrip(t *testing.T) {
device := newDefaultTestDevice()
deck := New(device)
deck.RegisterFactory(new(testButtonFactory))

reader, err := openTestConfig("testRoundtrip")
require.NoError(t, err)
defer reader.Close()
err = deck.ReadConfig(reader)
require.NoError(t, err)

require.Equal(t, 32, len(deck.buttons))
button := deck.buttons[12].(*testButton)

assert.Equal(t, "some_value", button.config["some_config"])
assert.True(t, button.attached)
assert.False(t, button.detached)
assert.False(t, button.pressed)
assert.False(t, button.released)

stopper := make(chan struct{})
wg := new(sync.WaitGroup)
wg.Add(1)
go func() {
deck.Run(stopper)
wg.Done()
}()

device.Press(12)
device.WaitForLastKey()
assert.True(t, button.pressed)
assert.False(t, button.released)

device.Release(12)
device.WaitForLastKey()
assert.True(t, button.released)

close(stopper)
wg.Wait()
}

/* Test Harness */

func openTestConfig(name string) (io.ReadCloser, error) {
return os.Open(filepath.Join("testdata", name+".json"))
}

type testDevice struct {
id string
serial string
firmwareVersion string
pixels int
rows int
columns int
keys chan Key
}

func newDefaultTestDevice() *testDevice {
return newTestDevice(128, 4, 8)
}

func newTestDevice(pixels int, rows int, columns int) *testDevice {
return &testDevice{
pixels: pixels,
rows: rows,
columns: columns,
keys: make(chan Key),
}
}

func (d *testDevice) Close() error { return nil }
func (d *testDevice) ID() string { return d.id }
func (d *testDevice) Serial() string { return d.serial }
func (d *testDevice) FirmwareVersion() string { return d.firmwareVersion }
func (d *testDevice) Pixels() int { return d.pixels }
func (d *testDevice) Rows() int { return d.rows }
func (d *testDevice) Columns() int { return d.columns }
func (d *testDevice) Clear() error { return nil }
func (d *testDevice) Reset() error { return nil }
func (d *testDevice) SetBrightness(int) error { return nil }
func (d *testDevice) SetImage(int, image.Image) error { return nil }
func (d *testDevice) ReadKeys() (chan Key, error) { return d.keys, nil }
func (d *testDevice) Press(index int) {
key := Key{
Index: index,
Pressed: true,
}
d.keys <- key
}
func (d *testDevice) Release(index int) {
key := Key{
Index: index,
Pressed: false,
}
d.keys <- key
}
func (d *testDevice) WaitForLastKey() {
d.keys <- Key{}
}

const (
testButtonType = "test.Button"
)

type testButtonFactory struct{}

func (f *testButtonFactory) Close() {}

func (f *testButtonFactory) CreateButton(config map[string]any) Button {
switch config[ConfigType] {
case testButtonType:
return f.createTestButton(config)
default:
return nil
}
}

func (f *testButtonFactory) createTestButton(config map[string]any) *testButton {
return &testButton{
config: config,
}
}

type testButton struct {
config map[string]any

pressed bool
released bool
attached bool
detached bool
}

func (b *testButton) Image(GraphicContext, bool) image.Image { return nil }
func (b *testButton) Pressed() { b.pressed = true }
func (b *testButton) Released() { b.released = true }
func (b *testButton) Attached(ButtonContext) { b.attached = true }
func (b *testButton) Detached() { b.detached = true }
9 changes: 9 additions & 0 deletions pkg/hamdeck/testdata/testRoundtrip.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"buttons": [
{
"type": "test.Button",
"index": 12,
"some_config": "some_value"
}
]
}

0 comments on commit 15071ff

Please sign in to comment.