From a4f9994bc5938ae1f8fb31e934d27d3056d9e9bc Mon Sep 17 00:00:00 2001 From: Kirill Sysoev Date: Sun, 7 Apr 2024 18:22:10 +0800 Subject: [PATCH] Adds basic tests for dispatcher classes --- dispatch/dispatcher_test.go | 64 +++++++++++ dispatch/request_test.go | 48 ++++++++ mocks/mock_Backend.go | 84 ++++++++++++++ mocks/mock_Connection.go | 208 +++++++++++++++++++++++++++++++++++ mocks/mock_RequestHandler.go | 84 ++++++++++++++ 5 files changed, 488 insertions(+) create mode 100644 dispatch/dispatcher_test.go create mode 100644 dispatch/request_test.go create mode 100644 mocks/mock_Backend.go create mode 100644 mocks/mock_Connection.go create mode 100644 mocks/mock_RequestHandler.go diff --git a/dispatch/dispatcher_test.go b/dispatch/dispatcher_test.go new file mode 100644 index 0000000..7da2ad3 --- /dev/null +++ b/dispatch/dispatcher_test.go @@ -0,0 +1,64 @@ +package dispatch + +import ( + "context" + "fmt" + "testing" + + "github.com/ksysoev/wasabi" + "github.com/ksysoev/wasabi/mocks" +) + +func TestNewPipeDispatcher(t *testing.T) { + backend := mocks.NewMockBackend(t) + dispatcher := NewPipeDispatcher(backend) + + if dispatcher.backend != backend { + t.Errorf("Expected backend to be %v, but got %v", backend, dispatcher.backend) + } + + if len(dispatcher.middlewares) != 0 { + t.Errorf("Expected no middlewares, but got %d", len(dispatcher.middlewares)) + } +} + +func TestPipeDispatcher_Dispatch(t *testing.T) { + backend := mocks.NewMockBackend(t) + dispatcher := NewPipeDispatcher(backend) + + conn := mocks.NewMockConnection(t) + data := []byte("test data") + testError := fmt.Errorf("test error") + + conn.On("Context").Return(context.Background()) + backend.EXPECT().Handle(conn, NewRawRequest(conn.Context(), data)).Return(testError) + + dispatcher.Dispatch(conn, data) +} + +func TestPipeDispatcher_Use(t *testing.T) { + backend := mocks.NewMockBackend(t) + dispatcher := NewPipeDispatcher(backend) + + middleware := RequestMiddlewere(func(next wasabi.RequestHandler) wasabi.RequestHandler { return next }) + dispatcher.Use(middleware) + + if len(dispatcher.middlewares) != 1 { + t.Errorf("Expected 1 middleware, but got %d", len(dispatcher.middlewares)) + } +} + +func TestPipeDispatcher_useMiddleware(t *testing.T) { + backend := mocks.NewMockBackend(t) + dispatcher := NewPipeDispatcher(backend) + + middleware := RequestMiddlewere(func(next wasabi.RequestHandler) wasabi.RequestHandler { return next }) + dispatcher.Use(middleware) + + handler := mocks.NewMockRequestHandler(t) + result := dispatcher.useMiddleware(handler) + + if result == nil { + t.Error("Expected non-nil result") + } +} diff --git a/dispatch/request_test.go b/dispatch/request_test.go new file mode 100644 index 0000000..260be4b --- /dev/null +++ b/dispatch/request_test.go @@ -0,0 +1,48 @@ +package dispatch + +import ( + "bytes" + "context" + "testing" +) + +func TestRawRequest_Data(t *testing.T) { + data := []byte("test data") + req := NewRawRequest(context.Background(), data) + + if !bytes.Equal(req.Data(), data) { + t.Errorf("Expected data to be '%s', but got '%s'", data, req.Data()) + } +} + +func TestRawRequest_RoutingKey(t *testing.T) { + req := NewRawRequest(context.Background(), []byte{}) + + if req.RoutingKey() != "" { + t.Errorf("Expected routing key to be empty, but got %v", req.RoutingKey()) + } +} + +func TestRawRequest_Context(t *testing.T) { + ctx := context.Background() + req := NewRawRequest(ctx, []byte{}) + + if req.Context() != ctx { + t.Errorf("Expected context to be %v, but got %v", ctx, req.Context()) + } +} + +func TestRawRequest_WithContext(t *testing.T) { + ctx := context.Background() + req := NewRawRequest(context.Background(), []byte{}) + + newReq := req.WithContext(ctx) + + if newReq.Context() != ctx { + t.Errorf("Expected context to be %v, but got %v", ctx, newReq.Context()) + } + + if newReq != req { + t.Error("Expected WithContext to return the same request instance") + } +} diff --git a/mocks/mock_Backend.go b/mocks/mock_Backend.go new file mode 100644 index 0000000..95e5dd3 --- /dev/null +++ b/mocks/mock_Backend.go @@ -0,0 +1,84 @@ +// Code generated by mockery v2.42.1. DO NOT EDIT. + +//go:build !compile + +package mocks + +import ( + wasabi "github.com/ksysoev/wasabi" + mock "github.com/stretchr/testify/mock" +) + +// MockBackend is an autogenerated mock type for the Backend type +type MockBackend struct { + mock.Mock +} + +type MockBackend_Expecter struct { + mock *mock.Mock +} + +func (_m *MockBackend) EXPECT() *MockBackend_Expecter { + return &MockBackend_Expecter{mock: &_m.Mock} +} + +// Handle provides a mock function with given fields: conn, r +func (_m *MockBackend) Handle(conn wasabi.Connection, r wasabi.Request) error { + ret := _m.Called(conn, r) + + if len(ret) == 0 { + panic("no return value specified for Handle") + } + + var r0 error + if rf, ok := ret.Get(0).(func(wasabi.Connection, wasabi.Request) error); ok { + r0 = rf(conn, r) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockBackend_Handle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Handle' +type MockBackend_Handle_Call struct { + *mock.Call +} + +// Handle is a helper method to define mock.On call +// - conn wasabi.Connection +// - r wasabi.Request +func (_e *MockBackend_Expecter) Handle(conn interface{}, r interface{}) *MockBackend_Handle_Call { + return &MockBackend_Handle_Call{Call: _e.mock.On("Handle", conn, r)} +} + +func (_c *MockBackend_Handle_Call) Run(run func(conn wasabi.Connection, r wasabi.Request)) *MockBackend_Handle_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(wasabi.Connection), args[1].(wasabi.Request)) + }) + return _c +} + +func (_c *MockBackend_Handle_Call) Return(_a0 error) *MockBackend_Handle_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBackend_Handle_Call) RunAndReturn(run func(wasabi.Connection, wasabi.Request) error) *MockBackend_Handle_Call { + _c.Call.Return(run) + return _c +} + +// NewMockBackend creates a new instance of MockBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockBackend(t interface { + mock.TestingT + Cleanup(func()) +}) *MockBackend { + mock := &MockBackend{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/mock_Connection.go b/mocks/mock_Connection.go new file mode 100644 index 0000000..04d5fb1 --- /dev/null +++ b/mocks/mock_Connection.go @@ -0,0 +1,208 @@ +// Code generated by mockery v2.42.1. DO NOT EDIT. + +//go:build !compile + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// MockConnection is an autogenerated mock type for the Connection type +type MockConnection struct { + mock.Mock +} + +type MockConnection_Expecter struct { + mock *mock.Mock +} + +func (_m *MockConnection) EXPECT() *MockConnection_Expecter { + return &MockConnection_Expecter{mock: &_m.Mock} +} + +// Context provides a mock function with given fields: +func (_m *MockConnection) Context() context.Context { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Context") + } + + var r0 context.Context + if rf, ok := ret.Get(0).(func() context.Context); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(context.Context) + } + } + + return r0 +} + +// MockConnection_Context_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Context' +type MockConnection_Context_Call struct { + *mock.Call +} + +// Context is a helper method to define mock.On call +func (_e *MockConnection_Expecter) Context() *MockConnection_Context_Call { + return &MockConnection_Context_Call{Call: _e.mock.On("Context")} +} + +func (_c *MockConnection_Context_Call) Run(run func()) *MockConnection_Context_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockConnection_Context_Call) Return(_a0 context.Context) *MockConnection_Context_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockConnection_Context_Call) RunAndReturn(run func() context.Context) *MockConnection_Context_Call { + _c.Call.Return(run) + return _c +} + +// HandleRequests provides a mock function with given fields: +func (_m *MockConnection) HandleRequests() { + _m.Called() +} + +// MockConnection_HandleRequests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HandleRequests' +type MockConnection_HandleRequests_Call struct { + *mock.Call +} + +// HandleRequests is a helper method to define mock.On call +func (_e *MockConnection_Expecter) HandleRequests() *MockConnection_HandleRequests_Call { + return &MockConnection_HandleRequests_Call{Call: _e.mock.On("HandleRequests")} +} + +func (_c *MockConnection_HandleRequests_Call) Run(run func()) *MockConnection_HandleRequests_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockConnection_HandleRequests_Call) Return() *MockConnection_HandleRequests_Call { + _c.Call.Return() + return _c +} + +func (_c *MockConnection_HandleRequests_Call) RunAndReturn(run func()) *MockConnection_HandleRequests_Call { + _c.Call.Return(run) + return _c +} + +// ID provides a mock function with given fields: +func (_m *MockConnection) ID() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ID") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockConnection_ID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ID' +type MockConnection_ID_Call struct { + *mock.Call +} + +// ID is a helper method to define mock.On call +func (_e *MockConnection_Expecter) ID() *MockConnection_ID_Call { + return &MockConnection_ID_Call{Call: _e.mock.On("ID")} +} + +func (_c *MockConnection_ID_Call) Run(run func()) *MockConnection_ID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockConnection_ID_Call) Return(_a0 string) *MockConnection_ID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockConnection_ID_Call) RunAndReturn(run func() string) *MockConnection_ID_Call { + _c.Call.Return(run) + return _c +} + +// Send provides a mock function with given fields: msg +func (_m *MockConnection) Send(msg []byte) error { + ret := _m.Called(msg) + + if len(ret) == 0 { + panic("no return value specified for Send") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]byte) error); ok { + r0 = rf(msg) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockConnection_Send_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Send' +type MockConnection_Send_Call struct { + *mock.Call +} + +// Send is a helper method to define mock.On call +// - msg []byte +func (_e *MockConnection_Expecter) Send(msg interface{}) *MockConnection_Send_Call { + return &MockConnection_Send_Call{Call: _e.mock.On("Send", msg)} +} + +func (_c *MockConnection_Send_Call) Run(run func(msg []byte)) *MockConnection_Send_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockConnection_Send_Call) Return(_a0 error) *MockConnection_Send_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockConnection_Send_Call) RunAndReturn(run func([]byte) error) *MockConnection_Send_Call { + _c.Call.Return(run) + return _c +} + +// NewMockConnection creates a new instance of MockConnection. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockConnection(t interface { + mock.TestingT + Cleanup(func()) +}) *MockConnection { + mock := &MockConnection{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/mock_RequestHandler.go b/mocks/mock_RequestHandler.go new file mode 100644 index 0000000..006025b --- /dev/null +++ b/mocks/mock_RequestHandler.go @@ -0,0 +1,84 @@ +// Code generated by mockery v2.42.1. DO NOT EDIT. + +//go:build !compile + +package mocks + +import ( + wasabi "github.com/ksysoev/wasabi" + mock "github.com/stretchr/testify/mock" +) + +// MockRequestHandler is an autogenerated mock type for the RequestHandler type +type MockRequestHandler struct { + mock.Mock +} + +type MockRequestHandler_Expecter struct { + mock *mock.Mock +} + +func (_m *MockRequestHandler) EXPECT() *MockRequestHandler_Expecter { + return &MockRequestHandler_Expecter{mock: &_m.Mock} +} + +// Handle provides a mock function with given fields: conn, req +func (_m *MockRequestHandler) Handle(conn wasabi.Connection, req wasabi.Request) error { + ret := _m.Called(conn, req) + + if len(ret) == 0 { + panic("no return value specified for Handle") + } + + var r0 error + if rf, ok := ret.Get(0).(func(wasabi.Connection, wasabi.Request) error); ok { + r0 = rf(conn, req) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockRequestHandler_Handle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Handle' +type MockRequestHandler_Handle_Call struct { + *mock.Call +} + +// Handle is a helper method to define mock.On call +// - conn wasabi.Connection +// - req wasabi.Request +func (_e *MockRequestHandler_Expecter) Handle(conn interface{}, req interface{}) *MockRequestHandler_Handle_Call { + return &MockRequestHandler_Handle_Call{Call: _e.mock.On("Handle", conn, req)} +} + +func (_c *MockRequestHandler_Handle_Call) Run(run func(conn wasabi.Connection, req wasabi.Request)) *MockRequestHandler_Handle_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(wasabi.Connection), args[1].(wasabi.Request)) + }) + return _c +} + +func (_c *MockRequestHandler_Handle_Call) Return(_a0 error) *MockRequestHandler_Handle_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockRequestHandler_Handle_Call) RunAndReturn(run func(wasabi.Connection, wasabi.Request) error) *MockRequestHandler_Handle_Call { + _c.Call.Return(run) + return _c +} + +// NewMockRequestHandler creates a new instance of MockRequestHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockRequestHandler(t interface { + mock.TestingT + Cleanup(func()) +}) *MockRequestHandler { + mock := &MockRequestHandler{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +}