Skip to content

Commit d5df728

Browse files
Copilotkevwan
andcommitted
Add comprehensive integration test for inline struct handling
- Add TestGenWithInlineStructs to verify end-to-end generation - Test verifies correct parameter generation, flattening of inline structs - Test verifies no incorrect Headers interfaces are generated - Test verifies correct argument counts in function calls Co-authored-by: kevwan <[email protected]>
1 parent 8a49f33 commit d5df728

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

tools/goctl/api/tsgen/gen_test.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package tsgen
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"strings"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/zeromicro/go-zero/tools/goctl/api/parser"
11+
)
12+
13+
func TestGenWithInlineStructs(t *testing.T) {
14+
// Create a temporary directory for the test
15+
tmpDir := t.TempDir()
16+
apiFile := filepath.Join(tmpDir, "test.api")
17+
18+
// Write the test API file
19+
apiContent := `syntax = "v1"
20+
21+
info (
22+
title: "Test ts generator"
23+
desc: "Test inline struct handling"
24+
author: "test"
25+
version: "v1"
26+
)
27+
28+
// common pagination request
29+
type PaginationReq {
30+
PageNum int ` + "`form:\"pageNum\"`" + `
31+
PageSize int ` + "`form:\"pageSize\"`" + `
32+
}
33+
34+
// base response
35+
type BaseResp {
36+
Code int64 ` + "`json:\"code\"`" + `
37+
Msg string ` + "`json:\"msg\"`" + `
38+
}
39+
40+
// common req
41+
type GetListCommonReq {
42+
Sth string ` + "`form:\"sth\"`" + `
43+
PageNum int ` + "`form:\"pageNum\"`" + `
44+
PageSize int ` + "`form:\"pageSize\"`" + `
45+
}
46+
47+
// bad req to ts - inline struct with form tags
48+
type GetListBadReq {
49+
Sth string ` + "`form:\"sth\"`" + `
50+
PaginationReq
51+
}
52+
53+
// bad req to ts 2 - only inline struct with form tags
54+
type GetListBad2Req {
55+
PaginationReq
56+
}
57+
58+
// GetListResp - inline struct with json tags
59+
type GetListResp {
60+
BaseResp
61+
}
62+
63+
service test-api {
64+
@doc "common req"
65+
@handler getListCommon
66+
get /getListCommon (GetListCommonReq) returns (GetListResp)
67+
68+
@doc "bad req"
69+
@handler getListBad
70+
get /getListBad (GetListBadReq) returns (GetListResp)
71+
72+
@doc "bad req 2"
73+
@handler getListBad2
74+
get /getListBad2 (GetListBad2Req) returns (GetListResp)
75+
76+
@doc "no req"
77+
@handler getListNoReq
78+
get /getListNoReq returns (GetListResp)
79+
}`
80+
81+
err := os.WriteFile(apiFile, []byte(apiContent), 0644)
82+
assert.NoError(t, err)
83+
84+
// Parse the API file
85+
api, err := parser.Parse(apiFile)
86+
assert.NoError(t, err)
87+
88+
// Generate TypeScript files
89+
outputDir := filepath.Join(tmpDir, "output")
90+
err = os.MkdirAll(outputDir, 0755)
91+
assert.NoError(t, err)
92+
93+
// Generate the files directly
94+
api.Service = api.Service.JoinPrefix()
95+
err = genRequest(outputDir)
96+
assert.NoError(t, err)
97+
err = genHandler(outputDir, ".", "webapi", api, false)
98+
assert.NoError(t, err)
99+
err = genComponents(outputDir, api)
100+
assert.NoError(t, err)
101+
102+
// Read generated handler file
103+
handlerFile := filepath.Join(outputDir, "test.ts")
104+
handlerContent, err := os.ReadFile(handlerFile)
105+
assert.NoError(t, err)
106+
handler := string(handlerContent)
107+
108+
// Read generated components file
109+
componentsFile := filepath.Join(outputDir, "testComponents.ts")
110+
componentsContent, err := os.ReadFile(componentsFile)
111+
assert.NoError(t, err)
112+
components := string(componentsContent)
113+
114+
// Verify getListBad function signature and call
115+
assert.Contains(t, handler, "export function getListBad(params: components.GetListBadReqParams)")
116+
assert.Contains(t, handler, "return webapi.get<components.GetListResp>(`/getListBad`, params)")
117+
// Should NOT contain 4 arguments
118+
assert.NotContains(t, handler, "getListBad`, params, req, headers")
119+
120+
// Verify getListBad2 function signature and call
121+
assert.Contains(t, handler, "export function getListBad2(params: components.GetListBad2ReqParams)")
122+
assert.Contains(t, handler, "return webapi.get<components.GetListResp>(`/getListBad2`, params)")
123+
// Should NOT reference non-existent headers
124+
assert.NotContains(t, handler, "GetListBad2ReqHeaders")
125+
126+
// Verify getListCommon function signature and call
127+
assert.Contains(t, handler, "export function getListCommon(params: components.GetListCommonReqParams)")
128+
assert.Contains(t, handler, "return webapi.get<components.GetListResp>(`/getListCommon`, params)")
129+
130+
// Verify getListNoReq function signature and call
131+
assert.Contains(t, handler, "export function getListNoReq()")
132+
assert.Contains(t, handler, "return webapi.get<components.GetListResp>(`/getListNoReq`)")
133+
134+
// Verify GetListBadReqParams contains flattened fields
135+
assert.Contains(t, components, "export interface GetListBadReqParams")
136+
// Count occurrences of fields in GetListBadReqParams
137+
paramsStart := strings.Index(components, "export interface GetListBadReqParams")
138+
paramsEnd := strings.Index(components[paramsStart:], "}")
139+
paramsSection := components[paramsStart : paramsStart+paramsEnd]
140+
assert.Contains(t, paramsSection, "sth: string")
141+
assert.Contains(t, paramsSection, "pageNum: number")
142+
assert.Contains(t, paramsSection, "pageSize: number")
143+
144+
// Verify GetListBad2ReqParams contains flattened fields from inline PaginationReq
145+
assert.Contains(t, components, "export interface GetListBad2ReqParams")
146+
params2Start := strings.Index(components, "export interface GetListBad2ReqParams")
147+
params2End := strings.Index(components[params2Start:], "}")
148+
params2Section := components[params2Start : params2Start+params2End]
149+
assert.Contains(t, params2Section, "pageNum: number")
150+
assert.Contains(t, params2Section, "pageSize: number")
151+
152+
// Verify no empty Headers interfaces are generated
153+
assert.NotContains(t, components, "GetListBadReqHeaders")
154+
assert.NotContains(t, components, "GetListBad2ReqHeaders")
155+
156+
// Verify GetListResp contains flattened fields from BaseResp
157+
assert.Contains(t, components, "export interface GetListResp")
158+
respStart := strings.Index(components, "export interface GetListResp")
159+
respEnd := strings.Index(components[respStart:], "}")
160+
respSection := components[respStart : respStart+respEnd]
161+
assert.Contains(t, respSection, "code: number")
162+
assert.Contains(t, respSection, "msg: string")
163+
}

0 commit comments

Comments
 (0)