From f85abf4bfd5ab9fc74d26bc5c0674fbf4bb7ff54 Mon Sep 17 00:00:00 2001 From: Ahmad Moudani Date: Tue, 18 Apr 2023 18:05:17 -0700 Subject: [PATCH 01/28] Fix #165 Signed-off-by: Ahmad Moudani --- responses.go | 27 +++++++--- responses_test.go | 133 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 responses_test.go diff --git a/responses.go b/responses.go index 4efb6f8..16c3076 100644 --- a/responses.go +++ b/responses.go @@ -19,6 +19,7 @@ import ( "fmt" "reflect" "strconv" + "strings" "github.com/go-openapi/swag" ) @@ -62,6 +63,7 @@ func (r *Responses) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &r.ResponsesProps); err != nil { return err } + if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { return err } @@ -107,20 +109,31 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals responses from JSON func (r *ResponsesProps) UnmarshalJSON(data []byte) error { - var res map[string]Response + var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { - return nil + return err } + if v, ok := res["default"]; ok { - r.Default = &v + var defaultRes Response + if err := json.Unmarshal(v, &defaultRes); err != nil { + return err + } + r.Default = &defaultRes delete(res, "default") } for k, v := range res { - if nk, err := strconv.Atoi(k); err == nil { - if r.StatusCodeResponses == nil { - r.StatusCodeResponses = map[int]Response{} + if !strings.HasPrefix(k, "x-") { + var statusCodeResp Response + if err := json.Unmarshal(v, &statusCodeResp); err != nil { + return err + } + if nk, err := strconv.Atoi(k); err == nil { + if r.StatusCodeResponses == nil { + r.StatusCodeResponses = map[int]Response{} + } + r.StatusCodeResponses[nk] = statusCodeResp } - r.StatusCodeResponses[nk] = v } } return nil diff --git a/responses_test.go b/responses_test.go new file mode 100644 index 0000000..746575f --- /dev/null +++ b/responses_test.go @@ -0,0 +1,133 @@ +// Copyright 2017 go-swagger maintainers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spec + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +var responses = Responses{ + VendorExtensible: VendorExtensible{ + Extensions: map[string]interface{}{ + "x-go-name": "PutDogExists", + }, + }, + ResponsesProps: ResponsesProps{ + StatusCodeResponses: map[int]Response{ + 200: { + Refable: Refable{Ref: MustCreateRef("Dog")}, + VendorExtensible: VendorExtensible{ + Extensions: map[string]interface{}{ + "x-go-name": "PutDogExists", + }, + }, + ResponseProps: ResponseProps{ + Description: "Dog exists", + Schema: &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}}, + }, + }, + }, + }, +} + +const responsesJSON = `{ + "x-go-name": "PutDogExists", + "200": { + "$ref": "Dog", + "x-go-name": "PutDogExists", + "description": "Dog exists", + "schema": { + "type": "string" + } + } +}` + +func TestIntegrationResponses(t *testing.T) { + var actual Responses + if assert.NoError(t, json.Unmarshal([]byte(responsesJSON), &actual)) { + assert.EqualValues(t, actual, responses) + } + + assertParsesJSON(t, responsesJSON, responses) +} + +func TestJSONLookupResponses(t *testing.T) { + resp200, ok := responses.StatusCodeResponses[200] + if !assert.True(t, ok) { + t.FailNow() + return + } + + res, err := resp200.JSONLookup("$ref") + if !assert.NoError(t, err) { + t.FailNow() + return + } + if assert.IsType(t, &Ref{}, res) { + ref := res.(*Ref) + assert.EqualValues(t, MustCreateRef("Dog"), *ref) + } + + var def string + res, err = resp200.JSONLookup("description") + if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, def, res) { + t.FailNow() + return + } + def = res.(string) + assert.Equal(t, "Dog exists", def) + + var x *interface{} + res, err = responses.JSONLookup("x-go-name") + if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, x, res) { + t.FailNow() + return + } + + x = res.(*interface{}) + assert.EqualValues(t, "PutDogExists", *x) + + res, err = responses.JSONLookup("unknown") + if !assert.Error(t, err) || !assert.Nil(t, res) { + t.FailNow() + return + } +} + +func TestResponsesBuild(t *testing.T) { + resp := NewResponse(). + WithDescription("some response"). + WithSchema(new(Schema).Typed("object", "")). + AddHeader("x-header", ResponseHeader().Typed("string", "")). + AddExample("application/json", `{"key":"value"}`) + jazon, _ := json.MarshalIndent(resp, "", " ") + assert.JSONEq(t, `{ + "description": "some response", + "schema": { + "type": "object" + }, + "headers": { + "x-header": { + "type": "string" + } + }, + "examples": { + "application/json": "{\"key\":\"value\"}" + } + }`, string(jazon)) +} From b123375b48daebf61f70cd51443f95c51e4b64eb Mon Sep 17 00:00:00 2001 From: ChandanChainani Date: Mon, 6 Mar 2023 12:29:12 +0530 Subject: [PATCH 02/28] Fix `x-order` not working with number value #162 Signed-off-by: ChandanChainani --- info.go | 19 +++++++++++++++++++ properties.go | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/info.go b/info.go index c458b49..582f0fd 100644 --- a/info.go +++ b/info.go @@ -16,6 +16,7 @@ package spec import ( "encoding/json" + "strconv" "strings" "github.com/go-openapi/jsonpointer" @@ -40,6 +41,24 @@ func (e Extensions) GetString(key string) (string, bool) { return "", false } +// GetInt gets a int value from the extensions +func (e Extensions) GetInt(key string) (int, bool) { + realKey := strings.ToLower(key) + + if v, ok := e.GetString(realKey); ok { + if r, err := strconv.Atoi(v); err == nil { + return r, true + } + } + + if v, ok := e[realKey]; ok { + if r, rOk := v.(float64); rOk { + return int(r), true + } + } + return -1, false +} + // GetBool gets a string value from the extensions func (e Extensions) GetBool(key string) (bool, bool) { if v, ok := e[strings.ToLower(key)]; ok { diff --git a/properties.go b/properties.go index 2af1378..91d2435 100644 --- a/properties.go +++ b/properties.go @@ -42,8 +42,8 @@ func (items OrderSchemaItems) MarshalJSON() ([]byte, error) { func (items OrderSchemaItems) Len() int { return len(items) } func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] } func (items OrderSchemaItems) Less(i, j int) (ret bool) { - ii, oki := items[i].Extensions.GetString("x-order") - ij, okj := items[j].Extensions.GetString("x-order") + ii, oki := items[i].Extensions.GetInt("x-order") + ij, okj := items[j].Extensions.GetInt("x-order") if oki { if okj { defer func() { @@ -56,7 +56,7 @@ func (items OrderSchemaItems) Less(i, j int) (ret bool) { ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String() } }() - return reflect.ValueOf(ii).Int() < reflect.ValueOf(ij).Int() + return ii < ij } return true } else if okj { From 32e224fa44f2606581f73b07fc83caeba482f5f1 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Thu, 30 Nov 2023 14:39:29 +0100 Subject: [PATCH 03/28] fixed json unmarshal for BoolOrSchema According to the json draft 4 (or later) spec, empty schema is equivalent to true. * checked with the OP's test case (spec expansion) * added unit test * fixes #148 Signed-off-by: Frederic BIDON --- expander_test.go | 31 +++++++++++++++++++++++++++++++ fixtures/bugs/schema-148.json | 10 ++++++++++ swagger.go | 4 ++-- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 fixtures/bugs/schema-148.json diff --git a/expander_test.go b/expander_test.go index 471b567..087dfab 100644 --- a/expander_test.go +++ b/expander_test.go @@ -42,6 +42,37 @@ var ( specs = filepath.Join("fixtures", "specs") ) +func TestExpand_Issue148(t *testing.T) { + fp := filepath.Join("fixtures", "bugs", "schema-148.json") + b, err := jsonDoc(fp) + require.NoError(t, err) + + assertAdditionalProps := func(sp Swagger) func(*testing.T) { + return func(t *testing.T) { + require.Len(t, sp.Definitions, 2) + + require.Contains(t, sp.Definitions, "empty") + empty := sp.Definitions["empty"] + require.NotNil(t, empty.AdditionalProperties) + require.NotNil(t, empty.AdditionalProperties.Schema) + require.True(t, empty.AdditionalProperties.Allows) + + require.Contains(t, sp.Definitions, "false") + additionalIsFalse := sp.Definitions["false"] + require.NotNil(t, additionalIsFalse.AdditionalProperties) + require.Nil(t, additionalIsFalse.AdditionalProperties.Schema) + require.False(t, additionalIsFalse.AdditionalProperties.Allows) + } + } + + var sp Swagger + require.NoError(t, json.Unmarshal(b, &sp)) + t.Run("check additional properties", assertAdditionalProps(sp)) + + require.NoError(t, ExpandSpec(&sp, nil)) + t.Run("check additional properties after expansion", assertAdditionalProps(sp)) +} + func TestExpand_KnownRef(t *testing.T) { // json schema draft 4 meta schema is embedded by default: it resolves without setup schema := RefProperty("http://json-schema.org/draft-04/schema#") diff --git a/fixtures/bugs/schema-148.json b/fixtures/bugs/schema-148.json new file mode 100644 index 0000000..a233257 --- /dev/null +++ b/fixtures/bugs/schema-148.json @@ -0,0 +1,10 @@ +{ + "definitions": { + "empty": { + "additionalProperties": {} + }, + "false": { + "additionalProperties": false + } + } +} diff --git a/swagger.go b/swagger.go index 44722ff..1590fd1 100644 --- a/swagger.go +++ b/swagger.go @@ -253,7 +253,7 @@ func (s SchemaOrBool) MarshalJSON() ([]byte, error) { // UnmarshalJSON converts this bool or schema object from a JSON structure func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { var nw SchemaOrBool - if len(data) >= 4 { + if len(data) > 0 { if data[0] == '{' { var sch Schema if err := json.Unmarshal(data, &sch); err != nil { @@ -261,7 +261,7 @@ func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { } nw.Schema = &sch } - nw.Allows = !(data[0] == 'f' && data[1] == 'a' && data[2] == 'l' && data[3] == 's' && data[4] == 'e') + nw.Allows = !bytes.Equal(data, []byte("false")) } *s = nw return nil From d8ccc3636a330f1a20e3b7e6c6141ebefd415bbd Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Thu, 30 Nov 2023 16:27:23 +0100 Subject: [PATCH 04/28] ci: re-enacted linting * re-enacted golangci-lint run in github action * re-enacted codecov uploads in github action Signed-off-by: Frederic BIDON --- .github/workflows/go-test.yml | 43 ++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 79a485c..e1a95c7 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -1,23 +1,50 @@ -name: Go Test +name: go test on: [push, pull_request] jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: stable + check-latest: true + cache: true + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest + only-new-issues: true test: - - name: Test + name: Unit tests runs-on: ${{ matrix.os }} strategy: matrix: os: [ ubuntu-latest, macos-latest, windows-latest ] - steps: + go_version: ['oldstable', 'stable' ] - - uses: actions/setup-go@v2 + steps: + - name: Run unit tests + uses: actions/setup-go@v4 with: - go-version: 1.x + go-version: '${{ matrix.go_version }}' + check-latest: true + cache: true + + - uses: actions/checkout@v3 - - uses: actions/checkout@v2 + - run: go test -v -race -coverprofile="coverage-${{ matrix.os }}.${{ matrix.go_version }}.out" -covermode=atomic ./... - - run: go test + - name: Upload coverage to codecov + uses: codecov/codecov-action@v3 + with: + files: './coverage-${{ matrix.os }}.${{ matrix.go_version }}.out' + flags: '${{ matrix.go_version }}' + os: '${{ matrix.os }}' + fail_ci_if_error: false + verbose: true From 0da2f93109bbb1035ab116280bca183753cb3ac6 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Thu, 30 Nov 2023 18:43:02 +0100 Subject: [PATCH 05/28] chore: updated linting config, relinted * updated linter config * refactored tests: if !assert => require * fixed a few other linting issues other than test code: x := append(y, z...), typos Signed-off-by: Frederic BIDON --- .golangci.yml | 21 ++- circular_test.go | 4 +- contact_info_test.go | 11 +- expander.go | 1 - expander_test.go | 10 +- header_test.go | 49 +++---- helpers_spec_test.go | 2 +- helpers_test.go | 2 +- info_test.go | 19 +-- items_test.go | 52 ++++---- license_test.go | 11 +- normalizer_nonwindows.go | 2 +- normalizer_test.go | 11 +- operation.go | 5 +- operation_test.go | 86 ++++++------- parameter.go | 42 +++--- parameters_test.go | 10 +- path_item_test.go | 6 +- paths_test.go | 6 +- ref_test.go | 19 ++- resolver_test.go | 2 +- response_test.go | 53 ++++---- responses_test.go | 53 ++++---- schema_test.go | 95 +++++++------- spec.go | 2 +- structs_test.go | 6 +- swagger_test.go | 267 +++++++++++++++++++-------------------- validations_test.go | 1 - xml_object_test.go | 36 +++--- 29 files changed, 434 insertions(+), 450 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 835d55e..22f8d21 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -11,7 +11,7 @@ linters-settings: threshold: 200 goconst: min-len: 2 - min-occurrences: 2 + min-occurrences: 3 linters: enable-all: true @@ -40,3 +40,22 @@ linters: - tparallel - thelper - ifshort + - exhaustruct + - varnamelen + - gci + - depguard + - errchkjson + - inamedparam + - nonamedreturns + - musttag + - ireturn + - forcetypeassert + - cyclop + # deprecated linters + - deadcode + - interfacer + - scopelint + - varcheck + - structcheck + - golint + - nosnakecase diff --git a/circular_test.go b/circular_test.go index 90bc6d2..3dbb45a 100644 --- a/circular_test.go +++ b/circular_test.go @@ -219,7 +219,7 @@ func TestExpandCircular_SpecExpansion(t *testing.T) { func TestExpandCircular_RemoteCircularID(t *testing.T) { go func() { - err := http.ListenAndServe("localhost:1234", http.FileServer(http.Dir("fixtures/more_circulars/remote"))) + err := http.ListenAndServe("localhost:1234", http.FileServer(http.Dir("fixtures/more_circulars/remote"))) //#nosec if err != nil { panic(err.Error()) } @@ -232,7 +232,7 @@ func TestExpandCircular_RemoteCircularID(t *testing.T) { assertRefResolve(t, jazon, "", root, &ExpandOptions{RelativeBase: fixturePath}) assertRefExpand(t, jazon, "", root, &ExpandOptions{RelativeBase: fixturePath}) - assert.NoError(t, ExpandSchemaWithBasePath(root, nil, &ExpandOptions{})) + require.NoError(t, ExpandSchemaWithBasePath(root, nil, &ExpandOptions{})) jazon = asJSON(t, root) diff --git a/contact_info_test.go b/contact_info_test.go index 3ca2315..fedd81a 100644 --- a/contact_info_test.go +++ b/contact_info_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const contactInfoJSON = `{ @@ -36,13 +37,11 @@ var contactInfo = ContactInfo{ContactInfoProps: ContactInfoProps{ func TestIntegrationContactInfo(t *testing.T) { b, err := json.MarshalIndent(contactInfo, "", "\t") - if assert.NoError(t, err) { - assert.Equal(t, contactInfoJSON, string(b)) - } + require.NoError(t, err) + assert.Equal(t, contactInfoJSON, string(b)) actual := ContactInfo{} err = json.Unmarshal([]byte(contactInfoJSON), &actual) - if assert.NoError(t, err) { - assert.EqualValues(t, contactInfo, actual) - } + require.NoError(t, err) + assert.EqualValues(t, contactInfo, actual) } diff --git a/expander.go b/expander.go index d4ea889..012a462 100644 --- a/expander.go +++ b/expander.go @@ -27,7 +27,6 @@ import ( // all relative $ref's will be resolved from there. // // PathLoader injects a document loading method. By default, this resolves to the function provided by the SpecLoader package variable. -// type ExpandOptions struct { RelativeBase string // the path to the root document to expand. This is a file, not a directory SkipSchemas bool // do not expand schemas, just paths, parameters and responses diff --git a/expander_test.go b/expander_test.go index 471b567..b044e71 100644 --- a/expander_test.go +++ b/expander_test.go @@ -353,7 +353,7 @@ func TestExpand_ContinueOnError(t *testing.T) { // missing $ref in spec missingRefDoc, err := jsonDoc(specPath) - assert.NoError(t, err) + require.NoError(t, err) testCase := struct { Input *Swagger `json:"input"` @@ -367,7 +367,7 @@ func TestExpand_ContinueOnError(t *testing.T) { } require.NoError(t, ExpandSpec(testCase.Input, opts)) - assert.Equal(t, testCase.Input, testCase.Expected, "Should continue expanding spec when a definition can't be found.") + assert.Equal(t, testCase.Expected, testCase.Input, "Should continue expanding spec when a definition can't be found.") // missing $ref in items doc, err := jsonDoc("fixtures/expansion/missingItemRef.json") @@ -791,7 +791,7 @@ func resolutionContextServer() *httptest.Server { ctnt["id"] = servedAt rw.Header().Set("Content-Type", "application/json") - rw.WriteHeader(200) + rw.WriteHeader(http.StatusOK) bb, _ := json.Marshal(ctnt) _, _ = rw.Write(bb) return @@ -803,7 +803,6 @@ func resolutionContextServer() *httptest.Server { ctnt["id"] = servedAt rw.Header().Set("Content-Type", "application/json") - rw.WriteHeader(200) bb, _ := json.Marshal(ctnt) _, _ = rw.Write(bb) return @@ -811,7 +810,6 @@ func resolutionContextServer() *httptest.Server { if req.URL.Path == "/boolProp.json" { rw.Header().Set("Content-Type", "application/json") - rw.WriteHeader(200) b, _ := json.Marshal(map[string]interface{}{ "type": "boolean", }) @@ -821,7 +819,6 @@ func resolutionContextServer() *httptest.Server { if req.URL.Path == "/deeper/stringProp.json" { rw.Header().Set("Content-Type", "application/json") - rw.WriteHeader(200) b, _ := json.Marshal(map[string]interface{}{ "type": "string", }) @@ -831,7 +828,6 @@ func resolutionContextServer() *httptest.Server { if req.URL.Path == "/deeper/arrayProp.json" { rw.Header().Set("Content-Type", "application/json") - rw.WriteHeader(200) b, _ := json.Marshal(map[string]interface{}{ "type": "array", "items": map[string]interface{}{ diff --git a/header_test.go b/header_test.go index 19d08cc..67a893a 100644 --- a/header_test.go +++ b/header_test.go @@ -20,8 +20,11 @@ import ( "github.com/go-openapi/swag" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) +const epsilon = 1e-9 + func float64Ptr(f float64) *float64 { return &f } @@ -83,9 +86,8 @@ const headerJSON = `{ func TestIntegrationHeader(t *testing.T) { var actual Header - if assert.NoError(t, json.Unmarshal([]byte(headerJSON), &actual)) { - assert.EqualValues(t, actual, header) - } + require.NoError(t, json.Unmarshal([]byte(headerJSON), &actual)) + assert.EqualValues(t, actual, header) assertParsesJSON(t, headerJSON, header) } @@ -93,37 +95,38 @@ func TestIntegrationHeader(t *testing.T) { func TestJSONLookupHeader(t *testing.T) { var def string res, err := header.JSONLookup("default") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, def, res) { - t.FailNow() - return - } - def = res.(string) + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, def, res) + + var ok bool + def, ok = res.(string) + require.True(t, ok) assert.Equal(t, "8", def) var x *interface{} res, err = header.JSONLookup("x-framework") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, x, res) { - t.FailNow() - return - } + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, x, res) - x = res.(*interface{}) + x, ok = res.(*interface{}) + require.True(t, ok) assert.EqualValues(t, "swagger-go", *x) res, err = header.JSONLookup("unknown") - if !assert.Error(t, err) || !assert.Nil(t, res) { - t.FailNow() - return - } + require.Error(t, err) + require.Nil(t, res) var max *float64 res, err = header.JSONLookup("maximum") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, max, res) { - t.FailNow() - return - } - max = res.(*float64) - assert.Equal(t, float64(100), *max) + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, max, res) + + max, ok = res.(*float64) + require.True(t, ok) + assert.InDelta(t, float64(100), *max, epsilon) } func TestResponseHeaueder(t *testing.T) { diff --git a/helpers_spec_test.go b/helpers_spec_test.go index 40fa75b..4dd12c5 100644 --- a/helpers_spec_test.go +++ b/helpers_spec_test.go @@ -71,7 +71,7 @@ func assertRefInJSONRegexp(t testing.TB, jazon, match string) { // assertRefExpand ensures that all $ref in some json doc expand properly against a root document. // // "exclude" is a regexp pattern to ignore certain $ref (e.g. some specs may embed $ref that are not processed, such as extensions). -func assertRefExpand(t *testing.T, jazon, exclude string, root interface{}, opts ...*spec.ExpandOptions) { +func assertRefExpand(t *testing.T, jazon, _ string, root interface{}, opts ...*spec.ExpandOptions) { if len(opts) > 0 { assertRefWithFunc(t, "expand-with-base", jazon, "", func(t *testing.T, match string) { ref := spec.RefSchema(match) diff --git a/helpers_test.go b/helpers_test.go index 0d54150..f16a4dd 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -105,7 +105,7 @@ func assertNoRef(t testing.TB, jazon string) { // assertRefExpand ensures that all $ref in some json doc expand properly against a root document. // // "exclude" is a regexp pattern to ignore certain $ref (e.g. some specs may embed $ref that are not processed, such as extensions). -func assertRefExpand(t *testing.T, jazon, exclude string, root interface{}, opts ...*ExpandOptions) { +func assertRefExpand(t *testing.T, jazon, _ string, root interface{}, opts ...*ExpandOptions) { assertRefWithFunc(t, jazon, "", func(t *testing.T, match string) { ref := RefSchema(match) if len(opts) > 0 { diff --git a/info_test.go b/info_test.go index 5ecf1bb..a8e3fbe 100644 --- a/info_test.go +++ b/info_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const infoJSON = `{ @@ -57,25 +58,19 @@ var info = Info{ func TestIntegrationInfo_Serialize(t *testing.T) { b, err := json.MarshalIndent(info, "", "\t") - if assert.NoError(t, err) { - assert.Equal(t, infoJSON, string(b)) - } + require.NoError(t, err) + assert.Equal(t, infoJSON, string(b)) } func TestIntegrationInfo_Deserialize(t *testing.T) { actual := Info{} - err := json.Unmarshal([]byte(infoJSON), &actual) - if assert.NoError(t, err) { - assert.EqualValues(t, info, actual) - } + require.NoError(t, json.Unmarshal([]byte(infoJSON), &actual)) + assert.EqualValues(t, info, actual) } func TestInfoGobEncoding(t *testing.T) { var src, dst Info - if assert.NoError(t, json.Unmarshal([]byte(infoJSON), &src)) { - assert.EqualValues(t, src, info) - } else { - t.FailNow() - } + require.NoError(t, json.Unmarshal([]byte(infoJSON), &src)) + assert.EqualValues(t, src, info) doTestAnyGobEncoding(t, &src, &dst) } diff --git a/items_test.go b/items_test.go index edd75c2..4d4e458 100644 --- a/items_test.go +++ b/items_test.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var items = Items{ @@ -74,9 +75,8 @@ const itemsJSON = `{ func TestIntegrationItems(t *testing.T) { var actual Items - if assert.NoError(t, json.Unmarshal([]byte(itemsJSON), &actual)) { - assert.EqualValues(t, actual, items) - } + require.NoError(t, json.Unmarshal([]byte(itemsJSON), &actual)) + assert.EqualValues(t, actual, items) assertParsesJSON(t, itemsJSON, items) } @@ -152,38 +152,38 @@ func TestItemsBuilder(t *testing.T) { func TestJSONLookupItems(t *testing.T) { res, err := items.JSONLookup("$ref") - if !assert.NoError(t, err) { - t.FailNow() - return - } - if assert.IsType(t, &Ref{}, res) { - ref := res.(*Ref) - assert.EqualValues(t, MustCreateRef("Dog"), *ref) - } + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, &Ref{}, res) + + var ok bool + ref, ok := res.(*Ref) + require.True(t, ok) + assert.EqualValues(t, MustCreateRef("Dog"), *ref) var max *float64 res, err = items.JSONLookup("maximum") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, max, res) { - t.FailNow() - return - } - max = res.(*float64) - assert.Equal(t, float64(100), *max) + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, max, res) + + max, ok = res.(*float64) + require.True(t, ok) + assert.InDelta(t, float64(100), *max, epsilon) var f string res, err = items.JSONLookup("collectionFormat") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, f, res) { - t.FailNow() - return - } - f = res.(string) + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, f, res) + + f, ok = res.(string) + require.True(t, ok) assert.Equal(t, "csv", f) res, err = items.JSONLookup("unknown") - if !assert.Error(t, err) || !assert.Nil(t, res) { - t.FailNow() - return - } + require.Error(t, err) + require.Nil(t, res) } func TestItemsWithValidation(t *testing.T) { diff --git a/license_test.go b/license_test.go index 407df73..398f0d8 100644 --- a/license_test.go +++ b/license_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var license = License{ @@ -36,13 +37,11 @@ func TestIntegrationLicense(t *testing.T) { // const licenseYAML = "name: the name\nurl: the url\n" b, err := json.MarshalIndent(license, "", "\t") - if assert.NoError(t, err) { - assert.Equal(t, licenseJSON, string(b)) - } + require.NoError(t, err) + assert.Equal(t, licenseJSON, string(b)) actual := License{} err = json.Unmarshal([]byte(licenseJSON), &actual) - if assert.NoError(t, err) { - assert.EqualValues(t, license, actual) - } + require.NoError(t, err) + assert.EqualValues(t, license, actual) } diff --git a/normalizer_nonwindows.go b/normalizer_nonwindows.go index 2df0723..f19f1a8 100644 --- a/normalizer_nonwindows.go +++ b/normalizer_nonwindows.go @@ -40,5 +40,5 @@ func repairURI(in string) (*url.URL, string) { return u, "" } -func fixWindowsURI(u *url.URL, in string) { +func fixWindowsURI(_ *url.URL, _ string) { } diff --git a/normalizer_test.go b/normalizer_test.go index b152297..66f30bf 100644 --- a/normalizer_test.go +++ b/normalizer_test.go @@ -245,6 +245,7 @@ func TestNormalizer_NormalizeBase(t *testing.T) { if runtime.GOOS == windowsOS { cwd = "/" + strings.ToLower(filepath.ToSlash(cwd)) } + const fileScheme = "file:///" for _, toPin := range []struct { Base, Expected string @@ -317,7 +318,7 @@ func TestNormalizer_NormalizeBase(t *testing.T) { { // path clean Base: "///folder//subfolder///file.json/", - Expected: "file:///" + currentDriveLetter + ":/folder/subfolder/file.json", + Expected: fileScheme + currentDriveLetter + ":/folder/subfolder/file.json", Windows: true, }, { @@ -344,18 +345,18 @@ func TestNormalizer_NormalizeBase(t *testing.T) { { // handling dots (3/6): valid, cleaned to /c:/ on windows Base: "/..", - Expected: "file:///" + currentDriveLetter + ":", + Expected: fileScheme + currentDriveLetter + ":", Windows: true, }, { // handling dots (4/6): dodgy specification - resolved to / Base: `file:/.`, - Expected: "file:///", + Expected: fileScheme, }, { // handling dots (5/6): dodgy specification - resolved to / Base: `file:/..`, - Expected: "file:///", + Expected: fileScheme, }, { // handling dots (6/6) @@ -377,7 +378,7 @@ func TestNormalizer_NormalizeBase(t *testing.T) { // windows-only cases { Base: "/base/sub/file.json", - Expected: "file:///" + currentDriveLetter + ":/base/sub/file.json", // on windows, filepath.Abs("/a/b") prepends the "c:" drive + Expected: fileScheme + currentDriveLetter + ":/base/sub/file.json", // on windows, filepath.Abs("/a/b") prepends the "c:" drive Windows: true, }, { diff --git a/operation.go b/operation.go index 995ce6a..a69cca8 100644 --- a/operation.go +++ b/operation.go @@ -217,9 +217,12 @@ func (o *Operation) AddParam(param *Parameter) *Operation { for i, p := range o.Parameters { if p.Name == param.Name && p.In == param.In { - params := append(o.Parameters[:i], *param) + params := make([]Parameter, 0, len(o.Parameters)+1) + params = append(params, o.Parameters[:i]...) + params = append(params, *param) params = append(params, o.Parameters[i+1:]...) o.Parameters = params + return o } } diff --git a/operation_test.go b/operation_test.go index 812cdda..495f609 100644 --- a/operation_test.go +++ b/operation_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var operation = Operation{ @@ -82,30 +83,28 @@ func TestSuccessResponse(t *testing.T) { resp, n, f := ope.SuccessResponse() assert.Nil(t, resp) assert.Equal(t, 0, n) - assert.Equal(t, false, f) + assert.False(t, f) resp, n, f = operation.SuccessResponse() - if assert.NotNil(t, resp) { - assert.Equal(t, "void response", resp.Description) - } + require.NotNil(t, resp) + assert.Equal(t, "void response", resp.Description) + assert.Equal(t, 0, n) - assert.Equal(t, false, f) + assert.False(t, f) + + require.NoError(t, json.Unmarshal([]byte(operationJSON), ope)) - err := json.Unmarshal([]byte(operationJSON), ope) - if !assert.Nil(t, err) { - t.FailNow() - } ope = ope.RespondsWith(301, &Response{ ResponseProps: ResponseProps{ Description: "failure", }, }) resp, n, f = ope.SuccessResponse() - if assert.NotNil(t, resp) { - assert.Equal(t, "void response", resp.Description) - } + require.NotNil(t, resp) + assert.Equal(t, "void response", resp.Description) + assert.Equal(t, 0, n) - assert.Equal(t, false, f) + assert.False(t, f) ope = ope.RespondsWith(200, &Response{ ResponseProps: ResponseProps{ @@ -114,11 +113,11 @@ func TestSuccessResponse(t *testing.T) { }) resp, n, f = ope.SuccessResponse() - if assert.NotNil(t, resp) { - assert.Equal(t, "success", resp.Description) - } + require.NotNil(t, resp) + assert.Equal(t, "success", resp.Description) + assert.Equal(t, 200, n) - assert.Equal(t, true, f) + assert.True(t, f) } func TestOperationBuilder(t *testing.T) { @@ -146,7 +145,9 @@ func TestOperationBuilder(t *testing.T) { WithSummary("my summary"). WithExternalDocs("some doc", "https://www.example.com") - jazon, _ := json.MarshalIndent(ope, "", " ") + jazon, err := json.MarshalIndent(ope, "", " ") + require.NoError(t, err) + assert.JSONEq(t, `{ "operationId": "operationID", "description": "test operation", @@ -201,8 +202,11 @@ func TestOperationBuilder(t *testing.T) { // check token lookup token, err := ope.JSONLookup("responses") - assert.NoError(t, err) - jazon, _ = json.MarshalIndent(token, "", " ") + require.NoError(t, err) + + jazon, err = json.MarshalIndent(token, "", " ") + require.NoError(t, err) + assert.JSONEq(t, `{ "200": { "description": "success" @@ -219,7 +223,9 @@ func TestOperationBuilder(t *testing.T) { RemoveParam("fakeParam", "query"). Undeprecate(). WithExternalDocs("", "") - jazon, _ = json.MarshalIndent(ope, "", " ") + jazon, err = json.MarshalIndent(ope, "", " ") + require.NoError(t, err) + assert.JSONEq(t, `{ "security": [ { @@ -252,9 +258,8 @@ func TestOperationBuilder(t *testing.T) { func TestIntegrationOperation(t *testing.T) { var actual Operation - if assert.NoError(t, json.Unmarshal([]byte(operationJSON), &actual)) { - assert.EqualValues(t, actual, operation) - } + require.NoError(t, json.Unmarshal([]byte(operationJSON), &actual)) + assert.EqualValues(t, actual, operation) assertParsesJSON(t, operationJSON, operation) } @@ -263,21 +268,19 @@ func TestSecurityProperty(t *testing.T) { // Ensure we omit security key when unset securityNotSet := OperationProps{} jsonResult, err := json.Marshal(securityNotSet) - if assert.NoError(t, err) { - assert.NotContains(t, string(jsonResult), "security", "security key should be omitted when unset") - } + require.NoError(t, err) + assert.NotContains(t, string(jsonResult), "security", "security key should be omitted when unset") // Ensure we preserve the security key when it contains an empty (zero length) slice securityContainsEmptyArray := OperationProps{ Security: []map[string][]string{}, } jsonResult, err = json.Marshal(securityContainsEmptyArray) - if assert.NoError(t, err) { - var props OperationProps - if assert.NoError(t, json.Unmarshal(jsonResult, &props)) { - assert.Equal(t, securityContainsEmptyArray, props) - } - } + require.NoError(t, err) + + var props OperationProps + require.NoError(t, json.Unmarshal(jsonResult, &props)) + assert.Equal(t, securityContainsEmptyArray, props) } func TestOperationGobEncoding(t *testing.T) { @@ -346,10 +349,7 @@ func TestOperationGobEncoding(t *testing.T) { func doTestOperationGobEncoding(t *testing.T, fixture string) { var src, dst Operation - - if !assert.NoError(t, json.Unmarshal([]byte(fixture), &src)) { - t.FailNow() - } + require.NoError(t, json.Unmarshal([]byte(fixture), &src)) doTestAnyGobEncoding(t, &src, &dst) } @@ -359,18 +359,12 @@ func doTestAnyGobEncoding(t *testing.T, src, dst interface{}) { var b bytes.Buffer err := gob.NewEncoder(&b).Encode(src) - if !assert.NoError(t, err) { - t.FailNow() - } + require.NoError(t, err) err = gob.NewDecoder(&b).Decode(dst) - if !assert.NoError(t, err) { - t.FailNow() - } + require.NoError(t, err) jazon, err := json.MarshalIndent(dst, "", " ") - if !assert.NoError(t, err) { - t.FailNow() - } + require.NoError(t, err) assert.JSONEq(t, string(expectedJSON), string(jazon)) } diff --git a/parameter.go b/parameter.go index 2b2b89b..bd4f1cd 100644 --- a/parameter.go +++ b/parameter.go @@ -84,27 +84,27 @@ type ParamProps struct { // Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn). // // There are five possible parameter types. -// * Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part -// of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, -// the path parameter is `itemId`. -// * Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`. -// * Header - Custom headers that are expected as part of the request. -// * Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be -// _one_ body parameter. The name of the body parameter has no effect on the parameter itself and is used for -// documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist -// together for the same operation. -// * Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or -// `multipart/form-data` are used as the content type of the request (in Swagger's definition, -// the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used -// to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be -// declared together with a body parameter for the same operation. Form parameters have a different format based on -// the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4). -// * `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload. -// For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple -// parameters that are being transferred. -// * `multipart/form-data` - each parameter takes a section in the payload with an internal header. -// For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is -// `submit-name`. This type of form parameters is more commonly used for file transfers. +// - Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part +// of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, +// the path parameter is `itemId`. +// - Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`. +// - Header - Custom headers that are expected as part of the request. +// - Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be +// _one_ body parameter. The name of the body parameter has no effect on the parameter itself and is used for +// documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist +// together for the same operation. +// - Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or +// `multipart/form-data` are used as the content type of the request (in Swagger's definition, +// the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used +// to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be +// declared together with a body parameter for the same operation. Form parameters have a different format based on +// the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4). +// - `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload. +// For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple +// parameters that are being transferred. +// - `multipart/form-data` - each parameter takes a section in the payload with an internal header. +// For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is +// `submit-name`. This type of form parameters is more commonly used for file transfers. // // For more information: http://goo.gl/8us55a#parameterObject type Parameter struct { diff --git a/parameters_test.go b/parameters_test.go index 0f5ad3c..702d867 100644 --- a/parameters_test.go +++ b/parameters_test.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var parameter = Parameter{ @@ -92,9 +93,8 @@ var parameterJSON = `{ func TestIntegrationParameter(t *testing.T) { var actual Parameter - if assert.NoError(t, json.Unmarshal([]byte(parameterJSON), &actual)) { - assert.EqualValues(t, actual, parameter) - } + require.NoError(t, json.Unmarshal([]byte(parameterJSON), &actual)) + assert.EqualValues(t, actual, parameter) assertParsesJSON(t, parameterJSON, parameter) } @@ -158,9 +158,7 @@ func TestParameterSerialization(t *testing.T) { func TestParameterGobEncoding(t *testing.T) { var src, dst Parameter - if !assert.NoError(t, json.Unmarshal([]byte(parameterJSON), &src)) { - t.FailNow() - } + require.NoError(t, json.Unmarshal([]byte(parameterJSON), &src)) doTestAnyGobEncoding(t, &src, &dst) } diff --git a/path_item_test.go b/path_item_test.go index 3c78e90..c3507a0 100644 --- a/path_item_test.go +++ b/path_item_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var pathItem = PathItem{ @@ -73,9 +74,8 @@ const pathItemJSON = `{ func TestIntegrationPathItem(t *testing.T) { var actual PathItem - if assert.NoError(t, json.Unmarshal([]byte(pathItemJSON), &actual)) { - assert.EqualValues(t, actual, pathItem) - } + require.NoError(t, json.Unmarshal([]byte(pathItemJSON), &actual)) + assert.EqualValues(t, actual, pathItem) assertParsesJSON(t, pathItemJSON, pathItem) } diff --git a/paths_test.go b/paths_test.go index ff5626a..4592818 100644 --- a/paths_test.go +++ b/paths_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var paths = Paths{ @@ -34,9 +35,8 @@ const pathsJSON = `{"x-framework":"go-swagger","/":{"$ref":"cats"}}` func TestIntegrationPaths(t *testing.T) { var actual Paths - if assert.NoError(t, json.Unmarshal([]byte(pathsJSON), &actual)) { - assert.EqualValues(t, actual, paths) - } + require.NoError(t, json.Unmarshal([]byte(pathsJSON), &actual)) + assert.EqualValues(t, actual, paths) assertParsesJSON(t, pathsJSON, paths) diff --git a/ref_test.go b/ref_test.go index 7dc2f59..6f4c0de 100644 --- a/ref_test.go +++ b/ref_test.go @@ -21,27 +21,24 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // pin pointing go-swagger/go-swagger#1816 issue with cloning ref's func TestCloneRef(t *testing.T) { var b bytes.Buffer src := MustCreateRef("#/definitions/test") - err := gob.NewEncoder(&b).Encode(&src) - if !assert.NoError(t, err) { - t.FailNow() - } + require.NoError(t, + gob.NewEncoder(&b).Encode(&src), + ) var dst Ref - err = gob.NewDecoder(&b).Decode(&dst) - if !assert.NoError(t, err) { - t.FailNow() - } + require.NoError(t, + gob.NewDecoder(&b).Decode(&dst), + ) jazon, err := json.Marshal(dst) - if !assert.NoError(t, err) { - t.FailNow() - } + require.NoError(t, err) assert.Equal(t, `{"$ref":"#/definitions/test"}`, string(jazon)) } diff --git a/resolver_test.go b/resolver_test.go index 21df897..7f59135 100644 --- a/resolver_test.go +++ b/resolver_test.go @@ -189,7 +189,7 @@ func TestResolveRemoteRef_FromInvalidFragment(t *testing.T) { require.NoError(t, err) resolver := defaultSchemaLoader(rootDoc, nil, nil, nil) - assert.Error(t, resolver.Resolve(&ref, &tgt, "")) + require.Error(t, resolver.Resolve(&ref, &tgt, "")) } /* This next test will have to wait until we do full $ID analysis for every subschema on every file that is referenced */ diff --git a/response_test.go b/response_test.go index 71578ab..d03720c 100644 --- a/response_test.go +++ b/response_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var response = Response{ @@ -45,48 +46,46 @@ const responseJSON = `{ func TestIntegrationResponse(t *testing.T) { var actual Response - if assert.NoError(t, json.Unmarshal([]byte(responseJSON), &actual)) { - assert.EqualValues(t, actual, response) - } + require.NoError(t, json.Unmarshal([]byte(responseJSON), &actual)) + assert.EqualValues(t, actual, response) assertParsesJSON(t, responseJSON, response) } func TestJSONLookupResponse(t *testing.T) { res, err := response.JSONLookup("$ref") - if !assert.NoError(t, err) { - t.FailNow() - return - } - if assert.IsType(t, &Ref{}, res) { - ref := res.(*Ref) - assert.EqualValues(t, MustCreateRef("Dog"), *ref) - } + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, &Ref{}, res) + + var ok bool + ref, ok := res.(*Ref) + require.True(t, ok) + assert.EqualValues(t, MustCreateRef("Dog"), *ref) var def string res, err = response.JSONLookup("description") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, def, res) { - t.FailNow() - return - } - def = res.(string) + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, def, res) + + def, ok = res.(string) + require.True(t, ok) assert.Equal(t, "Dog exists", def) var x *interface{} res, err = response.JSONLookup("x-go-name") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, x, res) { - t.FailNow() - return - } + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, x, res) - x = res.(*interface{}) + x, ok = res.(*interface{}) + require.True(t, ok) assert.EqualValues(t, "PutDogExists", *x) res, err = response.JSONLookup("unknown") - if !assert.Error(t, err) || !assert.Nil(t, res) { - t.FailNow() - return - } + require.Error(t, err) + require.Nil(t, res) } func TestResponseBuild(t *testing.T) { @@ -95,7 +94,9 @@ func TestResponseBuild(t *testing.T) { WithSchema(new(Schema).Typed("object", "")). AddHeader("x-header", ResponseHeader().Typed("string", "")). AddExample("application/json", `{"key":"value"}`) - jazon, _ := json.MarshalIndent(resp, "", " ") + jazon, err := json.MarshalIndent(resp, "", " ") + require.NoError(t, err) + assert.JSONEq(t, `{ "description": "some response", "schema": { diff --git a/responses_test.go b/responses_test.go index 746575f..fc626bf 100644 --- a/responses_test.go +++ b/responses_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var responses = Responses{ @@ -59,54 +60,48 @@ const responsesJSON = `{ func TestIntegrationResponses(t *testing.T) { var actual Responses - if assert.NoError(t, json.Unmarshal([]byte(responsesJSON), &actual)) { - assert.EqualValues(t, actual, responses) - } + require.NoError(t, json.Unmarshal([]byte(responsesJSON), &actual)) + assert.EqualValues(t, actual, responses) assertParsesJSON(t, responsesJSON, responses) } func TestJSONLookupResponses(t *testing.T) { resp200, ok := responses.StatusCodeResponses[200] - if !assert.True(t, ok) { - t.FailNow() - return - } + require.True(t, ok) res, err := resp200.JSONLookup("$ref") - if !assert.NoError(t, err) { - t.FailNow() - return - } - if assert.IsType(t, &Ref{}, res) { - ref := res.(*Ref) - assert.EqualValues(t, MustCreateRef("Dog"), *ref) - } + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, &Ref{}, res) + + ref, ok := res.(*Ref) + require.True(t, ok) + assert.EqualValues(t, MustCreateRef("Dog"), *ref) var def string res, err = resp200.JSONLookup("description") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, def, res) { - t.FailNow() - return - } - def = res.(string) + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, def, res) + + def, ok = res.(string) + require.True(t, ok) assert.Equal(t, "Dog exists", def) var x *interface{} res, err = responses.JSONLookup("x-go-name") - if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, x, res) { - t.FailNow() - return - } + require.NoError(t, err) + require.NotNil(t, res) + require.IsType(t, x, res) - x = res.(*interface{}) + x, ok = res.(*interface{}) + require.True(t, ok) assert.EqualValues(t, "PutDogExists", *x) res, err = responses.JSONLookup("unknown") - if !assert.Error(t, err) || !assert.Nil(t, res) { - t.FailNow() - return - } + require.Error(t, err) + require.Nil(t, res) } func TestResponsesBuild(t *testing.T) { diff --git a/schema_test.go b/schema_test.go index 110764e..038284c 100644 --- a/schema_test.go +++ b/schema_test.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var schema = Schema{ @@ -153,56 +154,56 @@ func TestSchema(t *testing.T) { expected := map[string]interface{}{} _ = json.Unmarshal([]byte(schemaJSON), &expected) b, err := json.Marshal(schema) - if assert.NoError(t, err) { - var actual map[string]interface{} - _ = json.Unmarshal(b, &actual) - assert.Equal(t, expected, actual) - } + require.NoError(t, err) + + var actual map[string]interface{} + require.NoError(t, json.Unmarshal(b, &actual)) + assert.Equal(t, expected, actual) actual2 := Schema{} - if assert.NoError(t, json.Unmarshal([]byte(schemaJSON), &actual2)) { - assert.Equal(t, schema.Ref, actual2.Ref) - assert.Equal(t, schema.Description, actual2.Description) - assert.Equal(t, schema.Maximum, actual2.Maximum) - assert.Equal(t, schema.Minimum, actual2.Minimum) - assert.Equal(t, schema.ExclusiveMinimum, actual2.ExclusiveMinimum) - assert.Equal(t, schema.ExclusiveMaximum, actual2.ExclusiveMaximum) - assert.Equal(t, schema.MaxLength, actual2.MaxLength) - assert.Equal(t, schema.MinLength, actual2.MinLength) - assert.Equal(t, schema.Pattern, actual2.Pattern) - assert.Equal(t, schema.MaxItems, actual2.MaxItems) - assert.Equal(t, schema.MinItems, actual2.MinItems) - assert.True(t, actual2.UniqueItems) - assert.Equal(t, schema.MultipleOf, actual2.MultipleOf) - assert.Equal(t, schema.Enum, actual2.Enum) - assert.Equal(t, schema.Type, actual2.Type) - assert.Equal(t, schema.Format, actual2.Format) - assert.Equal(t, schema.Title, actual2.Title) - assert.Equal(t, schema.MaxProperties, actual2.MaxProperties) - assert.Equal(t, schema.MinProperties, actual2.MinProperties) - assert.Equal(t, schema.Required, actual2.Required) - assert.Equal(t, schema.Items, actual2.Items) - assert.Equal(t, schema.AllOf, actual2.AllOf) - assert.Equal(t, schema.Properties, actual2.Properties) - assert.Equal(t, schema.Discriminator, actual2.Discriminator) - assert.Equal(t, schema.ReadOnly, actual2.ReadOnly) - assert.Equal(t, schema.XML, actual2.XML) - assert.Equal(t, schema.ExternalDocs, actual2.ExternalDocs) - assert.Equal(t, schema.AdditionalProperties, actual2.AdditionalProperties) - assert.Equal(t, schema.Extensions, actual2.Extensions) - examples := actual2.Example.([]interface{}) - expEx := schema.Example.([]interface{}) - ex1 := examples[0].(map[string]interface{}) - ex2 := examples[1].(map[string]interface{}) - exp1 := expEx[0].(map[string]interface{}) - exp2 := expEx[1].(map[string]interface{}) - - assert.EqualValues(t, exp1["id"], ex1["id"]) - assert.Equal(t, exp1["name"], ex1["name"]) - assert.EqualValues(t, exp2["id"], ex2["id"]) - assert.Equal(t, exp2["name"], ex2["name"]) - } + require.NoError(t, json.Unmarshal([]byte(schemaJSON), &actual2)) + + assert.Equal(t, schema.Ref, actual2.Ref) + assert.Equal(t, schema.Description, actual2.Description) + assert.Equal(t, schema.Maximum, actual2.Maximum) + assert.Equal(t, schema.Minimum, actual2.Minimum) + assert.Equal(t, schema.ExclusiveMinimum, actual2.ExclusiveMinimum) + assert.Equal(t, schema.ExclusiveMaximum, actual2.ExclusiveMaximum) + assert.Equal(t, schema.MaxLength, actual2.MaxLength) + assert.Equal(t, schema.MinLength, actual2.MinLength) + assert.Equal(t, schema.Pattern, actual2.Pattern) + assert.Equal(t, schema.MaxItems, actual2.MaxItems) + assert.Equal(t, schema.MinItems, actual2.MinItems) + assert.True(t, actual2.UniqueItems) + assert.Equal(t, schema.MultipleOf, actual2.MultipleOf) + assert.Equal(t, schema.Enum, actual2.Enum) + assert.Equal(t, schema.Type, actual2.Type) + assert.Equal(t, schema.Format, actual2.Format) + assert.Equal(t, schema.Title, actual2.Title) + assert.Equal(t, schema.MaxProperties, actual2.MaxProperties) + assert.Equal(t, schema.MinProperties, actual2.MinProperties) + assert.Equal(t, schema.Required, actual2.Required) + assert.Equal(t, schema.Items, actual2.Items) + assert.Equal(t, schema.AllOf, actual2.AllOf) + assert.Equal(t, schema.Properties, actual2.Properties) + assert.Equal(t, schema.Discriminator, actual2.Discriminator) + assert.Equal(t, schema.ReadOnly, actual2.ReadOnly) + assert.Equal(t, schema.XML, actual2.XML) + assert.Equal(t, schema.ExternalDocs, actual2.ExternalDocs) + assert.Equal(t, schema.AdditionalProperties, actual2.AdditionalProperties) + assert.Equal(t, schema.Extensions, actual2.Extensions) + + examples := actual2.Example.([]interface{}) + expEx := schema.Example.([]interface{}) + ex1 := examples[0].(map[string]interface{}) + ex2 := examples[1].(map[string]interface{}) + exp1 := expEx[0].(map[string]interface{}) + exp2 := expEx[1].(map[string]interface{}) + assert.EqualValues(t, exp1["id"], ex1["id"]) + assert.Equal(t, exp1["name"], ex1["name"]) + assert.EqualValues(t, exp2["id"], ex2["id"]) + assert.Equal(t, exp2["name"], ex2["name"]) } func BenchmarkSchemaUnmarshal(b *testing.B) { diff --git a/spec.go b/spec.go index 7d38b6e..b388503 100644 --- a/spec.go +++ b/spec.go @@ -26,7 +26,7 @@ import ( const ( // SwaggerSchemaURL the url for the swagger 2.0 schema to validate specs SwaggerSchemaURL = "http://swagger.io/v2/schema.json#" - // JSONSchemaURL the url for the json schema schema + // JSONSchemaURL the url for the json schema JSONSchemaURL = "http://json-schema.org/draft-04/schema#" ) diff --git a/structs_test.go b/structs_test.go index d4b87f4..7b076b4 100644 --- a/structs_test.go +++ b/structs_test.go @@ -28,7 +28,7 @@ func assertSerializeJSON(t testing.TB, actual interface{}, expected string) bool if err != nil { return assert.Fail(t, "unable to marshal to json (%s): %#v", err, actual) } - return assert.Equal(t, string(ser), expected) + return assert.Equal(t, expected, string(ser)) } func assertSerializeYAML(t testing.TB, actual interface{}, expected string) bool { @@ -36,7 +36,7 @@ func assertSerializeYAML(t testing.TB, actual interface{}, expected string) bool if err != nil { return assert.Fail(t, "unable to marshal to yaml (%s): %#v", err, actual) } - return assert.Equal(t, string(ser), expected) + return assert.Equal(t, expected, string(ser)) } func derefTypeOf(expected interface{}) (tpe reflect.Type) { @@ -65,7 +65,7 @@ func assertParsesJSON(t testing.TB, actual string, expected interface{}) bool { if !isPointed(expected) { act = reflect.Indirect(parsed).Interface() } - return assert.Equal(t, act, expected) + return assert.Equal(t, expected, act) } func assertParsesYAML(t testing.TB, actual string, expected interface{}) bool { diff --git a/swagger_test.go b/swagger_test.go index 23aa509..cb288e6 100644 --- a/swagger_test.go +++ b/swagger_test.go @@ -107,7 +107,6 @@ const specJSON = `{ "x-schemes": ["unix","amqp"] }` -// // func verifySpecSerialize(specJSON []byte, spec Swagger) { // expected := map[string]interface{}{} // json.Unmarshal(specJSON, &expected) @@ -120,96 +119,96 @@ const specJSON = `{ // } /* -// assertEquivalent is currently unused -func assertEquivalent(t testing.TB, actual, expected interface{}) bool { - if actual == nil || expected == nil || reflect.DeepEqual(actual, expected) { - return true - } - - actualType := reflect.TypeOf(actual) - expectedType := reflect.TypeOf(expected) - if reflect.TypeOf(actual).ConvertibleTo(expectedType) { - expectedValue := reflect.ValueOf(expected) - if swag.IsZero(expectedValue) && swag.IsZero(reflect.ValueOf(actual)) { + // assertEquivalent is currently unused + func assertEquivalent(t testing.TB, actual, expected interface{}) bool { + if actual == nil || expected == nil || reflect.DeepEqual(actual, expected) { return true } - // Attempt comparison after type conversion - if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) { + actualType := reflect.TypeOf(actual) + expectedType := reflect.TypeOf(expected) + if reflect.TypeOf(actual).ConvertibleTo(expectedType) { + expectedValue := reflect.ValueOf(expected) + if swag.IsZero(expectedValue) && swag.IsZero(reflect.ValueOf(actual)) { + return true + } + + // Attempt comparison after type conversion + if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) { + return true + } + } + + // Last ditch effort + if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) { return true } + errFmt := "Expected: '%[1]T(%[1]#v)'\nActual: '%[2]T(%[2]#v)'\n(Should be equivalent)!" + return assert.Fail(t, errFmt, expected, actual) } - // Last ditch effort - if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) { - return true - } - errFmt := "Expected: '%T(%#v)'\nActual: '%T(%#v)'\n(Should be equivalent)!" - return assert.Fail(t, errFmt, expected, expected, actual, actual) -} + // ShouldBeEquivalentTo is currently unused + func ShouldBeEquivalentTo(actual interface{}, expecteds ...interface{}) string { + expected := expecteds[0] + if actual == nil || expected == nil { + return "" + } -// ShouldBeEquivalentTo is currently unused -func ShouldBeEquivalentTo(actual interface{}, expecteds ...interface{}) string { - expected := expecteds[0] - if actual == nil || expected == nil { - return "" - } + if reflect.DeepEqual(expected, actual) { + return "" + } - if reflect.DeepEqual(expected, actual) { - return "" - } + actualType := reflect.TypeOf(actual) + expectedType := reflect.TypeOf(expected) + if reflect.TypeOf(actual).ConvertibleTo(expectedType) { + expectedValue := reflect.ValueOf(expected) + if swag.IsZero(expectedValue) && swag.IsZero(reflect.ValueOf(actual)) { + return "" + } - actualType := reflect.TypeOf(actual) - expectedType := reflect.TypeOf(expected) - if reflect.TypeOf(actual).ConvertibleTo(expectedType) { - expectedValue := reflect.ValueOf(expected) - if swag.IsZero(expectedValue) && swag.IsZero(reflect.ValueOf(actual)) { - return "" + // Attempt comparison after type conversion + if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) { + return "" + } } - // Attempt comparison after type conversion - if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) { + // Last ditch effort + if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) { return "" } + errFmt := "Expected: '%[1]T(%[1]#v)'\nActual: '%[2]T(%[2]#v)'\n(Should be equivalent)!" + return fmt.Sprintf(errFmt, expected, actual) } - // Last ditch effort - if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) { - return "" - } - errFmt := "Expected: '%T(%#v)'\nActual: '%T(%#v)'\n(Should be equivalent)!" - return fmt.Sprintf(errFmt, expected, expected, actual, actual) - -} - -// assertSpecMaps is currently unused -func assertSpecMaps(t testing.TB, actual, expected map[string]interface{}) bool { - res := true - if id, ok := expected["id"]; ok { - res = assert.Equal(t, id, actual["id"]) + // assertSpecMaps is currently unused + func assertSpecMaps(t testing.TB, actual, expected map[string]interface{}) bool { + res := true + if id, ok := expected["id"]; ok { + res = assert.Equal(t, id, actual["id"]) + } + res = res && assert.Equal(t, expected["consumes"], actual["consumes"]) + res = res && assert.Equal(t, expected["produces"], actual["produces"]) + res = res && assert.Equal(t, expected["schemes"], actual["schemes"]) + res = res && assert.Equal(t, expected["swagger"], actual["swagger"]) + res = res && assert.Equal(t, expected["info"], actual["info"]) + res = res && assert.Equal(t, expected["host"], actual["host"]) + res = res && assert.Equal(t, expected["basePath"], actual["basePath"]) + res = res && assert.Equal(t, expected["paths"], actual["paths"]) + res = res && assert.Equal(t, expected["definitions"], actual["definitions"]) + res = res && assert.Equal(t, expected["responses"], actual["responses"]) + res = res && assert.Equal(t, expected["securityDefinitions"], actual["securityDefinitions"]) + res = res && assert.Equal(t, expected["tags"], actual["tags"]) + res = res && assert.Equal(t, expected["externalDocs"], actual["externalDocs"]) + res = res && assert.Equal(t, expected["x-some-extension"], actual["x-some-extension"]) + res = res && assert.Equal(t, expected["x-schemes"], actual["x-schemes"]) + + return res } - res = res && assert.Equal(t, expected["consumes"], actual["consumes"]) - res = res && assert.Equal(t, expected["produces"], actual["produces"]) - res = res && assert.Equal(t, expected["schemes"], actual["schemes"]) - res = res && assert.Equal(t, expected["swagger"], actual["swagger"]) - res = res && assert.Equal(t, expected["info"], actual["info"]) - res = res && assert.Equal(t, expected["host"], actual["host"]) - res = res && assert.Equal(t, expected["basePath"], actual["basePath"]) - res = res && assert.Equal(t, expected["paths"], actual["paths"]) - res = res && assert.Equal(t, expected["definitions"], actual["definitions"]) - res = res && assert.Equal(t, expected["responses"], actual["responses"]) - res = res && assert.Equal(t, expected["securityDefinitions"], actual["securityDefinitions"]) - res = res && assert.Equal(t, expected["tags"], actual["tags"]) - res = res && assert.Equal(t, expected["externalDocs"], actual["externalDocs"]) - res = res && assert.Equal(t, expected["x-some-extension"], actual["x-some-extension"]) - res = res && assert.Equal(t, expected["x-schemes"], actual["x-schemes"]) - - return res -} */ + func assertSpecs(t testing.TB, actual, expected Swagger) bool { expected.Swagger = "2.0" - return assert.Equal(t, actual, expected) + return assert.Equal(t, expected, actual) } /* @@ -233,7 +232,7 @@ func assertSpecJSON(t testing.TB, specJSON []byte) bool { if !assert.NoError(t, json.Unmarshal(cb, &actual)) { return false } - return assertSpecMaps(t, actual, expected) + return assertSpecMaps(t, expected, actual ) } */ @@ -241,48 +240,41 @@ func TestSwaggerSpec_Serialize(t *testing.T) { expected := make(map[string]interface{}) _ = json.Unmarshal([]byte(specJSON), &expected) b, err := json.MarshalIndent(spec, "", " ") - if assert.NoError(t, err) { - var actual map[string]interface{} - err := json.Unmarshal(b, &actual) - if assert.NoError(t, err) { - assert.EqualValues(t, actual, expected) - } - } + require.NoError(t, err) + var actual map[string]interface{} + require.NoError(t, json.Unmarshal(b, &actual)) + assert.EqualValues(t, actual, expected) } func TestSwaggerSpec_Deserialize(t *testing.T) { var actual Swagger - err := json.Unmarshal([]byte(specJSON), &actual) - if assert.NoError(t, err) { - assert.EqualValues(t, actual, spec) - } + require.NoError(t, json.Unmarshal([]byte(specJSON), &actual)) + assert.EqualValues(t, actual, spec) } func TestVendorExtensionStringSlice(t *testing.T) { var actual Swagger - err := json.Unmarshal([]byte(specJSON), &actual) - if assert.NoError(t, err) { - schemes, ok := actual.Extensions.GetStringSlice("x-schemes") - if assert.True(t, ok) { - assert.EqualValues(t, []string{"unix", "amqp"}, schemes) - } - notSlice, ok := actual.Extensions.GetStringSlice("x-some-extension") - assert.Nil(t, notSlice) - assert.False(t, ok) - - actual.AddExtension("x-another-ext", 100) - notString, ok := actual.Extensions.GetStringSlice("x-another-ext") - assert.Nil(t, notString) - assert.False(t, ok) - - actual.AddExtension("x-another-slice-ext", []interface{}{100, 100}) - notStringSlice, ok := actual.Extensions.GetStringSlice("x-another-slice-ext") - assert.Nil(t, notStringSlice) - assert.False(t, ok) - - _, ok = actual.Extensions.GetStringSlice("x-notfound-ext") - assert.False(t, ok) - } + require.NoError(t, json.Unmarshal([]byte(specJSON), &actual)) + schemes, ok := actual.Extensions.GetStringSlice("x-schemes") + require.True(t, ok) + assert.EqualValues(t, []string{"unix", "amqp"}, schemes) + + notSlice, ok := actual.Extensions.GetStringSlice("x-some-extension") + assert.Nil(t, notSlice) + assert.False(t, ok) + + actual.AddExtension("x-another-ext", 100) + notString, ok := actual.Extensions.GetStringSlice("x-another-ext") + assert.Nil(t, notString) + assert.False(t, ok) + + actual.AddExtension("x-another-slice-ext", []interface{}{100, 100}) + notStringSlice, ok := actual.Extensions.GetStringSlice("x-another-slice-ext") + assert.Nil(t, notStringSlice) + assert.False(t, ok) + + _, ok = actual.Extensions.GetStringSlice("x-notfound-ext") + assert.False(t, ok) } func TestOptionalSwaggerProps_Serialize(t *testing.T) { @@ -307,26 +299,25 @@ func TestOptionalSwaggerProps_Serialize(t *testing.T) { var minimalSpec Swagger err := json.Unmarshal(minimalJSONSpec, &minimalSpec) - if assert.NoError(t, err) { - bytes, err := json.Marshal(&minimalSpec) - if assert.NoError(t, err) { - var ms map[string]interface{} - if err := json.Unmarshal(bytes, &ms); assert.NoError(t, err) { - assert.NotContains(t, ms, "consumes") - assert.NotContains(t, ms, "produces") - assert.NotContains(t, ms, "schemes") - assert.NotContains(t, ms, "host") - assert.NotContains(t, ms, "basePath") - assert.NotContains(t, ms, "definitions") - assert.NotContains(t, ms, "parameters") - assert.NotContains(t, ms, "responses") - assert.NotContains(t, ms, "securityDefinitions") - assert.NotContains(t, ms, "security") - assert.NotContains(t, ms, "tags") - assert.NotContains(t, ms, "externalDocs") - } - } - } + require.NoError(t, err) + bytes, err := json.Marshal(&minimalSpec) + require.NoError(t, err) + + var ms map[string]interface{} + require.NoError(t, json.Unmarshal(bytes, &ms)) + + assert.NotContains(t, ms, "consumes") + assert.NotContains(t, ms, "produces") + assert.NotContains(t, ms, "schemes") + assert.NotContains(t, ms, "host") + assert.NotContains(t, ms, "basePath") + assert.NotContains(t, ms, "definitions") + assert.NotContains(t, ms, "parameters") + assert.NotContains(t, ms, "responses") + assert.NotContains(t, ms, "securityDefinitions") + assert.NotContains(t, ms, "security") + assert.NotContains(t, ms, "tags") + assert.NotContains(t, ms, "externalDocs") } var minimalJSONSpec = []byte(`{ @@ -376,16 +367,15 @@ var minimalJSONSpec = []byte(`{ func TestSecurityRequirements(t *testing.T) { var minimalSpec Swagger - err := json.Unmarshal(minimalJSONSpec, &minimalSpec) - if assert.NoError(t, err) { - sec := minimalSpec.Paths.Paths["/"].Get.Security - require.Len(t, sec, 3) - assert.Contains(t, sec[0], "basic") - assert.Contains(t, sec[0], "apiKey") - assert.NotNil(t, sec[1]) - assert.Empty(t, sec[1]) - assert.Contains(t, sec[2], "queryKey") - } + require.NoError(t, json.Unmarshal(minimalJSONSpec, &minimalSpec)) + + sec := minimalSpec.Paths.Paths["/"].Get.Security + require.Len(t, sec, 3) + assert.Contains(t, sec[0], "basic") + assert.Contains(t, sec[0], "apiKey") + assert.NotNil(t, sec[1]) + assert.Empty(t, sec[1]) + assert.Contains(t, sec[2], "queryKey") } func TestSwaggerGobEncoding(t *testing.T) { @@ -396,10 +386,7 @@ func TestSwaggerGobEncoding(t *testing.T) { func doTestSwaggerGobEncoding(t *testing.T, fixture string) { var src, dst Swagger - - if !assert.NoError(t, json.Unmarshal([]byte(fixture), &src)) { - t.FailNow() - } + require.NoError(t, json.Unmarshal([]byte(fixture), &src)) doTestAnyGobEncoding(t, &src, &dst) } diff --git a/validations_test.go b/validations_test.go index b62f82e..993547c 100644 --- a/validations_test.go +++ b/validations_test.go @@ -75,7 +75,6 @@ func TestValidations(t *testing.T) { expectedSV.PatternProperties = nil expectedSV.MinProperties = nil expectedSV.MaxProperties = nil - val = mkVal() val = mkVal() cv.SetValidations(val) diff --git a/xml_object_test.go b/xml_object_test.go index da616a9..8573e82 100644 --- a/xml_object_test.go +++ b/xml_object_test.go @@ -19,14 +19,14 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestXmlObject_Serialize(t *testing.T) { obj1 := XMLObject{} actual, err := json.Marshal(obj1) - if assert.NoError(t, err) { - assert.Equal(t, "{}", string(actual)) - } + require.NoError(t, err) + assert.Equal(t, "{}", string(actual)) obj2 := XMLObject{ Name: "the name", @@ -37,24 +37,22 @@ func TestXmlObject_Serialize(t *testing.T) { } actual, err = json.Marshal(obj2) - if assert.NoError(t, err) { - var ad map[string]interface{} - if assert.NoError(t, json.Unmarshal(actual, &ad)) { - assert.Equal(t, obj2.Name, ad["name"]) - assert.Equal(t, obj2.Namespace, ad["namespace"]) - assert.Equal(t, obj2.Prefix, ad["prefix"]) - assert.True(t, ad["attribute"].(bool)) - assert.True(t, ad["wrapped"].(bool)) - } - } + require.NoError(t, err) + + var ad map[string]interface{} + require.NoError(t, json.Unmarshal(actual, &ad)) + assert.Equal(t, obj2.Name, ad["name"]) + assert.Equal(t, obj2.Namespace, ad["namespace"]) + assert.Equal(t, obj2.Prefix, ad["prefix"]) + assert.True(t, ad["attribute"].(bool)) + assert.True(t, ad["wrapped"].(bool)) } func TestXmlObject_Deserialize(t *testing.T) { expected := XMLObject{} actual := XMLObject{} - if assert.NoError(t, json.Unmarshal([]byte("{}"), &actual)) { - assert.Equal(t, expected, actual) - } + require.NoError(t, json.Unmarshal([]byte("{}"), &actual)) + assert.Equal(t, expected, actual) completed := `{"name":"the name","namespace":"the namespace","prefix":"the prefix","attribute":true,"wrapped":true}` expected = XMLObject{ @@ -64,8 +62,8 @@ func TestXmlObject_Deserialize(t *testing.T) { Attribute: true, Wrapped: true, } + actual = XMLObject{} - if assert.NoError(t, json.Unmarshal([]byte(completed), &actual)) { - assert.Equal(t, expected, actual) - } + require.NoError(t, json.Unmarshal([]byte(completed), &actual)) + assert.Equal(t, expected, actual) } From 2341568dac7df514958ddc3a7d7ff65b1fe33e70 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Thu, 30 Nov 2023 18:47:19 +0100 Subject: [PATCH 06/28] ci: removed deprecated appveyor CI * appveyor used to be our sole CI for windows * this has now been handed over to github actions * removing this config and the need to manage tokens * fixes #161 * fixes #167 (duplicate) Signed-off-by: Frederic BIDON --- appveyor.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 0903593..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: "0.1.{build}" - -clone_folder: C:\go-openapi\spec -shallow_clone: true # for startup speed -pull_requests: - do_not_increment_build_number: true - -#skip_tags: true -#skip_branch_with_pr: true - -# appveyor.yml -build: off - -environment: - GOPATH: c:\gopath - -stack: go 1.15 - -test_script: - - go test -v -timeout 20m ./... - -deploy: off - -notifications: - - provider: Slack - incoming_webhook: https://hooks.slack.com/services/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 - auth_token: - secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4= - channel: bots - on_build_success: false - on_build_failure: true - on_build_status_changed: true From d6c58be69dc7ed17a96c430f7e31526b16915f75 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Mon, 4 Dec 2023 15:04:35 +0100 Subject: [PATCH 07/28] updated go version * updated minimum go version required to go1.19 (like most other go-openapi repos) * fixed wrong badges/links in README * relinted, removing deprecated stdlib function calls Signed-off-by: Frederic BIDON --- README.md | 5 +---- circular_test.go | 4 ++-- debug_test.go | 3 +-- expander_test.go | 10 +++++----- go.mod | 19 ++++++++++++++----- go.sum | 49 ++++++++++++++++++++++++------------------------ resolver_test.go | 22 +++++++++++----------- 7 files changed, 59 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 18782c6..8218c4a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,5 @@ -# OAI object model +# OpenAPI v2 object model [![Build Status](https://github.com/go-openapi/spec/actions/workflows/go-test.yaml/badge.svg)](https://github.com/go-openapi/strfmt/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) -[![Build Status](https://travis-ci.org/go-openapi/spec.svg?branch=master)](https://travis-ci.org/go-openapi/spec) - -[![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE) [![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/spec.svg)](https://pkg.go.dev/github.com/go-openapi/spec) diff --git a/circular_test.go b/circular_test.go index 3dbb45a..c064b61 100644 --- a/circular_test.go +++ b/circular_test.go @@ -2,9 +2,9 @@ package spec import ( "encoding/json" - "io/ioutil" "net/http" "net/http/httptest" + "os" "path/filepath" "testing" "time" @@ -175,7 +175,7 @@ func TestExpandCircular_Bitbucket(t *testing.T) { func TestExpandCircular_ResponseWithRoot(t *testing.T) { rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join("fixtures", "more_circulars", "resp.json")) + b, err := os.ReadFile(filepath.Join("fixtures", "more_circulars", "resp.json")) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, rootDoc)) diff --git a/debug_test.go b/debug_test.go index 74c2a78..c74fc28 100644 --- a/debug_test.go +++ b/debug_test.go @@ -15,7 +15,6 @@ package spec import ( - "io/ioutil" "os" "sync" "testing" @@ -28,7 +27,7 @@ var ( ) func TestDebug(t *testing.T) { - tmpFile, _ := ioutil.TempFile("", "debug-test") + tmpFile, _ := os.CreateTemp("", "debug-test") tmpName := tmpFile.Name() defer func() { Debug = false diff --git a/expander_test.go b/expander_test.go index 719ef44..fcb8710 100644 --- a/expander_test.go +++ b/expander_test.go @@ -16,7 +16,7 @@ package spec import ( "encoding/json" - "io/ioutil" + "io" "log" "net/http" "net/http/httptest" @@ -380,7 +380,7 @@ func TestExpand_ContinueOnError(t *testing.T) { specPath := filepath.Join("fixtures", "expansion", "missingRef.json") defer log.SetOutput(os.Stdout) - log.SetOutput(ioutil.Discard) + log.SetOutput(io.Discard) // missing $ref in spec missingRefDoc, err := jsonDoc(specPath) @@ -816,7 +816,7 @@ func resolutionContextServer() *httptest.Server { server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if req.URL.Path == "/resolution.json" { - b, _ := ioutil.ReadFile(filepath.Join(specs, "resolution.json")) + b, _ := os.ReadFile(filepath.Join(specs, "resolution.json")) var ctnt map[string]interface{} _ = json.Unmarshal(b, &ctnt) ctnt["id"] = servedAt @@ -828,7 +828,7 @@ func resolutionContextServer() *httptest.Server { return } if req.URL.Path == "/resolution2.json" { - b, _ := ioutil.ReadFile(filepath.Join(specs, "resolution2.json")) + b, _ := os.ReadFile(filepath.Join(specs, "resolution2.json")) var ctnt map[string]interface{} _ = json.Unmarshal(b, &ctnt) ctnt["id"] = servedAt @@ -936,7 +936,7 @@ func TestExpand_RemoteRefWithNestedResolutionContextWithFragment(t *testing.T) { func TestExpand_TransitiveRefs(t *testing.T) { basePath := filepath.Join(specs, "todos.json") - rawSpec, err := ioutil.ReadFile(basePath) + rawSpec, err := os.ReadFile(basePath) require.NoError(t, err) var spec *Swagger diff --git a/go.mod b/go.mod index 9e3e36f..f9d343e 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,20 @@ module github.com/go-openapi/spec require ( - github.com/go-openapi/jsonpointer v0.19.5 - github.com/go-openapi/jsonreference v0.20.0 - github.com/go-openapi/swag v0.19.15 - github.com/stretchr/testify v1.6.1 + github.com/go-openapi/jsonpointer v0.20.0 + github.com/go-openapi/jsonreference v0.20.2 + github.com/go-openapi/swag v0.22.4 + github.com/stretchr/testify v1.8.4 gopkg.in/yaml.v2 v2.4.0 ) -go 1.13 +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +go 1.19 diff --git a/go.sum b/go.sum index 7427dbd..9d6f790 100644 --- a/go.sum +++ b/go.sum @@ -2,40 +2,41 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/resolver_test.go b/resolver_test.go index 7f59135..b1c977a 100644 --- a/resolver_test.go +++ b/resolver_test.go @@ -2,9 +2,9 @@ package spec import ( "encoding/json" - "io/ioutil" "net/http" "net/http/httptest" + "os" "path/filepath" "testing" @@ -132,7 +132,7 @@ func TestResolveRemoteRef_RootSame(t *testing.T) { defer server.Close() rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, rootDoc)) @@ -160,7 +160,7 @@ func TestResolveRemoteRef_FromFragment(t *testing.T) { defer server.Close() rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, rootDoc)) @@ -180,7 +180,7 @@ func TestResolveRemoteRef_FromInvalidFragment(t *testing.T) { defer server.Close() rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, rootDoc)) @@ -199,7 +199,7 @@ func TestResolveRemoteRef_FromInvalidFragment(t *testing.T) { // defer server.Close() // // rootDoc := new(Swagger) -// b, err := ioutil.ReadFile("fixtures/specs/refed.json") +// b, err := os.ReadFile("fixtures/specs/refed.json") // require.NoError(t, err) && assert.NoError(t, json.Unmarshal(b, rootDoc)) // // var tgt Schema @@ -217,7 +217,7 @@ func TestResolveRemoteRef_ToParameter(t *testing.T) { defer server.Close() rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, rootDoc)) @@ -242,7 +242,7 @@ func TestResolveRemoteRef_ToPathItem(t *testing.T) { defer server.Close() rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, rootDoc)) @@ -261,7 +261,7 @@ func TestResolveRemoteRef_ToResponse(t *testing.T) { defer server.Close() rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, rootDoc)) @@ -312,7 +312,7 @@ func TestResolveLocalRef_FromInvalidFragment(t *testing.T) { func TestResolveLocalRef_Parameter(t *testing.T) { rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) basePath := filepath.Join(specs, "refed.json") @@ -335,7 +335,7 @@ func TestResolveLocalRef_Parameter(t *testing.T) { func TestResolveLocalRef_PathItem(t *testing.T) { rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) basePath := filepath.Join(specs, "refed.json") @@ -352,7 +352,7 @@ func TestResolveLocalRef_PathItem(t *testing.T) { func TestResolveLocalRef_Response(t *testing.T) { rootDoc := new(Swagger) - b, err := ioutil.ReadFile(filepath.Join(specs, "refed.json")) + b, err := os.ReadFile(filepath.Join(specs, "refed.json")) require.NoError(t, err) basePath := filepath.Join(specs, "refed.json") From 5762ed37dc0ff2cc809f48608a2d65ffadde8f55 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Mon, 4 Dec 2023 16:07:53 +0100 Subject: [PATCH 08/28] Removed dependency on bindata Starting with go1.16 go standard library exposes an embedded FS. Replaced bindata codegen by assets embedded with the standard library. Signed-off-by: Frederic BIDON --- bindata.go | 297 ----------------------------------------------------- embed.go | 17 +++ spec.go | 4 +- 3 files changed, 19 insertions(+), 299 deletions(-) delete mode 100644 bindata.go create mode 100644 embed.go diff --git a/bindata.go b/bindata.go deleted file mode 100644 index afc8385..0000000 --- a/bindata.go +++ /dev/null @@ -1,297 +0,0 @@ -// Code generated by go-bindata. DO NOT EDIT. -// sources: -// schemas/jsonschema-draft-04.json (4.357kB) -// schemas/v2/schema.json (40.248kB) - -package spec - -import ( - "bytes" - "compress/gzip" - "crypto/sha256" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo - digest [sha256.Size]byte -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindataFileInfo) Name() string { - return fi.name -} -func (fi bindataFileInfo) Size() int64 { - return fi.size -} -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} -func (fi bindataFileInfo) IsDir() bool { - return false -} -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _jsonschemaDraft04Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x57\x3d\x6f\xdb\x3c\x10\xde\xf3\x2b\x08\x26\x63\xf2\x2a\x2f\xd0\xc9\x5b\xd1\x2e\x01\x5a\x34\x43\x37\x23\x03\x6d\x9d\x6c\x06\x14\xa9\x50\x54\x60\xc3\xd0\x7f\x2f\x28\x4a\x14\x29\x91\x92\x2d\xa7\x8d\x97\x28\xbc\xaf\xe7\x8e\xf7\xc5\xd3\x0d\x42\x08\x61\x9a\xe2\x15\xc2\x7b\xa5\x8a\x55\x92\xbc\x96\x82\x3f\x94\xdb\x3d\xe4\xe4\x3f\x21\x77\x49\x2a\x49\xa6\x1e\x1e\xbf\x24\xe6\xec\x16\xdf\x1b\xa1\x3b\xf3\xff\x02\xc9\x14\xca\xad\xa4\x85\xa2\x82\x6b\xe9\x6f\x42\x02\x32\x2c\x28\x07\x45\x5a\x15\x3d\x77\x46\x39\xd5\xcc\x25\x5e\x21\x83\xb8\x21\x18\xb6\xaf\x52\x92\xa3\x47\x68\x88\xea\x58\x80\x56\x4e\x1a\xf2\xbd\x4f\xcc\x29\x7f\x52\x90\x6b\x7d\xff\x0f\x48\xb4\x3d\x3f\x21\x7c\x27\x21\xd3\x2a\x6e\x31\xaa\x2d\x53\xdd\xf3\xe3\x42\x94\x54\xd1\x77\x78\xe2\x0a\x76\x20\xe3\x20\x68\xcb\x30\x86\x41\xf3\x2a\xc7\x2b\xf4\x78\x8e\xfe\xef\x90\x91\x8a\xa9\xc7\xb1\x1d\xc2\xd8\x2f\x0d\x75\xed\xc1\x4e\x9c\xc8\x25\x43\xac\xa8\xbe\xd7\xcc\xa9\xd1\xa9\x21\xa0\x1a\xbd\x04\x61\x94\x34\x2f\x18\xfc\x3e\x16\x50\x8e\x4d\x03\x6f\x1c\x58\xdb\x48\x23\xbc\x11\x82\x01\xe1\xfa\xd3\x3a\x8e\x30\xaf\x18\x33\x7f\xf3\x8d\x39\x11\x9b\x57\xd8\x2a\xfd\x55\x2a\x49\xf9\x0e\xc7\xec\x37\xd4\x25\xf7\xec\x5c\x66\xc7\xd7\x99\xaa\xcf\x4f\x89\x8a\xd3\xb7\x0a\x3a\xaa\x92\x15\xf4\x30\x6f\x1c\xb0\xd6\x46\xe7\x98\x39\x2d\xa4\x28\x40\x2a\x3a\x88\x9e\x29\xba\x88\x37\x2d\xca\x60\x38\xfa\xba\x5b\x20\xac\xa8\x62\xb0\x4c\xd4\xaf\xda\x45\x0a\xba\x5c\x3b\xb9\xc7\x79\xc5\x14\x2d\x18\x34\x19\x1c\x51\xdb\x25\x4d\xb4\x7e\x06\x14\x38\x6c\x59\x55\xd2\x77\xf8\x69\x59\xfc\x7b\x73\xed\x93\x43\xcb\x32\x6d\x3c\x28\xdc\x1b\x9a\xd3\x62\xab\xc2\x27\xf7\x41\xc9\x08\x2b\x23\x08\xad\x13\x57\x21\x9c\xd3\x72\x0d\x42\x72\xf8\x01\x7c\xa7\xf6\x83\xce\x39\xd7\x82\x3c\x1f\x2f\xd6\x60\x1b\xa2\xdf\x35\x89\x52\x20\xe7\x73\x74\xe0\x66\x26\x64\x4e\xb4\x97\x58\xc2\x0e\x0e\xe1\x60\x92\x34\x6d\xa0\x10\xd6\xb5\x83\x61\x27\xe6\x47\xd3\x89\xbd\x63\xfd\x3b\x8d\x03\x3d\x6c\x42\x2d\x5b\x70\xee\xe8\xdf\x4b\xf4\x66\x4e\xe1\x01\x45\x17\x80\x74\xad\x4f\xc3\xf3\xae\xc6\x1d\xc6\xd7\xc2\xce\xc9\xe1\x29\x30\x86\x2f\x4a\xa6\x4b\x15\x84\x73\xc9\x6f\xfd\x7f\xa5\x6e\x9e\xbd\xf1\xb0\xd4\xdd\x45\x5a\xc2\x3e\x4b\x78\xab\xa8\x84\x74\x4a\x91\x3b\x92\x23\x05\xf2\x1c\x1e\x7b\xf3\x09\xf8\xcf\xab\x24\xb6\x60\xa2\xe8\x4c\x9f\x75\x77\xaa\x8c\xe6\x01\x45\x36\x86\xcf\xc3\x63\x3a\xea\xd4\x8d\x7e\x06\xac\x14\x0a\xe0\x29\xf0\xed\x07\x22\x1a\x65\xda\x44\xae\xa2\x73\x1a\xe6\x90\x69\xa2\x8c\x46\xb2\x2f\xde\x49\x38\x08\xed\xfe\xfd\x41\xaf\x9f\xa9\x55\xd7\xdd\x22\x8d\xfa\x45\x63\xc5\x0f\x80\xf3\xb4\x08\xd6\x79\x30\x9e\x93\xee\x59\xa6\xd0\x4b\xee\x22\xe3\x33\xc1\x3a\x27\x68\x36\x78\x7e\x87\x0a\x06\xd5\x2e\x20\xd3\xaf\x15\xfb\xd8\x3b\x73\x14\xbb\x92\xed\x05\x5d\x2e\x29\x38\x2c\x94\xe4\x42\x45\x5e\xd3\xb5\x7d\xdf\x47\xca\x38\xb4\x5c\xaf\xfb\x7d\xdd\x6d\xf4\xa1\x2d\x77\xdd\x2f\xce\x6d\xc4\x7b\x8b\x4e\x67\xa9\x6f\xfe\x04\x00\x00\xff\xff\xb1\xd1\x27\x78\x05\x11\x00\x00") - -func jsonschemaDraft04JsonBytes() ([]byte, error) { - return bindataRead( - _jsonschemaDraft04Json, - "jsonschema-draft-04.json", - ) -} - -func jsonschemaDraft04Json() (*asset, error) { - bytes, err := jsonschemaDraft04JsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "jsonschema-draft-04.json", size: 4357, mode: os.FileMode(0640), modTime: time.Unix(1568963823, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe1, 0x48, 0x9d, 0xb, 0x47, 0x55, 0xf0, 0x27, 0x93, 0x30, 0x25, 0x91, 0xd3, 0xfc, 0xb8, 0xf0, 0x7b, 0x68, 0x93, 0xa8, 0x2a, 0x94, 0xf2, 0x48, 0x95, 0xf8, 0xe4, 0xed, 0xf1, 0x1b, 0x82, 0xe2}} - return a, nil -} - -var _v2SchemaJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\x4f\x93\xdb\x36\xb2\xbf\xfb\x53\xa0\x14\x57\xd9\xae\xd8\x92\xe3\xf7\x2e\xcf\x97\xd4\xbc\xd8\x49\x66\x37\x5e\x4f\x79\x26\xbb\x87\x78\x5c\x05\x91\x2d\x09\x09\x09\x30\x00\x38\x33\x5a\xef\x7c\xf7\x2d\xf0\x9f\x08\x02\x20\x41\x8a\xd2\xc8\x0e\x0f\xa9\x78\x28\xa0\xd1\xdd\x68\x34\x7e\xdd\xf8\xf7\xf9\x11\x42\x33\x49\x64\x04\xb3\xd7\x68\x76\x86\xfe\x76\xf9\xfe\x1f\xe8\x32\xd8\x40\x8c\xd1\x8a\x71\x74\x79\x8b\xd7\x6b\xe0\xe8\xd5\xfc\x25\x3a\xbb\x38\x9f\xcf\x9e\xab\x0a\x24\x54\xa5\x37\x52\x26\xaf\x17\x0b\x91\x17\x99\x13\xb6\xb8\x79\xb5\x10\x59\xdd\xf9\xef\x82\xd1\x6f\xf2\xc2\x8f\xf3\x4f\xb5\x1a\xea\xc7\x17\x45\x41\xc6\xd7\x8b\x90\xe3\x95\x7c\xf1\xf2\x7f\x8b\xca\x45\x3d\xb9\x4d\x32\xa6\xd8\xf2\x77\x08\x64\xfe\x8d\xc3\x9f\x29\xe1\xa0\x9a\xff\xed\x11\x42\x08\xcd\x8a\xd6\xb3\x9f\x15\x67\x74\xc5\xca\x7f\x27\x58\x6e\xc4\xec\x11\x42\xd7\x59\x5d\x1c\x86\x44\x12\x46\x71\x74\xc1\x59\x02\x5c\x12\x10\xb3\xd7\x68\x85\x23\x01\x59\x81\x04\x4b\x09\x9c\x6a\xbf\x7e\xce\x49\x7d\xba\x7b\x51\xfd\xa1\x44\xe2\xb0\x52\xac\x7d\xb3\x08\x61\x45\x68\x46\x56\x2c\x6e\x80\x86\x8c\xbf\xbd\x93\x40\x05\x61\x74\x96\x95\xbe\x7f\x84\xd0\x7d\x4e\xde\x42\xb7\xe4\xbe\x46\xbb\x14\x5b\x48\x4e\xe8\xba\x90\x05\xa1\x19\xd0\x34\xae\xc4\xce\xbe\xbc\x9a\xbf\x9c\x15\x7f\x5d\x57\xc5\x42\x10\x01\x27\x89\xe2\x48\x51\xb9\xda\x40\xd5\x87\x37\xc0\x15\x5f\x88\xad\x90\xdc\x10\x81\x42\x16\xa4\x31\x50\x39\x2f\x38\xad\xab\xb0\x53\xd8\xac\x94\x56\x6f\xc3\x84\xf4\x11\xa4\x50\xb3\xfa\xe9\xd3\x6f\x9f\x3e\xdf\x2f\xd0\xeb\x8f\x1f\x3f\x7e\xbc\xfe\xf6\xe9\xf7\xaf\x5f\x7f\xfc\x18\x7e\xfb\xec\xfb\xc7\xb3\x36\x79\x54\x43\xe8\x29\xc5\x31\x20\xc6\x11\x49\x9e\xe5\x12\x41\x66\xa0\xe8\xed\x1d\x8e\x93\x08\x5e\xa3\x27\x3b\xc3\x7c\xa2\x73\xba\xc4\x02\x2e\xb0\xdc\xf4\xe5\x76\xd1\xca\x96\xa2\x8a\x94\xcd\x21\xc9\x6c\xec\x2c\x70\x42\x9e\x34\x74\x9d\x19\x7c\xcd\x20\x9c\xea\x2e\x0a\xfe\x42\x84\xd4\x29\x04\x8c\x8a\xb4\x41\xa2\xc1\xdc\x19\x8a\x88\x90\x4a\x49\xef\xce\xdf\xbd\x45\x4a\x52\x81\x70\x10\x40\x22\x21\x44\xcb\x6d\xc5\xec\x4e\x3c\x1c\x45\xef\x57\x9a\xb5\x7d\xae\xfe\xe5\xe4\x31\x86\x90\xe0\xab\x6d\x02\x3b\x2e\xcb\x11\x90\xd9\xa8\xc6\x77\xc2\x59\x98\x06\xfd\xf9\x2e\x78\x45\x01\xa6\xa8\xa0\x71\x5c\xbe\x33\xa7\xd2\xd9\x5f\x95\xef\xd9\xd5\xac\xfd\xdc\x5d\xbf\x5e\xb8\xd1\x3e\xc7\x31\x48\xe0\x5e\x4c\x14\x65\xdf\xb8\xa8\x71\x10\x09\xa3\xc2\xc7\x02\xcb\xa2\x4e\x5a\x02\x82\x94\x13\xb9\xf5\x30\xe6\xb2\xa4\xb5\xfe\x9b\x3e\x7a\xb2\x55\xd2\xa8\x4a\xbc\x16\xb6\x71\x8e\x39\xc7\xdb\x9d\xe1\x10\x09\x71\xbd\x9c\xb3\x41\x89\xd7\xa5\x89\xdc\x57\xb5\x53\x4a\xfe\x4c\xe1\xbc\xa0\x21\x79\x0a\x1a\x0f\x70\xa7\x5c\x08\x8e\xde\xb0\xc0\x43\x24\xad\x74\x63\x0e\xb1\xd9\x90\xe1\xb0\x2d\x13\xa7\x6d\x78\xfd\x04\x14\x38\x8e\x90\xaa\xce\x63\xac\x3e\x23\xbc\x64\xa9\xb4\xf8\x03\x63\xde\xcd\xbe\x16\x13\x4a\x55\xac\x82\x12\xc6\xac\xd4\x35\xf7\x22\xd4\x3a\xff\x22\x73\x0e\x6e\x51\xa0\x75\x1e\xae\x8f\xe8\x5d\xc7\x59\xe6\xe4\x9a\x18\x8d\xd6\x1c\x53\x84\x4d\xb7\x67\x28\x37\x09\x84\x69\x88\x12\x0e\x01\x11\x80\x32\xa2\xf5\xb9\xaa\xc6\xd9\x73\x53\xab\xfb\xb4\x2e\x20\xc6\x54\x92\xa0\x9a\xf3\x69\x1a\x2f\x81\x77\x37\xae\x53\x1a\xce\x40\xc4\xa8\x82\x1c\xb5\xef\xda\x24\x7d\xb9\x61\x69\x14\xa2\x25\xa0\x90\xac\x56\xc0\x81\x4a\xb4\xe2\x2c\xce\x4a\x64\x7a\x9a\x23\xf4\x13\x91\x3f\xa7\x4b\xf4\x63\x84\x6f\x18\x87\x10\xbd\xc3\xfc\x8f\x90\xdd\x52\x44\x04\xc2\x51\xc4\x6e\x21\x74\x48\x21\x81\xc7\xe2\xfd\xea\x12\xf8\x0d\x09\xf6\xe9\x47\x35\xaf\x67\xc4\x14\xf7\x22\x27\x97\xe1\xe2\x76\x2d\x06\x8c\x4a\x1c\x48\x3f\x73\x2d\x0b\x5b\x29\x45\x24\x00\x2a\x0c\x11\xec\x94\xca\xc2\xa6\xc1\x37\x21\x43\x83\x3b\x5f\x97\xf1\x43\x5e\x53\x73\x19\xa5\x36\xd8\x2d\x05\x2e\x34\x0b\xeb\x39\xfc\x1d\x63\x51\x01\xbd\x3d\xbb\x90\x84\x40\x25\x59\x6d\x09\x5d\xa3\x1c\x37\xe6\x5c\x16\x9a\x40\x09\x70\xc1\xe8\x82\xf1\x35\xa6\xe4\xdf\x99\x5c\x8e\x9e\x4d\x79\xb4\x27\x2f\xbf\x7e\xf8\x05\x25\x8c\x50\xa9\x98\x29\x90\x62\x60\xea\x75\xae\x13\xca\xbf\x2b\x1a\x29\x27\x76\xd6\x20\xc6\x64\x5f\xe6\x32\x1a\x08\x87\x21\x07\x21\xbc\xb4\xe4\xe0\x32\x67\xa6\xcd\xf3\x1e\xcd\xd9\x6b\xb6\x6f\x8e\x27\xa7\xed\xdb\xe7\xbc\xcc\x1a\x07\xce\x6f\x87\x33\xf0\xba\x51\x17\x22\x66\x78\x79\x8e\xce\xe5\x13\x81\x80\x06\x2c\xe5\x78\x0d\xa1\xb2\xb8\x54\xa8\x79\x09\xbd\xbf\x3c\x47\x01\x8b\x13\x2c\xc9\x32\xaa\xaa\x1d\xd5\xee\xab\x36\xbd\x6c\xfd\x54\x6c\xc8\x08\x01\x3c\xbd\xe7\x07\x88\xb0\x24\x37\x79\x90\x28\x4a\x1d\x10\x1a\x92\x1b\x12\xa6\x38\x42\x40\xc3\x4c\x43\x62\x8e\xae\x36\xb0\x45\x71\x2a\xa4\x9a\x23\x79\x59\xb1\xa8\xf2\xa4\x0c\x60\x9f\xcc\x8d\x40\xf5\x80\xca\xa8\x99\xc3\xa7\x85\x1f\x31\x25\xa9\x82\xc5\x6d\xbd\xd8\x36\x76\x7c\x02\x28\x97\xf6\x1d\x74\x3b\x11\x7e\x91\xae\x32\xf8\x6c\xf4\xe6\x7b\x9a\xa5\x1f\x62\xc6\x21\xcf\x9a\xe5\xed\x8b\x02\xf3\x2c\x33\x33\xdf\x00\xca\xc9\x09\xb4\x04\xf5\xa5\x08\xd7\xc3\x02\x18\x66\xf1\xab\x1e\x83\x37\x4c\xcd\x12\xc1\x1d\x50\xf6\xaa\xbd\xfe\xe2\x73\x48\x38\x08\xa0\x32\x9b\x18\x44\x86\x0b\x6a\xc1\xaa\x26\x96\x2d\x96\x3c\xa0\x54\x65\x73\xe3\x08\xb5\x8b\x99\xbd\x82\xbc\x9e\xc2\xe8\x53\x46\x83\x3f\x33\x54\x2b\x5b\xad\x92\x79\xd9\x8f\x5d\x93\x98\xf2\xe6\xc6\x1c\xe6\x9a\x9e\xfc\x43\x82\x31\x66\x8e\x53\x77\xfe\x90\xe7\xf3\xf6\xe9\x62\x23\x3f\x10\x93\x18\xae\x72\x1a\x9d\xf9\x48\xcb\xcc\x5a\x65\xc7\x4a\x04\xf0\xf3\xd5\xd5\x05\x8a\x41\x08\xbc\x86\x86\x43\x51\x6c\xe0\x46\x57\xf6\x44\x40\x0d\xfb\xff\xa2\xc3\x7c\x3d\x39\x84\xdc\x09\x22\x64\x4f\x12\xd9\xba\xaa\xf6\xe3\xbd\x56\xdd\x91\x25\x6a\x14\x9c\x89\x34\x8e\x31\xdf\xee\x15\x7e\x2f\x39\x81\x15\x2a\x28\x95\x66\x51\xf5\xfd\x83\xc5\xfe\x15\x07\xcf\xf7\x08\xee\x1d\x8e\xb6\xc5\x52\xcc\x8c\x5a\x93\x66\xc5\xd8\x79\x38\x46\xd6\xa7\x88\x37\xc9\x2e\xe3\xd2\xa5\x7b\x4b\x3a\xdc\xa1\xdc\x9e\x29\xf1\x8c\x8a\x99\x16\x47\x8d\xd4\x78\x8b\xf6\x1c\xe9\x71\x54\x1b\x69\xa8\x4a\x93\x37\xe5\xb2\x2c\x4f\x0c\x92\xab\xa0\x73\x32\x72\x59\xd3\xf0\x2d\x8d\xed\xca\x37\x16\x19\x9e\xdb\x1c\xab\x17\x49\xc3\x0f\x37\xdc\x88\xb1\xb4\xd4\x42\xcb\x58\x5e\x6a\x52\x0b\x15\x10\x0a\xb0\x04\xe7\xf8\x58\x32\x16\x01\xa6\xcd\x01\xb2\xc2\x69\x24\x35\x38\x6f\x30\x6a\xae\x1b\xb4\x71\xaa\xad\x1d\xa0\xd6\x20\x2d\x8b\x3c\xc6\x82\x62\x27\x34\x6d\x15\x84\x7b\x43\xb1\x35\x78\xa6\x24\x77\x28\xc1\x6e\xfc\xe9\x48\x74\xf4\x15\xe3\xe1\x84\x42\x88\x40\x7a\x26\x49\x3b\x48\xb1\xa4\x19\x8e\x0c\xa7\xb5\x01\x6c\x0c\x97\x61\x8a\xc2\x32\xd8\x8c\x44\x69\x24\xbf\x65\x1d\x74\xd6\xe5\x44\xef\xec\x48\x5e\xb7\x8a\xa3\x29\x8e\x41\x64\xce\x1f\x88\xdc\x00\x47\x4b\x40\x98\x6e\xd1\x0d\x8e\x48\x98\x63\x5c\x21\xb1\x4c\x05\x0a\x58\x98\xc5\x6d\x4f\x0a\x77\x53\x4f\x8b\xc4\x44\x1f\xb2\xdf\x8d\x3b\xea\x9f\xfe\xf6\xf2\xc5\xff\x5d\x7f\xfe\x9f\xfb\x67\x8f\xff\xf3\xe9\x69\xd1\xfe\xb3\xc7\xfd\x3c\xf8\x3f\x71\x94\x82\x23\xd1\x72\x00\xb7\x42\x99\x6c\xc0\x60\x7b\x0f\x79\xea\xa8\x53\x4b\x56\x31\xfa\x0b\x52\x9f\x96\xdb\xcd\x2f\xd7\x67\xcd\x04\x19\x85\xfe\xdb\x02\x9a\x59\x03\xad\x63\x3c\xea\xff\x2e\x18\xfd\x00\xd9\xe2\x56\x60\x59\x93\xb9\xb6\xb2\x3e\x3c\x2c\xab\x0f\xa7\xb2\x89\x43\xc7\xf6\xd5\xce\x2e\xad\xa6\xa9\xed\xa6\xc6\x5a\xb4\xa6\x67\xdf\x8c\x26\x7b\x50\x5a\x91\x08\x2e\x6d\xd4\x3a\xc1\x9d\xf2\xdb\xde\x1e\xb2\x2c\x6c\xa5\x64\xc9\x16\xb4\x90\xaa\x4a\xb7\x0c\xde\x13\xc3\x2a\x9a\x11\x9b\x7a\x1b\x3d\x95\x97\x37\x31\x6b\x69\x7e\x34\xc0\x67\x1f\x66\x19\x49\xef\xf1\x25\xf5\xac\x0e\xea\x0a\x28\x8d\x4d\x7e\xd9\x57\x4b\x49\xe5\xc6\xb3\x25\xfd\xe6\x57\x42\x25\xac\xcd\xcf\x36\x74\x8e\xca\x24\x47\xe7\x80\xa8\x92\x72\xbd\x3d\x84\x2d\x65\xe2\x82\x1a\x9c\xc4\x44\x92\x1b\x10\x79\x8a\xc4\x4a\x2f\x60\x51\x04\x81\xaa\xf0\xa3\x95\x27\xd7\x12\x7b\xa3\x96\x03\x45\x96\xc1\x8a\x07\xc9\xb2\xb0\x95\x52\x8c\xef\x48\x9c\xc6\x7e\x94\xca\xc2\x0e\x07\x12\x44\xa9\x20\x37\xf0\xae\x0f\x49\xa3\x96\x9d\x4b\x42\x7b\x70\x59\x14\xee\xe0\xb2\x0f\x49\xa3\x96\x4b\x97\xbf\x00\x5d\x4b\x4f\xfc\xbb\x2b\xee\x92\xb9\x17\xb5\xaa\xb8\x0b\x97\x17\x9b\x43\xfd\xd6\xc2\xb2\xc2\x2e\x29\xcf\xfd\x87\x4a\x55\xda\x25\x63\x1f\x5a\x65\x69\x2b\x2d\x3d\x67\xe9\x41\xae\x5e\xc1\x6e\x2b\xd4\xdb\x3e\xa8\xd3\x26\xd2\x48\x92\x24\xca\x61\x86\x8f\x8c\xbb\xf2\x8e\x91\xdf\x1f\x06\x19\x33\xf3\x03\x4d\xba\xcd\xe2\x2d\xfb\x69\xe9\x16\x15\x13\xd5\x56\x85\x4e\x3c\x5b\x8a\xbf\x25\x72\x83\xee\x5e\x20\x22\xf2\xc8\xaa\x7b\xdb\x8e\xe4\x29\x58\xca\x38\xb7\x3f\x2e\x59\xb8\xbd\xa8\x16\x16\xf7\xdb\x79\x51\x9f\x5a\xb4\x8d\x87\x3a\x6e\xbc\x3e\xc5\xb4\xcd\x58\xf9\xf5\x3c\xb9\x6f\x49\xaf\x57\xc1\xfa\x1c\x5d\x6d\x88\x8a\x8b\xd3\x28\xcc\xb7\xef\x10\x8a\x4a\x74\xa9\x4a\xa7\x62\xbf\x0d\x76\x23\x6f\x59\xd9\x31\xee\x40\x11\xfb\x28\xec\x8d\x22\x1c\x13\x5a\x64\x94\x23\x16\x60\xbb\xd2\x7c\xa0\x98\xb2\xe5\x6e\xbc\x54\x33\xe0\x3e\xb9\x52\x17\xdb\xb7\x1b\xc8\x12\x20\x8c\x23\xca\x64\x7e\x78\xa3\x62\x5b\x75\x56\xd9\x9e\x2a\x91\x27\xb0\x70\x34\x1f\x90\x89\xb5\x86\x73\x7e\x71\xda\x1e\xfb\x3a\x72\xdc\x5e\x79\x88\xcb\x74\x79\xd9\x64\xe4\xd4\xc2\x9e\xce\xb1\xfe\x85\x5a\xc0\xe9\x0c\x34\x3d\xd0\x43\xce\xa1\x36\x39\xd5\xa1\x4e\xf5\xf8\xb1\xa9\x23\x08\x75\x84\xac\x53\x6c\x3a\xc5\xa6\x53\x6c\x3a\xc5\xa6\x7f\xc5\xd8\xf4\x51\xfd\xff\x25\x4e\xfa\x33\x05\xbe\x9d\x60\xd2\x04\x93\x6a\x5f\x33\x9b\x98\x50\xd2\xe1\x50\x52\xc6\xcc\xdb\x38\x91\xdb\xe6\xaa\xa2\x8f\xa1\x6a\xa6\xd4\xc6\x56\xd6\x8c\x40\x02\x68\x48\xe8\x1a\xe1\x9a\xd9\x2e\xb7\x05\xc3\x34\xda\x2a\xbb\xcd\x12\x36\x98\x22\x50\x4c\xa1\x1b\xc5\xd5\x84\xf0\xbe\x24\x84\xf7\x2f\x22\x37\xef\x94\xd7\x9f\xa0\xde\x04\xf5\x26\xa8\x37\x41\x3d\x64\x40\x3d\xe5\xf2\xde\x60\x89\x27\xb4\x37\xa1\xbd\xda\xd7\xd2\x2c\x26\xc0\x37\x01\x3e\x1b\xef\x5f\x06\xe0\x6b\x7c\x5c\x91\x08\x26\x10\x38\x81\xc0\x09\x04\x76\x4a\x3d\x81\xc0\xbf\x12\x08\x4c\xb0\xdc\x7c\x99\x00\xd0\x75\x70\xb4\xf8\x5a\x7c\xea\xde\x3e\x39\x08\x30\x5a\x27\x35\xed\xb4\x65\xad\x69\x74\x10\x88\x79\xe2\x30\x52\x19\xd6\x04\x21\xa7\x95\xd5\x0e\x03\xf8\xda\x20\xd7\x84\xb4\x26\xa4\x35\x21\xad\x09\x69\x21\x03\x69\x51\x46\xff\xff\x18\x9b\x54\xed\x87\x47\x06\x9d\x4e\x73\x6e\x9a\xb3\xa9\xce\x83\x5e\x4b\xc6\x71\x20\x45\xd7\x72\xf5\x40\x72\x0e\x34\x6c\xf4\x6c\xf3\xba\x5e\x4b\x97\x0e\x52\xb8\xbe\x8b\x79\xa0\x10\x86\xa1\x75\xb0\x6f\xec\xc8\xf4\x3d\x4d\x7b\x86\xc2\x02\x31\x12\x51\xbf\x07\x94\xad\x10\xd6\x2e\x79\xcf\xe9\x1c\xf5\x1e\x31\x23\x5c\x18\xfb\x9c\xfb\x70\xe0\x62\xbd\xf7\xb5\x94\xcf\xf3\xf6\xfa\xc5\x4e\x9c\x85\x76\x1d\xae\x37\xbc\xde\xa3\x41\xcb\x29\xd0\x5e\x70\x67\x50\x93\x6d\x98\xa8\xd3\x67\x0f\x68\xb1\xeb\x38\x47\x07\x10\x1b\xd2\xe2\x18\x68\x6d\x40\xbb\xa3\x40\xba\x21\xf2\x8e\x81\xfb\xf6\x92\x77\x2f\x70\xe8\xdb\xb2\x36\xbf\x30\x91\xc5\x21\xe7\x45\xcc\x34\x0c\x48\x8e\xd0\xf2\x9b\x7c\x3c\xbd\x1c\x04\x3e\x07\xe8\x7c\x2f\x84\x7a\x48\x4d\x1f\xba\xe1\x76\x45\x7b\x60\xe0\x01\xca\xee\x04\xca\x31\xbe\x73\x5f\xa3\x70\x0c\xad\x1f\xa5\xf5\x76\xd5\xbb\xd2\x7e\xfb\x30\x90\xcf\xfa\x67\x7a\xe6\xc3\x37\x42\x19\xe2\xc9\x9c\x61\x4c\xe7\xd1\x77\x55\x86\x6e\x8f\x7b\x85\x42\x33\xa3\xaa\x57\xae\xfd\xd5\xcc\x9c\x56\x68\xe2\xde\x0e\xa8\x2c\xa9\xb0\x7d\xf0\x54\x2d\x80\xf2\x48\x39\x3d\x98\x1a\x6d\x0b\x9d\xba\x53\xfb\xce\xf8\xd1\x7e\xbb\x60\x4f\x06\xf5\xce\xda\xab\xeb\xca\xcb\xd5\xac\x20\xda\x72\x3b\xa2\x4b\x38\xd7\xb5\x89\xbe\x42\xd9\xb9\x73\xc4\x0c\x6d\xb7\xd9\xf8\x8d\xbd\x3e\x9c\xf5\x53\x68\x48\x14\x36\x8f\x09\xc5\x92\xf1\x21\xd1\x09\x07\x1c\xbe\xa7\x91\xf3\x6a\xc8\xc1\x57\xb0\xdd\xc5\xc6\x1d\xad\x76\x1d\xa8\x82\x0e\x4c\x38\xfe\xa5\x8c\xc5\x0a\x40\x5d\xa1\xbb\x98\xd1\xfb\x74\x61\xed\x1a\x98\xaf\x3c\x8c\x1e\xe3\xc2\x92\x29\x74\x3e\x99\xd0\xf9\x41\x50\xd0\x38\x4b\x57\x7e\x5b\x7a\x0e\xe6\xce\x4e\xd7\x19\x35\x57\xbb\x3c\x3c\xd2\x5e\x4f\x4b\x4c\xf7\x0f\x4d\x2b\x91\x5d\x94\xa6\x95\xc8\x69\x25\x72\x5a\x89\x7c\xb8\x95\xc8\x07\x80\x8c\xda\x9c\x64\x7b\xb7\x71\xdf\x57\x12\x4b\x9a\x1f\x72\x0c\x13\x03\xad\x3c\xd5\x4e\xde\x8e\x57\x13\x6d\x34\x86\xcf\x97\xe6\xa4\x68\xc4\xb0\xf6\xc9\xc2\xeb\x8d\x0b\xd7\xcd\xfe\xba\xa6\xf5\x30\xeb\x30\x33\xbe\xc7\x56\x27\xab\x08\xd9\x6d\xbb\x09\xee\x7c\x2d\xcf\xee\x87\x38\xac\xc8\xdd\x90\x9a\x58\x4a\x4e\x96\xa9\x79\x79\xf3\xde\x20\xf0\x96\xe3\x24\x19\xeb\xba\xf2\x53\x19\xab\x12\xaf\x47\xb3\xa0\x3e\xef\x9b\x8d\x6d\x6d\x7b\xde\x3b\x3b\x1a\xc0\x3f\x95\x7e\xed\x78\xfb\x76\xb8\xaf\xb3\xdd\xc5\xeb\x95\xed\x5a\x62\x41\x82\xb3\x54\x6e\x80\x4a\x92\x6f\x36\xbd\x34\xae\xde\x6f\xa4\xc0\xbc\x08\xe3\x84\xfc\x1d\xb6\xe3\xd0\x62\x38\x95\x9b\x57\xe7\x71\x12\x91\x80\xc8\x31\x69\x5e\x60\x21\x6e\x19\x0f\xc7\xa4\x79\x96\x28\x3e\x47\x54\x65\x41\x36\x08\x40\x88\x1f\x58\x08\x56\xaa\xd5\xbf\xaf\xad\x96\xd7\xd6\xcf\x87\xf5\x34\x0f\x71\x93\x6e\x26\xed\x98\x5b\x9f\x4f\xcf\x95\x34\xc6\xd7\x11\xfa\xb0\x81\x22\x1a\xdb\xdf\x8e\xdc\xc3\xb9\xf8\xdd\x5d\x3c\x74\xe6\xea\xb7\x8b\xbf\xf5\x6e\xb3\x46\x2e\x64\xf4\xab\x3c\x4e\xcf\x36\x1d\xfe\xfa\xb8\x36\xba\x8a\xd8\xad\xf6\xc6\x41\x2a\x37\x8c\x17\x0f\xda\xfe\xda\xe7\x65\xbc\x71\x2c\x36\x57\x8a\x47\x12\x4c\xf1\xbd\x77\x6b\xa4\x50\x7e\x77\x7b\x22\x60\x89\xef\xcd\xf5\xb9\x0c\x97\x79\x0d\x2b\x35\x43\xcb\x3d\x24\xf1\x78\xfc\xf8\xcb\x1f\x15\x06\xe2\x78\xd8\x51\x21\xd9\x1f\xf0\xf5\x8f\x86\xa4\x50\xfa\xb1\x47\x43\xa5\xdd\x69\x14\xe8\xa3\xc0\x86\x91\xa7\x81\x50\xb4\x7c\xc0\x81\x80\x77\x7a\x9f\xc6\xc2\xa9\x8c\x05\x33\xb0\x3b\x31\xa4\xf4\xd7\x1b\x26\x55\x97\x7c\x65\xf8\x69\x1a\x84\x8e\x41\x78\xd9\xec\xc5\x11\x16\x1e\x74\x91\xf5\x56\xf5\x57\x49\x47\x5c\x92\xa9\x1e\x99\x36\xf4\xdb\xb1\x0e\xd3\x78\x02\xb0\x9b\x25\xcb\xe9\xe9\x1d\x0d\x44\x01\x42\x08\x91\x64\xd9\xdd\x37\x08\x17\xef\xf9\xe5\x0f\xbd\x46\x91\xf5\xf9\x89\x92\x37\xdd\x89\x59\x44\x1f\x9c\xee\x34\x1e\xbe\x47\x83\x32\x72\x8e\x37\xdf\xac\x69\x38\xef\x75\xb0\xda\xdb\xac\x83\x94\x2f\x39\xa6\x62\x05\x1c\x25\x9c\x49\x16\xb0\xa8\x3c\xc7\x7e\x76\x71\x3e\x6f\xb5\x24\xe7\xe8\xb7\xb9\xc7\x6c\x43\x92\xee\x21\xd4\x17\xa1\x7f\xba\x35\xfe\xae\x39\xbc\xde\xba\x69\xd9\x8e\xe1\x62\xde\x64\x7d\x16\x88\x1b\xed\x29\x11\xfd\x4f\xa9\xff\x99\x90\xc4\xf6\xf4\xf9\x6e\xe9\x28\x23\xd7\xca\xe5\xee\xee\x9f\x63\xb1\x5b\xfb\x10\xd7\x2f\x1d\xf2\xe3\xbf\xb9\xb5\x6f\xa4\x6d\x7d\x25\x79\xfb\x24\x31\xea\x56\xbe\x5d\x53\xcd\x2d\x36\xa3\x6d\xdf\xab\x1c\xb8\x6d\x6f\xc0\x98\xa7\xdd\xaa\x86\x8c\x1d\x39\xa3\x9d\x70\x2b\x9b\x68\xd9\xfd\x33\xfe\xa9\xb6\x4a\x2e\x63\x0f\xcf\x68\x27\xd9\x4c\xb9\x46\x6d\xcb\xbe\xa1\xa8\xd6\x5f\xc6\xd6\x9f\xf1\x4f\xf4\xd4\xb4\x78\xd0\xd6\xf4\x13\x3c\x3b\xac\xd0\xdc\x90\x34\xda\xc9\xb4\x9a\x1a\x8d\xbd\x93\x87\xd4\xe2\x21\x1b\xb3\x2b\xd1\xbe\xe7\x69\xd4\x53\x67\xd5\x40\xa0\xe3\x19\x3f\x6d\x1a\xbc\x0e\x86\x3c\x10\xb4\x3d\x2a\xcd\x78\x32\xe6\xab\xbd\x36\xc9\xf4\x3a\x58\xae\xc3\xf4\x47\xea\xbf\xfb\x47\xff\x0d\x00\x00\xff\xff\xd2\x32\x5a\x28\x38\x9d\x00\x00") - -func v2SchemaJsonBytes() ([]byte, error) { - return bindataRead( - _v2SchemaJson, - "v2/schema.json", - ) -} - -func v2SchemaJson() (*asset, error) { - bytes, err := v2SchemaJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "v2/schema.json", size: 40248, mode: os.FileMode(0640), modTime: time.Unix(1568964748, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xab, 0x88, 0x5e, 0xf, 0xbf, 0x17, 0x74, 0x0, 0xb2, 0x5a, 0x7f, 0xbc, 0x58, 0xcd, 0xc, 0x25, 0x73, 0xd5, 0x29, 0x1c, 0x7a, 0xd0, 0xce, 0x79, 0xd4, 0x89, 0x31, 0x27, 0x90, 0xf2, 0xff, 0xe6}} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// AssetString returns the asset contents as a string (instead of a []byte). -func AssetString(name string) (string, error) { - data, err := Asset(name) - return string(data), err -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// MustAssetString is like AssetString but panics when Asset would return an -// error. It simplifies safe initialization of global variables. -func MustAssetString(name string) string { - return string(MustAsset(name)) -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetDigest returns the digest of the file with the given name. It returns an -// error if the asset could not be found or the digest could not be loaded. -func AssetDigest(name string) ([sha256.Size]byte, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { - a, err := f() - if err != nil { - return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) - } - return a.digest, nil - } - return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) -} - -// Digests returns a map of all known files and their checksums. -func Digests() (map[string][sha256.Size]byte, error) { - mp := make(map[string][sha256.Size]byte, len(_bindata)) - for name := range _bindata { - a, err := _bindata[name]() - if err != nil { - return nil, err - } - mp[name] = a.digest - } - return mp, nil -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "jsonschema-draft-04.json": jsonschemaDraft04Json, - - "v2/schema.json": v2SchemaJson, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"}, -// AssetDir("data/img") would return []string{"a.png", "b.png"}, -// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - canonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(canonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} - -var _bintree = &bintree{nil, map[string]*bintree{ - "jsonschema-draft-04.json": {jsonschemaDraft04Json, map[string]*bintree{}}, - "v2": {nil, map[string]*bintree{ - "schema.json": {v2SchemaJson, map[string]*bintree{}}, - }}, -}} - -// RestoreAsset restores an asset under the given directory. -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) -} - -// RestoreAssets restores an asset under the given directory recursively. -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - canonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) -} diff --git a/embed.go b/embed.go new file mode 100644 index 0000000..1f42847 --- /dev/null +++ b/embed.go @@ -0,0 +1,17 @@ +package spec + +import ( + "embed" + "path" +) + +//go:embed schemas/*.json schemas/*/*.json +var assets embed.FS + +func jsonschemaDraft04JSONBytes() ([]byte, error) { + return assets.ReadFile(path.Join("schemas", "jsonschema-draft-04.json")) +} + +func v2SchemaJSONBytes() ([]byte, error) { + return assets.ReadFile(path.Join("schemas", "v2", "schema.json")) +} diff --git a/spec.go b/spec.go index b388503..876aa12 100644 --- a/spec.go +++ b/spec.go @@ -41,7 +41,7 @@ func MustLoadJSONSchemaDraft04() *Schema { // JSONSchemaDraft04 loads the json schema document for json shema draft04 func JSONSchemaDraft04() (*Schema, error) { - b, err := Asset("jsonschema-draft-04.json") + b, err := jsonschemaDraft04JSONBytes() if err != nil { return nil, err } @@ -65,7 +65,7 @@ func MustLoadSwagger20Schema() *Schema { // Swagger20Schema loads the swagger 2.0 schema from the embedded assets func Swagger20Schema() (*Schema, error) { - b, err := Asset("v2/schema.json") + b, err := v2SchemaJSONBytes() if err != nil { return nil, err } From b2509827dd3d96e9a7bb38da2fa08b65194f32ce Mon Sep 17 00:00:00 2001 From: fredbi Date: Mon, 4 Dec 2023 22:47:35 +0100 Subject: [PATCH 09/28] Revert fix #146 (#172) A more thorough investigation on loading specs from a generated server from paths containing special characters (such as blank spaces, parenthesis) did not conclude that it was necessary to alter how cache entries are matched. Indeed, this change deeply altered how keys in the cache are managed and was therefore at best, a risky bet. * reverted commit e8e27ff * added check to ensure that the root pseudo-document is preloaded in cache under all conditions * added more unit tests to check the behavior of the normalizers against escaped characters * closes #145 Signed-off-by: Frederic BIDON --- .gitignore | 3 +- expander.go | 16 +- expander_test.go | 47 +++ .../145/Program Files (x86)/AppName/ref.json | 17 + .../AppName/todos.common.json | 103 ++++++ .../Program Files (x86)/AppName/todos.json | 336 ++++++++++++++++++ normalizer_test.go | 29 ++ schema_loader.go | 9 +- schema_loader_test.go | 33 ++ 9 files changed, 578 insertions(+), 15 deletions(-) create mode 100644 fixtures/bugs/145/Program Files (x86)/AppName/ref.json create mode 100644 fixtures/bugs/145/Program Files (x86)/AppName/todos.common.json create mode 100644 fixtures/bugs/145/Program Files (x86)/AppName/todos.json create mode 100644 schema_loader_test.go diff --git a/.gitignore b/.gitignore index dd91ed6..f47cb20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -secrets.yml -coverage.out +*.out diff --git a/expander.go b/expander.go index 012a462..fae9c12 100644 --- a/expander.go +++ b/expander.go @@ -102,15 +102,21 @@ const rootBase = ".root" // baseForRoot loads in the cache the root document and produces a fake ".root" base path entry // for further $ref resolution -// -// Setting the cache is optional and this parameter may safely be left to nil. func baseForRoot(root interface{}, cache ResolutionCache) string { + // cache the root document to resolve $ref's + normalizedBase := normalizeBase(rootBase) + if root == nil { - return "" + // ensure that we never leave a nil root: always cache the root base pseudo-document + cachedRoot, found := cache.Get(normalizedBase) + if found && cachedRoot != nil { + // the cache is already preloaded with a root + return normalizedBase + } + + root = map[string]interface{}{} } - // cache the root document to resolve $ref's - normalizedBase := normalizeBase(rootBase) cache.Set(normalizedBase, root) return normalizedBase diff --git a/expander_test.go b/expander_test.go index 719ef44..9bdeb6c 100644 --- a/expander_test.go +++ b/expander_test.go @@ -1098,6 +1098,53 @@ func TestExpand_ExtraItems(t *testing.T) { }`, jazon) } +func TestExpand_Issue145(t *testing.T) { + cwd, err := os.Getwd() + require.NoError(t, err) + pseudoRoot := normalizeBase(filepath.Join(cwd, rootBase)) + + // assert the internal behavior of baseForRoot() + t.Run("with nil root, empty cache", func(t *testing.T) { + cache := defaultResolutionCache() + require.Equal(t, pseudoRoot, baseForRoot(nil, cache)) + + t.Run("empty root is cached", func(t *testing.T) { + value, ok := cache.Get(pseudoRoot) + require.True(t, ok) // found in cache + asMap, ok := value.(map[string]interface{}) + require.True(t, ok) + require.Empty(t, asMap) + }) + }) + + t.Run("with non-nil root, empty cache", func(t *testing.T) { + cache := defaultResolutionCache() + require.Equal(t, pseudoRoot, baseForRoot(map[string]interface{}{"key": "arbitrary"}, cache)) + + t.Run("non-empty root is cached", func(t *testing.T) { + value, ok := cache.Get(pseudoRoot) + require.True(t, ok) // found in cache + asMap, ok := value.(map[string]interface{}) + require.True(t, ok) + require.Contains(t, asMap, "key") + require.Equal(t, "arbitrary", asMap["key"]) + }) + + t.Run("with nil root, non-empty cache", func(t *testing.T) { + require.Equal(t, pseudoRoot, baseForRoot(nil, cache)) + + t.Run("non-empty root is kept", func(t *testing.T) { + value, ok := cache.Get(pseudoRoot) + require.True(t, ok) // found in cache + asMap, ok := value.(map[string]interface{}) + require.True(t, ok) + require.Contains(t, asMap, "key") + require.Equal(t, "arbitrary", asMap["key"]) + }) + }) + }) +} + // PetStore20 json doc for swagger 2.0 pet store const PetStore20 = `{ "swagger": "2.0", diff --git a/fixtures/bugs/145/Program Files (x86)/AppName/ref.json b/fixtures/bugs/145/Program Files (x86)/AppName/ref.json new file mode 100644 index 0000000..10a8cb7 --- /dev/null +++ b/fixtures/bugs/145/Program Files (x86)/AppName/ref.json @@ -0,0 +1,17 @@ +{ +"definitions": { + "todo-partial": { + "title": "Todo Partial", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "completed": { + "type": ["boolean", "null"] + } + }, + "required": ["name", "completed"] + } + } +} diff --git a/fixtures/bugs/145/Program Files (x86)/AppName/todos.common.json b/fixtures/bugs/145/Program Files (x86)/AppName/todos.common.json new file mode 100644 index 0000000..1c43908 --- /dev/null +++ b/fixtures/bugs/145/Program Files (x86)/AppName/todos.common.json @@ -0,0 +1,103 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0", + "title": "To-do Demo", + "description": + "### Notes:\n\nThis OAS2 (Swagger 2) specification defines common models and responses, that other specifications may reference.\n\nFor example, check out the user poperty in the main.oas2 todo-partial model - it references the user model in this specification!\n\nLikewise, the main.oas2 operations reference the shared error responses in this common specification.", + "contact": { + "name": "Stoplight", + "url": "https://stoplight.io" + }, + "license": { + "name": "MIT" + } + }, + "host": "example.com", + "securityDefinitions": {}, + "paths": {}, + "responses": { + "401": { + "description": "", + "schema": { + "$ref": "#/definitions/error-response" + }, + "examples": { + "application/json": { + "status": "401", + "error": "Not Authorized" + } + } + }, + "403": { + "description": "", + "schema": { + "$ref": "#/definitions/error-response" + }, + "examples": { + "application/json": { + "status": "403", + "error": "Forbbiden" + } + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/error-response" + }, + "examples": { + "application/json": { + "status": "404", + "error": "Not Found" + } + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/error-response" + }, + "examples": { + "application/json": { + "status": "500", + "error": "Server Error" + } + } + } + }, + "definitions": { + "user": { + "title": "User", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The user's full name." + }, + "age": { + "type": "number", + "minimum": 0, + "maximum": 150 + }, + "error": { + "$ref": "#/definitions/error-response" + } + }, + "required": ["name", "age"] + }, + "error-response": { + "type": "object", + "title": "Error Response", + "properties": { + "status": { + "type": "string" + }, + "error": { + "type": "string" + } + }, + "required": ["status", "error"] + } + } +} diff --git a/fixtures/bugs/145/Program Files (x86)/AppName/todos.json b/fixtures/bugs/145/Program Files (x86)/AppName/todos.json new file mode 100644 index 0000000..9c5072e --- /dev/null +++ b/fixtures/bugs/145/Program Files (x86)/AppName/todos.json @@ -0,0 +1,336 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0", + "title": "To-do Demo", + "description": "This OAS2 (Swagger 2) file represents a real API that lives at http://todos.stoplight.io.\n\nFor authentication information, click the apikey security scheme in the editor sidebar.", + "contact": { + "name": "Stoplight", + "url": "https://stoplight.io" + }, + "license": { + "name": "MIT" + } + }, + "host": "todos.stoplight.io", + "schemes": ["http"], + "consumes": ["application/json"], + "produces": ["application/json"], + "securityDefinitions": { + "Basic": { + "type": "basic" + }, + "API Key": { + "type": "apiKey", + "name": "apikey", + "in": "query" + } + }, + "paths": { + "/todos/{todoId}": { + "parameters": [{ + "name": "todoId", + "in": "path", + "required": true, + "type": "string" + }], + "get": { + "operationId": "GET_todo", + "summary": "Get Todo", + "tags": ["Todos"], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/todo-full" + }, + "examples": { + "application/json": { + "id": 1, + "name": "get food", + "completed": false, + "completed_at": "1955-04-23T13:22:52.685Z", + "created_at": "1994-11-05T03:26:51.471Z", + "updated_at": "1989-07-29T11:30:06.701Z" + }, + "/todos/foobar": "{\n\t\"foo\": \"bar\"\n}\n", + "/todos/chores": { + "id": 9000, + "name": "Do Chores", + "completed": false, + "created_at": "2014-08-28T14:14:28.494Z", + "updated_at": "2014-08-28T14:14:28.494Z" + }, + "new": { + "name": "esse qui proident labore", + "completed": null, + "id": 920778, + "completed_at": "2014-01-07T07:49:55.123Z", + "created_at": "1948-04-21T12:04:21.282Z", + "updated_at": "1951-12-19T11:10:34.039Z", + "user": { + "name": "irure deserunt fugiat", + "age": 121.45395681110494 + }, + "float": -47990796.228164576 + } + } + }, + "404": { + "$ref": "./todos.common.json#/responses/404" + }, + "500": { + "$ref": "./todos.common.json#/responses/500" + } + }, + "parameters": [{ + "in": "query", + "name": "", + "type": "string" + }] + }, + "put": { + "operationId": "PUT_todos", + "summary": "Update Todo", + "tags": ["Todos"], + "parameters": [{ + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/todo-partial", + "example": { + "name": "my todo's new name", + "completed": false + } + } + }], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/todo-full" + }, + "examples": { + "application/json": { + "id": 9000, + "name": "It's Over 9000!!!", + "completed": true, + "completed_at": null, + "created_at": "2014-08-28T14:14:28.494Z", + "updated_at": "2015-08-28T14:14:28.494Z" + } + } + }, + "401": { + "$ref": "./todos.common.json#/responses/401" + }, + "404": { + "$ref": "./todos.common.json#/responses/404" + }, + "500": { + "$ref": "./todos.common.json#/responses/500" + } + }, + "security": [{ + "Basic": [] + }, + { + "API Key": [] + } + ] + }, + "delete": { + "operationId": "DELETE_todo", + "summary": "Delete Todo", + "tags": ["Todos"], + "responses": { + "204": { + "description": "" + }, + "401": { + "$ref": "./todos.common.json#/responses/401" + }, + "404": { + "$ref": "./todos.common.json#/responses/404" + }, + "500": { + "$ref": "./todos.common.json#/responses/500" + } + }, + "security": [{ + "Basic": [] + }, + { + "API Key": [] + } + ] + } + }, + "/todos": { + "post": { + "operationId": "POST_todos", + "summary": "Create Todo", + "tags": ["Todos"], + "parameters": [{ + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/todo-partial", + "example": { + "name": "my todo's name", + "completed": false + } + } + }], + "responses": { + "201": { + "description": "", + "schema": { + "$ref": "#/definitions/todo-full" + }, + "examples": { + "application/json": { + "id": 9000, + "name": "It's Over 9000!!!", + "completed": null, + "completed_at": null, + "created_at": "2014-08-28T14:14:28.494Z", + "updated_at": "2014-08-28T14:14:28.494Z" + }, + "/todos/chores": { + "id": 9000, + "name": "Do Chores", + "completed": false, + "created_at": "2014-08-28T14:14:28.494Z", + "updated_at": "2014-08-28T14:14:28.494Z" + } + } + }, + "401": { + "$ref": "./todos.common.json#/responses/401" + }, + "500": { + "$ref": "./todos.common.json#/responses/500" + } + }, + "security": [{ + "API Key": [] + }, + { + "Basic": [] + } + ], + "description": "This creates a Todo object.\n\nTesting `inline code`." + }, + "get": { + "operationId": "GET_todos", + "summary": "List Todos", + "tags": ["Todos"], + "parameters": [{ + "$ref": "#/parameters/limit" + }, + { + "$ref": "#/parameters/skip" + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/todo-full" + } + }, + "examples": { + "application/json": [{ + "id": 1, + "name": "design the thingz", + "completed": true + }, + { + "id": 2, + "name": "mock the thingz", + "completed": true + }, + { + "id": 3, + "name": "code the thingz", + "completed": false + } + ], + "empty": [] + }, + "headers": { + "foo": { + "type": "string", + "default": "bar" + } + } + }, + "500": { + "$ref": "./todos.common.json#/responses/500" + } + }, + "description": "​" + } + } + }, + "parameters": { + "limit": { + "name": "limit", + "in": "query", + "description": "This is how it works.", + "required": false, + "type": "integer", + "maximum": 100 + }, + "skip": { + "name": "skip", + "in": "query", + "required": false, + "type": "string" + } + }, + "definitions": { + "todo-partial": { + "$ref": "ref.json#/definitions/todo-partial" + }, + "todo-full": { + "title": "Todo Full", + "allOf": [{ + "$ref": "#/definitions/todo-partial" + }, + { + "type": "object", + "properties": { + "id": { + "type": "integer", + "minimum": 0, + "maximum": 1000000 + }, + "completed_at": { + "type": ["string", "null"], + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user": { + "$ref": "./todos.common.json#/definitions/user" + } + }, + "required": ["id", "user"] + } + ] + } + }, + "tags": [{ + "name": "Todos" + }] +} diff --git a/normalizer_test.go b/normalizer_test.go index 66f30bf..8d72c28 100644 --- a/normalizer_test.go +++ b/normalizer_test.go @@ -219,6 +219,30 @@ func TestNormalizer_NormalizeURI(t *testing.T) { base: `https://example.com//base/Spec.json`, expOutput: `https://example.com/base/Resources.yaml#/definitions/Pets`, }, + { + // escaped characters in base (1) + refPath: `Resources.yaml#/definitions/Pets`, + base: `https://example.com/base (x86)/Spec.json`, + expOutput: `https://example.com/base%20%28x86%29/Resources.yaml#/definitions/Pets`, + }, + { + // escaped characters in base (2) + refPath: `Resources.yaml#/definitions/Pets`, + base: `https://example.com/base [x86]/Spec.json`, + expOutput: `https://example.com/base%20%5Bx86%5D/Resources.yaml#/definitions/Pets`, + }, + { + // escaped characters in joined fragment + refPath: `Resources.yaml#/definitions (x86)/Pets`, + base: `https://example.com/base/Spec.json`, + expOutput: `https://example.com/base/Resources.yaml#/definitions%20(x86)/Pets`, + }, + { + // escaped characters in joined path + refPath: `Resources [x86].yaml#/definitions/Pets`, + base: `https://example.com/base/Spec.json`, + expOutput: `https://example.com/base/Resources%20%5Bx86%5D.yaml#/definitions/Pets`, + }, } }() @@ -423,6 +447,11 @@ func TestNormalizer_NormalizeBase(t *testing.T) { Expected: "file:///e:/base/sub/file.json", Windows: true, }, + { + // escaped characters in base (1) + Base: `file:///c:/base (x86)/spec.json`, + Expected: `file:///c:/base%20%28x86%29/spec.json`, + }, } { testCase := toPin if testCase.Windows && runtime.GOOS != windowsOS { diff --git a/schema_loader.go b/schema_loader.go index b81175a..0059b99 100644 --- a/schema_loader.go +++ b/schema_loader.go @@ -168,14 +168,7 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error) normalized := normalizeBase(pth) debugLog("loading doc from: %s", normalized) - unescaped, err := url.PathUnescape(normalized) - if err != nil { - return nil, url.URL{}, false, err - } - - u := url.URL{Path: unescaped} - - data, fromCache := r.cache.Get(u.RequestURI()) + data, fromCache := r.cache.Get(normalized) if fromCache { return data, toFetch, fromCache, nil } diff --git a/schema_loader_test.go b/schema_loader_test.go new file mode 100644 index 0000000..67a1e79 --- /dev/null +++ b/schema_loader_test.go @@ -0,0 +1,33 @@ +package spec + +import ( + "encoding/json" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestLoader_Issue145(t *testing.T) { + t.Run("with ExpandSpec", func(t *testing.T) { + basePath := filepath.Join("fixtures", "bugs", "145", "Program Files (x86)", "AppName", "todos.json") + todosDoc, err := jsonDoc(basePath) + require.NoError(t, err) + + spec := new(Swagger) + require.NoError(t, json.Unmarshal(todosDoc, spec)) + + require.NoError(t, ExpandSpec(spec, &ExpandOptions{RelativeBase: basePath})) + }) + + t.Run("with ExpandSchema", func(t *testing.T) { + basePath := filepath.Join("fixtures", "bugs", "145", "Program Files (x86)", "AppName", "ref.json") + schemaDoc, err := jsonDoc(basePath) + require.NoError(t, err) + + sch := new(Schema) + require.NoError(t, json.Unmarshal(schemaDoc, sch)) + + require.NoError(t, ExpandSchema(sch, nil, nil)) + }) +} From 7d71edaf65842e0225e448e7107960b34fa471b1 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Tue, 5 Dec 2023 10:11:56 +0100 Subject: [PATCH 10/28] doc: fixed typo in badge link Signed-off-by: Frederic BIDON --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8218c4a..ce4cc52 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# OpenAPI v2 object model [![Build Status](https://github.com/go-openapi/spec/actions/workflows/go-test.yaml/badge.svg)](https://github.com/go-openapi/strfmt/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) +# OpenAPI v2 object model [![Build Status](https://github.com/go-openapi/spec/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/strfmt/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE) From 4df02b2822b3e0b1dbc3e8d1789bf3349437fbd7 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Tue, 5 Dec 2023 22:18:32 +0100 Subject: [PATCH 11/28] fixed yet another typo with badges Signed-off-by: Frederic BIDON --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce4cc52..822172f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# OpenAPI v2 object model [![Build Status](https://github.com/go-openapi/spec/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/strfmt/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) +# OpenAPI v2 object model [![Build Status](https://github.com/go-openapi/spec/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/spec/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE) From 94a1c0d6107d48df2acf85b961984d3f15d3212c Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Sun, 17 Dec 2023 18:51:16 +0100 Subject: [PATCH 12/28] updated dependencies Signed-off-by: Frederic BIDON --- go.mod | 10 ++++------ go.sum | 31 ++++++------------------------- structs_test.go | 2 +- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index f9d343e..a5b4f1f 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/go-openapi/spec require ( - github.com/go-openapi/jsonpointer v0.20.0 - github.com/go-openapi/jsonreference v0.20.2 - github.com/go-openapi/swag v0.22.4 + github.com/go-openapi/jsonpointer v0.20.1 + github.com/go-openapi/jsonreference v0.20.3 + github.com/go-openapi/swag v0.22.5 github.com/stretchr/testify v1.8.4 - gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -13,8 +13,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) go 1.19 diff --git a/go.sum b/go.sum index 9d6f790..b9ffcdc 100644 --- a/go.sum +++ b/go.sum @@ -1,42 +1,23 @@ -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.20.1 h1:MkK4VEIEZMj4wT9PmjaUmGflVBr9nvud4Q4UVFbDoBE= +github.com/go-openapi/jsonpointer v0.20.1/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.3 h1:EjGcjTW8pD1mRis6+w/gmoBdqv5+RbE9B85D1NgDOVQ= +github.com/go-openapi/jsonreference v0.20.3/go.mod h1:FviDZ46i9ivh810gqzFLl5NttD5q3tSlMLqLr6okedM= +github.com/go-openapi/swag v0.22.5 h1:fVS63IE3M0lsuWRzuom3RLwUMVI2peDH01s6M70ugys= +github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/structs_test.go b/structs_test.go index 7b076b4..c8e191a 100644 --- a/structs_test.go +++ b/structs_test.go @@ -20,7 +20,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v2" + "gopkg.in/yaml.v3" ) func assertSerializeJSON(t testing.TB, actual interface{}, expected string) bool { From 8789dc37e2d3077dfc083c5127054e1b1640b5c4 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Sun, 17 Dec 2023 19:01:25 +0100 Subject: [PATCH 13/28] removed pre-go1.19 code Signed-off-by: Frederic BIDON --- url_go18.go | 8 -------- url_go19.go | 3 --- 2 files changed, 11 deletions(-) delete mode 100644 url_go18.go diff --git a/url_go18.go b/url_go18.go deleted file mode 100644 index 60b7851..0000000 --- a/url_go18.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !go1.19 -// +build !go1.19 - -package spec - -import "net/url" - -var parseURL = url.Parse diff --git a/url_go19.go b/url_go19.go index 392e3e6..5bdfe40 100644 --- a/url_go19.go +++ b/url_go19.go @@ -1,6 +1,3 @@ -//go:build go1.19 -// +build go1.19 - package spec import "net/url" From ee158dfb98f491cb7278fd91cd35f94f3839c2d7 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Fri, 22 Dec 2023 12:28:08 +0100 Subject: [PATCH 14/28] chore(deps): updated go-openapi deps Signed-off-by: Frederic BIDON --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index a5b4f1f..898a3e9 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/go-openapi/spec require ( - github.com/go-openapi/jsonpointer v0.20.1 - github.com/go-openapi/jsonreference v0.20.3 - github.com/go-openapi/swag v0.22.5 + github.com/go-openapi/jsonpointer v0.20.2 + github.com/go-openapi/jsonreference v0.20.4 + github.com/go-openapi/swag v0.22.6 github.com/stretchr/testify v1.8.4 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index b9ffcdc..3d2ef0b 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.20.1 h1:MkK4VEIEZMj4wT9PmjaUmGflVBr9nvud4Q4UVFbDoBE= -github.com/go-openapi/jsonpointer v0.20.1/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.3 h1:EjGcjTW8pD1mRis6+w/gmoBdqv5+RbE9B85D1NgDOVQ= -github.com/go-openapi/jsonreference v0.20.3/go.mod h1:FviDZ46i9ivh810gqzFLl5NttD5q3tSlMLqLr6okedM= -github.com/go-openapi/swag v0.22.5 h1:fVS63IE3M0lsuWRzuom3RLwUMVI2peDH01s6M70ugys= -github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/swag v0.22.6 h1:dnqg1XfHXL9aBxSbktBqFR5CxVyVI+7fYWhAf1JOeTw= +github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= From b445199da3b5022c502fdf4f6b7fd2c534e8d376 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Mon, 25 Dec 2023 12:51:17 +0100 Subject: [PATCH 15/28] fix(ci): muted warnings in CI runs due to cache conflicts Every time a job is posted, I receive false alarm failure notifications because of some cache conflict during the linting job. Reference: golangci/golangci-lint-action#807 Signed-off-by: Frederic BIDON --- .github/workflows/go-test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index e1a95c7..62682bf 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -18,6 +18,7 @@ jobs: with: version: latest only-new-issues: true + skip-cache: true test: name: Unit tests @@ -38,7 +39,7 @@ jobs: - uses: actions/checkout@v3 - - run: go test -v -race -coverprofile="coverage-${{ matrix.os }}.${{ matrix.go_version }}.out" -covermode=atomic ./... + - run: go test -v -race -coverprofile="coverage-${{ matrix.os }}.${{ matrix.go_version }}.out" -covermode=atomic -coverpkg=$(go list)/... ./... - name: Upload coverage to codecov uses: codecov/codecov-action@v3 From ed00e7169ddfe4d5d2d6c668d81f54867bc24047 Mon Sep 17 00:00:00 2001 From: fredbi Date: Tue, 9 Jan 2024 08:23:18 +0100 Subject: [PATCH 16/28] fix(expand): parameters & responses should properly follow remote doc resolution when SKipSchema (#183) * fix(expand): parameters & responses should properly follow remote doc resolution when SKipSchema * fixes #182 * contributes go-swagger/go-swagger#2743 Signed-off-by: Frederic BIDON * fixed assertion in test for windows paths Signed-off-by: Frederic BIDON --------- Signed-off-by: Frederic BIDON --- expander.go | 56 +++++++++++-------- fixtures/bugs/2743/not-working/minimal.yaml | 7 +++ fixtures/bugs/2743/not-working/spec.yaml | 11 ++++ .../2743/not-working/swagger/definitions.yml | 9 +++ .../bugs/2743/not-working/swagger/items.yml | 15 +++++ .../2743/not-working/swagger/paths/bar.yml | 8 +++ .../2743/not-working/swagger/paths/foo.yml | 8 +++ .../2743/not-working/swagger/paths/index.yml | 6 ++ .../2743/not-working/swagger/paths/nested.yml | 14 +++++ .../2743/not-working/swagger/user/index.yml | 2 + .../2743/not-working/swagger/user/model.yml | 4 ++ fixtures/bugs/2743/working/spec.yaml | 11 ++++ .../bugs/2743/working/swagger/definitions.yml | 9 +++ fixtures/bugs/2743/working/swagger/items.yml | 15 +++++ .../bugs/2743/working/swagger/paths/bar.yml | 8 +++ .../bugs/2743/working/swagger/paths/foo.yml | 8 +++ .../bugs/2743/working/swagger/paths/index.yml | 6 ++ .../2743/working/swagger/paths/nested.yml | 14 +++++ .../bugs/2743/working/swagger/user/index.yml | 2 + .../bugs/2743/working/swagger/user/model.yml | 4 ++ spec_test.go | 32 +++++++++++ 21 files changed, 225 insertions(+), 24 deletions(-) create mode 100644 fixtures/bugs/2743/not-working/minimal.yaml create mode 100644 fixtures/bugs/2743/not-working/spec.yaml create mode 100644 fixtures/bugs/2743/not-working/swagger/definitions.yml create mode 100644 fixtures/bugs/2743/not-working/swagger/items.yml create mode 100644 fixtures/bugs/2743/not-working/swagger/paths/bar.yml create mode 100644 fixtures/bugs/2743/not-working/swagger/paths/foo.yml create mode 100644 fixtures/bugs/2743/not-working/swagger/paths/index.yml create mode 100644 fixtures/bugs/2743/not-working/swagger/paths/nested.yml create mode 100644 fixtures/bugs/2743/not-working/swagger/user/index.yml create mode 100644 fixtures/bugs/2743/not-working/swagger/user/model.yml create mode 100644 fixtures/bugs/2743/working/spec.yaml create mode 100644 fixtures/bugs/2743/working/swagger/definitions.yml create mode 100644 fixtures/bugs/2743/working/swagger/items.yml create mode 100644 fixtures/bugs/2743/working/swagger/paths/bar.yml create mode 100644 fixtures/bugs/2743/working/swagger/paths/foo.yml create mode 100644 fixtures/bugs/2743/working/swagger/paths/index.yml create mode 100644 fixtures/bugs/2743/working/swagger/paths/nested.yml create mode 100644 fixtures/bugs/2743/working/swagger/user/index.yml create mode 100644 fixtures/bugs/2743/working/swagger/user/model.yml diff --git a/expander.go b/expander.go index fae9c12..74f91c3 100644 --- a/expander.go +++ b/expander.go @@ -213,7 +213,19 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba } if target.Ref.String() != "" { - return expandSchemaRef(target, parentRefs, resolver, basePath) + if !resolver.options.SkipSchemas { + return expandSchemaRef(target, parentRefs, resolver, basePath) + } + + // when "expand" with SkipSchema, we just rebase the existing $ref without replacing + // the full schema. + rebasedRef, err := NewRef(normalizeURI(target.Ref.String(), basePath)) + if err != nil { + return nil, err + } + target.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID) + + return &target, nil } for k := range target.Definitions { @@ -525,21 +537,25 @@ func getRefAndSchema(input interface{}) (*Ref, *Schema, error) { } func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePath string) error { - ref, _, err := getRefAndSchema(input) + ref, sch, err := getRefAndSchema(input) if err != nil { return err } - if ref == nil { + if ref == nil && sch == nil { // nothing to do return nil } parentRefs := make([]string, 0, 10) - if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) { - return err + if ref != nil { + // dereference this $ref + if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) { + return err + } + + ref, sch, _ = getRefAndSchema(input) } - ref, sch, _ := getRefAndSchema(input) if ref.String() != "" { transitiveResolver := resolver.transitiveResolver(basePath, *ref) basePath = resolver.updateBasePath(transitiveResolver, basePath) @@ -551,6 +567,7 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa if ref != nil { *ref = Ref{} } + return nil } @@ -560,38 +577,29 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa return ern } - switch { - case resolver.isCircular(&rebasedRef, basePath, parentRefs...): + if resolver.isCircular(&rebasedRef, basePath, parentRefs...) { // this is a circular $ref: stop expansion if !resolver.options.AbsoluteCircularRef { sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID) } else { sch.Ref = rebasedRef } - case !resolver.options.SkipSchemas: - // schema expanded to a $ref in another root - sch.Ref = rebasedRef - debugLog("rebased to: %s", sch.Ref.String()) - default: - // skip schema expansion but rebase $ref to schema - sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID) } } + // $ref expansion or rebasing is performed by expandSchema below if ref != nil { *ref = Ref{} } // expand schema - if !resolver.options.SkipSchemas { - s, err := expandSchema(*sch, parentRefs, resolver, basePath) - if resolver.shouldStopOnError(err) { - return err - } - if s == nil { - // guard for when continuing on error - return nil - } + // yes, we do it even if options.SkipSchema is true: we have to go down that rabbit hole and rebase nested $ref) + s, err := expandSchema(*sch, parentRefs, resolver, basePath) + if resolver.shouldStopOnError(err) { + return err + } + + if s != nil { // guard for when continuing on error *sch = *s } diff --git a/fixtures/bugs/2743/not-working/minimal.yaml b/fixtures/bugs/2743/not-working/minimal.yaml new file mode 100644 index 0000000..2c46773 --- /dev/null +++ b/fixtures/bugs/2743/not-working/minimal.yaml @@ -0,0 +1,7 @@ +swagger: '2.0' +info: + version: 0.0.0 + title: Simple API +paths: + /bar: + $ref: 'swagger/paths/bar.yml' diff --git a/fixtures/bugs/2743/not-working/spec.yaml b/fixtures/bugs/2743/not-working/spec.yaml new file mode 100644 index 0000000..9255173 --- /dev/null +++ b/fixtures/bugs/2743/not-working/spec.yaml @@ -0,0 +1,11 @@ +swagger: '2.0' +info: + version: 0.0.0 + title: Simple API +paths: + /foo: + $ref: 'swagger/paths/foo.yml' + /bar: + $ref: 'swagger/paths/bar.yml' + /nested: + $ref: 'swagger/paths/nested.yml#/response' diff --git a/fixtures/bugs/2743/not-working/swagger/definitions.yml b/fixtures/bugs/2743/not-working/swagger/definitions.yml new file mode 100644 index 0000000..438d6ee --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/definitions.yml @@ -0,0 +1,9 @@ +ErrorPayload: + title: Error Payload + required: + - errors + properties: + errors: + type: array + items: + $ref: './items.yml#/ErrorDetailsItem' \ No newline at end of file diff --git a/fixtures/bugs/2743/not-working/swagger/items.yml b/fixtures/bugs/2743/not-working/swagger/items.yml new file mode 100644 index 0000000..e4a050c --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/items.yml @@ -0,0 +1,15 @@ +ErrorDetailsItem: + title: Error details item + description: Represents an item of the list of details of an error. + required: + - message + - code + properties: + message: + type: string + code: + type: string + details: + type: array + items: + type: string \ No newline at end of file diff --git a/fixtures/bugs/2743/not-working/swagger/paths/bar.yml b/fixtures/bugs/2743/not-working/swagger/paths/bar.yml new file mode 100644 index 0000000..c813579 --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/paths/bar.yml @@ -0,0 +1,8 @@ +get: + responses: + 200: + description: OK + schema: + type: array + items: + $ref: '../user/index.yml#/User' ## this doesn't work \ No newline at end of file diff --git a/fixtures/bugs/2743/not-working/swagger/paths/foo.yml b/fixtures/bugs/2743/not-working/swagger/paths/foo.yml new file mode 100644 index 0000000..a5c0de1 --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/paths/foo.yml @@ -0,0 +1,8 @@ +get: + responses: + 200: + description: OK + 500: + description: OK + schema: + $ref: '../definitions.yml#/ErrorPayload' diff --git a/fixtures/bugs/2743/not-working/swagger/paths/index.yml b/fixtures/bugs/2743/not-working/swagger/paths/index.yml new file mode 100644 index 0000000..7cdcdd4 --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/paths/index.yml @@ -0,0 +1,6 @@ +/foo: + $ref: ./foo.yml +/bar: + $ref: ./bar.yml +/nested: + $ref: ./nested.yml#/response diff --git a/fixtures/bugs/2743/not-working/swagger/paths/nested.yml b/fixtures/bugs/2743/not-working/swagger/paths/nested.yml new file mode 100644 index 0000000..5c7cf0d --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/paths/nested.yml @@ -0,0 +1,14 @@ +response: + get: + responses: + 200: + description: OK + schema: + $ref: '#/definitions/SameFileReference' + +definitions: + SameFileReference: + type: object + properties: + name: + type: string diff --git a/fixtures/bugs/2743/not-working/swagger/user/index.yml b/fixtures/bugs/2743/not-working/swagger/user/index.yml new file mode 100644 index 0000000..99c1c6f --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/user/index.yml @@ -0,0 +1,2 @@ +User: + $ref: './model.yml' diff --git a/fixtures/bugs/2743/not-working/swagger/user/model.yml b/fixtures/bugs/2743/not-working/swagger/user/model.yml new file mode 100644 index 0000000..5cb91cd --- /dev/null +++ b/fixtures/bugs/2743/not-working/swagger/user/model.yml @@ -0,0 +1,4 @@ +type: object +properties: + name: + type: string diff --git a/fixtures/bugs/2743/working/spec.yaml b/fixtures/bugs/2743/working/spec.yaml new file mode 100644 index 0000000..9255173 --- /dev/null +++ b/fixtures/bugs/2743/working/spec.yaml @@ -0,0 +1,11 @@ +swagger: '2.0' +info: + version: 0.0.0 + title: Simple API +paths: + /foo: + $ref: 'swagger/paths/foo.yml' + /bar: + $ref: 'swagger/paths/bar.yml' + /nested: + $ref: 'swagger/paths/nested.yml#/response' diff --git a/fixtures/bugs/2743/working/swagger/definitions.yml b/fixtures/bugs/2743/working/swagger/definitions.yml new file mode 100644 index 0000000..438d6ee --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/definitions.yml @@ -0,0 +1,9 @@ +ErrorPayload: + title: Error Payload + required: + - errors + properties: + errors: + type: array + items: + $ref: './items.yml#/ErrorDetailsItem' \ No newline at end of file diff --git a/fixtures/bugs/2743/working/swagger/items.yml b/fixtures/bugs/2743/working/swagger/items.yml new file mode 100644 index 0000000..e4a050c --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/items.yml @@ -0,0 +1,15 @@ +ErrorDetailsItem: + title: Error details item + description: Represents an item of the list of details of an error. + required: + - message + - code + properties: + message: + type: string + code: + type: string + details: + type: array + items: + type: string \ No newline at end of file diff --git a/fixtures/bugs/2743/working/swagger/paths/bar.yml b/fixtures/bugs/2743/working/swagger/paths/bar.yml new file mode 100644 index 0000000..41dc76a --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/paths/bar.yml @@ -0,0 +1,8 @@ +get: + responses: + 200: + description: OK + schema: + type: array + items: + $ref: './swagger/user/index.yml#/User' ## this works \ No newline at end of file diff --git a/fixtures/bugs/2743/working/swagger/paths/foo.yml b/fixtures/bugs/2743/working/swagger/paths/foo.yml new file mode 100644 index 0000000..a5c0de1 --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/paths/foo.yml @@ -0,0 +1,8 @@ +get: + responses: + 200: + description: OK + 500: + description: OK + schema: + $ref: '../definitions.yml#/ErrorPayload' diff --git a/fixtures/bugs/2743/working/swagger/paths/index.yml b/fixtures/bugs/2743/working/swagger/paths/index.yml new file mode 100644 index 0000000..7cdcdd4 --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/paths/index.yml @@ -0,0 +1,6 @@ +/foo: + $ref: ./foo.yml +/bar: + $ref: ./bar.yml +/nested: + $ref: ./nested.yml#/response diff --git a/fixtures/bugs/2743/working/swagger/paths/nested.yml b/fixtures/bugs/2743/working/swagger/paths/nested.yml new file mode 100644 index 0000000..5c7cf0d --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/paths/nested.yml @@ -0,0 +1,14 @@ +response: + get: + responses: + 200: + description: OK + schema: + $ref: '#/definitions/SameFileReference' + +definitions: + SameFileReference: + type: object + properties: + name: + type: string diff --git a/fixtures/bugs/2743/working/swagger/user/index.yml b/fixtures/bugs/2743/working/swagger/user/index.yml new file mode 100644 index 0000000..99c1c6f --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/user/index.yml @@ -0,0 +1,2 @@ +User: + $ref: './model.yml' diff --git a/fixtures/bugs/2743/working/swagger/user/model.yml b/fixtures/bugs/2743/working/swagger/user/model.yml new file mode 100644 index 0000000..5cb91cd --- /dev/null +++ b/fixtures/bugs/2743/working/swagger/user/model.yml @@ -0,0 +1,4 @@ +type: object +properties: + name: + type: string diff --git a/spec_test.go b/spec_test.go index 8274c95..ae7d492 100644 --- a/spec_test.go +++ b/spec_test.go @@ -25,6 +25,38 @@ import ( ) // Test unitary fixture for dev and bug fixing + +func TestSpec_Issue2743(t *testing.T) { + t.Run("should expand but produce unresolvable $ref", func(t *testing.T) { + path := filepath.Join("fixtures", "bugs", "2743", "working", "spec.yaml") + sp := loadOrFail(t, path) + require.NoError(t, + spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader}), + ) + + t.Run("all $ref do not resolve when expanding again", func(t *testing.T) { + err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}) + require.Error(t, err) + require.ErrorContains(t, err, filepath.FromSlash("swagger/paths/swagger/user/index.yml")) + }) + }) + + t.Run("should expand and produce resolvable $ref", func(t *testing.T) { + path := filepath.Join("fixtures", "bugs", "2743", "not-working", "spec.yaml") + sp := loadOrFail(t, path) + require.NoError(t, + spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader}), + ) + + t.Run("all $ref properly reolve when expanding again", func(t *testing.T) { + require.NoError(t, + spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}), + ) + require.NotContainsf(t, asJSON(t, sp), "$ref", "all $ref's should have been expanded properly") + }) + }) +} + func TestSpec_Issue1429(t *testing.T) { path := filepath.Join("fixtures", "bugs", "1429", "swagger.yaml") From 63dcade976ce31d51cdc2341efecf22e0661a97c Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Tue, 9 Jan 2024 12:53:45 +0100 Subject: [PATCH 17/28] doc(faq): transfered questions to README These discussion threads are valuable, but no longer active. * fixes #164 * fixes #23 Signed-off-by: Frederic BIDON --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 822172f..7fd2810 100644 --- a/README.md +++ b/README.md @@ -29,3 +29,26 @@ The object model for OpenAPI specification documents. > This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story. > > An early attempt to support Swagger 3 may be found at: https://github.com/go-openapi/spec3 + +* Does the unmarshaling support YAML? + +> Not directly. The exposed types know only how to unmarshal from JSON. +> +> In order to load a YAML document as a Swagger spec, you need to use the loaders provided by +> github.com/go-openapi/loads +> +> Take a look at the example there: https://pkg.go.dev/github.com/go-openapi/loads#example-Spec +> +> See also https://github.com/go-openapi/spec/issues/164 + +* How can I validate a spec? + +> Validation is provided by [the validate package](http://github.com/go-openapi/validate) + +* Why do we have an `ID` field for `Schema` which is not part of the swagger spec? + +> We found jsonschema compatibility more important: since `id` in jsonschema influences +> how `$ref` are resolved. +> This `id` does not conflict with any property named `id`. +> +> See also https://github.com/go-openapi/spec/issues/23 From 4c02b815d46a94aa68106670eff4baf842573ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20BIDON?= Date: Thu, 1 Feb 2024 08:53:10 +0100 Subject: [PATCH 18/28] ci(dependencies): automate dependencies updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frédéric BIDON --- .github/dependabot.yaml | 56 ++++++++++++++++++++++++++++++++ .github/workflows/auto-merge.yml | 43 ++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 .github/dependabot.yaml create mode 100644 .github/workflows/auto-merge.yml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..976af1b --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,56 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "friday" + open-pull-requests-limit: 2 # <- default is 5 + groups: # <- group all github actions updates in a single PR + # 1. development-dependencies are auto-merged + development-dependencies: + patterns: + - '*' + + - package-ecosystem: "gomod" + # We define 4 groups of dependencies to regroup update pull requests: + # - development (e.g. test dependencies) + # - go-openapi updates + # - golang.org (e.g. golang.org/x/... packages) + # - other dependencies (direct or indirect) + # + # * All groups are checked once a week and each produce at most 1 PR. + # * All dependabot PRs are auto-approved + # + # Auto-merging policy, when requirements are met: + # 1. development-dependencies are auto-merged + # 2. golang.org-dependencies are auto-merged + # 3. go-openapi patch updates are auto-merged. Minor/major version updates require a manual merge. + # 4. other dependencies require a manual merge + directory: "/" + schedule: + interval: "weekly" + day: "friday" + open-pull-requests-limit: 4 + groups: + development-dependencies: + dependency-type: development + patterns: + - "github.com/stretchr/testify" + + golang.org-dependencies: + dependency-type: production + patterns: + - "golang.org/*" + + go-openapi-dependencies: + dependency-type: production + patterns: + - "github.com/go-openapi/*" + + other-dependencies: + dependency-type: production + exclude-patterns: + - "github.com/go-openapi/*" + - "github.com/stretchr/testify" + - "golang.org/*" diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 0000000..b4009db --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,43 @@ +name: Dependabot auto-merge +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + dependabot: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v1 + + - name: Auto-approve all dependabot PRs + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Auto-merge dependabot PRs for development dependencies + if: contains(steps.metadata.outputs.dependency-group, 'development-dependencies') + run: gh pr merge --auto --rebase "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Auto-merge dependabot PRs for go-openapi patches + if: contains(steps.metadata.outputs.dependency-group, 'go-openapi-dependencies') && (steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch') + run: gh pr merge --auto --rebase "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Auto-merge dependabot PRs for golang.org updates + if: contains(steps.metadata.outputs.dependency-group, 'golang.org-dependencies') + run: gh pr merge --auto --rebase "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} + From 7e0aabf82f8048872d640c18333309f1c31b9e28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 08:51:36 +0000 Subject: [PATCH 19/28] Bump the go-openapi-dependencies group with 1 update Bumps the go-openapi-dependencies group with 1 update: [github.com/go-openapi/swag](https://github.com/go-openapi/swag). Updates `github.com/go-openapi/swag` from 0.22.6 to 0.22.9 - [Commits](https://github.com/go-openapi/swag/compare/v0.22.6...v0.22.9) --- updated-dependencies: - dependency-name: github.com/go-openapi/swag dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-openapi-dependencies ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 898a3e9..2d9a6a7 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/go-openapi/spec require ( github.com/go-openapi/jsonpointer v0.20.2 github.com/go-openapi/jsonreference v0.20.4 - github.com/go-openapi/swag v0.22.6 + github.com/go-openapi/swag v0.22.9 github.com/stretchr/testify v1.8.4 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 3d2ef0b..dde7eae 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbX github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.6 h1:dnqg1XfHXL9aBxSbktBqFR5CxVyVI+7fYWhAf1JOeTw= -github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= +github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= +github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= From 5c52f3d762b7c2b858b4ad639d9758b78aad8398 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 08:59:43 +0000 Subject: [PATCH 20/28] Bump the development-dependencies group with 3 updates Bumps the development-dependencies group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-go](https://github.com/actions/setup-go) and [codecov/codecov-action](https://github.com/codecov/codecov-action). Updates `actions/checkout` from 3 to 4 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) Updates `actions/setup-go` from 4 to 5 - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4...v5) Updates `codecov/codecov-action` from 3 to 4 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] --- .github/workflows/go-test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 62682bf..325633e 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -7,8 +7,8 @@ jobs: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 with: go-version: stable check-latest: true @@ -31,18 +31,18 @@ jobs: steps: - name: Run unit tests - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: '${{ matrix.go_version }}' check-latest: true cache: true - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: go test -v -race -coverprofile="coverage-${{ matrix.os }}.${{ matrix.go_version }}.out" -covermode=atomic -coverpkg=$(go list)/... ./... - name: Upload coverage to codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: files: './coverage-${{ matrix.os }}.${{ matrix.go_version }}.out' flags: '${{ matrix.go_version }}' From 817cb94124889248da3ff0bc5424acb4b96e598e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20BIDON?= Date: Thu, 1 Feb 2024 10:59:38 +0100 Subject: [PATCH 21/28] chore(ci): prevents duplicate workflow runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frédéric BIDON --- .github/workflows/go-test.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 325633e..e3c7dda 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -1,6 +1,17 @@ name: go test -on: [push, pull_request] +on: + push: + tags: + - v* + branches: + - master + paths-ignore: + - '**.md' + + pull_request: + paths-ignore: + - '**.md' jobs: lint: @@ -42,7 +53,7 @@ jobs: - run: go test -v -race -coverprofile="coverage-${{ matrix.os }}.${{ matrix.go_version }}.out" -covermode=atomic -coverpkg=$(go list)/... ./... - name: Upload coverage to codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v3 with: files: './coverage-${{ matrix.os }}.${{ matrix.go_version }}.out' flags: '${{ matrix.go_version }}' From c21b34fcd3928962331fde836c8ec4110a8a7a94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 09:27:01 +0000 Subject: [PATCH 22/28] Bump the development-dependencies group with 1 update Bumps the development-dependencies group with 1 update: [codecov/codecov-action](https://github.com/codecov/codecov-action). Updates `codecov/codecov-action` from 3 to 4 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3...v4) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] --- .github/workflows/go-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index e3c7dda..5910868 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -53,7 +53,7 @@ jobs: - run: go test -v -race -coverprofile="coverage-${{ matrix.os }}.${{ matrix.go_version }}.out" -covermode=atomic -coverpkg=$(go list)/... ./... - name: Upload coverage to codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: files: './coverage-${{ matrix.os }}.${{ matrix.go_version }}.out' flags: '${{ matrix.go_version }}' From a68da9ed30f11c14e257f4d0fb3f8f92fc5af927 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Sat, 3 Feb 2024 18:29:39 +0100 Subject: [PATCH 23/28] ci: remove paths-ignore Using paths-ignore as a short-circuit for doc-only PRs does not work: branch protection rules cannot be passed. Signed-off-by: Frederic BIDON --- .github/workflows/go-test.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 5910868..1ffa6c7 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -6,12 +6,8 @@ on: - v* branches: - master - paths-ignore: - - '**.md' pull_request: - paths-ignore: - - '**.md' jobs: lint: From 397f81bfd6cb4af1f4d6b0257b1aba7b5ceadf8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 09:31:48 +0000 Subject: [PATCH 24/28] Bump the development-dependencies group with 1 update Bumps the development-dependencies group with 1 update: [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action). Updates `golangci/golangci-lint-action` from 3 to 4 - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v3...v4) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] --- .github/workflows/go-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index 1ffa6c7..e1c413e 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -21,7 +21,7 @@ jobs: check-latest: true cache: true - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 with: version: latest only-new-issues: true From c786eed0d1cdcda706b7b63b035a422c86578352 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Mon, 4 Mar 2024 10:21:48 +0100 Subject: [PATCH 25/28] fix(ci): remove dependency-type from dependabot groups dependency-type is irrelevant in the gomod ecosystem. This setting prevented some updates to auto-merge as expected. Signed-off-by: Frederic BIDON --- .github/dependabot.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 976af1b..7dc7009 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -34,22 +34,18 @@ updates: open-pull-requests-limit: 4 groups: development-dependencies: - dependency-type: development patterns: - "github.com/stretchr/testify" golang.org-dependencies: - dependency-type: production patterns: - "golang.org/*" go-openapi-dependencies: - dependency-type: production patterns: - "github.com/go-openapi/*" other-dependencies: - dependency-type: production exclude-patterns: - "github.com/go-openapi/*" - "github.com/stretchr/testify" From fc76ee8940734eba89b15691fb3be6e06ae63a65 Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Mon, 4 Mar 2024 10:26:16 +0100 Subject: [PATCH 26/28] chore(lint): relinted Signed-off-by: Frederic BIDON --- expander.go | 2 +- structs_test.go | 2 +- swagger_test.go | 2 +- validations_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/expander.go b/expander.go index 74f91c3..b81a569 100644 --- a/expander.go +++ b/expander.go @@ -57,7 +57,7 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error { if !options.SkipSchemas { for key, definition := range spec.Definitions { parentRefs := make([]string, 0, 10) - parentRefs = append(parentRefs, fmt.Sprintf("#/definitions/%s", key)) + parentRefs = append(parentRefs, "#/definitions/"+key) def, err := expandSchema(definition, parentRefs, resolver, specBasePath) if resolver.shouldStopOnError(err) { diff --git a/structs_test.go b/structs_test.go index c8e191a..d464b93 100644 --- a/structs_test.go +++ b/structs_test.go @@ -78,7 +78,7 @@ func assertParsesYAML(t testing.TB, actual string, expected interface{}) bool { if !isPointed(expected) { act = reflect.Indirect(parsed).Interface() } - return assert.EqualValues(t, act, expected) + return assert.EqualValues(t, expected, act) } func TestSerialization_SerializeJSON(t *testing.T) { diff --git a/swagger_test.go b/swagger_test.go index cb288e6..59e2403 100644 --- a/swagger_test.go +++ b/swagger_test.go @@ -243,7 +243,7 @@ func TestSwaggerSpec_Serialize(t *testing.T) { require.NoError(t, err) var actual map[string]interface{} require.NoError(t, json.Unmarshal(b, &actual)) - assert.EqualValues(t, actual, expected) + assert.EqualValues(t, expected, actual) } func TestSwaggerSpec_Deserialize(t *testing.T) { diff --git a/validations_test.go b/validations_test.go index 993547c..6582921 100644 --- a/validations_test.go +++ b/validations_test.go @@ -109,7 +109,7 @@ func TestValidations(t *testing.T) { require.False(t, cv.HasArrayValidations()) sv.SetValidations(val) - sv.ClearObjectValidations(func(validation string, value interface{}) { + sv.ClearObjectValidations(func(validation string, _ interface{}) { switch validation { case "minProperties", "maxProperties", "patternProperties": return From 8937a3ddfae994f670d25c96abac22ea361a9b3a Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Mon, 4 Mar 2024 11:08:38 +0100 Subject: [PATCH 27/28] updated dependencies Signed-off-by: Frederic BIDON --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 2d9a6a7..9fe020d 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module github.com/go-openapi/spec require ( - github.com/go-openapi/jsonpointer v0.20.2 - github.com/go-openapi/jsonreference v0.20.4 - github.com/go-openapi/swag v0.22.9 - github.com/stretchr/testify v1.8.4 + github.com/go-openapi/jsonpointer v0.20.3 + github.com/go-openapi/jsonreference v0.20.5 + github.com/go-openapi/swag v0.22.10 + github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index dde7eae..8d4b5dc 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= -github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= +github.com/go-openapi/jsonpointer v0.20.3 h1:jykzYWS/kyGtsHfRt6aV8JTB9pcQAXPIA7qlZ5aRlyk= +github.com/go-openapi/jsonpointer v0.20.3/go.mod h1:c7l0rjoouAuIxCm8v/JWKRgMjDG/+/7UBWsXMrv6PsM= +github.com/go-openapi/jsonreference v0.20.5 h1:hutI+cQI+HbSQaIGSfsBsYI0pHk+CATf8Fk5gCSj0yI= +github.com/go-openapi/jsonreference v0.20.5/go.mod h1:thAqAp31UABtI+FQGKAQfmv7DbFpKNUlva2UPCxKu2Y= +github.com/go-openapi/swag v0.22.10 h1:4y86NVn7Z2yYd6pfS4Z+Nyh3aAUL3Nul+LMbhFKy0gA= +github.com/go-openapi/swag v0.22.10/go.mod h1:Cnn8BYtRlx6BNE3DPN86f/xkapGIcLWzh3CLEb4C1jI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -15,8 +15,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From af9bab81cf9ab52283c1498b1d076ec68a1a2bcd Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Sat, 9 Mar 2024 19:27:31 +0100 Subject: [PATCH 28/28] chore(go): go-openapi requires go.1.20 across the board Signed-off-by: Frederic BIDON --- go.mod | 8 ++++---- go.sum | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 9fe020d..996f90a 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/go-openapi/spec require ( - github.com/go-openapi/jsonpointer v0.20.3 - github.com/go-openapi/jsonreference v0.20.5 - github.com/go-openapi/swag v0.22.10 + github.com/go-openapi/jsonpointer v0.21.0 + github.com/go-openapi/jsonreference v0.21.0 + github.com/go-openapi/swag v0.23.0 github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -15,4 +15,4 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect ) -go 1.19 +go 1.20 diff --git a/go.sum b/go.sum index 8d4b5dc..b5bc1d1 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-openapi/jsonpointer v0.20.3 h1:jykzYWS/kyGtsHfRt6aV8JTB9pcQAXPIA7qlZ5aRlyk= -github.com/go-openapi/jsonpointer v0.20.3/go.mod h1:c7l0rjoouAuIxCm8v/JWKRgMjDG/+/7UBWsXMrv6PsM= -github.com/go-openapi/jsonreference v0.20.5 h1:hutI+cQI+HbSQaIGSfsBsYI0pHk+CATf8Fk5gCSj0yI= -github.com/go-openapi/jsonreference v0.20.5/go.mod h1:thAqAp31UABtI+FQGKAQfmv7DbFpKNUlva2UPCxKu2Y= -github.com/go-openapi/swag v0.22.10 h1:4y86NVn7Z2yYd6pfS4Z+Nyh3aAUL3Nul+LMbhFKy0gA= -github.com/go-openapi/swag v0.22.10/go.mod h1:Cnn8BYtRlx6BNE3DPN86f/xkapGIcLWzh3CLEb4C1jI= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=