gobot.io/x/gobot@v1.16.0/drivers/i2c/ccs811_driver_test.go (about)

     1  package i2c
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  
     7  	"gobot.io/x/gobot"
     8  	"gobot.io/x/gobot/gobottest"
     9  )
    10  
    11  // The CCS811 Meets the Driver Definition
    12  var _ gobot.Driver = (*CCS811Driver)(nil)
    13  
    14  // --------- HELPERS
    15  func initTestCCS811Driver() (driver *CCS811Driver) {
    16  	driver, _ = initTestCCS811DriverWithStubbedAdaptor()
    17  	return
    18  }
    19  
    20  func initTestCCS811DriverWithStubbedAdaptor() (*CCS811Driver, *i2cTestAdaptor) {
    21  	adaptor := newI2cTestAdaptor()
    22  	return NewCCS811Driver(adaptor), adaptor
    23  }
    24  
    25  // --------- BASE TESTS
    26  func TestNewCCS811Driver(t *testing.T) {
    27  	// Does it return a pointer to an instance of CCS811Driver?
    28  	var c interface{} = NewCCS811Driver(newI2cTestAdaptor())
    29  	_, ok := c.(*CCS811Driver)
    30  	if !ok {
    31  		t.Errorf("NewCCS811Driver() should have returned a *CCS811Driver")
    32  	}
    33  }
    34  
    35  func TestCCS811DriverSetName(t *testing.T) {
    36  	// Does it change the name of the driver
    37  	d := initTestCCS811Driver()
    38  	d.SetName("TESTME")
    39  	gobottest.Assert(t, d.Name(), "TESTME")
    40  }
    41  
    42  func TestCCS811Connection(t *testing.T) {
    43  	// Does it create an instance of gobot.Connection
    44  	ccs811 := initTestCCS811Driver()
    45  	gobottest.Refute(t, ccs811.Connection(), nil)
    46  }
    47  
    48  // // --------- CONFIG OVERIDE TESTS
    49  
    50  func TestCCS811DriverWithBus(t *testing.T) {
    51  	// Can it update the bus
    52  	d := NewCCS811Driver(newI2cTestAdaptor(), WithBus(2))
    53  	gobottest.Assert(t, d.GetBusOrDefault(1), 2)
    54  }
    55  
    56  func TestCCS811DriverWithAddress(t *testing.T) {
    57  	// Can it update the address
    58  	d := NewCCS811Driver(newI2cTestAdaptor(), WithAddress(0xFF))
    59  	gobottest.Assert(t, d.GetAddressOrDefault(0x5a), 0xFF)
    60  }
    61  
    62  func TestCCS811DriverWithCCS811MeasMode(t *testing.T) {
    63  	// Can it update the measurement mode
    64  	d := NewCCS811Driver(newI2cTestAdaptor(), WithCCS811MeasMode(CCS811DriveMode10Sec))
    65  	gobottest.Assert(t, d.measMode.driveMode, CCS811DriveMode(CCS811DriveMode10Sec))
    66  }
    67  
    68  func TestCCS811DriverWithCCS811NTCResistance(t *testing.T) {
    69  	// Can it update the ntc resitor value used for temp calcuations
    70  	d := NewCCS811Driver(newI2cTestAdaptor(), WithCCS811NTCResistance(0xFF))
    71  	gobottest.Assert(t, d.ntcResistanceValue, uint32(0xFF))
    72  }
    73  
    74  // // --------- DRIVER SPECIFIC TESTS
    75  
    76  func TestCCS811DriverGetGasData(t *testing.T) {
    77  
    78  	cases := []struct {
    79  		readReturn func([]byte) (int, error)
    80  		eco2       uint16
    81  		tvoc       uint16
    82  		err        error
    83  	}{
    84  		// Can it compute the gas data with ideal values taken from the bus
    85  		{
    86  			readReturn: func(b []byte) (int, error) {
    87  				copy(b, []byte{1, 156, 0, 86})
    88  				return 4, nil
    89  			},
    90  			eco2: 412,
    91  			tvoc: 86,
    92  			err:  nil,
    93  		},
    94  		// Can it compute the gas data with the max values possible taken from the bus
    95  		{
    96  			readReturn: func(b []byte) (int, error) {
    97  				copy(b, []byte{255, 255, 255, 255})
    98  				return 4, nil
    99  			},
   100  			eco2: 65535,
   101  			tvoc: 65535,
   102  			err:  nil,
   103  		},
   104  		// Does it return an error when the i2c operation fails
   105  		{
   106  			readReturn: func(b []byte) (int, error) {
   107  				copy(b, []byte{255, 255, 255, 255})
   108  				return 4, errors.New("Error")
   109  			},
   110  			eco2: 0,
   111  			tvoc: 0,
   112  			err:  errors.New("Error"),
   113  		},
   114  	}
   115  
   116  	d, adaptor := initTestCCS811DriverWithStubbedAdaptor()
   117  	// Create stub function as it is needed by read submethod in driver code
   118  	adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, nil }
   119  
   120  	d.Start()
   121  	for _, c := range cases {
   122  		adaptor.i2cReadImpl = c.readReturn
   123  		eco2, tvoc, err := d.GetGasData()
   124  		gobottest.Assert(t, eco2, c.eco2)
   125  		gobottest.Assert(t, tvoc, c.tvoc)
   126  		gobottest.Assert(t, err, c.err)
   127  	}
   128  
   129  }
   130  
   131  func TestCCS811DriverGetTemperature(t *testing.T) {
   132  
   133  	cases := []struct {
   134  		readReturn func([]byte) (int, error)
   135  		temp       float32
   136  		err        error
   137  	}{
   138  		// Can it compute the temperature data with ideal values taken from the bus
   139  		{
   140  			readReturn: func(b []byte) (int, error) {
   141  				copy(b, []byte{10, 197, 0, 248})
   142  				return 4, nil
   143  			},
   144  			temp: 27.811005,
   145  			err:  nil,
   146  		},
   147  		// Can it compute the temperature data without bus values overflowing
   148  		{
   149  			readReturn: func(b []byte) (int, error) {
   150  				copy(b, []byte{129, 197, 10, 248})
   151  				return 4, nil
   152  			},
   153  			temp: 29.48822,
   154  			err:  nil,
   155  		},
   156  		// Can it compute a negative temperature
   157  		{
   158  			readReturn: func(b []byte) (int, error) {
   159  				copy(b, []byte{255, 255, 255, 255})
   160  				return 4, nil
   161  			},
   162  			temp: -25.334152,
   163  			err:  nil,
   164  		},
   165  		// Does it return an error if the i2c bus errors
   166  		{
   167  			readReturn: func(b []byte) (int, error) {
   168  				copy(b, []byte{129, 197, 0, 248})
   169  				return 4, errors.New("Error")
   170  			},
   171  			temp: 0,
   172  			err:  errors.New("Error"),
   173  		},
   174  	}
   175  
   176  	d, adaptor := initTestCCS811DriverWithStubbedAdaptor()
   177  	// Create stub function as it is needed by read submethod in driver code
   178  	adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, nil }
   179  
   180  	d.Start()
   181  	for _, c := range cases {
   182  		adaptor.i2cReadImpl = c.readReturn
   183  		temp, err := d.GetTemperature()
   184  		gobottest.Assert(t, temp, c.temp)
   185  		gobottest.Assert(t, err, c.err)
   186  	}
   187  
   188  }
   189  
   190  func TestCCS811DriverHasData(t *testing.T) {
   191  
   192  	cases := []struct {
   193  		readReturn func([]byte) (int, error)
   194  		result     bool
   195  		err        error
   196  	}{
   197  		// Does it return true for HasError = 0 and DataRdy = 1
   198  		{
   199  			readReturn: func(b []byte) (int, error) {
   200  				copy(b, []byte{0x08})
   201  				return 1, nil
   202  			},
   203  			result: true,
   204  			err:    nil,
   205  		},
   206  		// Does it return false for HasError = 1 and DataRdy = 1
   207  		{
   208  			readReturn: func(b []byte) (int, error) {
   209  				copy(b, []byte{0x09})
   210  				return 1, nil
   211  			},
   212  			result: false,
   213  			err:    nil,
   214  		},
   215  		// Does it return false for HasError = 1 and DataRdy = 0
   216  		{
   217  			readReturn: func(b []byte) (int, error) {
   218  				copy(b, []byte{0x01})
   219  				return 1, nil
   220  			},
   221  			result: false,
   222  			err:    nil,
   223  		},
   224  		// Does it return false for HasError = 0 and DataRdy = 0
   225  		{
   226  			readReturn: func(b []byte) (int, error) {
   227  				copy(b, []byte{0x00})
   228  				return 1, nil
   229  			},
   230  			result: false,
   231  			err:    nil,
   232  		},
   233  		// Does it return an error when the i2c read operation fails
   234  		{
   235  			readReturn: func(b []byte) (int, error) {
   236  				copy(b, []byte{0x00})
   237  				return 1, errors.New("Error")
   238  			},
   239  			result: false,
   240  			err:    errors.New("Error"),
   241  		},
   242  	}
   243  
   244  	d, adaptor := initTestCCS811DriverWithStubbedAdaptor()
   245  	// Create stub function as it is needed by read submethod in driver code
   246  	adaptor.i2cWriteImpl = func([]byte) (int, error) { return 0, nil }
   247  
   248  	d.Start()
   249  	for _, c := range cases {
   250  		adaptor.i2cReadImpl = c.readReturn
   251  		result, err := d.HasData()
   252  		gobottest.Assert(t, result, c.result)
   253  		gobottest.Assert(t, err, c.err)
   254  	}
   255  
   256  }