diff --git a/mux_test.go b/mux_test.go index 7eb39ef..5acbf0f 100644 --- a/mux_test.go +++ b/mux_test.go @@ -7,6 +7,7 @@ import ( "fmt" "math" "os" + "reflect" "strings" "testing" @@ -18,6 +19,10 @@ type IntegrationTestPayload struct { B int `json:"b"` } +type IntegrationTestContext struct { + AuthKey string `json:"Auth-Key"` +} + var ( stdoutTerminationSequence = strings.Repeat("\x00", 5) daemonTerminationSequence = strings.Repeat("\x00", 6) @@ -34,7 +39,7 @@ func buildOptions(entrypoint string) []string { } // we use a simplified type here in order to make the tests less cluttered -type testHandlerFunc func(*testing.T, e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) +type testHandlerFunc func(*testing.T, e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) var ( defaultPayload, _ = json.Marshal(map[string]interface{}{ @@ -42,7 +47,10 @@ var ( "params": map[string][]string{ "test-param": {"a", "b"}, }, - "data": IntegrationTestPayload{A: 2, B: 3}, + "data": map[string]int{ + "a": 2, + "b": 3, + }, "request_headers": map[string]string{ "test-header": "test-header-value", }, @@ -57,7 +65,27 @@ var ( }, }, }) - defaultHandler testHandlerFunc = func(*testing.T, e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + expectedRequest = e5e.Request[IntegrationTestPayload, IntegrationTestContext]{ + Event: e5e.Event[IntegrationTestPayload]{ + Params: map[string][]string{ + "test-param": {"a", "b"}, + }, + RequestHeaders: map[string]string{ + "test-header": "test-header-value", + }, + Type: e5e.EventDataTypeObject, + Data: IntegrationTestPayload{A: 2, B: 3}, + }, + Context: e5e.Context[IntegrationTestContext]{ + Async: false, + Date: "2022-08-04T14:15:53.885414", + Type: "go-library-test", + Data: IntegrationTestContext{ + AuthKey: "my-auth-key", + }, + }, + } + defaultHandler testHandlerFunc = func(*testing.T, e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return &e5e.Result{}, nil } ) @@ -88,14 +116,14 @@ func TestResponse(t *testing.T) { }{ { name: "empty result", - handler: func(*testing.T, e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + handler: func(*testing.T, e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return &e5e.Result{Data: nil}, nil }, result: `{"result":{"data":null}}`, }, { name: "nil result", - handler: func(*testing.T, e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + handler: func(*testing.T, e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return &e5e.Result{Status: 200}, nil }, result: `{"result":{"status":200,"data":null}}`, @@ -104,7 +132,7 @@ func TestResponse(t *testing.T) { name: "print stdout", stdout: "print", stderr: "error print", - handler: func(*testing.T, e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + handler: func(*testing.T, e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { fmt.Print("print") _, _ = fmt.Fprint(os.Stderr, "error print") return nil, nil @@ -113,55 +141,19 @@ func TestResponse(t *testing.T) { }, { name: "sum", - handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return &e5e.Result{Data: r.Data().A + r.Data().B}, nil }, result: `{"result":{"data":5}}`, }, { - name: "header can be read", - handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { - HasKey(t, r.Event.RequestHeaders, "test-header") - return &e5e.Result{}, nil - }, - result: `{"result":{"data":null}}`, - }, - { - name: "param can be read", - handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { - HasKey(t, r.Event.Params, "test-param") + name: "request contains all keys and values", + handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { + DeepEqual(t, r, expectedRequest, "request does not match") return &e5e.Result{}, nil }, result: `{"result":{"data":null}}`, }, - { - name: "context can be fetched", - handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { - if r.Context.Type == "" { - return nil, errors.New("handler was executed without event context") - } - - return &e5e.Result{}, nil - }, - result: `{"result":{"data":null}}`, - }, - { - name: "special context keys can be fetched", - handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { - asMap, ok := r.Context.Data.(map[string]any) - if !ok { - t.Errorf("cannot convert %#v into map[string]any", r.Context.Data) - } - - HasKey(t, asMap, "Auth-Key") - - key := asMap["Auth-Key"].(string) - Equal(t, "my-auth-key", key, "Auth-Key header should match") - - return &e5e.Result{Data: key}, nil - }, - result: `{"result":{"data":"my-auth-key"}}`, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -172,7 +164,7 @@ func TestResponse(t *testing.T) { tt.handler = defaultHandler } - e5e.AddHandlerFunc(t.Name(), func(ctx context.Context, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + e5e.AddHandlerFunc(t.Name(), func(ctx context.Context, r e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return tt.handler(t, r) }) @@ -199,13 +191,13 @@ func TestErrors(t *testing.T) { }, { name: "handler returns error", - handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return nil, errors.New("error") }, }, { name: "invalid result (infinity)", - handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + handler: func(t *testing.T, r e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return &e5e.Result{Data: math.Inf(0)}, nil }, }, @@ -216,7 +208,7 @@ func TestErrors(t *testing.T) { tt.handler = defaultHandler } - e5e.AddHandlerFunc(t.Name(), func(ctx context.Context, r e5e.Request[IntegrationTestPayload, any]) (*e5e.Result, error) { + e5e.AddHandlerFunc(t.Name(), func(ctx context.Context, r e5e.Request[IntegrationTestPayload, IntegrationTestContext]) (*e5e.Result, error) { return tt.handler(t, r) }) @@ -313,24 +305,16 @@ func TestCancellation(t *testing.T) { Equal(t, "", stderr, "stderr does not match") } -func HasKey[TKey comparable, TValue any](t *testing.T, data map[TKey]TValue, key TKey) { +func Equal[T comparable](t *testing.T, expected, actual T, message string) { t.Helper() - if data == nil { - t.Fatalf("passed nil to HasKey") - } - - for k := range data { - if k == key { - return - } + if actual != expected { + t.Fatalf("%s:\n\tgot:\t%v\n\twanted:\t%v", message, actual, expected) } - - t.Fatalf("Key %v is not in map: %#v", key, data) } -func Equal[T comparable](t *testing.T, expected, actual T, message string) { +func DeepEqual(t *testing.T, expected interface{}, actual interface{}, message string) { t.Helper() - if actual != expected { - t.Fatalf("%s:\n\tgot:\t%v\n\twanted:\t%v", message, actual, expected) + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("%s:\n\tgot:\t%+v\n\twanted:\t%+v", message, actual, expected) } }