Skip to content

Commit 9dfe7ff

Browse files
committed
Added support for Parameters
1 parent 9c222aa commit 9dfe7ff

File tree

4 files changed

+231
-73
lines changed

4 files changed

+231
-73
lines changed

build-map-keys.go

+3
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@ const (
2323
keyFlows = "flows"
2424
keyAuthorizationURL = "authorizationUrl"
2525
keyScopes = "scopes"
26+
keyParameters = "parameters"
27+
keyRequired = "required"
28+
keySchema = "schema"
2629
)

build.go

+39
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func (oas *OAS) BuildStream(w io.Writer) error {
6464
if err != nil {
6565
return fmt.Errorf("writing issue occurred: %w", err)
6666
}
67+
6768
return nil
6869
}
6970

@@ -157,6 +158,7 @@ func makeAllPathsMap(paths *Paths) pathsMap {
157158
pathMap[keySecurity] = makeSecurityMap(&path.Security)
158159
pathMap[keyRequestBody] = makeRequestBodyMap(&path.RequestBody)
159160
pathMap[keyResponses] = makeResponsesMap(&path.Responses)
161+
pathMap[keyParameters] = makeParametersMap(&path.Parameters)
160162

161163
allPaths[path.Route][strings.ToLower(path.HTTPMethod)] = pathMap
162164
}
@@ -345,3 +347,40 @@ const emptyStr = ""
345347
func isStrEmpty(s string) bool {
346348
return s == emptyStr
347349
}
350+
351+
func makeParametersMap(parameters *Parameters) []map[string]interface{} {
352+
parametersMap := []map[string]interface{}{}
353+
354+
for _, param := range *parameters {
355+
paramMap := make(map[string]interface{})
356+
357+
paramMap[keyName] = param.Name
358+
paramMap[keyIn] = param.In
359+
paramMap[keyDescription] = param.Description
360+
paramMap[keyRequired] = param.Required
361+
paramMap[keySchema] = makeSchemaMap(&param.Schema)
362+
363+
parametersMap = append(parametersMap, paramMap)
364+
}
365+
366+
return parametersMap
367+
}
368+
369+
func makeSchemaMap(schema *Schema) map[string]interface{} {
370+
schemaMap := make(map[string]interface{})
371+
372+
if !isStrEmpty(schema.Ref) {
373+
schemaMap[keyRef] = schema.Ref
374+
} else {
375+
schemaMap[keyName] = schema.Name
376+
schemaMap[keyType] = schema.Type
377+
if len(schema.Properties) > 0 {
378+
schemaMap[keyProperties] = makePropertiesMap(&schema.Properties)
379+
}
380+
if schema.XML.Name != "" {
381+
schemaMap[keyXML] = map[string]interface{}{"name": schema.XML.Name}
382+
}
383+
}
384+
385+
return schemaMap
386+
}

build_test.go

+172-73
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,59 @@ package docs
22

33
import (
44
"bytes"
5+
"reflect"
56
"testing"
67
)
78

9+
const (
10+
buildStreamTestWant = `openapi: 3.0.1
11+
info:
12+
title: Test
13+
description: Test object
14+
termsOfService: ""
15+
contact:
16+
email: ""
17+
license:
18+
name: ""
19+
url: ""
20+
version: ""
21+
externalDocs:
22+
description: ""
23+
url: ""
24+
servers: []
25+
tags: []
26+
paths: {}
27+
components:
28+
schemas:
29+
schema_testing:
30+
properties:
31+
EnumProp:
32+
description: short desc
33+
enum:
34+
- enum
35+
- test
36+
- strSlc
37+
type: enum
38+
intProp:
39+
default: 1337
40+
description: short desc
41+
format: int64
42+
type: integer
43+
type: ""
44+
xml:
45+
name: XML entry test
46+
securitySchemes:
47+
ses_scheme_testing:
48+
flows:
49+
implicit:
50+
authorizationUrl: http://petstore.swagger.io/oauth/dialog
51+
scopes:
52+
read:pets: Read Pets
53+
write:pets: Write to Pets
54+
in: not empty
55+
`
56+
)
57+
858
func TestUnitBuild(t *testing.T) {
959
t.Parallel()
1060

@@ -114,6 +164,8 @@ func TestUnitGetPathFromFirstElem(t *testing.T) {
114164
// QUICK CHECK TESTS ARE COMING WITH NEXT RELEASE.
115165

116166
func TestOAS_BuildStream(t *testing.T) {
167+
t.Parallel()
168+
117169
tests := []struct {
118170
name string
119171
oas *OAS
@@ -124,27 +176,19 @@ func TestOAS_BuildStream(t *testing.T) {
124176
name: "success",
125177
oas: &OAS{
126178
OASVersion: "3.0.1",
127-
Info: Info{
128-
Title: "Test",
129-
Description: "Test object",
130-
},
179+
Info: Info{Title: "Test", Description: "Test object"},
131180
Components: Components{
132181
Component{
133182
Schemas: Schemas{Schema{
134183
Name: "schema_testing",
135184
Properties: SchemaProperties{
136185
SchemaProperty{
137-
Name: "EnumProp",
138-
Type: "enum",
139-
Description: "short desc",
140-
Enum: []string{"enum", "test", "strSlc"},
186+
Name: "EnumProp", Type: "enum", Description: "short desc",
187+
Enum: []string{"enum", "test", "strSlc"},
141188
},
142189
SchemaProperty{
143-
Name: "intProp",
144-
Type: "integer",
145-
Format: "int64",
146-
Description: "short desc",
147-
Default: 1337,
190+
Name: "intProp", Type: "integer", Format: "int64",
191+
Description: "short desc", Default: 1337,
148192
},
149193
},
150194
XML: XMLEntry{Name: "XML entry test"},
@@ -156,79 +200,134 @@ func TestOAS_BuildStream(t *testing.T) {
156200
Type: "implicit",
157201
AuthURL: "http://petstore.swagger.io/oauth/dialog",
158202
Scopes: SecurityScopes{
159-
SecurityScope{
160-
Name: "write:pets",
161-
Description: "Write to Pets",
162-
},
163-
SecurityScope{
164-
Name: "read:pets",
165-
Description: "Read Pets",
166-
},
203+
SecurityScope{Name: "write:pets", Description: "Write to Pets"},
204+
SecurityScope{Name: "read:pets", Description: "Read Pets"},
167205
},
168206
}},
169207
}},
170208
},
171209
},
172210
},
173211
wantErr: false,
174-
wantW: `openapi: 3.0.1
175-
info:
176-
title: Test
177-
description: Test object
178-
termsOfService: ""
179-
contact:
180-
email: ""
181-
license:
182-
name: ""
183-
url: ""
184-
version: ""
185-
externalDocs:
186-
description: ""
187-
url: ""
188-
servers: []
189-
tags: []
190-
paths: {}
191-
components:
192-
schemas:
193-
schema_testing:
194-
$ref: ""
195-
properties:
196-
EnumProp:
197-
description: short desc
198-
enum:
199-
- enum
200-
- test
201-
- strSlc
202-
type: enum
203-
intProp:
204-
default: 1337
205-
description: short desc
206-
format: int64
207-
type: integer
208-
type: ""
209-
xml:
210-
name: XML entry test
211-
securitySchemes:
212-
ses_scheme_testing:
213-
flows:
214-
implicit:
215-
authorizationUrl: http://petstore.swagger.io/oauth/dialog
216-
scopes:
217-
read:pets: Read Pets
218-
write:pets: Write to Pets
219-
in: not empty
220-
`,
212+
wantW: buildStreamTestWant,
221213
},
222214
}
215+
223216
for _, tt := range tests {
224-
t.Run(tt.name, func(t *testing.T) {
217+
trn := tt
218+
219+
t.Run(trn.name, func(t *testing.T) {
220+
t.Parallel()
221+
225222
w := &bytes.Buffer{}
226-
if err := tt.oas.BuildStream(w); (err != nil) != tt.wantErr {
227-
t.Errorf("OAS.BuildStream() error = %v, wantErr %v", err, tt.wantErr)
223+
if err := trn.oas.BuildStream(w); (err != nil) != trn.wantErr {
224+
t.Errorf("OAS.BuildStream() error = %v, wantErr %v", err, trn.wantErr)
228225
return
229226
}
230-
if gotW := w.String(); gotW != tt.wantW {
231-
t.Errorf("OAS.BuildStream() = [%v], want {%v}", gotW, tt.wantW)
227+
if gotW := w.String(); gotW != trn.wantW {
228+
t.Errorf("OAS.BuildStream() = [%v], want {%v}", gotW, trn.wantW)
229+
}
230+
})
231+
}
232+
}
233+
234+
func Test_makeParametersMap(t *testing.T) {
235+
type args struct {
236+
parameters *Parameters
237+
}
238+
tests := []struct {
239+
name string
240+
args args
241+
want []map[string]interface{}
242+
}{
243+
{
244+
name: "success-minimal",
245+
args: args{
246+
parameters: &Parameters{{
247+
Name: "id",
248+
In: "path",
249+
Description: "test",
250+
Required: true,
251+
Schema: Schema{Name: "id", Type: "integer"},
252+
}},
253+
},
254+
want: []map[string]interface{}{{
255+
"name": "id",
256+
"in": "path",
257+
"description": "test",
258+
"required": true,
259+
"schema": map[string]interface{}{"name": "id", "type": "integer"},
260+
}},
261+
},
262+
{
263+
name: "success-full",
264+
args: args{
265+
parameters: &Parameters{{
266+
Name: "id",
267+
In: "path",
268+
Description: "test",
269+
Required: true,
270+
Schema: Schema{
271+
Name: "id",
272+
Type: "integer",
273+
Properties: SchemaProperties{{Name: "id", Type: "integer"}},
274+
},
275+
}},
276+
},
277+
want: []map[string]interface{}{{
278+
"name": "id",
279+
"in": "path",
280+
"description": "test",
281+
"required": true,
282+
"schema": map[string]interface{}{"name": "id", "type": "integer",
283+
"properties": map[string]interface{}{
284+
"id": map[string]interface{}{"type": "integer"},
285+
}},
286+
}},
287+
},
288+
{
289+
name: "success-ref",
290+
args: args{
291+
parameters: &Parameters{{
292+
Name: "id",
293+
In: "path",
294+
Description: "test",
295+
Required: true,
296+
Schema: Schema{Ref: "$some-ref"},
297+
}},
298+
},
299+
want: []map[string]interface{}{{
300+
"name": "id",
301+
"in": "path",
302+
"description": "test",
303+
"required": true,
304+
"schema": map[string]interface{}{"$ref": "$some-ref"},
305+
}},
306+
},
307+
{
308+
name: "success-xml-entry",
309+
args: args{
310+
parameters: &Parameters{{
311+
Name: "id",
312+
In: "path",
313+
Description: "test",
314+
Required: true,
315+
Schema: Schema{Name: "id", Type: "integer", XML: XMLEntry{Name: "id"}},
316+
}},
317+
},
318+
want: []map[string]interface{}{{
319+
"name": "id",
320+
"in": "path",
321+
"description": "test",
322+
"required": true,
323+
"schema": map[string]interface{}{"name": "id", "type": "integer", "xml": map[string]interface{}{"name": "id"}},
324+
}},
325+
},
326+
}
327+
for _, tt := range tests {
328+
t.Run(tt.name, func(t *testing.T) {
329+
if got := makeParametersMap(tt.args.parameters); !reflect.DeepEqual(got, tt.want) {
330+
t.Errorf("makeParametersMap() = %+v, want %+v", got, tt.want)
232331
}
233332
})
234333
}

models.go

+17
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ type Path struct {
103103
RequestBody RequestBody `yaml:"requestBody"`
104104
Responses Responses `yaml:"responses"`
105105
Security SecurityEntities `yaml:"security,omitempty"`
106+
Parameters Parameters `yaml:"parameters,omitempty"`
106107
HandlerFuncName string `yaml:"-"`
107108
}
108109

@@ -210,6 +211,22 @@ type SecurityScope struct {
210211
Description string `yaml:"description,omitempty"`
211212
}
212213

214+
// Parameters
215+
type Parameters []Parameter
216+
217+
type Parameter struct {
218+
// If in is "path", the name field MUST correspond to a template expression occurring within the path field in the Paths Object. See Path Templating for further information.
219+
// If in is "header" and the name field is "Accept", "Content-Type" or "Authorization", the parameter definition SHALL be ignored.
220+
// For all other cases, the name corresponds to the parameter name used by the in property.
221+
Name string `yaml:"name,omitempty"`
222+
In string `yaml:"in,omitempty"` // "query", "header", "path" or "cookie".
223+
Description string `yaml:"description,omitempty"`
224+
Required bool `yaml:"required,omitempty"`
225+
Deprecated bool `yaml:"deprecated,omitempty"`
226+
AllowEmptyValue bool `yaml:"allowEmptyValue,omitempty"`
227+
Schema Schema
228+
}
229+
213230
// isEmpty checks if *ExternalDocs struct is empty.
214231
func (ed *ExternalDocs) isEmpty() bool {
215232
if ed == nil {

0 commit comments

Comments
 (0)