gobot.io/x/gobot/v2@v2.1.0/drivers/i2c/pcf8583_driver_test.go (about)

     1  package i2c
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  	"time"
     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 = (*PCF8583Driver)(nil)
    15  
    16  func initTestPCF8583WithStubbedAdaptor() (*PCF8583Driver, *i2cTestAdaptor) {
    17  	a := newI2cTestAdaptor()
    18  	d := NewPCF8583Driver(a)
    19  	d.Start()
    20  	return d, a
    21  }
    22  
    23  func TestNewPCF8583Driver(t *testing.T) {
    24  	var di interface{} = NewPCF8583Driver(newI2cTestAdaptor())
    25  	d, ok := di.(*PCF8583Driver)
    26  	if !ok {
    27  		t.Errorf("NewPCF8583Driver() should have returned a *PCF8583Driver")
    28  	}
    29  	gobottest.Refute(t, d.Driver, nil)
    30  	gobottest.Assert(t, strings.HasPrefix(d.name, "PCF8583"), true)
    31  	gobottest.Assert(t, d.defaultAddress, 0x50)
    32  	gobottest.Assert(t, d.mode, PCF8583Control(0x00))
    33  	gobottest.Assert(t, d.yearOffset, 0)
    34  	gobottest.Assert(t, d.ramOffset, uint8(0x10))
    35  }
    36  
    37  func TestPCF8583Options(t *testing.T) {
    38  	// This is a general test, that options are applied in constructor by using the common WithBus() option and
    39  	// least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)".
    40  	d := NewPCF8583Driver(newI2cTestAdaptor(), WithBus(2), WithPCF8583Mode(PCF8583CtrlModeClock50))
    41  	gobottest.Assert(t, d.GetBusOrDefault(1), 2)
    42  	gobottest.Assert(t, d.mode, PCF8583CtrlModeClock50)
    43  }
    44  
    45  func TestPCF8583CommandsWriteTime(t *testing.T) {
    46  	// arrange
    47  	d, a := initTestPCF8583WithStubbedAdaptor()
    48  	readCtrlState := uint8(0x10) // clock 50Hz
    49  	// arrange writes
    50  	a.i2cWriteImpl = func(b []byte) (int, error) {
    51  		return len(b), nil
    52  	}
    53  	// arrange reads
    54  	numCallsRead := 0
    55  	a.i2cReadImpl = func(b []byte) (int, error) {
    56  		numCallsRead++
    57  		b[len(b)-1] = readCtrlState
    58  		return len(b), nil
    59  	}
    60  	// act
    61  	result := d.Command("WriteTime")(map[string]interface{}{"val": time.Now()})
    62  	// assert
    63  	gobottest.Assert(t, result.(map[string]interface{})["err"], nil)
    64  }
    65  
    66  func TestPCF8583CommandsReadTime(t *testing.T) {
    67  	// arrange
    68  	d, a := initTestPCF8583WithStubbedAdaptor()
    69  	d.yearOffset = 2019
    70  	milliSec := 550 * time.Millisecond // 0.55 sec = 550 ms
    71  	want := time.Date(2021, time.December, 24, 18, 00, 00, int(milliSec), time.UTC)
    72  	reg0Val := uint8(0x00) // clock mode 32.768 kHz
    73  	reg1Val := uint8(0x55) // BCD: 1/10 and 1/100 sec (55)
    74  	reg2Val := uint8(0x00) // BCD: 10 and 1 sec (00)
    75  	reg3Val := uint8(0x00) // BCD: 10 and 1 min (00)
    76  	reg4Val := uint8(0x18) // BCD: 10 and 1 hour (18)
    77  	reg5Val := uint8(0xA4) // year (2) and BCD: date (24)
    78  	reg6Val := uint8(0xB2) // weekday 5, bit 5 and bit 7 (0xA0) and BCD: month (0x12)
    79  	returnRead := [2][]uint8{
    80  		{reg0Val},
    81  		{reg1Val, reg2Val, reg3Val, reg4Val, reg5Val, reg6Val},
    82  	}
    83  	// arrange reads
    84  	// arrange reads
    85  	numCallsRead := 0
    86  	a.i2cReadImpl = func(b []byte) (int, error) {
    87  		numCallsRead++
    88  		rr := returnRead[numCallsRead-1]
    89  		for i := 0; i < len(b); i++ {
    90  			b[i] = rr[i]
    91  		}
    92  		return len(b), nil
    93  	}
    94  	// act
    95  	result := d.Command("ReadTime")(map[string]interface{}{})
    96  	// assert
    97  	gobottest.Assert(t, result.(map[string]interface{})["err"], nil)
    98  	gobottest.Assert(t, result.(map[string]interface{})["val"], want)
    99  }
   100  
   101  func TestPCF8583CommandsWriteCounter(t *testing.T) {
   102  	// arrange
   103  	d, a := initTestPCF8583WithStubbedAdaptor()
   104  	readCtrlState := uint8(0x20) // counter
   105  	// arrange writes
   106  	a.i2cWriteImpl = func(b []byte) (int, error) {
   107  		return len(b), nil
   108  	}
   109  	// arrange reads
   110  	numCallsRead := 0
   111  	a.i2cReadImpl = func(b []byte) (int, error) {
   112  		numCallsRead++
   113  		b[len(b)-1] = readCtrlState
   114  		return len(b), nil
   115  	}
   116  	// act
   117  	result := d.Command("WriteCounter")(map[string]interface{}{"val": int32(123456)})
   118  	// assert
   119  	gobottest.Assert(t, result.(map[string]interface{})["err"], nil)
   120  }
   121  
   122  func TestPCF8583CommandsReadCounter(t *testing.T) {
   123  	// arrange
   124  	d, a := initTestPCF8583WithStubbedAdaptor()
   125  	want := int32(123456)
   126  	reg0Val := uint8(0x20) // counter mode
   127  	reg1Val := uint8(0x56) // BCD: 56
   128  	reg2Val := uint8(0x34) // BCD: 34
   129  	reg3Val := uint8(0x12) // BCD: 12
   130  	returnRead := [2][]uint8{
   131  		{reg0Val},
   132  		{reg1Val, reg2Val, reg3Val},
   133  	}
   134  	// arrange reads
   135  	// arrange reads
   136  	numCallsRead := 0
   137  	a.i2cReadImpl = func(b []byte) (int, error) {
   138  		numCallsRead++
   139  		rr := returnRead[numCallsRead-1]
   140  		for i := 0; i < len(b); i++ {
   141  			b[i] = rr[i]
   142  		}
   143  		return len(b), nil
   144  	}
   145  	// act
   146  	result := d.Command("ReadCounter")(map[string]interface{}{})
   147  	// assert
   148  	gobottest.Assert(t, result.(map[string]interface{})["err"], nil)
   149  	gobottest.Assert(t, result.(map[string]interface{})["val"], want)
   150  }
   151  
   152  func TestPCF8583CommandsWriteRAM(t *testing.T) {
   153  	// arrange
   154  	d, _ := initTestPCF8583WithStubbedAdaptor()
   155  	var addressValue = map[string]interface{}{
   156  		"address": uint8(0x12),
   157  		"val":     uint8(0x45),
   158  	}
   159  	// act
   160  	result := d.Command("WriteRAM")(addressValue)
   161  	// assert
   162  	gobottest.Assert(t, result.(map[string]interface{})["err"], nil)
   163  }
   164  
   165  func TestPCF8583CommandsReadRAM(t *testing.T) {
   166  	// arrange
   167  	d, _ := initTestPCF8583WithStubbedAdaptor()
   168  	var address = map[string]interface{}{
   169  		"address": uint8(0x34),
   170  	}
   171  	// act
   172  	result := d.Command("ReadRAM")(address)
   173  	// assert
   174  	gobottest.Assert(t, result.(map[string]interface{})["err"], nil)
   175  	gobottest.Assert(t, result.(map[string]interface{})["val"], uint8(0))
   176  }
   177  
   178  func TestPCF8583WriteTime(t *testing.T) {
   179  	// sequence to write the time:
   180  	// * read control register for get current state and ensure an clock mode is set
   181  	// * write the control register (stop counting)
   182  	// * create the values for date registers (default is 24h mode)
   183  	// * write the clock and calendar registers with auto increment
   184  	// * write the control register (start counting)
   185  	// arrange
   186  	d, a := initTestPCF8583WithStubbedAdaptor()
   187  	a.written = []byte{}               // reset writes of Start() and former test
   188  	readCtrlState := uint8(0x07)       // 32.768kHz clock mode
   189  	milliSec := 210 * time.Millisecond // 0.21 sec = 210 ms
   190  	initDate := time.Date(2022, time.December, 16, 15, 14, 13, int(milliSec), time.UTC)
   191  	wantCtrlStop := uint8(0x87)  // stop counting bit is set
   192  	wantReg1Val := uint8(0x21)   // BCD: 1/10 and 1/100 sec (21)
   193  	wantReg2Val := uint8(0x13)   // BCD: 10 and 1 sec (13)
   194  	wantReg3Val := uint8(0x14)   // BCD: 10 and 1 min (14)
   195  	wantReg4Val := uint8(0x15)   // BCD: 10 and 1 hour (15)
   196  	wantReg5Val := uint8(0x16)   // year (0) and BCD: date (16)
   197  	wantReg6Val := uint8(0xB2)   // weekday 5, bit 5 and bit 7 (0xA0) and BCD: month (0x12)
   198  	wantCrtlStart := uint8(0x07) // stop counting bit is reset
   199  	// arrange writes
   200  	a.i2cWriteImpl = func(b []byte) (int, error) {
   201  		return len(b), nil
   202  	}
   203  	// arrange reads
   204  	numCallsRead := 0
   205  	a.i2cReadImpl = func(b []byte) (int, error) {
   206  		numCallsRead++
   207  		b[len(b)-1] = readCtrlState
   208  		return len(b), nil
   209  	}
   210  	// act
   211  	err := d.WriteTime(initDate)
   212  	// assert
   213  	gobottest.Assert(t, err, nil)
   214  	gobottest.Assert(t, d.yearOffset, initDate.Year())
   215  	gobottest.Assert(t, numCallsRead, 1)
   216  	gobottest.Assert(t, len(a.written), 11)
   217  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   218  	gobottest.Assert(t, a.written[1], uint8(pcf8583Reg_CTRL))
   219  	gobottest.Assert(t, a.written[2], wantCtrlStop)
   220  	gobottest.Assert(t, a.written[3], wantReg1Val)
   221  	gobottest.Assert(t, a.written[4], wantReg2Val)
   222  	gobottest.Assert(t, a.written[5], wantReg3Val)
   223  	gobottest.Assert(t, a.written[6], wantReg4Val)
   224  	gobottest.Assert(t, a.written[7], wantReg5Val)
   225  	gobottest.Assert(t, a.written[8], wantReg6Val)
   226  	gobottest.Assert(t, a.written[9], uint8(pcf8583Reg_CTRL))
   227  	gobottest.Assert(t, a.written[10], wantCrtlStart)
   228  }
   229  
   230  func TestPCF8583WriteTimeNoTimeModeFails(t *testing.T) {
   231  	// arrange
   232  	d, a := initTestPCF8583WithStubbedAdaptor()
   233  	a.written = []byte{}         // reset writes of Start() and former test
   234  	readCtrlState := uint8(0x30) // test mode
   235  	// arrange writes
   236  	a.i2cWriteImpl = func(b []byte) (int, error) {
   237  		return len(b), nil
   238  	}
   239  	// arrange reads
   240  	numCallsRead := 0
   241  	a.i2cReadImpl = func(b []byte) (int, error) {
   242  		numCallsRead++
   243  		b[len(b)-1] = readCtrlState
   244  		return len(b), nil
   245  	}
   246  	// act
   247  	err := d.WriteTime(time.Now())
   248  	// assert
   249  	gobottest.Refute(t, err, nil)
   250  	gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x30"), true)
   251  	gobottest.Assert(t, len(a.written), 1)
   252  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   253  	gobottest.Assert(t, numCallsRead, 1)
   254  }
   255  
   256  func TestPCF8583ReadTime(t *testing.T) {
   257  	// sequence to read the time:
   258  	// * read the control register to determine mask flag and ensure an clock mode is set
   259  	// * read the clock and calendar registers with auto increment
   260  	// * create the value out of registers content
   261  	// arrange
   262  	d, a := initTestPCF8583WithStubbedAdaptor()
   263  	a.written = []byte{} // reset writes of Start() and former test
   264  	d.yearOffset = 2020
   265  	milliSec := 210 * time.Millisecond // 0.21 sec = 210 ms
   266  	want := time.Date(2022, time.December, 16, 15, 14, 13, int(milliSec), time.UTC)
   267  	reg0Val := uint8(0x10) // clock mode 50Hz
   268  	reg1Val := uint8(0x21) // BCD: 1/10 and 1/100 sec (21)
   269  	reg2Val := uint8(0x13) // BCD: 10 and 1 sec (13)
   270  	reg3Val := uint8(0x14) // BCD: 10 and 1 min (14)
   271  	reg4Val := uint8(0x15) // BCD: 10 and 1 hour (15)
   272  	reg5Val := uint8(0x96) // year (2) and BCD: date (16)
   273  	reg6Val := uint8(0xB2) // weekday 5, bit 5 and bit 7 (0xA0) and BCD: month (0x12)
   274  	returnRead := [2][]uint8{
   275  		{reg0Val},
   276  		{reg1Val, reg2Val, reg3Val, reg4Val, reg5Val, reg6Val},
   277  	}
   278  	// arrange writes
   279  	a.i2cWriteImpl = func(b []byte) (int, error) {
   280  		return len(b), nil
   281  	}
   282  	// arrange reads
   283  	numCallsRead := 0
   284  	a.i2cReadImpl = func(b []byte) (int, error) {
   285  		numCallsRead++
   286  		rr := returnRead[numCallsRead-1]
   287  		for i := 0; i < len(b); i++ {
   288  			b[i] = rr[i]
   289  		}
   290  		return len(b), nil
   291  	}
   292  	// act
   293  	got, err := d.ReadTime()
   294  	// assert
   295  	gobottest.Assert(t, err, nil)
   296  	gobottest.Assert(t, len(a.written), 1)
   297  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   298  	gobottest.Assert(t, numCallsRead, 2)
   299  	gobottest.Assert(t, got, want)
   300  }
   301  
   302  func TestPCF8583ReadTimeNoTimeModeFails(t *testing.T) {
   303  	// arrange
   304  	d, a := initTestPCF8583WithStubbedAdaptor()
   305  	a.written = []byte{}         // reset writes of Start() and former test
   306  	readCtrlState := uint8(0x20) // counter mode
   307  	// arrange writes
   308  	a.i2cWriteImpl = func(b []byte) (int, error) {
   309  		return len(b), nil
   310  	}
   311  	// arrange reads
   312  	numCallsRead := 0
   313  	a.i2cReadImpl = func(b []byte) (int, error) {
   314  		numCallsRead++
   315  		b[len(b)-1] = readCtrlState
   316  		return len(b), nil
   317  	}
   318  	// act
   319  	got, err := d.ReadTime()
   320  	// assert
   321  	gobottest.Refute(t, err, nil)
   322  	gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x20"), true)
   323  	gobottest.Assert(t, got, time.Time{})
   324  	gobottest.Assert(t, len(a.written), 1)
   325  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   326  	gobottest.Assert(t, numCallsRead, 1)
   327  }
   328  
   329  func TestPCF8583WriteCounter(t *testing.T) {
   330  	// sequence to write the counter:
   331  	// * read control register for get current state and ensure the event counter mode is set
   332  	// * write the control register (stop counting)
   333  	// * create the values for counter registers
   334  	// * write the counter registers
   335  	// * write the control register (start counting)
   336  	// arrange
   337  	d, a := initTestPCF8583WithStubbedAdaptor()
   338  	a.written = []byte{}         // reset writes of Start() and former test
   339  	readCtrlState := uint8(0x27) // counter mode
   340  	initCount := int32(654321)   // 6 digits used of 10 possible with int32
   341  	wantCtrlStop := uint8(0xA7)  // stop counting bit is set
   342  	wantReg1Val := uint8(0x21)   // BCD: 21
   343  	wantReg2Val := uint8(0x43)   // BCD: 43
   344  	wantReg3Val := uint8(0x65)   // BCD: 65
   345  	wantCtrlStart := uint8(0x27) // counter mode
   346  	// arrange writes
   347  	a.i2cWriteImpl = func(b []byte) (int, error) {
   348  		return len(b), nil
   349  	}
   350  	// arrange reads
   351  	numCallsRead := 0
   352  	a.i2cReadImpl = func(b []byte) (int, error) {
   353  		numCallsRead++
   354  		b[len(b)-1] = readCtrlState
   355  		return len(b), nil
   356  	}
   357  	// act
   358  	err := d.WriteCounter(initCount)
   359  	// assert
   360  	gobottest.Assert(t, err, nil)
   361  	gobottest.Assert(t, numCallsRead, 1)
   362  	gobottest.Assert(t, len(a.written), 8)
   363  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   364  	gobottest.Assert(t, a.written[1], uint8(pcf8583Reg_CTRL))
   365  	gobottest.Assert(t, a.written[2], wantCtrlStop)
   366  	gobottest.Assert(t, a.written[3], wantReg1Val)
   367  	gobottest.Assert(t, a.written[4], wantReg2Val)
   368  	gobottest.Assert(t, a.written[5], wantReg3Val)
   369  	gobottest.Assert(t, a.written[6], uint8(pcf8583Reg_CTRL))
   370  	gobottest.Assert(t, a.written[7], wantCtrlStart)
   371  }
   372  
   373  func TestPCF8583WriteCounterNoCounterModeFails(t *testing.T) {
   374  	// arrange
   375  	d, a := initTestPCF8583WithStubbedAdaptor()
   376  	a.written = []byte{}         // reset writes of Start() and former test
   377  	readCtrlState := uint8(0x10) // 50Hz mode
   378  	// arrange writes
   379  	a.i2cWriteImpl = func(b []byte) (int, error) {
   380  		return len(b), nil
   381  	}
   382  	// arrange reads
   383  	numCallsRead := 0
   384  	a.i2cReadImpl = func(b []byte) (int, error) {
   385  		numCallsRead++
   386  		b[len(b)-1] = readCtrlState
   387  		return len(b), nil
   388  	}
   389  	// act
   390  	err := d.WriteCounter(123)
   391  	// assert
   392  	gobottest.Refute(t, err, nil)
   393  	gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x10"), true)
   394  	gobottest.Assert(t, len(a.written), 1)
   395  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   396  	gobottest.Assert(t, numCallsRead, 1)
   397  }
   398  
   399  func TestPCF8583ReadCounter(t *testing.T) {
   400  	// sequence to read the counter:
   401  	// * read the control register to ensure the event counter mode is set
   402  	// * read the counter registers
   403  	// * create the value out of registers content
   404  	// arrange
   405  	d, a := initTestPCF8583WithStubbedAdaptor()
   406  	a.written = []byte{} // reset writes of Start() and former test
   407  	want := int32(654321)
   408  	reg0Val := uint8(0x20) // counter mode
   409  	reg1Val := uint8(0x21) // BCD: 21
   410  	reg2Val := uint8(0x43) // BCD: 43
   411  	reg3Val := uint8(0x65) // BCD: 65
   412  	returnRead := [2][]uint8{
   413  		{reg0Val},
   414  		{reg1Val, reg2Val, reg3Val},
   415  	}
   416  	// arrange writes
   417  	a.i2cWriteImpl = func(b []byte) (int, error) {
   418  		return len(b), nil
   419  	}
   420  	// arrange reads
   421  	numCallsRead := 0
   422  	a.i2cReadImpl = func(b []byte) (int, error) {
   423  		numCallsRead++
   424  		rr := returnRead[numCallsRead-1]
   425  		for i := 0; i < len(b); i++ {
   426  			b[i] = rr[i]
   427  		}
   428  		return len(b), nil
   429  	}
   430  	// act
   431  	got, err := d.ReadCounter()
   432  	// assert
   433  	gobottest.Assert(t, err, nil)
   434  	gobottest.Assert(t, len(a.written), 1)
   435  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   436  	gobottest.Assert(t, numCallsRead, 2)
   437  	gobottest.Assert(t, got, want)
   438  }
   439  
   440  func TestPCF8583ReadCounterNoCounterModeFails(t *testing.T) {
   441  	// arrange
   442  	d, a := initTestPCF8583WithStubbedAdaptor()
   443  	a.written = []byte{}         // reset writes of Start() and former test
   444  	readCtrlState := uint8(0x30) // test mode
   445  	// arrange writes
   446  	a.i2cWriteImpl = func(b []byte) (int, error) {
   447  		return len(b), nil
   448  	}
   449  	// arrange reads
   450  	numCallsRead := 0
   451  	a.i2cReadImpl = func(b []byte) (int, error) {
   452  		numCallsRead++
   453  		b[len(b)-1] = readCtrlState
   454  		return len(b), nil
   455  	}
   456  	// act
   457  	got, err := d.ReadCounter()
   458  	// assert
   459  	gobottest.Refute(t, err, nil)
   460  	gobottest.Assert(t, strings.Contains(err.Error(), "wrong mode 0x30"), true)
   461  	gobottest.Assert(t, got, int32(0))
   462  	gobottest.Assert(t, len(a.written), 1)
   463  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   464  	gobottest.Assert(t, numCallsRead, 1)
   465  }
   466  
   467  func TestPCF8583WriteRam(t *testing.T) {
   468  	// sequence to write the RAM:
   469  	// * calculate the RAM address and check for valid range
   470  	// * write the given value to the given RAM address
   471  	// arrange
   472  	d, a := initTestPCF8583WithStubbedAdaptor()
   473  	a.written = []byte{} // reset writes of Start() and former test
   474  	wantRAMAddress := uint8(0xFF)
   475  	wantRAMValue := uint8(0xEF)
   476  	// arrange writes
   477  	a.i2cWriteImpl = func(b []byte) (int, error) {
   478  		return len(b), nil
   479  	}
   480  	// act
   481  	err := d.WriteRAM(wantRAMAddress-pcf8583RamOffset, wantRAMValue)
   482  	// assert
   483  	gobottest.Assert(t, err, nil)
   484  	gobottest.Assert(t, len(a.written), 2)
   485  	gobottest.Assert(t, a.written[0], wantRAMAddress)
   486  	gobottest.Assert(t, a.written[1], wantRAMValue)
   487  }
   488  
   489  func TestPCF8583WriteRamAddressOverflowFails(t *testing.T) {
   490  	// arrange
   491  	d, a := initTestPCF8583WithStubbedAdaptor()
   492  	a.written = []byte{} // reset writes of Start() and former test
   493  	// act
   494  	err := d.WriteRAM(uint8(0xF0), 15)
   495  	// assert
   496  	gobottest.Refute(t, err, nil)
   497  	gobottest.Assert(t, strings.Contains(err.Error(), "overflow 256"), true)
   498  	gobottest.Assert(t, len(a.written), 0)
   499  }
   500  
   501  func TestPCF8583ReadRam(t *testing.T) {
   502  	// sequence to read the RAM:
   503  	// * calculate the RAM address and check for valid range
   504  	// * read the value from the given RAM address
   505  	// arrange
   506  	d, a := initTestPCF8583WithStubbedAdaptor()
   507  	a.written = []byte{} // reset writes of Start() and former test
   508  	wantRAMAddress := uint8(pcf8583RamOffset)
   509  	want := uint8(0xAB)
   510  	// arrange writes
   511  	a.i2cWriteImpl = func(b []byte) (int, error) {
   512  		return len(b), nil
   513  	}
   514  	// arrange reads
   515  	numCallsRead := 0
   516  	a.i2cReadImpl = func(b []byte) (int, error) {
   517  		numCallsRead++
   518  		b[len(b)-1] = want
   519  		return len(b), nil
   520  	}
   521  	// act
   522  	got, err := d.ReadRAM(wantRAMAddress - pcf8583RamOffset)
   523  	// assert
   524  	gobottest.Assert(t, err, nil)
   525  	gobottest.Assert(t, got, want)
   526  	gobottest.Assert(t, len(a.written), 1)
   527  	gobottest.Assert(t, a.written[0], wantRAMAddress)
   528  	gobottest.Assert(t, numCallsRead, 1)
   529  }
   530  
   531  func TestPCF8583ReadRamAddressOverflowFails(t *testing.T) {
   532  	// arrange
   533  	d, a := initTestPCF8583WithStubbedAdaptor()
   534  	a.written = []byte{} // reset writes of Start() and former test
   535  	// arrange writes
   536  	a.i2cWriteImpl = func(b []byte) (int, error) {
   537  		return len(b), nil
   538  	}
   539  	// arrange reads
   540  	numCallsRead := 0
   541  	a.i2cReadImpl = func(b []byte) (int, error) {
   542  		numCallsRead++
   543  		return len(b), nil
   544  	}
   545  	// act
   546  	got, err := d.ReadRAM(uint8(0xF0))
   547  	// assert
   548  	gobottest.Refute(t, err, nil)
   549  	gobottest.Assert(t, strings.Contains(err.Error(), "overflow 256"), true)
   550  	gobottest.Assert(t, got, uint8(0))
   551  	gobottest.Assert(t, len(a.written), 0)
   552  	gobottest.Assert(t, numCallsRead, 0)
   553  }
   554  
   555  func TestPCF8583_initializeNoModeSwitch(t *testing.T) {
   556  	// arrange
   557  	a := newI2cTestAdaptor()
   558  	d := NewPCF8583Driver(a)
   559  	a.written = []byte{}         // reset writes of former tests
   560  	readCtrlState := uint8(0x01) // 32.768kHz clock mode
   561  	// arrange writes
   562  	a.i2cWriteImpl = func(b []byte) (int, error) {
   563  		return len(b), nil
   564  	}
   565  	// arrange reads
   566  	numCallsRead := 0
   567  	a.i2cReadImpl = func(b []byte) (int, error) {
   568  		numCallsRead++
   569  		b[len(b)-1] = readCtrlState
   570  		return len(b), nil
   571  	}
   572  	// act, assert - initialize() must be called on Start()
   573  	err := d.Start()
   574  	// assert
   575  	gobottest.Assert(t, err, nil)
   576  	gobottest.Assert(t, numCallsRead, 1)
   577  	gobottest.Assert(t, len(a.written), 1)
   578  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   579  }
   580  
   581  func TestPCF8583_initializeWithModeSwitch(t *testing.T) {
   582  	// sequence to change mode:
   583  	// * read control register for get current state
   584  	// * reset old mode bits and set new mode bit
   585  	// * write the control register
   586  	// arrange
   587  	a := newI2cTestAdaptor()
   588  	d := NewPCF8583Driver(a)
   589  	d.mode = PCF8583CtrlModeCounter
   590  	a.written = []byte{}         // reset writes of former tests
   591  	readCtrlState := uint8(0x02) // 32.768kHz clock mode
   592  	wantReg0Val := uint8(0x22)   // event counter mode
   593  	// arrange writes
   594  	a.i2cWriteImpl = func(b []byte) (int, error) {
   595  		return len(b), nil
   596  	}
   597  	// arrange reads
   598  	numCallsRead := 0
   599  	a.i2cReadImpl = func(b []byte) (int, error) {
   600  		numCallsRead++
   601  		b[len(b)-1] = readCtrlState
   602  		return len(b), nil
   603  	}
   604  	// act, assert - initialize() must be called on Start()
   605  	err := d.Start()
   606  	// assert
   607  	gobottest.Assert(t, err, nil)
   608  	gobottest.Assert(t, numCallsRead, 1)
   609  	gobottest.Assert(t, len(a.written), 3)
   610  	gobottest.Assert(t, a.written[0], uint8(pcf8583Reg_CTRL))
   611  	gobottest.Assert(t, a.written[1], uint8(pcf8583Reg_CTRL))
   612  	gobottest.Assert(t, a.written[2], uint8(wantReg0Val))
   613  }