gobot.io/x/gobot/v2@v2.1.0/platforms/firmata/firmata_adaptor_test.go (about)

     1  package firmata
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"strings"
     9  	"testing"
    10  
    11  	"gobot.io/x/gobot/v2"
    12  	"gobot.io/x/gobot/v2/drivers/aio"
    13  	"gobot.io/x/gobot/v2/drivers/gpio"
    14  	"gobot.io/x/gobot/v2/gobottest"
    15  	"gobot.io/x/gobot/v2/platforms/firmata/client"
    16  )
    17  
    18  // make sure that this Adaptor fulfills all required analog and digital interfaces
    19  var _ gobot.Adaptor = (*Adaptor)(nil)
    20  var _ gpio.DigitalReader = (*Adaptor)(nil)
    21  var _ gpio.DigitalWriter = (*Adaptor)(nil)
    22  var _ aio.AnalogReader = (*Adaptor)(nil)
    23  var _ gpio.PwmWriter = (*Adaptor)(nil)
    24  var _ gpio.ServoWriter = (*Adaptor)(nil)
    25  var _ FirmataAdaptor = (*Adaptor)(nil)
    26  
    27  type readWriteCloser struct{}
    28  
    29  func (readWriteCloser) Write(p []byte) (int, error) {
    30  	return testWriteData.Write(p)
    31  }
    32  
    33  var testReadData = []byte{}
    34  var testWriteData = bytes.Buffer{}
    35  
    36  func (readWriteCloser) Read(b []byte) (int, error) {
    37  	size := len(b)
    38  	if len(testReadData) < size {
    39  		size = len(testReadData)
    40  	}
    41  	copy(b, []byte(testReadData)[:size])
    42  	testReadData = testReadData[size:]
    43  
    44  	return size, nil
    45  }
    46  
    47  func (readWriteCloser) Close() error {
    48  	return nil
    49  }
    50  
    51  type mockFirmataBoard struct {
    52  	disconnectError error
    53  	gobot.Eventer
    54  	pins []client.Pin
    55  }
    56  
    57  func newMockFirmataBoard() *mockFirmataBoard {
    58  	m := &mockFirmataBoard{
    59  		Eventer:         gobot.NewEventer(),
    60  		disconnectError: nil,
    61  		pins:            make([]client.Pin, 100),
    62  	}
    63  
    64  	m.pins[1].Value = 1
    65  	m.pins[15].Value = 133
    66  
    67  	return m
    68  }
    69  
    70  // setup mock for GPIO, PWM and servo tests
    71  func (mockFirmataBoard) Connect(io.ReadWriteCloser) error { return nil }
    72  func (m mockFirmataBoard) Disconnect() error {
    73  	return m.disconnectError
    74  }
    75  func (m mockFirmataBoard) Pins() []client.Pin {
    76  	return m.pins
    77  }
    78  func (mockFirmataBoard) AnalogWrite(int, int) error      { return nil }
    79  func (mockFirmataBoard) SetPinMode(int, int) error       { return nil }
    80  func (mockFirmataBoard) ReportAnalog(int, int) error     { return nil }
    81  func (mockFirmataBoard) ReportDigital(int, int) error    { return nil }
    82  func (mockFirmataBoard) DigitalWrite(int, int) error     { return nil }
    83  func (mockFirmataBoard) ServoConfig(int, int, int) error { return nil }
    84  func (mockFirmataBoard) WriteSysex([]byte) error         { return nil }
    85  
    86  // i2c functions unused in this test scenarios
    87  func (mockFirmataBoard) I2cRead(int, int) error     { return nil }
    88  func (mockFirmataBoard) I2cWrite(int, []byte) error { return nil }
    89  func (mockFirmataBoard) I2cConfig(int) error        { return nil }
    90  
    91  func initTestAdaptor() *Adaptor {
    92  	a := NewAdaptor("/dev/null")
    93  	a.Board = newMockFirmataBoard()
    94  	a.PortOpener = func(port string) (io.ReadWriteCloser, error) {
    95  		return &readWriteCloser{}, nil
    96  	}
    97  	a.Connect()
    98  	return a
    99  }
   100  
   101  func TestNewAdaptor(t *testing.T) {
   102  	a := NewAdaptor("/dev/null")
   103  	gobottest.Assert(t, a.Port(), "/dev/null")
   104  }
   105  
   106  func TestAdaptorFinalize(t *testing.T) {
   107  	a := initTestAdaptor()
   108  	gobottest.Assert(t, a.Finalize(), nil)
   109  
   110  	a = initTestAdaptor()
   111  	a.Board.(*mockFirmataBoard).disconnectError = errors.New("close error")
   112  	gobottest.Assert(t, a.Finalize(), errors.New("close error"))
   113  }
   114  
   115  func TestAdaptorConnect(t *testing.T) {
   116  	var openSP = func(port string) (io.ReadWriteCloser, error) {
   117  		return &readWriteCloser{}, nil
   118  	}
   119  	a := NewAdaptor("/dev/null")
   120  	a.PortOpener = openSP
   121  	a.Board = newMockFirmataBoard()
   122  	gobottest.Assert(t, a.Connect(), nil)
   123  
   124  	a = NewAdaptor("/dev/null")
   125  	a.Board = newMockFirmataBoard()
   126  	a.PortOpener = func(port string) (io.ReadWriteCloser, error) {
   127  		return nil, errors.New("connect error")
   128  	}
   129  	gobottest.Assert(t, a.Connect(), errors.New("connect error"))
   130  
   131  	a = NewAdaptor(&readWriteCloser{})
   132  	a.Board = newMockFirmataBoard()
   133  	gobottest.Assert(t, a.Connect(), nil)
   134  
   135  	a = NewAdaptor("/dev/null")
   136  	a.Board = nil
   137  	gobottest.Assert(t, a.Disconnect(), nil)
   138  }
   139  
   140  func TestAdaptorServoWrite(t *testing.T) {
   141  	a := initTestAdaptor()
   142  	gobottest.Assert(t, a.ServoWrite("1", 50), nil)
   143  }
   144  
   145  func TestAdaptorServoWriteBadPin(t *testing.T) {
   146  	a := initTestAdaptor()
   147  	gobottest.Refute(t, a.ServoWrite("xyz", 50), nil)
   148  }
   149  
   150  func TestAdaptorPwmWrite(t *testing.T) {
   151  	a := initTestAdaptor()
   152  	gobottest.Assert(t, a.PwmWrite("1", 50), nil)
   153  }
   154  
   155  func TestAdaptorPwmWriteBadPin(t *testing.T) {
   156  	a := initTestAdaptor()
   157  	gobottest.Refute(t, a.PwmWrite("xyz", 50), nil)
   158  }
   159  
   160  func TestAdaptorDigitalWrite(t *testing.T) {
   161  	a := initTestAdaptor()
   162  	gobottest.Assert(t, a.DigitalWrite("1", 1), nil)
   163  }
   164  
   165  func TestAdaptorDigitalWriteBadPin(t *testing.T) {
   166  	a := initTestAdaptor()
   167  	gobottest.Refute(t, a.DigitalWrite("xyz", 50), nil)
   168  }
   169  
   170  func TestAdaptorDigitalRead(t *testing.T) {
   171  	a := initTestAdaptor()
   172  	val, err := a.DigitalRead("1")
   173  	gobottest.Assert(t, err, nil)
   174  	gobottest.Assert(t, val, 1)
   175  
   176  	val, err = a.DigitalRead("0")
   177  	gobottest.Assert(t, err, nil)
   178  	gobottest.Assert(t, val, 0)
   179  }
   180  
   181  func TestAdaptorDigitalReadBadPin(t *testing.T) {
   182  	a := initTestAdaptor()
   183  	_, err := a.DigitalRead("xyz")
   184  	gobottest.Refute(t, err, nil)
   185  }
   186  
   187  func TestAdaptorAnalogRead(t *testing.T) {
   188  	a := initTestAdaptor()
   189  	val, err := a.AnalogRead("1")
   190  	gobottest.Assert(t, val, 133)
   191  	gobottest.Assert(t, err, nil)
   192  
   193  	val, err = a.AnalogRead("0")
   194  	gobottest.Assert(t, err, nil)
   195  	gobottest.Assert(t, val, 0)
   196  }
   197  
   198  func TestAdaptorAnalogReadBadPin(t *testing.T) {
   199  	a := initTestAdaptor()
   200  	_, err := a.AnalogRead("xyz")
   201  	gobottest.Refute(t, err, nil)
   202  }
   203  
   204  func TestServoConfig(t *testing.T) {
   205  	a := initTestAdaptor()
   206  	err := a.ServoConfig("9", 0, 0)
   207  	gobottest.Assert(t, err, nil)
   208  
   209  	// test atoi error
   210  	err = a.ServoConfig("a", 0, 0)
   211  	gobottest.Assert(t, true, strings.Contains(fmt.Sprintf("%v", err), "invalid syntax"))
   212  }