mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-26 13:48:49 +08:00
165 lines
5.7 KiB
Go
165 lines
5.7 KiB
Go
//nolint:forcetypeassert // ok here
|
|
package aio
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNewAnalogActuatorDriver(t *testing.T) {
|
|
// arrange
|
|
const pin = "47"
|
|
a := newAioTestAdaptor()
|
|
// act
|
|
d := NewAnalogActuatorDriver(a, pin)
|
|
// assert: driver attributes
|
|
assert.IsType(t, &AnalogActuatorDriver{}, d)
|
|
assert.NotNil(t, d.driverCfg)
|
|
assert.True(t, strings.HasPrefix(d.Name(), "AnalogActuator"))
|
|
assert.Equal(t, a, d.Connection())
|
|
require.NoError(t, d.afterStart())
|
|
require.NoError(t, d.beforeHalt())
|
|
assert.NotNil(t, d.Commander)
|
|
assert.NotNil(t, d.mutex)
|
|
// assert: actuator attributes
|
|
assert.Equal(t, pin, d.Pin())
|
|
assert.InDelta(t, 0.0, d.lastValue, 0, 0)
|
|
assert.Equal(t, 0, d.lastRawValue)
|
|
require.NotNil(t, d.actuatorCfg)
|
|
assert.NotNil(t, d.actuatorCfg.scale)
|
|
}
|
|
|
|
func TestNewAnalogActuatorDriver_options(t *testing.T) {
|
|
// This is a general test, that options are applied in constructor by using the common WithName() option, least one
|
|
// option of this driver and one of another driver (which should lead to panic). Further tests for options can also
|
|
// be done by call of "WithOption(val).apply(cfg)".
|
|
// arrange
|
|
myName := "relay 1"
|
|
myScaler := func(input float64) int { return int(2 * input) }
|
|
panicFunc := func() {
|
|
NewAnalogActuatorDriver(newAioTestAdaptor(), "1", WithName("crazy"), WithSensorCyclicRead(10*time.Millisecond))
|
|
}
|
|
// act
|
|
d := NewAnalogActuatorDriver(newAioTestAdaptor(), "1", WithName(myName), WithActuatorScaler(myScaler))
|
|
// assert
|
|
assert.Equal(t, myName, d.Name())
|
|
assert.Equal(t, 3, d.actuatorCfg.scale(1.5))
|
|
assert.PanicsWithValue(t, "'read interval option for analog sensors' can not be applied on 'crazy'", panicFunc)
|
|
}
|
|
|
|
func TestAnalogActuatorWriteRaw(t *testing.T) {
|
|
tests := map[string]struct {
|
|
inputVal int
|
|
simulateWriteErr bool
|
|
wantWritten int
|
|
wantErr string
|
|
}{
|
|
"write_raw": {inputVal: 100, wantWritten: 100},
|
|
"error_write": {inputVal: 12345, wantWritten: 12345, simulateWriteErr: true, wantErr: "write error"},
|
|
}
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
const pin = "47"
|
|
a := newAioTestAdaptor()
|
|
d := NewAnalogActuatorDriver(a, pin)
|
|
a.simulateWriteError = tc.simulateWriteErr
|
|
a.written = nil // reset previous writes
|
|
// act
|
|
err := d.WriteRaw(tc.inputVal)
|
|
// assert
|
|
if tc.wantErr != "" {
|
|
require.EqualError(t, err, tc.wantErr)
|
|
assert.Empty(t, a.written)
|
|
} else {
|
|
require.NoError(t, err)
|
|
assert.Len(t, a.written, 1)
|
|
assert.Equal(t, pin, a.written[0].pin)
|
|
assert.Equal(t, tc.wantWritten, a.written[0].val)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAnalogActuatorWriteRaw_AnalogWriteNotSupported(t *testing.T) {
|
|
// arrange
|
|
d := NewAnalogActuatorDriver(newAioTestAdaptor(), "1")
|
|
d.connection = &aioTestBareAdaptor{}
|
|
// act & assert
|
|
require.EqualError(t, d.WriteRaw(3), "AnalogWrite is not supported by the platform 'bare'")
|
|
}
|
|
|
|
func TestAnalogActuatorWrite_SetScaler(t *testing.T) {
|
|
tests := map[string]struct {
|
|
fromMin float64
|
|
fromMax float64
|
|
input float64
|
|
wantWritten int
|
|
}{
|
|
"byte_range_min": {fromMin: 0, fromMax: 255, input: 0, wantWritten: 0},
|
|
"byte_range_max": {fromMin: 0, fromMax: 255, input: 255, wantWritten: 255},
|
|
"signed_percent_range_min": {fromMin: -100, fromMax: 100, input: -100, wantWritten: 0},
|
|
"signed_percent_range_mid": {fromMin: -100, fromMax: 100, input: 0, wantWritten: 127},
|
|
"signed_percent_range_max": {fromMin: -100, fromMax: 100, input: 100, wantWritten: 255},
|
|
"voltage_range_min": {fromMin: 0, fromMax: 5.1, input: 0, wantWritten: 0},
|
|
"voltage_range_nearmin": {fromMin: 0, fromMax: 5.1, input: 0.02, wantWritten: 1},
|
|
"voltage_range_mid": {fromMin: 0, fromMax: 5.1, input: 2.55, wantWritten: 127},
|
|
"voltage_range_nearmax": {fromMin: 0, fromMax: 5.1, input: 5.08, wantWritten: 254},
|
|
"voltage_range_max": {fromMin: 0, fromMax: 5.1, input: 5.1, wantWritten: 255},
|
|
"upscale": {fromMin: 0, fromMax: 24, input: 12, wantWritten: 127},
|
|
"below_min": {fromMin: -10, fromMax: 10, input: -11, wantWritten: 0},
|
|
"exceed_max": {fromMin: 0, fromMax: 20, input: 21, wantWritten: 255},
|
|
}
|
|
|
|
const pin = "7"
|
|
a := newAioTestAdaptor()
|
|
d := NewAnalogActuatorDriver(a, pin)
|
|
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// arrange
|
|
d.SetScaler(AnalogActuatorLinearScaler(tc.fromMin, tc.fromMax, 0, 255))
|
|
a.written = nil // reset previous writes
|
|
// act
|
|
err := d.Write(tc.input)
|
|
// assert
|
|
require.NoError(t, err)
|
|
assert.Len(t, a.written, 1)
|
|
assert.Equal(t, pin, a.written[0].pin)
|
|
assert.Equal(t, tc.wantWritten, a.written[0].val)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAnalogActuatorCommands_WithActuatorScaler(t *testing.T) {
|
|
// arrange
|
|
const pin = "8"
|
|
a := newAioTestAdaptor()
|
|
d := NewAnalogActuatorDriver(a, pin, WithActuatorScaler(func(input float64) int { return int((input + 3) / 2.5) }))
|
|
a.written = nil // reset previous writes
|
|
// act & assert: WriteRaw
|
|
err := d.Command("WriteRaw")(map[string]interface{}{"val": "100"})
|
|
assert.Nil(t, err)
|
|
assert.Len(t, a.written, 1)
|
|
assert.Equal(t, pin, a.written[0].pin)
|
|
assert.Equal(t, 100, a.written[0].val)
|
|
assert.Equal(t, 100, d.RawValue())
|
|
assert.InDelta(t, 0.0, d.Value(), 0.0)
|
|
// act & assert: Write
|
|
err = d.Command("Write")(map[string]interface{}{"val": "247.0"})
|
|
assert.Nil(t, err)
|
|
assert.Len(t, a.written, 2)
|
|
assert.Equal(t, pin, a.written[1].pin)
|
|
assert.Equal(t, 100, a.written[1].val)
|
|
assert.Equal(t, 100, d.RawValue())
|
|
assert.InDelta(t, 247.0, d.Value(), 0.0)
|
|
// arrange & act & assert: Write with error
|
|
a.simulateWriteError = true
|
|
err = d.Command("Write")(map[string]interface{}{"val": "247.0"})
|
|
require.EqualError(t, err.(error), "write error")
|
|
}
|