hybridgroup.gobot/drivers/i2c/ccs811_driver_test.go

257 lines
6.2 KiB
Go

package i2c
import (
"errors"
"testing"
"gobot.io/x/gobot"
"gobot.io/x/gobot/gobottest"
)
// The CCS811 Meets the Driver Definition
var _ gobot.Driver = (*CCS811Driver)(nil)
// --------- HELPERS
func initTestCCS811Driver() (driver *CCS811Driver) {
driver, _ = initTestCCS811DriverWithStubbedAdaptor()
return
}
func initTestCCS811DriverWithStubbedAdaptor() (*CCS811Driver, *i2cTestAdaptor) {
adaptor := newI2cTestAdaptor()
return NewCCS811Driver(adaptor), adaptor
}
// --------- BASE TESTS
func TestNewCCS811Driver(t *testing.T) {
// Does it return a pointer to an instance of CCS811Driver?
var c interface{} = NewCCS811Driver(newI2cTestAdaptor())
_, ok := c.(*CCS811Driver)
if !ok {
t.Errorf("NewCCS811Driver() should have returned a *CCS811Driver")
}
}
func TestCCS811DriverSetName(t *testing.T) {
// Does it change the name of the driver
d := initTestCCS811Driver()
d.SetName("TESTME")
gobottest.Assert(t, d.Name(), "TESTME")
}
func TestCCS811Connection(t *testing.T) {
// Does it create an instance of gobot.Connection
ccs811 := initTestCCS811Driver()
gobottest.Refute(t, ccs811.Connection(), nil)
}
// // --------- CONFIG OVERIDE TESTS
func TestCCS811DriverWithBus(t *testing.T) {
// Can it update the bus
d := NewCCS811Driver(newI2cTestAdaptor(), WithBus(2))
gobottest.Assert(t, d.GetBusOrDefault(1), 2)
}
func TestCCS811DriverWithAddress(t *testing.T) {
// Can it update the address
d := NewCCS811Driver(newI2cTestAdaptor(), WithAddress(0xFF))
gobottest.Assert(t, d.GetAddressOrDefault(0x5a), 0xFF)
}
func TestCCS811DriverWithCCS811MeasMode(t *testing.T) {
// Can it update the measurement mode
d := NewCCS811Driver(newI2cTestAdaptor(), WithCCS811MeasMode(CCS811DriveMode10Sec))
gobottest.Assert(t, d.measMode.driveMode, CCS811DriveMode(CCS811DriveMode10Sec))
}
func TestCCS811DriverWithCCS811NTCResistance(t *testing.T) {
// Can it update the ntc resitor value used for temp calcuations
d := NewCCS811Driver(newI2cTestAdaptor(), WithCCS811NTCResistance(0xFF))
gobottest.Assert(t, d.ntcResistanceValue, uint32(0xFF))
}
// // --------- DRIVER SPECIFIC TESTS
func TestCCS811DriverGetGasData(t *testing.T) {
cases := []struct {
readReturn func([]byte) (int, error)
eco2 uint16
tvoc uint16
err error
}{
// Can it compute the gas data with ideal values taken from the bus
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{1, 156, 0, 86})
return 4, nil
},
eco2: 412,
tvoc: 86,
err: nil,
},
// Can it compute the gas data with the max values possible taken from the bus
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{255, 255, 255, 255})
return 4, nil
},
eco2: 65535,
tvoc: 65535,
err: nil,
},
// Does it return an error when the i2c operation fails
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{255, 255, 255, 255})
return 4, errors.New("Error")
},
eco2: 0,
tvoc: 0,
err: errors.New("Error"),
},
}
d, adaptor := initTestCCS811DriverWithStubbedAdaptor()
// Create stub function as it is needed by read submethod in driver code
adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, nil }
d.Start()
for _, c := range cases {
adaptor.i2cReadImpl = c.readReturn
eco2, tvoc, err := d.GetGasData()
gobottest.Assert(t, eco2, c.eco2)
gobottest.Assert(t, tvoc, c.tvoc)
gobottest.Assert(t, err, c.err)
}
}
func TestCCS811DriverGetTemperature(t *testing.T) {
cases := []struct {
readReturn func([]byte) (int, error)
temp float32
err error
}{
// Can it compute the temperature data with ideal values taken from the bus
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{10, 197, 0, 248})
return 4, nil
},
temp: 27.811005,
err: nil,
},
// Can it compute the temperature data without bus values overflowing
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{129, 197, 10, 248})
return 4, nil
},
temp: 29.48822,
err: nil,
},
// Can it compute a negative temperature
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{255, 255, 255, 255})
return 4, nil
},
temp: -25.334152,
err: nil,
},
// Does it return an error if the i2c bus errors
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{129, 197, 0, 248})
return 4, errors.New("Error")
},
temp: 0,
err: errors.New("Error"),
},
}
d, adaptor := initTestCCS811DriverWithStubbedAdaptor()
// Create stub function as it is needed by read submethod in driver code
adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, nil }
d.Start()
for _, c := range cases {
adaptor.i2cReadImpl = c.readReturn
temp, err := d.GetTemperature()
gobottest.Assert(t, temp, c.temp)
gobottest.Assert(t, err, c.err)
}
}
func TestCCS811DriverHasData(t *testing.T) {
cases := []struct {
readReturn func([]byte) (int, error)
result bool
err error
}{
// Does it return true for HasError = 0 and DataRdy = 1
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{0x08})
return 1, nil
},
result: true,
err: nil,
},
// Does it return false for HasError = 1 and DataRdy = 1
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{0x09})
return 1, nil
},
result: false,
err: nil,
},
// Does it return false for HasError = 1 and DataRdy = 0
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{0x01})
return 1, nil
},
result: false,
err: nil,
},
// Does it return false for HasError = 0 and DataRdy = 0
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{0x00})
return 1, nil
},
result: false,
err: nil,
},
// Does it return an error when the i2c read operation fails
{
readReturn: func(b []byte) (int, error) {
copy(b, []byte{0x00})
return 1, errors.New("Error")
},
result: false,
err: errors.New("Error"),
},
}
d, adaptor := initTestCCS811DriverWithStubbedAdaptor()
// Create stub function as it is needed by read submethod in driver code
adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, nil }
d.Start()
for _, c := range cases {
adaptor.i2cReadImpl = c.readReturn
result, err := d.HasData()
gobottest.Assert(t, result, c.result)
gobottest.Assert(t, err, c.err)
}
}