mirror of
https://github.com/kidoman/embd
synced 2025-07-03 11:57:38 +02:00
interface: add an abstraction layer for character displays
the characterdisplay package is an abstraction layer for controlling character displays also includes refactors to the hd44780 package to fit the characterdisplay Controller interface
This commit is contained in:
parent
dac729e4fd
commit
915b3b76a7
8 changed files with 489 additions and 364 deletions
129
interface/display/characterdisplay/characterdisplay_test.go
Normal file
129
interface/display/characterdisplay/characterdisplay_test.go
Normal file
|
@ -0,0 +1,129 @@
|
|||
package characterdisplay
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
rows = 4
|
||||
cols = 20
|
||||
)
|
||||
|
||||
type mockController struct {
|
||||
calls chan call
|
||||
}
|
||||
|
||||
type call struct {
|
||||
name string
|
||||
arguments []interface{}
|
||||
}
|
||||
|
||||
func noArgCall(name string) call {
|
||||
return call{name, []interface{}{}}
|
||||
}
|
||||
|
||||
func (mock *mockController) DisplayOff() error { mock.calls <- noArgCall("DisplayOff"); return nil }
|
||||
func (mock *mockController) DisplayOn() error { mock.calls <- noArgCall("DisplayOn"); return nil }
|
||||
func (mock *mockController) CursorOff() error { mock.calls <- noArgCall("CursorOff"); return nil }
|
||||
func (mock *mockController) CursorOn() error { mock.calls <- noArgCall("CursorOn"); return nil }
|
||||
func (mock *mockController) BlinkOff() error { mock.calls <- noArgCall("BlinkOff"); return nil }
|
||||
func (mock *mockController) BlinkOn() error { mock.calls <- noArgCall("BlinkOn"); return nil }
|
||||
func (mock *mockController) ShiftLeft() error { mock.calls <- noArgCall("ShiftLeft"); return nil }
|
||||
func (mock *mockController) ShiftRight() error { mock.calls <- noArgCall("ShiftRight"); return nil }
|
||||
func (mock *mockController) BacklightOff() error { mock.calls <- noArgCall("BacklightOff"); return nil }
|
||||
func (mock *mockController) BacklightOn() error { mock.calls <- noArgCall("BacklightOn"); return nil }
|
||||
func (mock *mockController) Home() error { mock.calls <- noArgCall("Home"); return nil }
|
||||
func (mock *mockController) Clear() error { mock.calls <- noArgCall("Clear"); return nil }
|
||||
func (mock *mockController) Close() error { mock.calls <- noArgCall("Close"); return nil }
|
||||
func (mock *mockController) WriteChar(b byte) error {
|
||||
mock.calls <- call{"WriteChar", []interface{}{b}}
|
||||
return nil
|
||||
}
|
||||
func (mock *mockController) SetCursor(col, row int) error {
|
||||
mock.calls <- call{"SetCursor", []interface{}{col, row}}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mock *mockController) testExpectedCalls(expectedCalls []call, t *testing.T) {
|
||||
for _, expectedCall := range expectedCalls {
|
||||
select {
|
||||
case actualCall := <-mock.calls:
|
||||
if !reflect.DeepEqual(expectedCall, actualCall) {
|
||||
t.Errorf("Expected call %+v, actual call %+v", expectedCall, actualCall)
|
||||
}
|
||||
case <-time.After(time.Millisecond * 1):
|
||||
t.Errorf("Timeout reading next call. Expected call %+v", expectedCall)
|
||||
}
|
||||
}
|
||||
|
||||
ExtraCallsCheck:
|
||||
for {
|
||||
select {
|
||||
case extraCall := <-mock.calls:
|
||||
t.Errorf("Unexpected call %+v", extraCall)
|
||||
case <-time.After(time.Millisecond * 1):
|
||||
break ExtraCallsCheck
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newMockController() *mockController {
|
||||
return &mockController{make(chan call, 256)}
|
||||
}
|
||||
|
||||
func TestNewline(t *testing.T) {
|
||||
mock := newMockController()
|
||||
disp := New(mock, cols, rows)
|
||||
disp.Newline()
|
||||
|
||||
expectedCalls := []call{
|
||||
call{"SetCursor", []interface{}{0, 1}},
|
||||
}
|
||||
|
||||
mock.testExpectedCalls(expectedCalls, t)
|
||||
}
|
||||
|
||||
func TestMessage(t *testing.T) {
|
||||
mock := newMockController()
|
||||
disp := New(mock, cols, rows)
|
||||
disp.Message("ab")
|
||||
|
||||
expectedCalls := []call{
|
||||
call{"WriteChar", []interface{}{byte('a')}},
|
||||
call{"WriteChar", []interface{}{byte('b')}},
|
||||
}
|
||||
|
||||
mock.testExpectedCalls(expectedCalls, t)
|
||||
}
|
||||
|
||||
func TestMessage_newLine(t *testing.T) {
|
||||
mock := newMockController()
|
||||
disp := New(mock, cols, rows)
|
||||
disp.Message("a\nb")
|
||||
|
||||
expectedCalls := []call{
|
||||
call{"WriteChar", []interface{}{byte('a')}},
|
||||
call{"SetCursor", []interface{}{0, 1}},
|
||||
call{"WriteChar", []interface{}{byte('b')}},
|
||||
}
|
||||
|
||||
mock.testExpectedCalls(expectedCalls, t)
|
||||
}
|
||||
|
||||
func TestMessage_wrap(t *testing.T) {
|
||||
mock := newMockController()
|
||||
disp := New(mock, cols, rows)
|
||||
disp.SetCursor(cols-1, 0)
|
||||
disp.Message("ab")
|
||||
|
||||
expectedCalls := []call{
|
||||
call{"SetCursor", []interface{}{cols - 1, 0}},
|
||||
call{"WriteChar", []interface{}{byte('a')}},
|
||||
call{"SetCursor", []interface{}{0, 1}},
|
||||
call{"WriteChar", []interface{}{byte('b')}},
|
||||
}
|
||||
|
||||
mock.testExpectedCalls(expectedCalls, t)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue