refactor: replace the go model from custom to the official (#439)
This commit is contained in:
parent
966a635768
commit
1dd9dd449a
|
@ -176,10 +176,10 @@ func (o *runOption) preRunE(cmd *cobra.Command, args []string) (err error) {
|
|||
}
|
||||
|
||||
if err == nil {
|
||||
var swaggerAPI apispec.APIConverage
|
||||
var swaggerAPI apispec.SwaggerAPI
|
||||
if o.swaggerURL != "" {
|
||||
if swaggerAPI, err = apispec.ParseURLToSwagger(o.swaggerURL); err == nil {
|
||||
o.reportWriter.WithAPIConverage(swaggerAPI)
|
||||
if swaggerAPI.Swagger, err = apispec.ParseURLToSwagger(o.swaggerURL); err == nil {
|
||||
o.reportWriter.WithAPIConverage(&swaggerAPI)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
6
go.mod
6
go.mod
|
@ -12,6 +12,7 @@ require (
|
|||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-logr/logr v1.4.1
|
||||
github.com/go-logr/zapr v1.3.0
|
||||
github.com/go-openapi/spec v0.21.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0
|
||||
github.com/h2non/gock v1.2.0
|
||||
|
@ -45,6 +46,9 @@ require (
|
|||
github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect
|
||||
github.com/cucumber/messages-go/v16 v16.0.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
|
@ -56,6 +60,8 @@ require (
|
|||
github.com/iancoleman/orderedmap v0.3.0 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/phpdave11/gofpdi v1.0.14-0.20211212211723-1f10f9844311 // indirect
|
||||
|
|
16
go.sum
16
go.sum
|
@ -43,6 +43,14 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
|||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||
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/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||
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/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
|
@ -93,6 +101,8 @@ github.com/invopop/jsonschema v0.7.0 h1:2vgQcBz1n256N+FpX3Jq7Y17AjYt46Ig3zIWyy77
|
|||
github.com/invopop/jsonschema v0.7.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
|
||||
github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls=
|
||||
github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k=
|
||||
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/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
|
@ -109,6 +119,8 @@ github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161 h1:dSL/ah6za
|
|||
github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161/go.mod h1:QX22v61PxpOfJa4Xug8qzGTbPjclDZFx2j1PlGLknJw=
|
||||
github.com/linuxsuren/unstructured v0.0.1 h1:ilUA8MUYbR6l9ebo/YPV2bKqlf62bzQursDSE+j00iU=
|
||||
github.com/linuxsuren/unstructured v0.0.1/go.mod h1:KH6aTj+FegzGBzc1vS6mzZx3/duhTUTEVyW5sO7p4as=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
|
@ -132,8 +144,8 @@ github.com/prometheus/common v0.50.0 h1:YSZE6aa9+luNa2da6/Tik0q0A5AbR+U003TItK57
|
|||
github.com/prometheus/common v0.50.0/go.mod h1:wHFBCEVWVmHMUpg7pYcOm2QUR/ocQdYSJVQJKnHc3xQ=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/santhosh-tekuri/jsonschema/v3 v3.1.0 h1:levPcBfnazlA1CyCMC3asL/QLZkq9pa8tQZOH513zQw=
|
||||
github.com/santhosh-tekuri/jsonschema/v3 v3.1.0/go.mod h1:8kzK2TC0k0YjOForaAHdNEa7ik0fokNa2k30BKJ/W7Y=
|
||||
|
|
|
@ -1384,7 +1384,6 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
|
|||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
|
||||
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
|
@ -1611,6 +1610,7 @@ github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi
|
|||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4 h1:BN/Nyn2nWMoqGRA7G7paDNDqTXE30mXGqzzybrfo05w=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
|
|
|
@ -17,61 +17,72 @@ limitations under the License.
|
|||
package apispec
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/go-openapi/spec"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Swagger struct {
|
||||
Swagger string `json:"swagger"`
|
||||
// Paths includes all the API requests.
|
||||
// The keys is the HTTP request method which as lower-case, for example: get, post.
|
||||
Paths map[string]map[string]SwaggerAPI `json:"paths"`
|
||||
Info SwaggerInfo `json:"info"`
|
||||
}
|
||||
|
||||
type SwaggerAPI struct {
|
||||
OperationId string `json:"operationId"`
|
||||
Parameters []Parameter `json:"parameters"`
|
||||
Summary string `json:"summary"`
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
Name string `json:"name"`
|
||||
// In represents the parameter type, supported values: query, path
|
||||
In string `json:"in"`
|
||||
Required bool `json:"required"`
|
||||
Schema Schema `json:"schema"`
|
||||
}
|
||||
|
||||
type Schema struct {
|
||||
Type string `json:"type"`
|
||||
Format string `json:"format"`
|
||||
}
|
||||
|
||||
type SwaggerInfo struct {
|
||||
Description string `json:"description"`
|
||||
Title string `json:"title"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type APIConverage interface {
|
||||
HaveAPI(path, method string) (exist bool)
|
||||
APICount() (count int)
|
||||
}
|
||||
|
||||
type SwaggerAPI struct {
|
||||
Swagger *spec.Swagger
|
||||
ApiMap map[string][]string
|
||||
}
|
||||
|
||||
func NewSwaggerAPI(swagger *spec.Swagger) *SwaggerAPI {
|
||||
return &SwaggerAPI{
|
||||
Swagger: swagger,
|
||||
ApiMap: buildAPIMap(swagger),
|
||||
}
|
||||
}
|
||||
|
||||
func buildAPIMap(swagger *spec.Swagger) map[string][]string {
|
||||
apiMap := make(map[string][]string)
|
||||
for path, pathItem := range swagger.Paths.Paths {
|
||||
var methods []string
|
||||
if pathItem.Get != nil {
|
||||
methods = append(methods, "get")
|
||||
}
|
||||
if pathItem.Put != nil {
|
||||
methods = append(methods, "put")
|
||||
}
|
||||
if pathItem.Post != nil {
|
||||
methods = append(methods, "post")
|
||||
}
|
||||
if pathItem.Delete != nil {
|
||||
methods = append(methods, "delete")
|
||||
}
|
||||
if pathItem.Options != nil {
|
||||
methods = append(methods, "options")
|
||||
}
|
||||
if pathItem.Head != nil {
|
||||
methods = append(methods, "head")
|
||||
}
|
||||
if pathItem.Patch != nil {
|
||||
methods = append(methods, "patch")
|
||||
}
|
||||
apiMap[path] = methods
|
||||
}
|
||||
return apiMap
|
||||
}
|
||||
|
||||
// HaveAPI check if the swagger has the API.
|
||||
// If the path is /api/v1/names/linuxsuren, then will match /api/v1/names/{name}
|
||||
func (s *Swagger) HaveAPI(path, method string) (exist bool) {
|
||||
func (s *SwaggerAPI) HaveAPI(path, method string) (exist bool) {
|
||||
method = strings.ToLower(method)
|
||||
for item := range s.Paths {
|
||||
if matchAPI(path, item) {
|
||||
for m := range s.Paths[item] {
|
||||
if strings.ToLower(m) == method {
|
||||
exist = true
|
||||
return
|
||||
for p := range s.ApiMap {
|
||||
if matchAPI(path, p) {
|
||||
if methods, ok := s.ApiMap[p]; ok {
|
||||
for _, m := range methods {
|
||||
if m == method {
|
||||
exist = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,22 +109,20 @@ func swaggerAPIConvert(text string) (result string) {
|
|||
}
|
||||
|
||||
// APICount return the count of APIs
|
||||
func (s *Swagger) APICount() (count int) {
|
||||
for path := range s.Paths {
|
||||
for range s.Paths[path] {
|
||||
count++
|
||||
}
|
||||
func (s *SwaggerAPI) APICount() (count int) {
|
||||
for _, methods := range s.ApiMap {
|
||||
count += len(methods)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ParseToSwagger(data []byte) (swagger *Swagger, err error) {
|
||||
swagger = &Swagger{}
|
||||
err = json.Unmarshal(data, swagger)
|
||||
func ParseToSwagger(data []byte) (swagger *spec.Swagger, err error) {
|
||||
swagger = &spec.Swagger{}
|
||||
err = swagger.UnmarshalJSON(data)
|
||||
return
|
||||
}
|
||||
|
||||
func ParseURLToSwagger(swaggerURL string) (swagger *Swagger, err error) {
|
||||
func ParseURLToSwagger(swaggerURL string) (swagger *spec.Swagger, err error) {
|
||||
var resp *http.Response
|
||||
if resp, err = http.Get(swaggerURL); err == nil && resp != nil && resp.StatusCode == http.StatusOK {
|
||||
swagger, err = ParseStreamToSwagger(resp.Body)
|
||||
|
@ -121,7 +130,7 @@ func ParseURLToSwagger(swaggerURL string) (swagger *Swagger, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func ParseStreamToSwagger(stream io.Reader) (swagger *Swagger, err error) {
|
||||
func ParseStreamToSwagger(stream io.Reader) (swagger *spec.Swagger, err error) {
|
||||
var data []byte
|
||||
if data, err = io.ReadAll(stream); err == nil {
|
||||
swagger, err = ParseToSwagger(data)
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package apispec_test
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/spec"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
|
@ -31,18 +32,18 @@ func TestParseURLToSwagger(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
swaggerURL string
|
||||
verify func(t *testing.T, swagger *apispec.Swagger, err error)
|
||||
verify func(t *testing.T, swagger *spec.Swagger, err error)
|
||||
}{{
|
||||
name: "normal",
|
||||
swaggerURL: urlFoo,
|
||||
verify: func(t *testing.T, swagger *apispec.Swagger, err error) {
|
||||
verify: func(t *testing.T, swagger *spec.Swagger, err error) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "2.0", swagger.Swagger)
|
||||
assert.Equal(t, apispec.SwaggerInfo{
|
||||
assert.Equal(t, spec.InfoProps{
|
||||
Description: "sample",
|
||||
Title: "sample",
|
||||
Version: "1.0.0",
|
||||
}, swagger.Info)
|
||||
}, swagger.Info.InfoProps)
|
||||
},
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
|
@ -93,8 +94,9 @@ func TestHaveAPI(t *testing.T) {
|
|||
defer gock.Off()
|
||||
|
||||
swagger, err := apispec.ParseURLToSwagger(tt.swaggerURL)
|
||||
swaggerAPI := apispec.NewSwaggerAPI(swagger)
|
||||
assert.NoError(t, err)
|
||||
exist := swagger.HaveAPI(tt.path, tt.method)
|
||||
exist := swaggerAPI.HaveAPI(tt.path, tt.method)
|
||||
assert.Equal(t, tt.expectExist, exist)
|
||||
})
|
||||
}
|
||||
|
@ -116,8 +118,9 @@ func TestAPICount(t *testing.T) {
|
|||
defer gock.Off()
|
||||
|
||||
swagger, err := apispec.ParseURLToSwagger(tt.swaggerURL)
|
||||
swaggerAPI := apispec.NewSwaggerAPI(swagger)
|
||||
assert.NoError(t, err)
|
||||
count := swagger.APICount()
|
||||
count := swaggerAPI.APICount()
|
||||
assert.Equal(t, tt.expectCount, count)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-openapi/spec"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
@ -230,13 +231,14 @@ func (r *simpleTestCaseRunner) GetSuggestedAPIs(suite *testing.TestSuite, api st
|
|||
return
|
||||
}
|
||||
|
||||
var swaggerAPI *apispec.Swagger
|
||||
if swaggerAPI, err = apispec.ParseURLToSwagger(suite.Spec.URL); err == nil && swaggerAPI != nil {
|
||||
var swagger *spec.Swagger
|
||||
if swagger, err = apispec.ParseURLToSwagger(suite.Spec.URL); err == nil && swagger != nil {
|
||||
result = []*testing.TestCase{}
|
||||
for api, item := range swaggerAPI.Paths {
|
||||
for method, oper := range item {
|
||||
swaggerAPI := apispec.NewSwaggerAPI(swagger)
|
||||
for api, methods := range swaggerAPI.ApiMap {
|
||||
for _, method := range methods {
|
||||
testcase := &testing.TestCase{
|
||||
Name: oper.OperationId,
|
||||
Name: swagger.ID,
|
||||
Request: testing.Request{
|
||||
API: api,
|
||||
Method: strings.ToUpper(method),
|
||||
|
@ -244,7 +246,7 @@ func (r *simpleTestCaseRunner) GetSuggestedAPIs(suite *testing.TestSuite, api st
|
|||
},
|
||||
}
|
||||
|
||||
for _, param := range oper.Parameters {
|
||||
for _, param := range swagger.Parameters {
|
||||
switch param.In {
|
||||
case "query":
|
||||
// TODO should have a better way to provide the initial value
|
||||
|
|
Loading…
Reference in New Issue