gobot.io/x/gobot/v2@v2.1.0/drivers/i2c/pca9501_driver_test.go (about) 1 package i2c 2 3 import ( 4 "errors" 5 "strings" 6 "testing" 7 8 "gobot.io/x/gobot/v2" 9 "gobot.io/x/gobot/v2/gobottest" 10 ) 11 12 // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver 13 // and tests all implementations, so no further tests needed here for gobot.Driver interface 14 var _ gobot.Driver = (*PCA9501Driver)(nil) 15 16 var ( 17 pinVal = map[string]interface{}{ 18 "pin": uint8(7), 19 "val": uint8(0), 20 } 21 pin = map[string]interface{}{ 22 "pin": uint8(7), 23 } 24 addressVal = map[string]interface{}{ 25 "address": uint8(15), 26 "val": uint8(7), 27 } 28 address = map[string]interface{}{ 29 "address": uint8(15), 30 } 31 ) 32 33 func initPCA9501WithStubbedAdaptor() (*PCA9501Driver, *i2cTestAdaptor) { 34 a := newI2cTestAdaptor() 35 d := NewPCA9501Driver(a) 36 if err := d.Start(); err != nil { 37 panic(err) 38 } 39 return d, a 40 } 41 42 func TestNewPCA9501Driver(t *testing.T) { 43 // arrange, act 44 var di interface{} = NewPCA9501Driver(newI2cTestAdaptor()) 45 // assert 46 d, ok := di.(*PCA9501Driver) 47 if !ok { 48 t.Errorf("NewPCA9501Driver() should have returned a *PCA9501Driver") 49 } 50 gobottest.Refute(t, d.Driver, nil) 51 gobottest.Assert(t, strings.HasPrefix(d.Name(), "PCA9501"), true) 52 gobottest.Assert(t, d.defaultAddress, 0x3f) 53 } 54 55 func TestPCA9501Options(t *testing.T) { 56 // This is a general test, that options are applied in constructor by using the common WithBus() option and 57 // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". 58 d := NewPCA9501Driver(newI2cTestAdaptor(), WithBus(2)) 59 gobottest.Assert(t, d.GetBusOrDefault(1), 2) 60 } 61 62 func TestPCA9501CommandsWriteGPIO(t *testing.T) { 63 // arrange 64 d, a := initPCA9501WithStubbedAdaptor() 65 a.i2cReadImpl = func(b []byte) (int, error) { 66 return len(b), nil 67 } 68 a.i2cWriteImpl = func([]byte) (int, error) { 69 return 0, nil 70 } 71 // act 72 result := d.Command("WriteGPIO")(pinVal) 73 // assert 74 gobottest.Assert(t, result.(map[string]interface{})["err"], nil) 75 } 76 77 func TestPCA9501CommandsReadGPIO(t *testing.T) { 78 // arrange 79 d, a := initPCA9501WithStubbedAdaptor() 80 a.i2cReadImpl = func(b []byte) (int, error) { 81 return len(b), nil 82 } 83 // act 84 result := d.Command("ReadGPIO")(pin) 85 // assert 86 gobottest.Assert(t, result.(map[string]interface{})["err"], nil) 87 } 88 89 func TestPCA9501CommandsWriteEEPROM(t *testing.T) { 90 // arrange 91 d, a := initPCA9501WithStubbedAdaptor() 92 a.i2cWriteImpl = func([]byte) (int, error) { 93 return 0, nil 94 } 95 // act 96 result := d.Command("WriteEEPROM")(addressVal) 97 // assert 98 gobottest.Assert(t, result.(map[string]interface{})["err"], nil) 99 } 100 101 func TestPCA9501CommandsReadEEPROM(t *testing.T) { 102 // arrange 103 d, a := initPCA9501WithStubbedAdaptor() 104 a.i2cWriteImpl = func([]byte) (int, error) { 105 return 0, nil 106 } 107 a.i2cReadImpl = func(b []byte) (int, error) { 108 return len(b), nil 109 } 110 // act 111 result := d.Command("ReadEEPROM")(address) 112 // assert 113 gobottest.Assert(t, result.(map[string]interface{})["err"], nil) 114 } 115 116 func TestPCA9501WriteGPIO(t *testing.T) { 117 var tests = map[string]struct { 118 setVal uint8 119 ioDirAllInput uint8 120 ioStateAllInput uint8 121 pin uint8 122 wantPin uint8 123 wantState uint8 124 }{ 125 "clear_bit": { 126 setVal: 0, 127 ioDirAllInput: 0xF1, 128 ioStateAllInput: 0xF2, 129 pin: 6, 130 wantPin: 0xB1, 131 wantState: 0xB2, 132 }, 133 "set_bit": { 134 setVal: 2, 135 ioDirAllInput: 0x1F, 136 ioStateAllInput: 0x20, 137 pin: 3, 138 wantPin: 0x17, 139 wantState: 0x28, 140 }, 141 } 142 for name, tc := range tests { 143 t.Run(name, func(t *testing.T) { 144 // arrange 145 d, a := initPCA9501WithStubbedAdaptor() 146 // prepare all reads 147 numCallsRead := 0 148 a.i2cReadImpl = func(b []byte) (int, error) { 149 numCallsRead++ 150 if numCallsRead == 1 { 151 // first call read current io direction of all pins 152 b[0] = tc.ioDirAllInput 153 } 154 if numCallsRead == 2 { 155 // second call read current state of all pins 156 b[0] = tc.ioStateAllInput 157 } 158 return len(b), nil 159 } 160 // act 161 err := d.WriteGPIO(tc.pin, tc.setVal) 162 // assert 163 gobottest.Assert(t, err, nil) 164 gobottest.Assert(t, numCallsRead, 2) 165 gobottest.Assert(t, len(a.written), 2) 166 gobottest.Assert(t, a.written[0], tc.wantPin) 167 gobottest.Assert(t, a.written[1], tc.wantState) 168 }) 169 } 170 } 171 172 func TestPCA9501WriteGPIOErrorAtWriteDirection(t *testing.T) { 173 // arrange 174 d, a := initPCA9501WithStubbedAdaptor() 175 wantErr := errors.New("write error") 176 // prepare all reads 177 numCallsRead := 0 178 a.i2cReadImpl = func(b []byte) (int, error) { 179 numCallsRead++ 180 return len(b), nil 181 } 182 // prepare all writes 183 numCallsWrite := 0 184 a.i2cWriteImpl = func([]byte) (int, error) { 185 numCallsWrite++ 186 if numCallsWrite == 1 { 187 // first call writes the CTRL register for port direction 188 return 0, wantErr 189 } 190 return 0, nil 191 } 192 // act 193 err := d.WriteGPIO(7, 0) 194 // assert 195 gobottest.Assert(t, err, wantErr) 196 gobottest.Assert(t, numCallsRead < 2, true) 197 gobottest.Assert(t, numCallsWrite, 1) 198 } 199 200 func TestPCA9501WriteGPIOErrorAtWriteValue(t *testing.T) { 201 // arrange 202 d, a := initPCA9501WithStubbedAdaptor() 203 wantErr := errors.New("write error") 204 // prepare all reads 205 a.i2cReadImpl = func(b []byte) (int, error) { 206 return len(b), nil 207 } 208 // prepare all writes 209 numCallsWrite := 0 210 a.i2cWriteImpl = func([]byte) (int, error) { 211 numCallsWrite++ 212 if numCallsWrite == 2 { 213 // second call writes the value to IO port 214 return 0, wantErr 215 } 216 return 0, nil 217 } 218 // act 219 err := d.WriteGPIO(7, 0) 220 // assert 221 gobottest.Assert(t, err, wantErr) 222 gobottest.Assert(t, numCallsWrite, 2) 223 } 224 225 func TestPCA9501ReadGPIO(t *testing.T) { 226 var tests = map[string]struct { 227 ctrlState uint8 228 want uint8 229 }{ 230 "pin_is_set": {ctrlState: 0x80, want: 1}, 231 "pin_is_not_set": {ctrlState: 0x7F, want: 0}, 232 } 233 for name, tc := range tests { 234 t.Run(name, func(t *testing.T) { 235 // arrange 236 const ( 237 pin = uint8(7) 238 wantCtrlState = uint8(0x80) 239 ) 240 d, a := initPCA9501WithStubbedAdaptor() 241 // prepare all reads 242 numCallsRead := 0 243 a.i2cReadImpl = func(b []byte) (int, error) { 244 numCallsRead++ 245 if numCallsRead == 1 { 246 // current state of io 247 b[0] = 0x00 248 } 249 if numCallsRead == 2 { 250 b[0] = tc.ctrlState 251 } 252 return len(b), nil 253 } 254 // act 255 got, err := d.ReadGPIO(pin) 256 // assert 257 gobottest.Assert(t, err, nil) 258 gobottest.Assert(t, got, tc.want) 259 gobottest.Assert(t, numCallsRead, 2) 260 gobottest.Assert(t, len(a.written), 1) 261 gobottest.Assert(t, a.written[0], wantCtrlState) 262 }) 263 } 264 } 265 266 func TestPCA9501ReadGPIOErrorAtReadDirection(t *testing.T) { 267 // arrange 268 d, a := initPCA9501WithStubbedAdaptor() 269 wantErr := errors.New("read error") 270 // prepare all reads 271 numCallsRead := 0 272 a.i2cReadImpl = func(b []byte) (int, error) { 273 numCallsRead++ 274 if numCallsRead == 1 { 275 // first read gets the CTRL register for pin direction 276 return 0, wantErr 277 } 278 return len(b), nil 279 } 280 // prepare all writes 281 numCallsWrite := 0 282 a.i2cWriteImpl = func([]byte) (int, error) { 283 numCallsWrite++ 284 return 0, nil 285 } 286 // act 287 _, err := d.ReadGPIO(1) 288 // assert 289 gobottest.Assert(t, err, wantErr) 290 gobottest.Assert(t, numCallsRead, 1) 291 gobottest.Assert(t, numCallsWrite, 0) 292 } 293 294 func TestPCA9501ReadGPIOErrorAtReadValue(t *testing.T) { 295 // arrange 296 d, a := initPCA9501WithStubbedAdaptor() 297 wantErr := errors.New("read error") 298 // prepare all reads 299 numCallsRead := 0 300 a.i2cReadImpl = func(b []byte) (int, error) { 301 numCallsRead++ 302 if numCallsRead == 2 { 303 // second read gets the value from IO port 304 return 0, wantErr 305 } 306 return len(b), nil 307 } 308 // prepare all writes 309 numCallsWrite := 0 310 a.i2cWriteImpl = func([]byte) (int, error) { 311 numCallsWrite++ 312 return 0, nil 313 } 314 // act 315 _, err := d.ReadGPIO(2) 316 // assert 317 gobottest.Assert(t, err, wantErr) 318 gobottest.Assert(t, numCallsWrite, 1) 319 } 320 321 func TestPCA9501WriteEEPROM(t *testing.T) { 322 // arrange 323 const ( 324 addressEEPROM = uint8(0x52) 325 want = uint8(0x25) 326 ) 327 d, a := initPCA9501WithStubbedAdaptor() 328 // prepare all writes 329 numCallsWrite := 0 330 a.i2cWriteImpl = func([]byte) (int, error) { 331 numCallsWrite++ 332 return 0, nil 333 } 334 // act 335 err := d.WriteEEPROM(addressEEPROM, want) 336 // assert 337 gobottest.Assert(t, err, nil) 338 gobottest.Assert(t, numCallsWrite, 1) 339 gobottest.Assert(t, a.written[0], addressEEPROM) 340 gobottest.Assert(t, a.written[1], want) 341 } 342 343 func TestPCA9501ReadEEPROM(t *testing.T) { 344 // arrange 345 const ( 346 addressEEPROM = uint8(51) 347 want = uint8(0x44) 348 ) 349 d, a := initPCA9501WithStubbedAdaptor() 350 // prepare all writes 351 numCallsWrite := 0 352 a.i2cWriteImpl = func(b []byte) (int, error) { 353 numCallsWrite++ 354 return 0, nil 355 } 356 // prepare all reads 357 numCallsRead := 0 358 a.i2cReadImpl = func(b []byte) (int, error) { 359 numCallsRead++ 360 b[0] = want 361 return len(b), nil 362 } 363 // act 364 val, err := d.ReadEEPROM(addressEEPROM) 365 // assert 366 gobottest.Assert(t, err, nil) 367 gobottest.Assert(t, val, want) 368 gobottest.Assert(t, numCallsWrite, 1) 369 gobottest.Assert(t, a.written[0], addressEEPROM) 370 gobottest.Assert(t, numCallsRead, 1) 371 } 372 373 func TestPCA9501ReadEEPROMErrorWhileWriteAddress(t *testing.T) { 374 // arrange 375 d, a := initPCA9501WithStubbedAdaptor() 376 wantErr := errors.New("error while write") 377 // prepare all writes 378 a.i2cWriteImpl = func([]byte) (int, error) { 379 return 0, wantErr 380 } 381 // prepare all reads 382 numCallsRead := 0 383 a.i2cReadImpl = func(b []byte) (int, error) { 384 numCallsRead++ 385 return len(b), nil 386 } 387 // act 388 _, err := d.ReadEEPROM(15) 389 // assert 390 gobottest.Assert(t, err, wantErr) 391 gobottest.Assert(t, numCallsRead, 0) 392 } 393 394 func TestPCA9501ReadEEPROMErrorWhileReadValue(t *testing.T) { 395 // arrange 396 d, a := initPCA9501WithStubbedAdaptor() 397 wantErr := errors.New("error while read") 398 // prepare all writes 399 numCallsWrite := 0 400 a.i2cWriteImpl = func([]byte) (int, error) { 401 numCallsWrite++ 402 return 0, nil 403 } 404 // prepare all reads 405 a.i2cReadImpl = func(b []byte) (int, error) { 406 return len(b), wantErr 407 } 408 // act 409 _, err := d.ReadEEPROM(15) 410 // assert 411 gobottest.Assert(t, numCallsWrite, 1) 412 gobottest.Assert(t, err, wantErr) 413 } 414 415 func TestPCA9501_initialize(t *testing.T) { 416 // arrange 417 const want = 0x7f 418 d, a := initPCA9501WithStubbedAdaptor() 419 // act 420 err := d.initialize() 421 // assert 422 gobottest.Assert(t, err, nil) 423 gobottest.Assert(t, a.address, want) 424 }