Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions fixtures/bugs/39/swagger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
swagger: "2.0"
info:
version: "1.0.0"
title: "fragment-param test"
schemes:
- http
basePath: /service
paths:
/foo/bar{fragment}.{subfragment}:
get:
description: "lookup foo with bar*.*, where * is some string"
parameters:
- name: "fragment"
in: "path"
type: string
required: true
description: "this fragment header parameter is not recognized by codegen"
- name: "subfragment"
in: "path"
type: string
required: true
description: "this subfragment header parameter is not recognized by codegen"
produces:
- text/plain
responses:
'200':
description: "Successful"
schema:
type: string
'400':
description: "Bad request"

30 changes: 27 additions & 3 deletions spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,15 @@ func (s *SpecValidator) validateParameters() *Result {
}
var fromPath []string
for _, i := range params {
fromPath = append(fromPath, knowns[i])
knowns[i] = "!"
knownsi := knowns[i]
iparams := extractPathParams(knownsi)
if len(iparams) > 0 {
fromPath = append(fromPath, iparams...)
for _, iparam := range iparams {
knownsi = strings.Replace(knownsi, iparam, "!", 1)
}
knowns[i] = knownsi
}
}
knownPath := strings.Join(knowns, "/")
if orig, ok := knownPaths[knownPath]; ok {
Expand Down Expand Up @@ -609,13 +616,30 @@ func (s *SpecValidator) validateParameters() *Result {
func parsePath(path string) (segments []string, params []int) {
for i, p := range strings.Split(path, "/") {
segments = append(segments, p)
if len(p) > 0 && p[0] == '{' && p[len(p)-1] == '}' {
if d0 := strings.Index(p, "{"); d0 >= 0 && d0 < strings.Index(p, "}") {
params = append(params, i)
}
}
return
}

func extractPathParams(segment string) (params []string) {
for {
d0 := strings.IndexByte(segment, '{')
if d0 < 0 {
break
}
d1 := strings.IndexByte(segment[d0:], '}')
if d1 > 0 {
params = append(params, segment[d0:d0+d1+1])
} else {
break
}
segment = segment[d1:]
}
return params
}

func (s *SpecValidator) validateReferencesValid() *Result {
// each reference must point to a valid object
res := new(Result)
Expand Down
16 changes: 16 additions & 0 deletions spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,22 @@ func TestIssue18(t *testing.T) {
}
}

// check if a fragment path parameter is recognized
func TestIssue39(t *testing.T) {
fp := filepath.Join("fixtures", "bugs", "39", "swagger.yml")

// as swagger spec
doc, err := loads.Spec(fp)
if assert.NoError(t, err) {
validator := NewSpecValidator(doc.Schema(), strfmt.Default)
res, _ := validator.Validate(doc)
for _, e := range res.Errors {
log.Println(e)
}
assert.True(t, res.IsValid())
}
}

func TestValidateDuplicatePropertyNames(t *testing.T) {
// simple allOf
doc, err := loads.Spec(filepath.Join("fixtures", "validation", "duplicateprops.json"))
Expand Down