2018-09-12 23:46:59 -04:00
|
|
|
package gpio
|
|
|
|
|
|
|
|
import (
|
2023-10-31 18:12:07 +01:00
|
|
|
"fmt"
|
2018-09-12 23:46:59 -04:00
|
|
|
"strings"
|
2023-10-31 18:12:07 +01:00
|
|
|
"sync"
|
2018-09-12 23:46:59 -04:00
|
|
|
"testing"
|
|
|
|
"time"
|
2023-05-20 14:25:21 +02:00
|
|
|
|
2023-10-20 10:27:09 +02:00
|
|
|
"github.com/stretchr/testify/assert"
|
2023-10-31 18:12:07 +01:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-09-12 23:46:59 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
stepAngle = 0.5 // use non int step angle to check int math
|
|
|
|
stepsPerRev = 720
|
|
|
|
)
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func initTestEasyDriverWithStubbedAdaptor() (*EasyDriver, *gpioTestAdaptor) {
|
|
|
|
a := newGpioTestAdaptor()
|
|
|
|
d := NewEasyDriver(a, stepAngle, "1", "2", "3", "4")
|
|
|
|
return d, a
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestNewEasyDriver(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
a := newGpioTestAdaptor()
|
|
|
|
// act
|
|
|
|
d := NewEasyDriver(a, stepAngle, "1", "2", "3", "4")
|
|
|
|
// assert
|
|
|
|
assert.IsType(t, &EasyDriver{}, d)
|
|
|
|
assert.True(t, strings.HasPrefix(d.name, "EasyDriver"))
|
|
|
|
assert.Equal(t, a, d.connection)
|
|
|
|
assert.NoError(t, d.afterStart())
|
|
|
|
assert.NoError(t, d.beforeHalt())
|
|
|
|
assert.NotNil(t, d.Commander)
|
|
|
|
assert.NotNil(t, d.mutex)
|
|
|
|
assert.Equal(t, "1", d.stepPin)
|
|
|
|
assert.Equal(t, "2", d.dirPin)
|
|
|
|
assert.Equal(t, "3", d.enPin)
|
|
|
|
assert.Equal(t, "4", d.sleepPin)
|
|
|
|
assert.Equal(t, float32(stepAngle), d.angle)
|
|
|
|
assert.Equal(t, uint(180), d.rpm)
|
|
|
|
assert.Equal(t, int8(1), d.dir)
|
|
|
|
assert.Equal(t, 0, d.stepNum)
|
|
|
|
assert.Equal(t, true, d.enabled)
|
|
|
|
assert.Equal(t, false, d.sleeping)
|
|
|
|
assert.Nil(t, d.runStopChan)
|
2018-09-20 14:02:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestEasyDriverHalt(t *testing.T) {
|
2023-10-31 18:12:07 +01:00
|
|
|
// arrange
|
|
|
|
d, _ := initTestEasyDriverWithStubbedAdaptor()
|
|
|
|
require.NoError(t, d.Run())
|
|
|
|
require.True(t, d.IsMoving())
|
|
|
|
// act
|
|
|
|
err := d.Halt()
|
|
|
|
// assert
|
|
|
|
assert.NoError(t, err)
|
2023-10-20 10:27:09 +02:00
|
|
|
assert.False(t, d.IsMoving())
|
2018-09-20 14:02:36 -04:00
|
|
|
}
|
|
|
|
|
2018-09-12 23:46:59 -04:00
|
|
|
func TestEasyDriverMove(t *testing.T) {
|
2023-10-31 18:12:07 +01:00
|
|
|
tests := map[string]struct {
|
|
|
|
inputSteps int
|
|
|
|
simulateDisabled bool
|
|
|
|
simulateAlreadyRunning bool
|
|
|
|
simulateWriteErr bool
|
|
|
|
wantWrites int
|
|
|
|
wantSteps int
|
|
|
|
wantMoving bool
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"move_one": {
|
|
|
|
inputSteps: 1,
|
|
|
|
wantWrites: 4,
|
|
|
|
wantSteps: 2,
|
|
|
|
wantMoving: false,
|
|
|
|
},
|
|
|
|
"move_more": {
|
|
|
|
inputSteps: 20,
|
|
|
|
wantWrites: 80,
|
|
|
|
wantSteps: 40,
|
|
|
|
wantMoving: false,
|
|
|
|
},
|
|
|
|
"error_disabled": {
|
|
|
|
simulateDisabled: true,
|
|
|
|
wantMoving: false,
|
|
|
|
wantErr: "is disabled",
|
|
|
|
},
|
|
|
|
"error_already_running": {
|
|
|
|
simulateAlreadyRunning: true,
|
|
|
|
wantMoving: true,
|
|
|
|
wantErr: "already running or moving",
|
|
|
|
},
|
|
|
|
"error_write": {
|
|
|
|
inputSteps: 1,
|
|
|
|
simulateWriteErr: true,
|
|
|
|
wantWrites: 1,
|
|
|
|
wantMoving: false,
|
|
|
|
wantErr: "write error",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
d, a := initTestEasyDriverWithStubbedAdaptor()
|
|
|
|
d.enabled = !tc.simulateDisabled
|
|
|
|
if tc.simulateAlreadyRunning {
|
|
|
|
d.runStopChan = make(chan struct{})
|
|
|
|
defer func() { close(d.runStopChan); d.runStopChan = nil }()
|
|
|
|
}
|
|
|
|
var numCallsWrite int
|
|
|
|
a.digitalWriteFunc = func(string, byte) error {
|
|
|
|
numCallsWrite++
|
|
|
|
if tc.simulateWriteErr {
|
|
|
|
return fmt.Errorf("write error")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// act
|
|
|
|
err := d.Move(tc.inputSteps)
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.ErrorContains(t, err, tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantSteps, d.stepNum)
|
|
|
|
assert.Equal(t, tc.wantWrites, numCallsWrite)
|
|
|
|
assert.Equal(t, tc.wantMoving, d.IsMoving())
|
|
|
|
})
|
|
|
|
}
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestEasyDriverRun_IsMoving(t *testing.T) {
|
|
|
|
tests := map[string]struct {
|
|
|
|
simulateDisabled bool
|
|
|
|
simulateAlreadyRunning bool
|
|
|
|
simulateWriteErr bool
|
|
|
|
wantMoving bool
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"run": {
|
|
|
|
wantMoving: true,
|
|
|
|
},
|
|
|
|
"error_disabled": {
|
|
|
|
simulateDisabled: true,
|
|
|
|
wantMoving: false,
|
|
|
|
wantErr: "is disabled",
|
|
|
|
},
|
|
|
|
"write_error_skipped": {
|
|
|
|
simulateWriteErr: true,
|
|
|
|
wantMoving: true,
|
|
|
|
},
|
|
|
|
"error_already_running": {
|
|
|
|
simulateAlreadyRunning: true,
|
|
|
|
wantMoving: true,
|
|
|
|
wantErr: "already running or moving",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
d, a := initTestEasyDriverWithStubbedAdaptor()
|
|
|
|
d.enabled = !tc.simulateDisabled
|
|
|
|
if tc.simulateAlreadyRunning {
|
|
|
|
d.runStopChan = make(chan struct{})
|
|
|
|
defer func() { close(d.runStopChan); d.runStopChan = nil }()
|
|
|
|
}
|
|
|
|
simWriteErr := tc.simulateWriteErr // to prevent data race in write function (go-called)
|
|
|
|
a.digitalWriteFunc = func(string, byte) error {
|
|
|
|
if simWriteErr {
|
|
|
|
simWriteErr = false // to prevent to much output
|
|
|
|
return fmt.Errorf("write error")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// act
|
|
|
|
err := d.Run()
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.ErrorContains(t, err, tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantMoving, d.IsMoving())
|
|
|
|
})
|
|
|
|
}
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestEasyDriverStop_IsMoving(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
d, _ := initTestEasyDriverWithStubbedAdaptor()
|
|
|
|
require.NoError(t, d.Run())
|
|
|
|
require.True(t, d.IsMoving())
|
|
|
|
// act
|
|
|
|
err := d.Stop()
|
|
|
|
// assert
|
|
|
|
assert.NoError(t, err)
|
2023-10-20 10:27:09 +02:00
|
|
|
assert.False(t, d.IsMoving())
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestEasyDriverStep(t *testing.T) {
|
2023-10-31 18:12:07 +01:00
|
|
|
tests := map[string]struct {
|
|
|
|
countCallsForth int
|
|
|
|
countCallsBack int
|
|
|
|
simulateAlreadyRunning bool
|
|
|
|
simulateWriteErr bool
|
|
|
|
wantSteps int
|
|
|
|
wantWritten []byte
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"single": {
|
|
|
|
countCallsForth: 1,
|
|
|
|
wantSteps: 1,
|
|
|
|
wantWritten: []byte{0x00, 0x01},
|
|
|
|
},
|
|
|
|
"many": {
|
|
|
|
countCallsForth: 4,
|
|
|
|
wantSteps: 4,
|
|
|
|
wantWritten: []byte{0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1},
|
|
|
|
},
|
|
|
|
"forth_and_back": {
|
|
|
|
countCallsForth: 5,
|
|
|
|
countCallsBack: 3,
|
|
|
|
wantSteps: 2,
|
|
|
|
wantWritten: []byte{0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1},
|
|
|
|
},
|
|
|
|
"reverse": {
|
|
|
|
countCallsBack: 3,
|
|
|
|
wantSteps: -3,
|
|
|
|
wantWritten: []byte{0x0, 0x1, 0x0, 0x1, 0x0, 0x1},
|
|
|
|
},
|
|
|
|
"error_already_running": {
|
|
|
|
countCallsForth: 1,
|
|
|
|
simulateAlreadyRunning: true,
|
|
|
|
wantErr: "already running or moving",
|
|
|
|
},
|
|
|
|
"error_write": {
|
|
|
|
simulateWriteErr: true,
|
|
|
|
wantWritten: []byte{0x00, 0x00},
|
|
|
|
countCallsBack: 2,
|
|
|
|
wantErr: "write error",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
d, a := initTestEasyDriverWithStubbedAdaptor()
|
|
|
|
if tc.simulateAlreadyRunning {
|
|
|
|
d.runStopChan = make(chan struct{})
|
|
|
|
defer func() { close(d.runStopChan); d.runStopChan = nil }()
|
|
|
|
}
|
|
|
|
var writtenValues []byte
|
|
|
|
a.digitalWriteFunc = func(pin string, val byte) error {
|
|
|
|
assert.Equal(t, d.stepPin, pin)
|
|
|
|
writtenValues = append(writtenValues, val)
|
|
|
|
if tc.simulateWriteErr {
|
|
|
|
return fmt.Errorf("write error")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
var errs []string
|
|
|
|
// act
|
|
|
|
for i := 0; i < tc.countCallsForth; i++ {
|
|
|
|
if err := d.Step(); err != nil {
|
|
|
|
errs = append(errs, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
d.dir = -1
|
|
|
|
for i := 0; i < tc.countCallsBack; i++ {
|
|
|
|
if err := d.Step(); err != nil {
|
|
|
|
errs = append(errs, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.Contains(t, strings.Join(errs, ","), tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.Nil(t, errs)
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantSteps, d.stepNum)
|
|
|
|
assert.Equal(t, tc.wantSteps, d.CurrentStep())
|
|
|
|
assert.Equal(t, tc.wantWritten, writtenValues)
|
|
|
|
})
|
|
|
|
}
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestEasyDriverSetDirection(t *testing.T) {
|
2023-10-31 18:12:07 +01:00
|
|
|
tests := map[string]struct {
|
|
|
|
dirPin string
|
|
|
|
input string
|
|
|
|
wantVal int8
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"cw": {
|
|
|
|
input: "cw",
|
|
|
|
dirPin: "10",
|
|
|
|
wantVal: 1,
|
|
|
|
},
|
|
|
|
"ccw": {
|
|
|
|
input: "ccw",
|
|
|
|
dirPin: "11",
|
|
|
|
wantVal: -1,
|
|
|
|
},
|
|
|
|
"unknown": {
|
|
|
|
input: "unknown",
|
|
|
|
dirPin: "12",
|
|
|
|
wantVal: 1,
|
|
|
|
},
|
|
|
|
"error_no_pin": {
|
|
|
|
dirPin: "",
|
|
|
|
wantVal: 1,
|
|
|
|
wantErr: "dirPin is not set",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
a := newGpioTestAdaptor()
|
|
|
|
d := NewEasyDriver(a, stepAngle, "1", tc.dirPin, "3", "4")
|
|
|
|
require.Equal(t, int8(1), d.dir)
|
|
|
|
// act
|
|
|
|
err := d.SetDirection(tc.input)
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.ErrorContains(t, err, tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantVal, d.dir)
|
|
|
|
})
|
|
|
|
}
|
2018-09-20 14:02:36 -04:00
|
|
|
}
|
|
|
|
|
2018-09-12 23:46:59 -04:00
|
|
|
func TestEasyDriverSetSpeed(t *testing.T) {
|
2023-10-31 18:12:07 +01:00
|
|
|
const (
|
|
|
|
angle = 10
|
|
|
|
max = 36 // 360/angle
|
|
|
|
)
|
2018-09-12 23:46:59 -04:00
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
tests := map[string]struct {
|
|
|
|
input uint
|
|
|
|
want uint
|
|
|
|
}{
|
|
|
|
"below_minimum": {
|
|
|
|
input: 0,
|
|
|
|
want: 1,
|
|
|
|
},
|
|
|
|
"minimum": {
|
|
|
|
input: 1,
|
|
|
|
want: 1,
|
|
|
|
},
|
|
|
|
"maximum": {
|
|
|
|
input: max,
|
|
|
|
want: max,
|
|
|
|
},
|
|
|
|
"above_maximum": {
|
|
|
|
input: max + 1,
|
|
|
|
want: max,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
d := EasyDriver{angle: angle}
|
|
|
|
// act
|
|
|
|
err := d.SetSpeed(tc.input)
|
|
|
|
// assert
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, tc.want, d.rpm)
|
|
|
|
})
|
|
|
|
}
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestEasyDriverMaxSpeed(t *testing.T) {
|
|
|
|
tests := map[string]struct {
|
|
|
|
angle float32
|
|
|
|
want uint
|
|
|
|
}{
|
|
|
|
"180": {
|
|
|
|
angle: 2.0,
|
|
|
|
want: 180,
|
|
|
|
},
|
|
|
|
"360": {
|
|
|
|
angle: 1.0,
|
|
|
|
want: 360,
|
|
|
|
},
|
|
|
|
"720": {
|
|
|
|
angle: 0.5,
|
|
|
|
want: 720,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
d := EasyDriver{angle: tc.angle}
|
|
|
|
// act & assert
|
|
|
|
assert.Equal(t, tc.want, d.MaxSpeed())
|
|
|
|
})
|
|
|
|
}
|
2018-09-20 14:02:36 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestEasyDriverEnable_IsEnabled(t *testing.T) {
|
|
|
|
tests := map[string]struct {
|
|
|
|
enPin string
|
|
|
|
simulateWriteErr bool
|
|
|
|
wantWrites int
|
|
|
|
wantEnabled bool
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"basic": {
|
|
|
|
enPin: "10",
|
|
|
|
wantWrites: 1,
|
|
|
|
wantEnabled: true,
|
|
|
|
},
|
|
|
|
"with_run": {
|
|
|
|
enPin: "11",
|
|
|
|
wantWrites: 1,
|
|
|
|
wantEnabled: true,
|
|
|
|
},
|
|
|
|
"error_no_pin": {
|
|
|
|
enPin: "",
|
|
|
|
wantWrites: 0,
|
|
|
|
wantEnabled: true, // is enabled by default
|
|
|
|
wantErr: "enPin is not set",
|
|
|
|
},
|
|
|
|
"error_write": {
|
|
|
|
enPin: "12",
|
|
|
|
simulateWriteErr: true,
|
|
|
|
wantWrites: 1,
|
|
|
|
wantEnabled: false,
|
|
|
|
wantErr: "write error",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
a := newGpioTestAdaptor()
|
|
|
|
d := NewEasyDriver(a, stepAngle, "1", "2", tc.enPin, "4")
|
|
|
|
var numCallsWrite int
|
|
|
|
var writtenPin string
|
|
|
|
writtenValue := byte(0xFF)
|
|
|
|
a.digitalWriteFunc = func(pin string, val byte) error {
|
|
|
|
numCallsWrite++
|
|
|
|
writtenPin = pin
|
|
|
|
writtenValue = val
|
|
|
|
if tc.simulateWriteErr {
|
|
|
|
return fmt.Errorf("write error")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
d.enabled = false
|
|
|
|
require.False(t, d.IsEnabled())
|
|
|
|
// act
|
|
|
|
err := d.Enable()
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.ErrorContains(t, err, tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, byte(0), writtenValue) // enable pin is active low
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantEnabled, d.IsEnabled())
|
|
|
|
assert.Equal(t, tc.wantWrites, numCallsWrite)
|
|
|
|
assert.Equal(t, tc.enPin, writtenPin)
|
|
|
|
})
|
|
|
|
}
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestEasyDriverDisable_IsEnabled(t *testing.T) {
|
|
|
|
tests := map[string]struct {
|
|
|
|
enPin string
|
|
|
|
runBefore bool
|
|
|
|
simulateWriteErr string
|
|
|
|
wantWrites int
|
|
|
|
wantEnabled bool
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"basic": {
|
|
|
|
enPin: "10",
|
|
|
|
wantWrites: 1,
|
|
|
|
wantEnabled: false,
|
|
|
|
},
|
|
|
|
"with_run": {
|
|
|
|
enPin: "10",
|
|
|
|
runBefore: true,
|
|
|
|
wantWrites: 1,
|
|
|
|
wantEnabled: false,
|
|
|
|
},
|
|
|
|
"error_no_pin": {
|
|
|
|
enPin: "",
|
|
|
|
wantWrites: 0,
|
|
|
|
wantEnabled: true, // is enabled by default
|
|
|
|
wantErr: "enPin is not set",
|
|
|
|
},
|
|
|
|
"error_write": {
|
|
|
|
enPin: "12",
|
|
|
|
simulateWriteErr: "write error",
|
|
|
|
wantWrites: 1,
|
|
|
|
wantEnabled: true,
|
|
|
|
wantErr: "write error",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
a := newGpioTestAdaptor()
|
|
|
|
d := NewEasyDriver(a, stepAngle, "1", "2", tc.enPin, "4")
|
|
|
|
writeMutex := sync.Mutex{}
|
|
|
|
var numCallsWrite int
|
|
|
|
var writtenPin string
|
|
|
|
writtenValue := byte(0xFF)
|
|
|
|
a.digitalWriteFunc = func(pin string, val byte) error {
|
|
|
|
writeMutex.Lock()
|
|
|
|
defer writeMutex.Unlock()
|
|
|
|
if pin == d.stepPin {
|
|
|
|
// we do not consider call of step()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
numCallsWrite++
|
|
|
|
writtenPin = pin
|
|
|
|
writtenValue = val
|
|
|
|
if tc.simulateWriteErr != "" {
|
|
|
|
return fmt.Errorf(tc.simulateWriteErr)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if tc.runBefore {
|
|
|
|
require.NoError(t, d.Run())
|
|
|
|
require.True(t, d.IsMoving())
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
}
|
|
|
|
d.enabled = true
|
|
|
|
require.True(t, d.IsEnabled())
|
|
|
|
// act
|
|
|
|
err := d.Disable()
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.ErrorContains(t, err, tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, byte(1), writtenValue) // enable pin is active low
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantEnabled, d.IsEnabled())
|
|
|
|
assert.False(t, d.IsMoving())
|
|
|
|
assert.Equal(t, tc.wantWrites, numCallsWrite)
|
|
|
|
assert.Equal(t, tc.enPin, writtenPin)
|
|
|
|
})
|
|
|
|
}
|
2018-09-20 14:02:36 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestEasyDriverSleep_IsSleeping(t *testing.T) {
|
|
|
|
tests := map[string]struct {
|
|
|
|
sleepPin string
|
|
|
|
runBefore bool
|
|
|
|
wantSleep bool
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"basic": {
|
|
|
|
sleepPin: "10",
|
|
|
|
wantSleep: true,
|
|
|
|
},
|
|
|
|
"with_run": {
|
|
|
|
sleepPin: "11",
|
|
|
|
runBefore: true,
|
|
|
|
wantSleep: true,
|
|
|
|
},
|
|
|
|
"error_no_pin": {
|
|
|
|
sleepPin: "",
|
|
|
|
wantSleep: false,
|
|
|
|
wantErr: "sleepPin is not set",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
a := newGpioTestAdaptor()
|
|
|
|
d := NewEasyDriver(a, stepAngle, "1", "2", "3", tc.sleepPin)
|
|
|
|
if tc.runBefore {
|
|
|
|
require.NoError(t, d.Run())
|
|
|
|
}
|
|
|
|
d.sleeping = false
|
|
|
|
require.False(t, d.IsSleeping())
|
|
|
|
// act
|
|
|
|
err := d.Sleep()
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.ErrorContains(t, err, tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantSleep, d.IsSleeping())
|
|
|
|
})
|
|
|
|
}
|
2018-09-20 14:02:36 -04:00
|
|
|
}
|
|
|
|
|
2023-10-31 18:12:07 +01:00
|
|
|
func TestEasyDriverWake_IsSleeping(t *testing.T) {
|
|
|
|
tests := map[string]struct {
|
|
|
|
sleepPin string
|
|
|
|
wantSleep bool
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
"basic": {
|
|
|
|
sleepPin: "10",
|
|
|
|
wantSleep: false,
|
|
|
|
},
|
|
|
|
"error_no_pin": {
|
|
|
|
sleepPin: "",
|
|
|
|
wantSleep: true,
|
|
|
|
wantErr: "sleepPin is not set",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// arrange
|
|
|
|
a := newGpioTestAdaptor()
|
|
|
|
d := NewEasyDriver(a, stepAngle, "1", "2", "3", tc.sleepPin)
|
|
|
|
d.sleeping = true
|
|
|
|
require.True(t, d.IsSleeping())
|
|
|
|
// act
|
|
|
|
err := d.Wake()
|
|
|
|
// assert
|
|
|
|
if tc.wantErr != "" {
|
|
|
|
assert.ErrorContains(t, err, tc.wantErr)
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.wantSleep, d.IsSleeping())
|
|
|
|
})
|
|
|
|
}
|
2018-09-12 23:46:59 -04:00
|
|
|
}
|