Documentation ¶
Overview ¶
Package mock implements a mocked lifxlan device listening on localhost, which can be used in test code to test API calls.
Please refer to examples to see how to use them in the test code.
Example (TestGetLabel) ¶
This example demonstrates how to mock a response in test code.
package main import ( "context" "testing" "time" "go.yhsif.com/lifxlan" "go.yhsif.com/lifxlan/mock" ) func main() { var t *testing.T t.Run( "GetLabel", func(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } const timeout = time.Millisecond * 200 var expected lifxlan.Label expected.Set("foo") service, device := mock.StartService(t) // This is the payload to be returned by the mock service. service.RawStateLabelPayload = &lifxlan.RawStateLabelPayload{ Label: expected, } ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() if err := device.GetLabel(ctx, nil); err != nil { t.Fatal(err) } if device.Label().String() != expected.String() { t.Errorf("Label expected %v, got %v", expected, device.Label()) } }, ) }
Output:
Example (TestGetLabelWithHandlerFunc) ¶
This example demonstrates how to mock a response with custom HandlerFunc.
package main import ( "bytes" "context" "encoding/binary" "net" "testing" "time" "go.yhsif.com/lifxlan" "go.yhsif.com/lifxlan/mock" ) func main() { var t *testing.T t.Run( "GetLabel", func(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } const timeout = time.Millisecond * 200 var expected lifxlan.Label expected.Set("foo") service, device := mock.StartService(t) // This defines the handler for GetLabel messages. service.Handlers[lifxlan.GetLabel] = func( s *mock.Service, conn net.PacketConn, addr net.Addr, orig *lifxlan.Response, ) { buf := new(bytes.Buffer) if err := binary.Write( buf, binary.LittleEndian, expected, ); err != nil { s.TB.Log(err) return } s.Reply(conn, addr, orig, lifxlan.StateLabel, buf.Bytes()) } ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() if err := device.GetLabel(ctx, nil); err != nil { t.Fatal(err) } if device.Label().String() != expected.String() { t.Errorf("Label expected %v, got %v", expected, device.Label()) } }, ) }
Output:
Example (TestNotEnoughAcks) ¶
This example demonstrates how to mock a not enough acks situation in test code.
package main import ( "context" "testing" "time" "go.yhsif.com/lifxlan/mock" "go.yhsif.com/lifxlan/tile" ) func main() { var t *testing.T t.Run( "SetColors", func(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } const timeout = time.Millisecond * 200 service, device := mock.StartService(t) rawTile1 := tile.RawTileDevice{ Width: 8, Height: 8, } rawTile2 := tile.RawTileDevice{ UserX: 1, Width: 8, Height: 8, } rawChain := &tile.RawStateDeviceChainPayload{ TotalCount: 2, } rawChain.TileDevices[0] = rawTile1 rawChain.TileDevices[1] = rawTile2 service.RawStateDeviceChainPayload = rawChain td, err := func() (tile.Device, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() return tile.Wrap(ctx, device, false) }() if err != nil { t.Fatal(err) } if td == nil { t.Fatal("Can't mock tile device.") } t.Run( "NotEnoughAcks", func(t *testing.T) { // The SetColors function will expect 2 acks. service.AcksToDrop = 1 ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() if err := td.SetColors(ctx, nil, nil, 0, true); err == nil { t.Error("Expected error when not enough acks returned, got nil") } }, ) }, ) }
Output:
Index ¶
Examples ¶
Constants ¶
const ListenAddr = "127.0.0.1:"
ListenAddr is the addr to listen on this device.
const Target lifxlan.Target = 1
Target is the mocked device target.
Variables ¶
This section is empty.
Functions ¶
func DefaultHandlerFunc ¶
DefaultHandlerFunc is the default HandlerFunc to be used when it's not in the Handlers map.
Types ¶
type HandlerFunc ¶
HandlerFunc defines the handler function.
func StateUnhandledHandler ¶
func StateUnhandledHandler(msg lifxlan.MessageType) HandlerFunc
StateUnhandledHandler generates a HandlerFunc to return StateUnhandled message.
type Service ¶
type Service struct { // Testing context TB testing.TB // When AcksToDrop > 0 and it's supposed to send an ack, // the ack won't be send and AcksToDrop will decrease by 1. AcksToDrop int // Any custom HandlerFunc to be used besides DefaultHandlerFunc. Handlers map[lifxlan.MessageType]HandlerFunc // If HandlerAcks is false, AcksToDrop is ignored and you have to handle acks // in your custom HandlerFunc. // // Please note that DefaultHandlerFunc doesn't handle acks. // // StartService sets HandleAcks to true. HandleAcks bool // Payloads to response with DefaultHandlerFunc. RawStatePowerPayload *lifxlan.RawStatePowerPayload RawStateLabelPayload *lifxlan.RawStateLabelPayload RawStateVersionPayload *lifxlan.RawStateVersionPayload RawStatePayload *light.RawStatePayload RawStateRPowerPayload *relay.RawStateRPowerPayload RawStateDeviceChainPayload *tile.RawStateDeviceChainPayload RawStateTileState64Payloads []*tile.RawStateTileState64Payload // The service context. // // Please note that it's different from the context of the API calls. Context context.Context Cancel context.CancelFunc // contains filtered or unexported fields }
Service is a mocked device listening on localhost.
All service functions require TB to be non-nil, or they will panic.
func StartService ¶
StartService starts a mock service, returns the service and the device.
func (*Service) Reply ¶
func (s *Service) Reply( conn net.PacketConn, addr net.Addr, orig *lifxlan.Response, message lifxlan.MessageType, payload []byte, )
Reply replies a request.