gobot.io/x/gobot/v2@v2.1.0/drivers/gpio/grove_drivers_test.go (about)

     1  package gpio
     2  
     3  import (
     4  	"errors"
     5  	"reflect"
     6  	"sync/atomic"
     7  	"testing"
     8  	"time"
     9  
    10  	"gobot.io/x/gobot/v2"
    11  	"gobot.io/x/gobot/v2/gobottest"
    12  )
    13  
    14  type DriverAndPinner interface {
    15  	gobot.Driver
    16  	gobot.Pinner
    17  }
    18  
    19  type DriverAndEventer interface {
    20  	gobot.Driver
    21  	gobot.Eventer
    22  }
    23  
    24  func TestDriverDefaults(t *testing.T) {
    25  	testAdaptor := newGpioTestAdaptor()
    26  	pin := "456"
    27  
    28  	drivers := []DriverAndPinner{
    29  		NewGroveTouchDriver(testAdaptor, pin),
    30  		NewGroveButtonDriver(testAdaptor, pin),
    31  		NewGroveBuzzerDriver(testAdaptor, pin),
    32  		NewGroveLedDriver(testAdaptor, pin),
    33  		NewGroveRelayDriver(testAdaptor, pin),
    34  		NewGroveMagneticSwitchDriver(testAdaptor, pin),
    35  	}
    36  
    37  	for _, driver := range drivers {
    38  		gobottest.Assert(t, driver.Connection(), testAdaptor)
    39  		gobottest.Assert(t, driver.Pin(), pin)
    40  	}
    41  }
    42  
    43  func TestDigitalDriverHalt(t *testing.T) {
    44  	testAdaptor := newGpioTestAdaptor()
    45  	pin := "456"
    46  
    47  	drivers := []DriverAndEventer{
    48  		NewGroveTouchDriver(testAdaptor, pin),
    49  		NewGroveButtonDriver(testAdaptor, pin),
    50  		NewGroveMagneticSwitchDriver(testAdaptor, pin),
    51  	}
    52  
    53  	for _, driver := range drivers {
    54  
    55  		var callCount int32
    56  		testAdaptor.testAdaptorDigitalRead = func(string) (int, error) {
    57  			atomic.AddInt32(&callCount, 1)
    58  			return 42, nil
    59  		}
    60  
    61  		// Start the driver and allow for multiple digital reads
    62  		driver.Start()
    63  		time.Sleep(20 * time.Millisecond)
    64  
    65  		driver.Halt()
    66  		lastCallCount := atomic.LoadInt32(&callCount)
    67  		// If driver was not halted, digital reads would still continue
    68  		time.Sleep(20 * time.Millisecond)
    69  		if atomic.LoadInt32(&callCount) != lastCallCount {
    70  			t.Errorf("DigitalRead was called after driver was halted")
    71  		}
    72  	}
    73  }
    74  
    75  func TestDriverPublishesError(t *testing.T) {
    76  	testAdaptor := newGpioTestAdaptor()
    77  	pin := "456"
    78  
    79  	drivers := []DriverAndEventer{
    80  		NewGroveTouchDriver(testAdaptor, pin),
    81  		NewGroveButtonDriver(testAdaptor, pin),
    82  		NewGroveMagneticSwitchDriver(testAdaptor, pin),
    83  	}
    84  
    85  	for _, driver := range drivers {
    86  		sem := make(chan struct{}, 1)
    87  		// send error
    88  		returnErr := func(string) (val int, err error) {
    89  			err = errors.New("read error")
    90  			return
    91  		}
    92  		testAdaptor.testAdaptorDigitalRead = returnErr
    93  
    94  		gobottest.Assert(t, driver.Start(), nil)
    95  
    96  		// expect error
    97  		driver.Once(driver.Event(Error), func(data interface{}) {
    98  			gobottest.Assert(t, data.(error).Error(), "read error")
    99  			close(sem)
   100  		})
   101  
   102  		select {
   103  		case <-sem:
   104  		case <-time.After(time.Second):
   105  			t.Errorf("%s Event \"Error\" was not published", getType(driver))
   106  		}
   107  
   108  		// Cleanup
   109  		driver.Halt()
   110  	}
   111  }
   112  
   113  func getType(driver interface{}) string {
   114  	d := reflect.TypeOf(driver)
   115  
   116  	if d.Kind() == reflect.Ptr {
   117  		return d.Elem().Name()
   118  	}
   119  
   120  	return d.Name()
   121  }