From 2ae950e96dc3ada11943cc3d442f9f7c35f44f8f Mon Sep 17 00:00:00 2001 From: deadprogram Date: Wed, 26 Aug 2020 22:59:35 +0200 Subject: [PATCH] tester: improve API surface and implement one more test function in lis2mdl driver Signed-off-by: deadprogram --- lis2mdl/lis2mdl_test.go | 19 ++++++++++++- tester/device.go | 59 +++++++++++++++++++++++++++++------------ tester/i2c.go | 20 ++++++-------- tester/tester.go | 8 ++++++ 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/lis2mdl/lis2mdl_test.go b/lis2mdl/lis2mdl_test.go index 6bf9c45..bd96812 100644 --- a/lis2mdl/lis2mdl_test.go +++ b/lis2mdl/lis2mdl_test.go @@ -7,9 +7,26 @@ import ( "tinygo.org/x/drivers/tester" ) -func TestI2CAddress(t *testing.T) { +func TestDefaultI2CAddress(t *testing.T) { c := qt.New(t) bus := tester.NewI2CBus(c) dev := New(bus) c.Assert(dev.Address, qt.Equals, uint8(MAG_ADDRESS)) } + +func TestWhoAmI(t *testing.T) { + c := qt.New(t) + bus := tester.NewI2CBus(c) + fake := tester.NewI2CDevice(c, MAG_ADDRESS) + bus.AddDevice(fake) + + dev := New(bus) + + fake.SetupRegisters([]uint8{ + 0x4F: 0x40, + }) + c.Assert(dev.Connected(), qt.Equals, true) + + fake.SetupRegister(0x4F, 0x99) + c.Assert(dev.Connected(), qt.Equals, false) +} diff --git a/tester/device.go b/tester/device.go index 43b669b..c0901a3 100644 --- a/tester/device.go +++ b/tester/device.go @@ -1,38 +1,63 @@ package tester -import ( - qt "github.com/frankban/quicktest" -) - -const maxRegisters = 200 +// MaxRegisters is the maximum number of registers supported for a Device. +const MaxRegisters = 200 // I2CDevice represents a mock I2C device on a mock I2C bus. type I2CDevice struct { - C *qt.C - Addr uint8 + c Failer + // addr is the i2c device address. + addr uint8 // Registers holds the device registers. It can be inspected // or changed as desired for testing. - Registers [maxRegisters]uint8 + registers [MaxRegisters]uint8 // If Err is non-nil, it will be returned as the error from the // I2C methods. Err error } // NewI2CDevice returns a new mock I2C device. -func NewI2CDevice(c *qt.C, addr uint8) *I2CDevice { +func NewI2CDevice(c Failer, addr uint8) *I2CDevice { return &I2CDevice{ - C: c, - Addr: addr, + c: c, + addr: addr, } } +// Addr returns the Device address. +func (d *I2CDevice) Addr() uint8 { + return d.addr +} + +// SetupRegisters sets all of the Device registers. +// It is intended to be used when setting up a fake device +// for testing expected vs. actual values. +func (d *I2CDevice) SetupRegisters(regs []uint8) { + if len(regs) > MaxRegisters { + panic("exceeded maximum number of registers for fake device") + } + for k, v := range regs { + d.registers[k] = v + } +} + +// SetupRegister sets one of the Device registers. +// It is intended to be used when setting up a fake device +// for testing expected vs. actual values. +func (d *I2CDevice) SetupRegister(r, v uint8) { + if r > MaxRegisters { + panic("exceeded maximum number of registers for fake device") + } + d.registers[r] = v +} + // ReadRegister implements I2C.ReadRegister. func (d *I2CDevice) ReadRegister(r uint8, buf []byte) error { if d.Err != nil { return d.Err } d.AssertRegisterRange(r, buf) - copy(buf, d.Registers[r:]) + copy(buf, d.registers[r:]) return nil } @@ -42,17 +67,17 @@ func (d *I2CDevice) WriteRegister(r uint8, buf []byte) error { return d.Err } d.AssertRegisterRange(r, buf) - copy(d.Registers[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 *I2CDevice) 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(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)) + 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)) } } diff --git a/tester/i2c.go b/tester/i2c.go index 79887c3..a2c3274 100644 --- a/tester/i2c.go +++ b/tester/i2c.go @@ -1,27 +1,23 @@ package tester -import ( - qt "github.com/frankban/quicktest" -) - // I2CBus implements the I2C interface in memory for testing. type I2CBus struct { - C *qt.C - Devices []*I2CDevice + c Failer + devices []*I2CDevice } // NewI2CBus returns an I2CBus mock I2C instance that uses c to flag errors // if they happen. After creating a I2C instance, add devices // to it with addDevice before using NewI2CBus interface. -func NewI2CBus(c *qt.C) *I2CBus { +func NewI2CBus(c Failer) *I2CBus { return &I2CBus{ - C: c, + c: c, } } // AddDevice adds a new mock device to the mock I2C bus. func (bus *I2CBus) AddDevice(d *I2CDevice) { - bus.Devices = append(bus.Devices, d) + bus.devices = append(bus.devices, d) } // ReadRegister implements I2C.ReadRegister. @@ -42,11 +38,11 @@ func (bus *I2CBus) Tx(addr uint16, input, output []byte) error { // FindDevice returns the device with the given address. func (bus *I2CBus) FindDevice(addr uint8) *I2CDevice { - for _, dev := range bus.Devices { - if dev.Addr == addr { + for _, dev := range bus.devices { + if dev.Addr() == addr { return dev } } - bus.C.Fatalf("invalid device addr %#x passed to i2c bus", addr) + bus.c.Fatalf("invalid device addr %#x passed to i2c bus", addr) panic("unreachable") } diff --git a/tester/tester.go b/tester/tester.go index 5caf27e..4cbdc22 100644 --- a/tester/tester.go +++ b/tester/tester.go @@ -3,3 +3,11 @@ // TODO: info on how to use this. // package tester // import "tinygo.org/x/drivers/tester" + +// Failer is used by the I2CDevice type to abort when it's used in +// unexpected ways, such as reading an out-of-range register. +type Failer interface { + // Fatalf prints the Printf-formatted message and exits the current + // goroutine. + Fatalf(f string, a ...interface{}) +}