gobot.io/x/gobot@v1.16.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  	"time"
    11  
    12  	"gobot.io/x/gobot"
    13  	"gobot.io/x/gobot/drivers/aio"
    14  	"gobot.io/x/gobot/drivers/gpio"
    15  	"gobot.io/x/gobot/drivers/i2c"
    16  	"gobot.io/x/gobot/gobottest"
    17  	"gobot.io/x/gobot/platforms/firmata/client"
    18  )
    19  
    20  // make sure that this Adaptor fullfills all the required interfaces
    21  var _ gobot.Adaptor = (*Adaptor)(nil)
    22  var _ gpio.DigitalReader = (*Adaptor)(nil)
    23  var _ gpio.DigitalWriter = (*Adaptor)(nil)
    24  var _ aio.AnalogReader = (*Adaptor)(nil)
    25  var _ gpio.PwmWriter = (*Adaptor)(nil)
    26  var _ gpio.ServoWriter = (*Adaptor)(nil)
    27  var _ i2c.Connector = (*Adaptor)(nil)
    28  var _ FirmataAdaptor = (*Adaptor)(nil)
    29  
    30  type readWriteCloser struct{}
    31  
    32  func (readWriteCloser) Write(p []byte) (int, error) {
    33  	return testWriteData.Write(p)
    34  }
    35  
    36  var testReadData = []byte{}
    37  var testWriteData = bytes.Buffer{}
    38  
    39  func (readWriteCloser) Read(b []byte) (int, error) {
    40  	size := len(b)
    41  	if len(testReadData) < size {
    42  		size = len(testReadData)
    43  	}
    44  	copy(b, []byte(testReadData)[:size])
    45  	testReadData = testReadData[size:]
    46  
    47  	return size, nil
    48  }
    49  
    50  func (readWriteCloser) Close() error {
    51  	return nil
    52  }
    53  
    54  type mockFirmataBoard struct {
    55  	disconnectError error
    56  	gobot.Eventer
    57  	pins []client.Pin
    58  }
    59  
    60  func newMockFirmataBoard() *mockFirmataBoard {
    61  	m := &mockFirmataBoard{
    62  		Eventer:         gobot.NewEventer(),
    63  		disconnectError: nil,
    64  		pins:            make([]client.Pin, 100),
    65  	}
    66  
    67  	m.pins[1].Value = 1
    68  	m.pins[15].Value = 133
    69  
    70  	m.AddEvent("I2cReply")
    71  	return m
    72  }
    73  
    74  func (mockFirmataBoard) Connect(io.ReadWriteCloser) error { return nil }
    75  func (m mockFirmataBoard) Disconnect() error {
    76  	return m.disconnectError
    77  }
    78  func (m mockFirmataBoard) Pins() []client.Pin {
    79  	return m.pins
    80  }
    81  func (mockFirmataBoard) AnalogWrite(int, int) error      { return nil }
    82  func (mockFirmataBoard) SetPinMode(int, int) error       { return nil }
    83  func (mockFirmataBoard) ReportAnalog(int, int) error     { return nil }
    84  func (mockFirmataBoard) ReportDigital(int, int) error    { return nil }
    85  func (mockFirmataBoard) DigitalWrite(int, int) error     { return nil }
    86  func (mockFirmataBoard) I2cRead(int, int) error          { return nil }
    87  func (mockFirmataBoard) I2cWrite(int, []byte) error      { return nil }
    88  func (mockFirmataBoard) I2cConfig(int) error             { return nil }
    89  func (mockFirmataBoard) ServoConfig(int, int, int) error { return nil }
    90  func (mockFirmataBoard) WriteSysex(data []byte) error    { return nil }
    91  
    92  func initTestAdaptor() *Adaptor {
    93  	a := NewAdaptor("/dev/null")
    94  	a.Board = newMockFirmataBoard()
    95  	a.PortOpener = func(port string) (io.ReadWriteCloser, error) {
    96  		return &readWriteCloser{}, nil
    97  	}
    98  	a.Connect()
    99  	return a
   100  }
   101  
   102  func TestAdaptor(t *testing.T) {
   103  	a := initTestAdaptor()
   104  	gobottest.Assert(t, a.Port(), "/dev/null")
   105  }
   106  
   107  func TestAdaptorFinalize(t *testing.T) {
   108  	a := initTestAdaptor()
   109  	gobottest.Assert(t, a.Finalize(), nil)
   110  
   111  	a = initTestAdaptor()
   112  	a.Board.(*mockFirmataBoard).disconnectError = errors.New("close error")
   113  	gobottest.Assert(t, a.Finalize(), errors.New("close error"))
   114  }
   115  
   116  func TestAdaptorConnect(t *testing.T) {
   117  	var openSP = func(port string) (io.ReadWriteCloser, error) {
   118  		return &readWriteCloser{}, nil
   119  	}
   120  	a := NewAdaptor("/dev/null")
   121  	a.PortOpener = openSP
   122  	a.Board = newMockFirmataBoard()
   123  	gobottest.Assert(t, a.Connect(), nil)
   124  
   125  	a = NewAdaptor("/dev/null")
   126  	a.Board = newMockFirmataBoard()
   127  	a.PortOpener = func(port string) (io.ReadWriteCloser, error) {
   128  		return nil, errors.New("connect error")
   129  	}
   130  	gobottest.Assert(t, a.Connect(), errors.New("connect error"))
   131  
   132  	a = NewAdaptor(&readWriteCloser{})
   133  	a.Board = newMockFirmataBoard()
   134  	gobottest.Assert(t, a.Connect(), nil)
   135  
   136  	a = NewAdaptor("/dev/null")
   137  	a.Board = nil
   138  	gobottest.Assert(t, a.Disconnect(), nil)
   139  }
   140  
   141  func TestAdaptorServoWrite(t *testing.T) {
   142  	a := initTestAdaptor()
   143  	gobottest.Assert(t, a.ServoWrite("1", 50), nil)
   144  }
   145  
   146  func TestAdaptorServoWriteBadPin(t *testing.T) {
   147  	a := initTestAdaptor()
   148  	gobottest.Refute(t, a.ServoWrite("xyz", 50), nil)
   149  }
   150  
   151  func TestAdaptorPwmWrite(t *testing.T) {
   152  	a := initTestAdaptor()
   153  	gobottest.Assert(t, a.PwmWrite("1", 50), nil)
   154  }
   155  
   156  func TestAdaptorPwmWriteBadPin(t *testing.T) {
   157  	a := initTestAdaptor()
   158  	gobottest.Refute(t, a.PwmWrite("xyz", 50), nil)
   159  }
   160  
   161  func TestAdaptorDigitalWrite(t *testing.T) {
   162  	a := initTestAdaptor()
   163  	gobottest.Assert(t, a.DigitalWrite("1", 1), nil)
   164  }
   165  
   166  func TestAdaptorDigitalWriteBadPin(t *testing.T) {
   167  	a := initTestAdaptor()
   168  	gobottest.Refute(t, a.DigitalWrite("xyz", 50), nil)
   169  }
   170  
   171  func TestAdaptorDigitalRead(t *testing.T) {
   172  	a := initTestAdaptor()
   173  	val, err := a.DigitalRead("1")
   174  	gobottest.Assert(t, err, nil)
   175  	gobottest.Assert(t, val, 1)
   176  
   177  	val, err = a.DigitalRead("0")
   178  	gobottest.Assert(t, err, nil)
   179  	gobottest.Assert(t, val, 0)
   180  }
   181  
   182  func TestAdaptorDigitalReadBadPin(t *testing.T) {
   183  	a := initTestAdaptor()
   184  	_, err := a.DigitalRead("xyz")
   185  	gobottest.Refute(t, err, nil)
   186  }
   187  
   188  func TestAdaptorAnalogRead(t *testing.T) {
   189  	a := initTestAdaptor()
   190  	val, err := a.AnalogRead("1")
   191  	gobottest.Assert(t, val, 133)
   192  	gobottest.Assert(t, err, nil)
   193  
   194  	val, err = a.AnalogRead("0")
   195  	gobottest.Assert(t, err, nil)
   196  	gobottest.Assert(t, val, 0)
   197  }
   198  
   199  func TestAdaptorAnalogReadBadPin(t *testing.T) {
   200  	a := initTestAdaptor()
   201  	_, err := a.AnalogRead("xyz")
   202  	gobottest.Refute(t, err, nil)
   203  }
   204  
   205  func TestAdaptorI2cStart(t *testing.T) {
   206  	a := initTestAdaptor()
   207  	i2c, err := a.GetConnection(0, 0)
   208  	gobottest.Assert(t, err, nil)
   209  	gobottest.Refute(t, i2c, nil)
   210  	gobottest.Assert(t, i2c.Close(), nil)
   211  }
   212  
   213  func TestAdaptorI2cRead(t *testing.T) {
   214  	a := initTestAdaptor()
   215  	i := []byte{100}
   216  	i2cReply := client.I2cReply{Data: i}
   217  	go func() {
   218  		<-time.After(10 * time.Millisecond)
   219  		a.Board.Publish(a.Board.Event("I2cReply"), i2cReply)
   220  	}()
   221  
   222  	con, err := a.GetConnection(0, 0)
   223  	gobottest.Assert(t, err, nil)
   224  
   225  	response := []byte{12}
   226  	_, err = con.Read(response)
   227  	gobottest.Assert(t, err, nil)
   228  	gobottest.Assert(t, response, i)
   229  }
   230  
   231  func TestAdaptorI2cReadByte(t *testing.T) {
   232  	a := initTestAdaptor()
   233  	i := []byte{100}
   234  	i2cReply := client.I2cReply{Data: i}
   235  	go func() {
   236  		<-time.After(10 * time.Millisecond)
   237  		a.Board.Publish(a.Board.Event("I2cReply"), i2cReply)
   238  	}()
   239  
   240  	con, err := a.GetConnection(0, 0)
   241  	gobottest.Assert(t, err, nil)
   242  
   243  	var val byte
   244  	val, err = con.ReadByte()
   245  	gobottest.Assert(t, err, nil)
   246  	gobottest.Assert(t, val, uint8(100))
   247  }
   248  
   249  func TestAdaptorI2cReadByteData(t *testing.T) {
   250  	a := initTestAdaptor()
   251  	i := []byte{100}
   252  	i2cReply := client.I2cReply{Data: i}
   253  	go func() {
   254  		<-time.After(10 * time.Millisecond)
   255  		a.Board.Publish(a.Board.Event("I2cReply"), i2cReply)
   256  	}()
   257  
   258  	con, err := a.GetConnection(0, 0)
   259  	gobottest.Assert(t, err, nil)
   260  
   261  	var val byte
   262  	val, err = con.ReadByteData(0x01)
   263  	gobottest.Assert(t, err, nil)
   264  	gobottest.Assert(t, val, uint8(100))
   265  }
   266  
   267  func TestAdaptorI2cReadWordData(t *testing.T) {
   268  	a := initTestAdaptor()
   269  	i := []byte{100}
   270  	i2cReply := client.I2cReply{Data: i}
   271  	go func() {
   272  		<-time.After(10 * time.Millisecond)
   273  		a.Board.Publish(a.Board.Event("I2cReply"), i2cReply)
   274  	}()
   275  
   276  	con, err := a.GetConnection(0, 0)
   277  	gobottest.Assert(t, err, nil)
   278  
   279  	var val uint16
   280  	val, err = con.ReadWordData(0x01)
   281  	gobottest.Assert(t, err, nil)
   282  	gobottest.Assert(t, val, uint16(100))
   283  }
   284  
   285  func TestAdaptorI2cWrite(t *testing.T) {
   286  	a := initTestAdaptor()
   287  	con, err := a.GetConnection(0, 0)
   288  	gobottest.Assert(t, err, nil)
   289  	written, _ := con.Write([]byte{0x00, 0x01})
   290  	gobottest.Assert(t, written, 2)
   291  }
   292  
   293  func TestAdaptorI2cWrite20bytes(t *testing.T) {
   294  	a := initTestAdaptor()
   295  	con, err := a.GetConnection(0, 0)
   296  	gobottest.Assert(t, err, nil)
   297  	written, _ := con.Write([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19})
   298  	gobottest.Assert(t, written, 20)
   299  }
   300  
   301  func TestAdaptorI2cWriteByte(t *testing.T) {
   302  	a := initTestAdaptor()
   303  	con, err := a.GetConnection(0, 0)
   304  	gobottest.Assert(t, err, nil)
   305  	gobottest.Assert(t, con.WriteByte(0x00), nil)
   306  }
   307  
   308  func TestAdaptorI2cWriteByteData(t *testing.T) {
   309  	a := initTestAdaptor()
   310  	con, err := a.GetConnection(0, 0)
   311  	gobottest.Assert(t, err, nil)
   312  	gobottest.Assert(t, con.WriteByteData(0x00, 0x02), nil)
   313  }
   314  
   315  func TestAdaptorI2cWriteWordData(t *testing.T) {
   316  	a := initTestAdaptor()
   317  	con, err := a.GetConnection(0, 0)
   318  	gobottest.Assert(t, err, nil)
   319  	gobottest.Assert(t, con.WriteWordData(0x00, 0x02), nil)
   320  }
   321  
   322  func TestAdaptorI2cWriteBlockData(t *testing.T) {
   323  	a := initTestAdaptor()
   324  	con, err := a.GetConnection(0, 0)
   325  	gobottest.Assert(t, err, nil)
   326  	gobottest.Assert(t, con.WriteBlockData(0x00, []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}), nil)
   327  }
   328  
   329  func TestServoConfig(t *testing.T) {
   330  	a := initTestAdaptor()
   331  	err := a.ServoConfig("9", 0, 0)
   332  	gobottest.Assert(t, err, nil)
   333  
   334  	// test atoi error
   335  	err = a.ServoConfig("a", 0, 0)
   336  	gobottest.Assert(t, true, strings.Contains(fmt.Sprintf("%v", err), "invalid syntax"))
   337  }
   338  
   339  func TestDefaultBus(t *testing.T) {
   340  	a := initTestAdaptor()
   341  	gobottest.Assert(t, a.GetDefaultBus(), 0)
   342  }
   343  
   344  func TestGetConnectionInvalidBus(t *testing.T) {
   345  	a := initTestAdaptor()
   346  	_, err := a.GetConnection(0x01, 99)
   347  	gobottest.Assert(t, err, errors.New("Invalid bus number 99, only 0 is supported"))
   348  }