fix isue #2976, to be compatible with bad response type definition for strict route function (#2977)

This commit is contained in:
John Guo
2023-09-25 20:40:32 +08:00
committed by GitHub
parent 7c9eefef3d
commit df92c483d0
2 changed files with 35 additions and 3 deletions

View File

@ -214,11 +214,15 @@ func (s *Server) checkAndCreateFuncInfo(f interface{}, pkgPath, structName, meth
// trimGeneric removes type definitions string from response type name if generic
func trimGeneric(structName string) string {
var (
leftBraceIndex = strings.LastIndex(structName, "[")
leftBraceIndex = strings.LastIndex(structName, "[") // for generic, it is faster to start at the end than at the beginning
rightBraceIndex = strings.LastIndex(structName, "]")
)
if leftBraceIndex == -1 && rightBraceIndex == -1 {
// no generic type usage.
if leftBraceIndex == -1 || rightBraceIndex == -1 {
// not found '[' or ']'
return structName
} else if leftBraceIndex+1 == rightBraceIndex {
// may be a slice, because generic is '[X]', not '[]'
// to be compatible with bad return parameter type: []XxxRes
return structName
}
return structName[:leftBraceIndex]

View File

@ -323,12 +323,29 @@ func Test_Router_Handler_Strict_WithGeneric(t *testing.T) {
},
}, nil
})
s.BindHandler("/test1_slice", func(ctx context.Context, req *TestReq) (res []Test1Res, err error) {
return []Test1Res{
Test1Res{
Age: TestGeneric[int]{
Test: req.Age,
},
},
}, nil
})
s.BindHandler("/test2", func(ctx context.Context, req *TestReq) (res *Test2Res, err error) {
return &Test2Res{
Test: req.Age,
}, nil
})
s.BindHandler("/test2_slice", func(ctx context.Context, req *TestReq) (res []Test2Res, err error) {
return []Test2Res{
Test2Res{
Test: req.Age,
},
}, nil
})
s.BindHandler("/test3", func(ctx context.Context, req *TestReq) (res *TestGenericRes[int], err error) {
return &TestGenericRes[int]{
Test: req.Age,
@ -339,13 +356,24 @@ func Test_Router_Handler_Strict_WithGeneric(t *testing.T) {
s.Start()
defer s.Shutdown()
s.BindHandler("/test3_slice", func(ctx context.Context, req *TestReq) (res []TestGenericRes[int], err error) {
return []TestGenericRes[int]{
TestGenericRes[int]{
Test: req.Age,
},
}, nil
})
time.Sleep(100 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
client := g.Client()
client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
t.Assert(client.GetContent(ctx, "/test1?age=1"), `{"code":0,"message":"","data":{"Age":{"Test":1}}}`)
t.Assert(client.GetContent(ctx, "/test1_slice?age=1"), `{"code":0,"message":"","data":[{"Age":{"Test":1}}]}`)
t.Assert(client.GetContent(ctx, "/test2?age=2"), `{"code":0,"message":"","data":{"Test":2}}`)
t.Assert(client.GetContent(ctx, "/test2_slice?age=2"), `{"code":0,"message":"","data":[{"Test":2}]}`)
t.Assert(client.GetContent(ctx, "/test3?age=3"), `{"code":0,"message":"","data":{"Test":3}}`)
t.Assert(client.GetContent(ctx, "/test3_slice?age=3"), `{"code":0,"message":"","data":[{"Test":3}]}`)
})
}