Files
drivers/mcp23017/fakedev_test.go
T
2021-01-20 12:56:22 +01:00

98 lines
2.4 KiB
Go

package mcp23017
import (
qt "github.com/frankban/quicktest"
)
// fakeBus implements the I2C interface in memory for testing.
type fakeBus struct {
c *qt.C
devs []*fakeDev
}
// newBus returns a fakeBus instance that uses c to flag errors
// if they happen. After creating a fakeBus instance, add devices
// to it with addDevice before using the interface.
func newBus(c *qt.C) *fakeBus {
return &fakeBus{
c: c,
}
}
// fakeDev represents a device on the bus.
type fakeDev struct {
c *qt.C
addr uint8
// Registers holds the device registers. It can be inspected
// or changed as desired for testing.
Registers [registerCount]uint8
// If Err is non-nil, it will be returned as the error from the
// I2C methods.
Err error
}
// addDevice adds a new device at the given address.
func (bus *fakeBus) addDevice(addr uint8) *fakeDev {
dev := &fakeDev{
c: bus.c,
addr: addr,
Registers: [registerCount]uint8{
// IODIRA and IODIRB are all ones by default.
rIODIR: 0xff,
rIODIR | portB: 0xff,
},
}
bus.devs = append(bus.devs, dev)
return dev
}
// ReadRegister implements I2C.ReadRegister.
func (bus *fakeBus) ReadRegister(addr uint8, r uint8, buf []byte) error {
return bus.findDev(addr).readRegister(r, buf)
}
// WriteRegister implements I2C.WriteRegister.
func (bus *fakeBus) WriteRegister(addr uint8, r uint8, buf []byte) error {
return bus.findDev(addr).writeRegister(r, buf)
}
func (d *fakeDev) readRegister(r uint8, buf []byte) error {
if d.Err != nil {
return d.Err
}
d.assertRegisterRange(r, buf)
copy(buf, d.Registers[r:])
return nil
}
func (d *fakeDev) writeRegister(r uint8, buf []byte) error {
if d.Err != nil {
return d.Err
}
d.assertRegisterRange(r, buf)
copy(d.Registers[r:], buf)
return nil
}
// assertRegisterRange asserts that reading or writing the given
// register and subsequent registers is in range of the available registers.
func (d *fakeDev) assertRegisterRange(r uint8, buf []byte) {
if int(r) >= len(d.Registers) {
d.c.Fatalf("register read/write [%#x, %#x] start out of range", r, int(r)+len(buf))
}
if int(r)+len(buf) > len(d.Registers) {
d.c.Fatalf("register read/write [%#x, %#x] end out of range", r, int(r)+len(buf))
}
}
// findDev returns the device with the given address.
func (bus *fakeBus) findDev(addr uint8) *fakeDev {
for _, dev := range bus.devs {
if dev.addr == addr {
return dev
}
}
bus.c.Fatalf("invalid device addr %#x passed to i2c bus", addr)
panic("unreachable")
}