diff --git a/wrap/template.go b/wrap/template.go index 4e08aa4..7b18670 100644 --- a/wrap/template.go +++ b/wrap/template.go @@ -328,30 +328,30 @@ import ( // Request Wrappers {{- range $request := .Requests }} -type {{ $request }}Wrapper struct { +type {{ $request.Request }}Wrapper struct { ctx context.Context - *{{ $request }} + *{{ $request.Request }} } -func (h *{{ $request }}Wrapper) Context() context.Context { +func (h *{{ $request.Request }}Wrapper) Context() context.Context { return h.ctx } -func (h *{{ $request }}Wrapper) Param(s string) string { +func (h *{{ $request.Request }}Wrapper) Param(s string) string { return "" } -func (h *{{ $request }}Wrapper) PathParam(s string) string { +func (h *{{ $request.Request }}Wrapper) PathParam(s string) string { return "" } -func (h *{{ $request }}Wrapper) Bind(p interface{}) error { +func (h *{{ $request.Request }}Wrapper) Bind(p interface{}) error { ptr := reflect.ValueOf(p) if ptr.Kind() != reflect.Ptr { return fmt.Errorf("expected a pointer, got %T", p) } - hValue := reflect.ValueOf(h.{{ $request }}).Elem() + hValue := reflect.ValueOf(h.{{ $request.Request }}).Elem() ptrValue := ptr.Elem() for i := 0; i < hValue.NumField(); i++ { @@ -368,11 +368,11 @@ func (h *{{ $request }}Wrapper) Bind(p interface{}) error { return nil } -func (h *{{ $request }}Wrapper) HostName() string { +func (h *{{ $request.Request }}Wrapper) HostName() string { return "" } -func (h *{{ $request }}Wrapper) Params(s string) []string { +func (h *{{ $request.Request }}Wrapper) Params(s string) []string { return nil } {{- end }}` diff --git a/wrap/template_test.go b/wrap/template_test.go new file mode 100644 index 0000000..bc40bf9 --- /dev/null +++ b/wrap/template_test.go @@ -0,0 +1,60 @@ +package wrap + +import ( + "strings" + "testing" + + "gofr.dev/pkg/gofr" + "gofr.dev/pkg/gofr/cmd" + gofrConfig "gofr.dev/pkg/gofr/config" + "gofr.dev/pkg/gofr/container" + "gofr.dev/pkg/gofr/logging" +) + +// createTestContext creates a test gofr.Context for CMD applications. +func createTestContext() *gofr.Context { + c := container.NewContainer(gofrConfig.NewEnvFile("", logging.NewMockLogger(logging.DEBUG))) + req := cmd.NewRequest([]string{}) + + return &gofr.Context{ + Context: req.Context(), + Request: req, + Container: c, + } +} + +// The request-wrapper template ranges over []ServiceRequest, so it must render +// the request type's Name, not the whole struct. Regression test for #75: +// `{{ $request }}` printed the struct as `{GetThingRequest GetThingRequest}`, +// producing `type {GetThingRequest GetThingRequest}Wrapper` that would not +// compile. +func TestGenerateGoFrRequestWrapper_UsesRequestTypeName(t *testing.T) { + out := generateGoFrRequestWrapper(createTestContext(), &WrapperData{ + Package: "example", + Source: "example.proto", + Requests: []ServiceRequest{ + {Request: "GetThingRequest"}, + {Request: "CreateThingRequest"}, + }, + }) + + // Every request type renders correctly, for both entries. + want := []string{ + "type GetThingRequestWrapper struct {", + "*GetThingRequest", + "func (h *GetThingRequestWrapper) Context() context.Context {", + "func (h *GetThingRequestWrapper) Bind(p interface{}) error {", + "reflect.ValueOf(h.GetThingRequest).Elem()", + "type CreateThingRequestWrapper struct {", + } + for _, s := range want { + if !strings.Contains(out, s) { + t.Errorf("generated request wrapper missing %q\n---\n%s", s, out) + } + } + + // The Go struct-literal formatting must not leak into the output. + if strings.Contains(out, "{GetThingRequest") || strings.Contains(out, "{CreateThingRequest") { + t.Errorf("request wrapper leaked a struct literal into the output:\n%s", out) + } +}