@@ -15,11 +15,6 @@ import (
15
15
"golang.org/x/xerrors"
16
16
)
17
17
18
- type route struct {
19
- path string
20
- method string
21
- }
22
-
23
18
type SwaggerComment struct {
24
19
summary string
25
20
id string
@@ -28,7 +23,8 @@ type SwaggerComment struct {
28
23
accept string
29
24
produce string
30
25
31
- routes []route
26
+ method string
27
+ router string
32
28
33
29
successes []response
34
30
failures []response
@@ -38,15 +34,6 @@ type SwaggerComment struct {
38
34
raw []* ast.Comment
39
35
}
40
36
41
- func (s * SwaggerComment ) hasPath (path string ) bool {
42
- for _ , route := range s .routes {
43
- if route .path == path {
44
- return true
45
- }
46
- }
47
- return false
48
- }
49
-
50
37
type parameter struct {
51
38
name string
52
39
kind string
@@ -118,10 +105,8 @@ func parseSwaggerComment(commentGroup *ast.CommentGroup) SwaggerComment {
118
105
119
106
switch annotationName {
120
107
case "@Router" :
121
- c .routes = append (c .routes , route {
122
- path : args [0 ],
123
- method : args [1 ][1 : len (args [1 ])- 1 ],
124
- })
108
+ c .router = args [0 ]
109
+ c .method = args [1 ][1 : len (args [1 ])- 1 ]
125
110
case "@Success" , "@Failure" :
126
111
var r response
127
112
if len (args ) > 0 {
@@ -175,7 +160,7 @@ func VerifySwaggerDefinitions(t *testing.T, router chi.Router, swaggerComments [
175
160
t .Run (method + " " + route , func (t * testing.T ) {
176
161
t .Parallel ()
177
162
178
- c := findSwaggerCommentByMethodAndPath (swaggerComments , method , route )
163
+ c := findSwaggerCommentByMethodAndRoute (swaggerComments , method , route )
179
164
assert .NotNil (t , c , "Missing @Router annotation" )
180
165
if c == nil {
181
166
return // do not fail next assertion for this route
@@ -199,13 +184,11 @@ func assertUniqueRoutes(t *testing.T, comments []SwaggerComment) {
199
184
m := map [string ]struct {}{}
200
185
201
186
for _ , c := range comments {
202
- for _ , r := range c .routes {
203
- key := r .method + " " + r .path
204
- _ , alreadyDefined := m [key ]
205
- assert .False (t , alreadyDefined , "defined route must be unique (method: %s, route: %s)" , r .method , r .path )
206
- if ! alreadyDefined {
207
- m [key ] = struct {}{}
208
- }
187
+ key := c .method + " " + c .router
188
+ _ , alreadyDefined := m [key ]
189
+ assert .False (t , alreadyDefined , "defined route must be unique (method: %s, route: %s)" , c .method , c .router )
190
+ if ! alreadyDefined {
191
+ m [key ] = struct {}{}
209
192
}
210
193
}
211
194
}
@@ -235,17 +218,15 @@ func assertSingleAnnotations(t *testing.T, comments []SwaggerComment) {
235
218
236
219
for _ , annotation := range uniqueAnnotations {
237
220
v := counters [annotation ]
238
- assert .LessOrEqual (t , 1 , v , "%s annotation for route %s must be defined only once" , annotation , comment .routes )
221
+ assert .Equal (t , 1 , v , "%s annotation for route %s must be defined only once" , annotation , comment .router )
239
222
}
240
223
}
241
224
}
242
225
243
- func findSwaggerCommentByMethodAndPath (comments []SwaggerComment , method , path string ) * SwaggerComment {
226
+ func findSwaggerCommentByMethodAndRoute (comments []SwaggerComment , method , route string ) * SwaggerComment {
244
227
for _ , c := range comments {
245
- for _ , r := range c .routes {
246
- if r .method == method && r .path == path {
247
- return & c
248
- }
228
+ if c .method == method && c .router == route {
229
+ return & c
249
230
}
250
231
}
251
232
return nil
@@ -269,7 +250,7 @@ func assertRequiredAnnotations(t *testing.T, comment SwaggerComment) {
269
250
assert .NotEmpty (t , comment .id , "@ID must be defined" )
270
251
assert .NotEmpty (t , comment .summary , "@Summary must be defined" )
271
252
assert .NotEmpty (t , comment .tags , "@Tags must be defined" )
272
- assert .NotEmpty (t , comment .routes , "@Router must be defined" )
253
+ assert .NotEmpty (t , comment .router , "@Router must be defined" )
273
254
}
274
255
275
256
func assertGoCommentFirst (t * testing.T , comment SwaggerComment ) {
@@ -293,11 +274,7 @@ func assertGoCommentFirst(t *testing.T, comment SwaggerComment) {
293
274
var urlParameterRegexp = regexp .MustCompile (`{[^{}]*}` )
294
275
295
276
func assertPathParametersDefined (t * testing.T , comment SwaggerComment ) {
296
- var paths []string
297
- for _ , r := range comment .routes {
298
- paths = append (paths , r .path )
299
- }
300
- matches := urlParameterRegexp .FindAllString (strings .Join (paths , "\n " ), - 1 )
277
+ matches := urlParameterRegexp .FindAllString (comment .router , - 1 )
301
278
if matches == nil {
302
279
return // router does not require any parameters
303
280
}
@@ -318,10 +295,10 @@ func assertPathParametersDefined(t *testing.T, comment SwaggerComment) {
318
295
}
319
296
320
297
func assertSecurityDefined (t * testing.T , comment SwaggerComment ) {
321
- if comment .hasPath ( "/updatecheck" ) ||
322
- comment .hasPath ( "/buildinfo" ) ||
323
- comment .hasPath ( "/" ) ||
324
- comment .hasPath ( "/users/login" ) {
298
+ if comment .router == "/updatecheck" ||
299
+ comment .router == "/buildinfo" ||
300
+ comment .router == "/" ||
301
+ comment .router == "/users/login" {
325
302
return // endpoints do not require authorization
326
303
}
327
304
assert .Equal (t , "CoderSessionToken" , comment .security , "@Security must be equal CoderSessionToken" )
@@ -342,14 +319,12 @@ func assertAccept(t *testing.T, comment SwaggerComment) {
342
319
hasAccept = true
343
320
}
344
321
345
- for _ , r := range comment .routes {
346
- if r .method == "get" {
347
- assert .Empty (t , comment .accept , "GET route does not require the @Accept annotation" )
348
- assert .False (t , hasRequestBody , "GET route does not require the request body" )
349
- } else {
350
- assert .False (t , hasRequestBody && ! hasAccept , "Route with the request body requires the @Accept annotation" )
351
- assert .False (t , ! hasRequestBody && hasAccept , "Route with @Accept annotation requires the request body or file formData parameter" )
352
- }
322
+ if comment .method == "get" {
323
+ assert .Empty (t , comment .accept , "GET route does not require the @Accept annotation" )
324
+ assert .False (t , hasRequestBody , "GET route does not require the request body" )
325
+ } else {
326
+ assert .False (t , hasRequestBody && ! hasAccept , "Route with the request body requires the @Accept annotation" )
327
+ assert .False (t , ! hasRequestBody && hasAccept , "Route with @Accept annotation requires the request body or file formData parameter" )
353
328
}
354
329
}
355
330
@@ -364,20 +339,18 @@ func assertProduce(t *testing.T, comment SwaggerComment) {
364
339
}
365
340
}
366
341
367
- for _ , r := range comment .routes {
368
- if hasResponseModel {
369
- assert .True (t , comment .produce != "" , "Route must have @Produce annotation as it responds with a model structure" )
370
- assert .Contains (t , allowedProduceTypes , comment .produce , "@Produce value is limited to specific types: %s" , strings .Join (allowedProduceTypes , "," ))
371
- } else {
372
- if (r .path == "/workspaceagents/me/app-health" && r .method == "post" ) ||
373
- (r .path == "/workspaceagents/me/startup" && r .method == "post" ) ||
374
- (r .path == "/workspaceagents/me/startup/logs" && r .method == "patch" ) ||
375
- (r .path == "/licenses/{id}" && r .method == "delete" ) ||
376
- (r .path == "/debug/coordinator" && r .method == "get" ) {
377
- return // Exception: HTTP 200 is returned without response entity
378
- }
379
-
380
- assert .True (t , comment .produce == "" , "Response model is undefined, so we can't predict the content type" , comment )
342
+ if hasResponseModel {
343
+ assert .True (t , comment .produce != "" , "Route must have @Produce annotation as it responds with a model structure" )
344
+ assert .Contains (t , allowedProduceTypes , comment .produce , "@Produce value is limited to specific types: %s" , strings .Join (allowedProduceTypes , "," ))
345
+ } else {
346
+ if (comment .router == "/workspaceagents/me/app-health" && comment .method == "post" ) ||
347
+ (comment .router == "/workspaceagents/me/startup" && comment .method == "post" ) ||
348
+ (comment .router == "/workspaceagents/me/startup/logs" && comment .method == "patch" ) ||
349
+ (comment .router == "/licenses/{id}" && comment .method == "delete" ) ||
350
+ (comment .router == "/debug/coordinator" && comment .method == "get" ) {
351
+ return // Exception: HTTP 200 is returned without response entity
381
352
}
353
+
354
+ assert .True (t , comment .produce == "" , "Response model is undefined, so we can't predict the content type" , comment )
382
355
}
383
356
}
0 commit comments