450 lines
9.2 KiB
Go
450 lines
9.2 KiB
Go
package system
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"gobot.io/x/gobot/v2"
|
|
)
|
|
|
|
var _ gobot.DigitalPinOptioner = (*digitalPinConfig)(nil)
|
|
|
|
func Test_newDigitalPinConfig(t *testing.T) {
|
|
// arrange
|
|
const (
|
|
label = "gobotio17"
|
|
)
|
|
// act
|
|
d := newDigitalPinConfig(label)
|
|
// assert
|
|
assert.NotNil(t, d)
|
|
assert.Equal(t, label, d.label)
|
|
assert.Equal(t, IN, d.direction)
|
|
assert.Equal(t, 0, d.outInitialState)
|
|
}
|
|
|
|
func Test_newDigitalPinConfigWithOption(t *testing.T) {
|
|
// arrange
|
|
const label = "gobotio18"
|
|
// act
|
|
d := newDigitalPinConfig("not used", WithPinLabel(label))
|
|
// assert
|
|
assert.NotNil(t, d)
|
|
assert.Equal(t, label, d.label)
|
|
}
|
|
|
|
func TestWithPinLabel(t *testing.T) {
|
|
const (
|
|
oldLabel = "old label"
|
|
newLabel = "my optional label"
|
|
)
|
|
tests := map[string]struct {
|
|
setLabel string
|
|
want bool
|
|
}{
|
|
"no_change": {
|
|
setLabel: oldLabel,
|
|
},
|
|
"change": {
|
|
setLabel: newLabel,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{label: oldLabel}
|
|
// act
|
|
got := WithPinLabel(tc.setLabel)(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, tc.setLabel, dpc.label)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinDirectionOutput(t *testing.T) {
|
|
const (
|
|
// values other than 0, 1 are normally not useful, just to test
|
|
oldVal = 3
|
|
newVal = 5
|
|
)
|
|
tests := map[string]struct {
|
|
oldDir string
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldDir: "out",
|
|
wantVal: oldVal,
|
|
},
|
|
"change": {
|
|
oldDir: "in",
|
|
want: true,
|
|
wantVal: newVal,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{direction: tc.oldDir, outInitialState: oldVal}
|
|
// act
|
|
got := WithPinDirectionOutput(newVal)(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, "out", dpc.direction)
|
|
assert.Equal(t, tc.wantVal, dpc.outInitialState)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinDirectionInput(t *testing.T) {
|
|
tests := map[string]struct {
|
|
oldDir string
|
|
want bool
|
|
}{
|
|
"no_change": {
|
|
oldDir: "in",
|
|
},
|
|
"change": {
|
|
oldDir: "out",
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
const initValOut = 2 // 2 is normally not useful, just to test that is not touched
|
|
dpc := &digitalPinConfig{direction: tc.oldDir, outInitialState: initValOut}
|
|
// act
|
|
got := WithPinDirectionInput()(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, "in", dpc.direction)
|
|
assert.Equal(t, initValOut, dpc.outInitialState)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinActiveLow(t *testing.T) {
|
|
tests := map[string]struct {
|
|
oldActiveLow bool
|
|
want bool
|
|
}{
|
|
"no_change": {
|
|
oldActiveLow: true,
|
|
},
|
|
"change": {
|
|
oldActiveLow: false,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{activeLow: tc.oldActiveLow}
|
|
// act
|
|
got := WithPinActiveLow()(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.True(t, dpc.activeLow)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinPullDown(t *testing.T) {
|
|
tests := map[string]struct {
|
|
oldBias int
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldBias: digitalPinBiasPullDown,
|
|
},
|
|
"change": {
|
|
oldBias: digitalPinBiasPullUp,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{bias: tc.oldBias}
|
|
// act
|
|
got := WithPinPullDown()(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, digitalPinBiasPullDown, dpc.bias)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinPullUp(t *testing.T) {
|
|
tests := map[string]struct {
|
|
oldBias int
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldBias: digitalPinBiasPullUp,
|
|
},
|
|
"change": {
|
|
oldBias: digitalPinBiasPullDown,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{bias: tc.oldBias}
|
|
// act
|
|
got := WithPinPullUp()(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, digitalPinBiasPullUp, dpc.bias)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinOpenDrain(t *testing.T) {
|
|
tests := map[string]struct {
|
|
oldDrive int
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldDrive: digitalPinDriveOpenDrain,
|
|
},
|
|
"change_from_pushpull": {
|
|
oldDrive: digitalPinDrivePushPull,
|
|
want: true,
|
|
},
|
|
"change_from_opensource": {
|
|
oldDrive: digitalPinDriveOpenSource,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{drive: tc.oldDrive}
|
|
// act
|
|
got := WithPinOpenDrain()(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, digitalPinDriveOpenDrain, dpc.drive)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinOpenSource(t *testing.T) {
|
|
tests := map[string]struct {
|
|
oldDrive int
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldDrive: digitalPinDriveOpenSource,
|
|
},
|
|
"change_from_pushpull": {
|
|
oldDrive: digitalPinDrivePushPull,
|
|
want: true,
|
|
},
|
|
"change_from_opendrain": {
|
|
oldDrive: digitalPinDriveOpenDrain,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{drive: tc.oldDrive}
|
|
// act
|
|
got := WithPinOpenSource()(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, digitalPinDriveOpenSource, dpc.drive)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinDebounce(t *testing.T) {
|
|
const (
|
|
oldVal = time.Duration(10)
|
|
newVal = time.Duration(14)
|
|
)
|
|
tests := map[string]struct {
|
|
oldDebouncePeriod time.Duration
|
|
want bool
|
|
wantVal time.Duration
|
|
}{
|
|
"no_change": {
|
|
oldDebouncePeriod: newVal,
|
|
},
|
|
"change": {
|
|
oldDebouncePeriod: oldVal,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{debouncePeriod: tc.oldDebouncePeriod}
|
|
// act
|
|
got := WithPinDebounce(newVal)(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, newVal, dpc.debouncePeriod)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinEventOnFallingEdge(t *testing.T) {
|
|
const (
|
|
oldVal = digitalPinEventNone
|
|
newVal = digitalPinEventOnFallingEdge
|
|
)
|
|
tests := map[string]struct {
|
|
oldEdge int
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldEdge: newVal,
|
|
want: false,
|
|
},
|
|
"change": {
|
|
oldEdge: oldVal,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{edge: tc.oldEdge}
|
|
handler := func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, lseqno uint32) {}
|
|
// act
|
|
got := WithPinEventOnFallingEdge(handler)(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, newVal, dpc.edge)
|
|
if tc.want {
|
|
assert.NotNil(t, dpc.edgeEventHandler)
|
|
} else {
|
|
assert.Nil(t, dpc.edgeEventHandler)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinEventOnRisingEdge(t *testing.T) {
|
|
const (
|
|
oldVal = digitalPinEventNone
|
|
newVal = digitalPinEventOnRisingEdge
|
|
)
|
|
tests := map[string]struct {
|
|
oldEdge int
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldEdge: newVal,
|
|
want: false,
|
|
},
|
|
"change": {
|
|
oldEdge: oldVal,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{edge: tc.oldEdge}
|
|
handler := func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, lseqno uint32) {}
|
|
// act
|
|
got := WithPinEventOnRisingEdge(handler)(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, newVal, dpc.edge)
|
|
if tc.want {
|
|
assert.NotNil(t, dpc.edgeEventHandler)
|
|
} else {
|
|
assert.Nil(t, dpc.edgeEventHandler)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinEventOnBothEdges(t *testing.T) {
|
|
const (
|
|
oldVal = digitalPinEventNone
|
|
newVal = digitalPinEventOnBothEdges
|
|
)
|
|
tests := map[string]struct {
|
|
oldEdge int
|
|
want bool
|
|
wantVal int
|
|
}{
|
|
"no_change": {
|
|
oldEdge: newVal,
|
|
want: false,
|
|
},
|
|
"change": {
|
|
oldEdge: oldVal,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{edge: tc.oldEdge}
|
|
handler := func(lineOffset int, timestamp time.Duration, detectedEdge string, seqno uint32, lseqno uint32) {}
|
|
// act
|
|
got := WithPinEventOnBothEdges(handler)(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, newVal, dpc.edge)
|
|
if tc.want {
|
|
assert.NotNil(t, dpc.edgeEventHandler)
|
|
} else {
|
|
assert.Nil(t, dpc.edgeEventHandler)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWithPinPollForEdgeDetection(t *testing.T) {
|
|
const (
|
|
oldVal = time.Duration(1)
|
|
newVal = time.Duration(3)
|
|
)
|
|
tests := map[string]struct {
|
|
oldPollInterval time.Duration
|
|
want bool
|
|
wantVal time.Duration
|
|
}{
|
|
"no_change": {
|
|
oldPollInterval: newVal,
|
|
},
|
|
"change": {
|
|
oldPollInterval: oldVal,
|
|
want: true,
|
|
},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
dpc := &digitalPinConfig{pollInterval: tc.oldPollInterval}
|
|
stopChan := make(chan struct{})
|
|
defer close(stopChan)
|
|
// act
|
|
got := WithPinPollForEdgeDetection(newVal, stopChan)(dpc)
|
|
// assert
|
|
assert.Equal(t, tc.want, got)
|
|
assert.Equal(t, newVal, dpc.pollInterval)
|
|
})
|
|
}
|
|
}
|