Skip to content

Commit 4225ae6

Browse files
committed
Add test for generateHarness() in testing/codegen
1 parent c64042d commit 4225ae6

3 files changed

Lines changed: 336 additions & 0 deletions

File tree

testing/codegen/harness_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package codegen
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
"goa.design/goa/v3/codegen"
9+
"goa.design/goa/v3/codegen/service"
10+
httpcodegen "goa.design/goa/v3/http/codegen"
11+
"goa.design/plugins/v3/testing/codegen/testdata"
12+
)
13+
14+
func TestGenerateHarness(t *testing.T) {
15+
cases := map[string]struct {
16+
DSL func()
17+
Code map[string][]string
18+
Path string
19+
}{
20+
"with-stream": {
21+
DSL: testdata.WithStreamDSL,
22+
Code: map[string][]string{
23+
"http-harness": {testdata.WithStreamCode},
24+
},
25+
Path: "gen/with_stream_service/with_stream_servicetest/harness.go",
26+
},
27+
"without-stream": {
28+
DSL: testdata.WithoutStreamDSL,
29+
Code: map[string][]string{
30+
"http-harness": {testdata.WithoutStreamCode},
31+
},
32+
Path: "gen/without_stream_service/without_stream_servicetest/harness.go",
33+
},
34+
}
35+
for name, c := range cases {
36+
t.Run(name, func(t *testing.T) {
37+
root := httpcodegen.RunHTTPDSL(t, c.DSL)
38+
services := service.NewServicesData(root)
39+
svc := root.Services[0]
40+
svcData := services.Get(svc.Name)
41+
f := generateHarness("", svcData, root, svc)
42+
assert.Equal(t, c.Path, f.Path)
43+
for sec, secCode := range c.Code {
44+
testCode(t, f, sec, secCode)
45+
}
46+
})
47+
}
48+
}
49+
50+
func testCode(t *testing.T, file *codegen.File, section string, expCode []string) {
51+
sections := file.Section(section)
52+
require.Len(t, sections, len(expCode))
53+
for i, c := range expCode {
54+
code := codegen.SectionCode(t, sections[i])
55+
assert.Equal(t, c, code)
56+
}
57+
}

testing/codegen/testdata/code.go

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
package testdata
2+
3+
var WithStreamCode = `// setupHTTP initializes the HTTP test server and client.
4+
func (h *Harness) setupHTTP() {
5+
// Create endpoints
6+
endpoints := withstreamservice.NewEndpoints(h.service)
7+
8+
// Create HTTP handler
9+
mux := goahttp.NewMuxer()
10+
// Create WebSocket upgrader for streaming endpoints
11+
upgrader := &websocket.Upgrader{
12+
CheckOrigin: func(r *http.Request) bool { return true },
13+
}
14+
server := httpsvr.New(endpoints, mux, goahttp.RequestDecoder, goahttp.ResponseEncoder, nil, nil, upgrader, nil)
15+
httpsvr.Mount(mux, server)
16+
17+
// Create test server
18+
h.httpSvr = httptest.NewServer(mux)
19+
20+
// Create HTTP client
21+
h.httpCli = &http.Client{
22+
Timeout: 10 * time.Second,
23+
}
24+
}
25+
26+
// HTTPClient returns an HTTP client configured for the test server.
27+
func (h *Harness) HTTPClient() *http.Client {
28+
if h.httpCli == nil {
29+
h.t.Fatal("HTTP transport not configured")
30+
}
31+
return h.httpCli
32+
}
33+
34+
// getHTTPClientImpl returns the underlying HTTP client implementation.
35+
func (h *Harness) getHTTPClientImpl() *httpcli.Client {
36+
if h.httpSvr == nil || h.httpCli == nil {
37+
h.t.Fatal("HTTP transport not configured")
38+
}
39+
u, err := url.Parse(h.httpSvr.URL)
40+
if err != nil {
41+
h.t.Fatalf("invalid test server URL: %v", err)
42+
}
43+
scheme := u.Scheme
44+
host := u.Host
45+
// Create WebSocket dialer for streaming endpoints
46+
wsDialer := &websocket.Dialer{
47+
Proxy: http.ProxyFromEnvironment,
48+
}
49+
50+
return httpcli.NewClient(
51+
scheme,
52+
host,
53+
h.httpCli,
54+
goahttp.RequestEncoder,
55+
goahttp.ResponseDecoder,
56+
false,
57+
wsDialer,
58+
nil,
59+
)
60+
}
61+
62+
// HTTPClientEndpoints creates HTTP client endpoints for the service.
63+
func (h *Harness) HTTPClientEndpoints() *withstreamservice.Endpoints {
64+
c := h.getHTTPClientImpl()
65+
return &withstreamservice.Endpoints{
66+
WithStreamMethod: c.WithStreamMethod(),
67+
}
68+
}
69+
70+
// HTTPURL returns the base URL of the test HTTP server.
71+
func (h *Harness) HTTPURL() string {
72+
if h.httpSvr == nil {
73+
h.t.Fatal("HTTP transport not configured")
74+
}
75+
return h.httpSvr.URL
76+
}
77+
78+
// HTTPRequest creates a new HTTP request for testing.
79+
func (h *Harness) HTTPRequest(method, path string, body any) *http.Request {
80+
h.t.Helper()
81+
82+
url := h.HTTPURL() + path
83+
84+
var bodyReader io.Reader
85+
if body != nil {
86+
data, err := json.Marshal(body)
87+
if err != nil {
88+
h.t.Fatalf("Failed to marshal request body: %v", err)
89+
}
90+
bodyReader = bytes.NewReader(data)
91+
}
92+
93+
req, err := http.NewRequestWithContext(h.ctx, method, url, bodyReader)
94+
if err != nil {
95+
h.t.Fatalf("Failed to create request: %v", err)
96+
}
97+
98+
if body != nil {
99+
req.Header.Set("Content-Type", "application/json")
100+
}
101+
102+
return req
103+
}
104+
105+
// HTTPWSURL builds a websocket URL from the base HTTP URL and path.
106+
func (h *Harness) HTTPWSURL(path string) string {
107+
base := h.HTTPURL()
108+
u, err := url.Parse(base)
109+
if err != nil {
110+
h.t.Fatalf("invalid base URL: %v", err)
111+
}
112+
if u.Scheme == "https" {
113+
u.Scheme = "wss"
114+
} else {
115+
u.Scheme = "ws"
116+
}
117+
u.Path = path
118+
return u.String()
119+
}
120+
121+
// HTTPDo performs an HTTP request and returns the response.
122+
func (h *Harness) HTTPDo(req *http.Request) *http.Response {
123+
h.t.Helper()
124+
125+
resp, err := h.HTTPClient().Do(req)
126+
if err != nil {
127+
h.t.Fatalf("HTTP request failed: %v", err)
128+
}
129+
130+
return resp
131+
}
132+
`
133+
134+
var WithoutStreamCode = `// setupHTTP initializes the HTTP test server and client.
135+
func (h *Harness) setupHTTP() {
136+
// Create endpoints
137+
endpoints := withoutstreamservice.NewEndpoints(h.service)
138+
139+
// Create HTTP handler
140+
mux := goahttp.NewMuxer()
141+
server := httpsvr.New(endpoints, mux, goahttp.RequestDecoder, goahttp.ResponseEncoder, nil, nil)
142+
httpsvr.Mount(mux, server)
143+
144+
// Create test server
145+
h.httpSvr = httptest.NewServer(mux)
146+
147+
// Create HTTP client
148+
h.httpCli = &http.Client{
149+
Timeout: 10 * time.Second,
150+
}
151+
}
152+
153+
// HTTPClient returns an HTTP client configured for the test server.
154+
func (h *Harness) HTTPClient() *http.Client {
155+
if h.httpCli == nil {
156+
h.t.Fatal("HTTP transport not configured")
157+
}
158+
return h.httpCli
159+
}
160+
161+
// getHTTPClientImpl returns the underlying HTTP client implementation.
162+
func (h *Harness) getHTTPClientImpl() *httpcli.Client {
163+
if h.httpSvr == nil || h.httpCli == nil {
164+
h.t.Fatal("HTTP transport not configured")
165+
}
166+
u, err := url.Parse(h.httpSvr.URL)
167+
if err != nil {
168+
h.t.Fatalf("invalid test server URL: %v", err)
169+
}
170+
scheme := u.Scheme
171+
host := u.Host
172+
173+
return httpcli.NewClient(
174+
scheme,
175+
host,
176+
h.httpCli,
177+
goahttp.RequestEncoder,
178+
goahttp.ResponseDecoder,
179+
false,
180+
)
181+
}
182+
183+
// HTTPClientEndpoints creates HTTP client endpoints for the service.
184+
func (h *Harness) HTTPClientEndpoints() *withoutstreamservice.Endpoints {
185+
c := h.getHTTPClientImpl()
186+
return &withoutstreamservice.Endpoints{
187+
WithoutStreamMethod: c.WithoutStreamMethod(),
188+
}
189+
}
190+
191+
// HTTPURL returns the base URL of the test HTTP server.
192+
func (h *Harness) HTTPURL() string {
193+
if h.httpSvr == nil {
194+
h.t.Fatal("HTTP transport not configured")
195+
}
196+
return h.httpSvr.URL
197+
}
198+
199+
// HTTPRequest creates a new HTTP request for testing.
200+
func (h *Harness) HTTPRequest(method, path string, body any) *http.Request {
201+
h.t.Helper()
202+
203+
url := h.HTTPURL() + path
204+
205+
var bodyReader io.Reader
206+
if body != nil {
207+
data, err := json.Marshal(body)
208+
if err != nil {
209+
h.t.Fatalf("Failed to marshal request body: %v", err)
210+
}
211+
bodyReader = bytes.NewReader(data)
212+
}
213+
214+
req, err := http.NewRequestWithContext(h.ctx, method, url, bodyReader)
215+
if err != nil {
216+
h.t.Fatalf("Failed to create request: %v", err)
217+
}
218+
219+
if body != nil {
220+
req.Header.Set("Content-Type", "application/json")
221+
}
222+
223+
return req
224+
}
225+
226+
// HTTPWSURL builds a websocket URL from the base HTTP URL and path.
227+
func (h *Harness) HTTPWSURL(path string) string {
228+
base := h.HTTPURL()
229+
u, err := url.Parse(base)
230+
if err != nil {
231+
h.t.Fatalf("invalid base URL: %v", err)
232+
}
233+
if u.Scheme == "https" {
234+
u.Scheme = "wss"
235+
} else {
236+
u.Scheme = "ws"
237+
}
238+
u.Path = path
239+
return u.String()
240+
}
241+
242+
// HTTPDo performs an HTTP request and returns the response.
243+
func (h *Harness) HTTPDo(req *http.Request) *http.Response {
244+
h.t.Helper()
245+
246+
resp, err := h.HTTPClient().Do(req)
247+
if err != nil {
248+
h.t.Fatalf("HTTP request failed: %v", err)
249+
}
250+
251+
return resp
252+
}
253+
`

testing/codegen/testdata/dsls.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package testdata
2+
3+
import (
4+
. "goa.design/goa/v3/dsl"
5+
)
6+
7+
var WithStreamDSL = func() {
8+
Service("WithStreamService", func() {
9+
Method("WithStreamMethod", func() {
10+
StreamingPayload(String)
11+
HTTP(func() {
12+
GET("/")
13+
})
14+
})
15+
})
16+
}
17+
18+
var WithoutStreamDSL = func() {
19+
Service("WithoutStreamService", func() {
20+
Method("WithoutStreamMethod", func() {
21+
HTTP(func() {
22+
GET("/")
23+
})
24+
})
25+
})
26+
}

0 commit comments

Comments
 (0)