From b9554c4f82269749992af764baefb583bd3bbd47 Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 8 Apr 2020 17:22:57 +1100 Subject: [PATCH 1/6] skip cgo package --- parser.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/parser.go b/parser.go index bb983355e..0043fa743 100644 --- a/parser.go +++ b/parser.go @@ -1449,6 +1449,10 @@ func (parser *Parser) getAllGoFileInfoFromDeps(pkg *depth.Pkg) error { return nil } + // Skip cgo + if pkg.Raw == nil && pkg.Name == "C" { + return nil + } srcDir := pkg.Raw.Dir files, err := ioutil.ReadDir(srcDir) // only parsing files in the dir(don't contains sub dir files) if err != nil { From 1e6c432ead6c480e8121e8d1a4aa8217c1d65590 Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 10 Apr 2020 08:35:27 +1100 Subject: [PATCH 2/6] Added unit test for cgo package import --- gen/gen_test.go | 26 +++++++ testdata/simple_cgo/api/api.go | 116 +++++++++++++++++++++++++++++ testdata/simple_cgo/cross/test.go | 6 ++ testdata/simple_cgo/main.go | 66 ++++++++++++++++ testdata/simple_cgo/web/handler.go | 97 ++++++++++++++++++++++++ 5 files changed, 311 insertions(+) create mode 100644 testdata/simple_cgo/api/api.go create mode 100644 testdata/simple_cgo/cross/test.go create mode 100644 testdata/simple_cgo/main.go create mode 100644 testdata/simple_cgo/web/handler.go diff --git a/gen/gen_test.go b/gen/gen_test.go index 075917b58..ac7f2bf9e 100644 --- a/gen/gen_test.go +++ b/gen/gen_test.go @@ -345,3 +345,29 @@ func TestGen_GeneratedDoc(t *testing.T) { os.Remove(expectedFile) } } + +func TestGen_cgoImports(t *testing.T) { + searchDir := "../testdata/simple_cgo" + + config := &Config{ + SearchDir: searchDir, + MainAPIFile: "./main.go", + OutputDir: "../testdata/simple_cgo/docs", + PropNamingStrategy: "", + ParseDependency: true, + } + + assert.NoError(t, New().Build(config)) + + expectedFiles := []string{ + path.Join(config.OutputDir, "docs.go"), + path.Join(config.OutputDir, "swagger.json"), + path.Join(config.OutputDir, "swagger.yaml"), + } + for _, expectedFile := range expectedFiles { + if _, err := os.Stat(expectedFile); os.IsNotExist(err) { + t.Fatal(err) + } + os.Remove(expectedFile) + } +} diff --git a/testdata/simple_cgo/api/api.go b/testdata/simple_cgo/api/api.go new file mode 100644 index 000000000..ba6734d71 --- /dev/null +++ b/testdata/simple_cgo/api/api.go @@ -0,0 +1,116 @@ +package api + +import ( + "github.com/gin-gonic/gin" +) + +// @Summary Add a new pet to the store +// @Description get string by ID +// @ID get-string-by-int +// @Accept json +// @Produce json +// @Param some_id path int true "Some ID" Format(int64) +// @Param some_id body web.Pet true "Some ID" +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 404 {object} web.APIError "Can not find ID" +// @Router /testapi/get-string-by-int/{some_id} [get] +func GetStringByInt(c *gin.Context) { + //write your code +} + +// @Description get struct array by ID +// @ID get-struct-array-by-string +// @Accept json +// @Produce json +// @Param some_id path string true "Some ID" +// @Param category query int true "Category" Enums(1, 2, 3) +// @Param offset query int true "Offset" Mininum(0) default(0) +// @Param limit query int true "Limit" Maxinum(50) default(10) +// @Param q query string true "q" Minlength(1) Maxlength(50) default("") +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 404 {object} web.APIError "Can not find ID" +// @Security ApiKeyAuth +// @Security BasicAuth +// @Security OAuth2Application[write] +// @Security OAuth2Implicit[read, admin] +// @Security OAuth2AccessCode[read] +// @Security OAuth2Password[admin] +// @Router /testapi/get-struct-array-by-string/{some_id} [get] +func GetStructArrayByString(c *gin.Context) { + //write your code +} + +// @Summary Upload file +// @Description Upload file +// @ID file.upload +// @Accept multipart/form-data +// @Produce json +// @Param file formData file true "this is a test file" +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 401 {array} string +// @Failure 404 {object} web.APIError "Can not find ID" +// @Router /file/upload [post] +func Upload(ctx *gin.Context) { + //write your code +} + +// @Summary use Anonymous field +// @Success 200 {object} web.RevValue "ok" +func AnonymousField() { + +} + +// @Summary use pet2 +// @Success 200 {object} web.Pet2 "ok" +func Pet2() { + +} + +// @Summary Use IndirectRecursiveTest +// @Success 200 {object} web.IndirectRecursiveTest +func IndirectRecursiveTest() { +} + +// @Summary Use Tags +// @Success 200 {object} web.Tags +func Tags() { +} + +// @Summary Use CrossAlias +// @Success 200 {object} web.CrossAlias +func CrossAlias() { +} + +// @Summary Use AnonymousStructArray +// @Success 200 {object} web.AnonymousStructArray +func AnonymousStructArray() { +} + +type Pet3 struct { + ID int `json:"id"` +} + +// @Success 200 {object} web.Pet5a "ok" +func GetPet5a() { + +} + +// @Success 200 {object} web.Pet5b "ok" +func GetPet5b() { + +} + +// @Success 200 {object} web.Pet5c "ok" +func GetPet5c() { + +} + +type SwagReturn []map[string]string + +// @Success 200 {object} api.SwagReturn "ok" +func GetPet6MapString() { + +} diff --git a/testdata/simple_cgo/cross/test.go b/testdata/simple_cgo/cross/test.go new file mode 100644 index 000000000..540e53f4f --- /dev/null +++ b/testdata/simple_cgo/cross/test.go @@ -0,0 +1,6 @@ +package cross + +type Cross struct { + Array []string + String string +} diff --git a/testdata/simple_cgo/main.go b/testdata/simple_cgo/main.go new file mode 100644 index 000000000..63deacc33 --- /dev/null +++ b/testdata/simple_cgo/main.go @@ -0,0 +1,66 @@ +package main + +/* +#include + +void Hello(){ + printf("Hello world\n"); +} +*/ +import "C" + +import ( + "github.com/gin-gonic/gin" + "github.com/swaggo/swag/testdata/simple/api" +) + +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server Petstore server. +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host petstore.swagger.io +// @BasePath /v2 + +// @securityDefinitions.basic BasicAuth + +// @securityDefinitions.apikey ApiKeyAuth +// @in header +// @name Authorization + +// @securitydefinitions.oauth2.application OAuth2Application +// @tokenUrl https://example.com/oauth/token +// @scope.write Grants write access +// @scope.admin Grants read and write access to administrative information + +// @securitydefinitions.oauth2.implicit OAuth2Implicit +// @authorizationurl https://example.com/oauth/authorize +// @scope.write Grants write access +// @scope.admin Grants read and write access to administrative information + +// @securitydefinitions.oauth2.password OAuth2Password +// @tokenUrl https://example.com/oauth/token +// @scope.read Grants read access +// @scope.write Grants write access +// @scope.admin Grants read and write access to administrative information + +// @securitydefinitions.oauth2.accessCode OAuth2AccessCode +// @tokenUrl https://example.com/oauth/token +// @authorizationurl https://example.com/oauth/authorize +// @scope.admin Grants read and write access to administrative information +func main() { + C.Hello() + + r := gin.New() + r.GET("/testapi/get-string-by-int/:some_id", api.GetStringByInt) + r.GET("/testapi/get-struct-array-by-string/:some_id", api.GetStructArrayByString) + r.POST("/testapi/upload", api.Upload) + r.Run() +} diff --git a/testdata/simple_cgo/web/handler.go b/testdata/simple_cgo/web/handler.go new file mode 100644 index 000000000..ece1628dc --- /dev/null +++ b/testdata/simple_cgo/web/handler.go @@ -0,0 +1,97 @@ +package web + +import ( + "time" + + "github.com/satori/go.uuid" + "github.com/shopspring/decimal" + "github.com/swaggo/swag/testdata/simple/cross" +) + +type Pet struct { + ID int `json:"id" example:"1" format:"int64" readonly:"true"` + Category struct { + ID int `json:"id" example:"1"` + Name string `json:"name" example:"category_name"` + PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" format:"url"` + SmallCategory struct { + ID int `json:"id" example:"1"` + Name string `json:"name" example:"detail_category_name" binding:"required" minLength:"4" maxLength:"16"` + PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg"` + } `json:"small_category"` + } `json:"category"` + Name string `json:"name" example:"poti" binding:"required"` + PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" binding:"required"` + Tags []Tag `json:"tags"` + Pets *[]Pet2 `json:"pets"` + Pets2 []*Pet2 `json:"pets2"` + Status string `json:"status" enums:"healthy,ill"` + Price float32 `json:"price" example:"3.25" minimum:"1.0" maximum:"1000"` + IsAlive bool `json:"is_alive" example:"true" default:"true"` + Data interface{} `json:"data"` + Hidden string `json:"-"` + UUID uuid.UUID `json:"uuid"` + Decimal decimal.Decimal `json:"decimal"` + IntArray []int `json:"int_array" example:"1,2"` + EnumArray []int `json:"enum_array" enums:"1,2,3,5,7"` +} + +type Tag struct { + ID int `json:"id" format:"int64"` + Name string `json:"name"` + Pets []Pet `json:"pets"` +} + +type Tags []*Tag + +type AnonymousStructArray []struct { + Foo string `json:"foo"` +} + +type CrossAlias cross.Cross + +type Pet2 struct { + ID int `json:"id"` + MiddleName *string `json:"middlename" extensions:"x-nullable,x-abc=def"` + DeletedAt *time.Time `json:"deleted_at"` +} + +type IndirectRecursiveTest struct { + Tags []Tag +} + +type APIError struct { + ErrorCode int + ErrorMessage string + CreatedAt time.Time +} + +type RevValueBase struct { + Status bool `json:"Status"` + + Err int32 `json:"Err,omitempty"` +} +type RevValue struct { + RevValueBase `json:"rev_value_base"` + + Data int `json:"Data"` + Cross cross.Cross `json:"cross"` + Crosses []cross.Cross `json:"crosses"` +} + +// Below we have Pet5b as base type and Pet5a and Pet5c both have Pet5b as anonymous field, inheriting it's properties +// By using these names we ensure that our test will fill if the order of parsing matters at all + +type Pet5a struct { + *Pet5b + Odd bool `json:"odd" binding:"required"` +} + +type Pet5b struct { + Name string `json:"name" binding:"required"` +} + +type Pet5c struct { + *Pet5b + Odd bool `json:"odd" binding:"required"` +} From 070af50f4f7408932e08e47dd574684db6639bba Mon Sep 17 00:00:00 2001 From: Damien Date: Thu, 16 Apr 2020 15:35:31 +1100 Subject: [PATCH 3/6] cleanup : removed unused source --- testdata/simple_cgo/api/api.go | 116 ----------------------------- testdata/simple_cgo/cross/test.go | 6 -- testdata/simple_cgo/web/handler.go | 97 ------------------------ 3 files changed, 219 deletions(-) delete mode 100644 testdata/simple_cgo/api/api.go delete mode 100644 testdata/simple_cgo/cross/test.go delete mode 100644 testdata/simple_cgo/web/handler.go diff --git a/testdata/simple_cgo/api/api.go b/testdata/simple_cgo/api/api.go deleted file mode 100644 index ba6734d71..000000000 --- a/testdata/simple_cgo/api/api.go +++ /dev/null @@ -1,116 +0,0 @@ -package api - -import ( - "github.com/gin-gonic/gin" -) - -// @Summary Add a new pet to the store -// @Description get string by ID -// @ID get-string-by-int -// @Accept json -// @Produce json -// @Param some_id path int true "Some ID" Format(int64) -// @Param some_id body web.Pet true "Some ID" -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 404 {object} web.APIError "Can not find ID" -// @Router /testapi/get-string-by-int/{some_id} [get] -func GetStringByInt(c *gin.Context) { - //write your code -} - -// @Description get struct array by ID -// @ID get-struct-array-by-string -// @Accept json -// @Produce json -// @Param some_id path string true "Some ID" -// @Param category query int true "Category" Enums(1, 2, 3) -// @Param offset query int true "Offset" Mininum(0) default(0) -// @Param limit query int true "Limit" Maxinum(50) default(10) -// @Param q query string true "q" Minlength(1) Maxlength(50) default("") -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 404 {object} web.APIError "Can not find ID" -// @Security ApiKeyAuth -// @Security BasicAuth -// @Security OAuth2Application[write] -// @Security OAuth2Implicit[read, admin] -// @Security OAuth2AccessCode[read] -// @Security OAuth2Password[admin] -// @Router /testapi/get-struct-array-by-string/{some_id} [get] -func GetStructArrayByString(c *gin.Context) { - //write your code -} - -// @Summary Upload file -// @Description Upload file -// @ID file.upload -// @Accept multipart/form-data -// @Produce json -// @Param file formData file true "this is a test file" -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 401 {array} string -// @Failure 404 {object} web.APIError "Can not find ID" -// @Router /file/upload [post] -func Upload(ctx *gin.Context) { - //write your code -} - -// @Summary use Anonymous field -// @Success 200 {object} web.RevValue "ok" -func AnonymousField() { - -} - -// @Summary use pet2 -// @Success 200 {object} web.Pet2 "ok" -func Pet2() { - -} - -// @Summary Use IndirectRecursiveTest -// @Success 200 {object} web.IndirectRecursiveTest -func IndirectRecursiveTest() { -} - -// @Summary Use Tags -// @Success 200 {object} web.Tags -func Tags() { -} - -// @Summary Use CrossAlias -// @Success 200 {object} web.CrossAlias -func CrossAlias() { -} - -// @Summary Use AnonymousStructArray -// @Success 200 {object} web.AnonymousStructArray -func AnonymousStructArray() { -} - -type Pet3 struct { - ID int `json:"id"` -} - -// @Success 200 {object} web.Pet5a "ok" -func GetPet5a() { - -} - -// @Success 200 {object} web.Pet5b "ok" -func GetPet5b() { - -} - -// @Success 200 {object} web.Pet5c "ok" -func GetPet5c() { - -} - -type SwagReturn []map[string]string - -// @Success 200 {object} api.SwagReturn "ok" -func GetPet6MapString() { - -} diff --git a/testdata/simple_cgo/cross/test.go b/testdata/simple_cgo/cross/test.go deleted file mode 100644 index 540e53f4f..000000000 --- a/testdata/simple_cgo/cross/test.go +++ /dev/null @@ -1,6 +0,0 @@ -package cross - -type Cross struct { - Array []string - String string -} diff --git a/testdata/simple_cgo/web/handler.go b/testdata/simple_cgo/web/handler.go deleted file mode 100644 index ece1628dc..000000000 --- a/testdata/simple_cgo/web/handler.go +++ /dev/null @@ -1,97 +0,0 @@ -package web - -import ( - "time" - - "github.com/satori/go.uuid" - "github.com/shopspring/decimal" - "github.com/swaggo/swag/testdata/simple/cross" -) - -type Pet struct { - ID int `json:"id" example:"1" format:"int64" readonly:"true"` - Category struct { - ID int `json:"id" example:"1"` - Name string `json:"name" example:"category_name"` - PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" format:"url"` - SmallCategory struct { - ID int `json:"id" example:"1"` - Name string `json:"name" example:"detail_category_name" binding:"required" minLength:"4" maxLength:"16"` - PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg"` - } `json:"small_category"` - } `json:"category"` - Name string `json:"name" example:"poti" binding:"required"` - PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" binding:"required"` - Tags []Tag `json:"tags"` - Pets *[]Pet2 `json:"pets"` - Pets2 []*Pet2 `json:"pets2"` - Status string `json:"status" enums:"healthy,ill"` - Price float32 `json:"price" example:"3.25" minimum:"1.0" maximum:"1000"` - IsAlive bool `json:"is_alive" example:"true" default:"true"` - Data interface{} `json:"data"` - Hidden string `json:"-"` - UUID uuid.UUID `json:"uuid"` - Decimal decimal.Decimal `json:"decimal"` - IntArray []int `json:"int_array" example:"1,2"` - EnumArray []int `json:"enum_array" enums:"1,2,3,5,7"` -} - -type Tag struct { - ID int `json:"id" format:"int64"` - Name string `json:"name"` - Pets []Pet `json:"pets"` -} - -type Tags []*Tag - -type AnonymousStructArray []struct { - Foo string `json:"foo"` -} - -type CrossAlias cross.Cross - -type Pet2 struct { - ID int `json:"id"` - MiddleName *string `json:"middlename" extensions:"x-nullable,x-abc=def"` - DeletedAt *time.Time `json:"deleted_at"` -} - -type IndirectRecursiveTest struct { - Tags []Tag -} - -type APIError struct { - ErrorCode int - ErrorMessage string - CreatedAt time.Time -} - -type RevValueBase struct { - Status bool `json:"Status"` - - Err int32 `json:"Err,omitempty"` -} -type RevValue struct { - RevValueBase `json:"rev_value_base"` - - Data int `json:"Data"` - Cross cross.Cross `json:"cross"` - Crosses []cross.Cross `json:"crosses"` -} - -// Below we have Pet5b as base type and Pet5a and Pet5c both have Pet5b as anonymous field, inheriting it's properties -// By using these names we ensure that our test will fill if the order of parsing matters at all - -type Pet5a struct { - *Pet5b - Odd bool `json:"odd" binding:"required"` -} - -type Pet5b struct { - Name string `json:"name" binding:"required"` -} - -type Pet5c struct { - *Pet5b - Odd bool `json:"odd" binding:"required"` -} From 3cafd99d2fc4251b955e5d3800404e4d5016be7e Mon Sep 17 00:00:00 2001 From: Damien Date: Thu, 16 Apr 2020 16:24:30 +1100 Subject: [PATCH 4/6] Revert "cleanup : removed unused source" This reverts commit 070af50f4f7408932e08e47dd574684db6639bba. --- testdata/simple_cgo/api/api.go | 116 +++++++++++++++++++++++++++++ testdata/simple_cgo/cross/test.go | 6 ++ testdata/simple_cgo/web/handler.go | 97 ++++++++++++++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 testdata/simple_cgo/api/api.go create mode 100644 testdata/simple_cgo/cross/test.go create mode 100644 testdata/simple_cgo/web/handler.go diff --git a/testdata/simple_cgo/api/api.go b/testdata/simple_cgo/api/api.go new file mode 100644 index 000000000..ba6734d71 --- /dev/null +++ b/testdata/simple_cgo/api/api.go @@ -0,0 +1,116 @@ +package api + +import ( + "github.com/gin-gonic/gin" +) + +// @Summary Add a new pet to the store +// @Description get string by ID +// @ID get-string-by-int +// @Accept json +// @Produce json +// @Param some_id path int true "Some ID" Format(int64) +// @Param some_id body web.Pet true "Some ID" +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 404 {object} web.APIError "Can not find ID" +// @Router /testapi/get-string-by-int/{some_id} [get] +func GetStringByInt(c *gin.Context) { + //write your code +} + +// @Description get struct array by ID +// @ID get-struct-array-by-string +// @Accept json +// @Produce json +// @Param some_id path string true "Some ID" +// @Param category query int true "Category" Enums(1, 2, 3) +// @Param offset query int true "Offset" Mininum(0) default(0) +// @Param limit query int true "Limit" Maxinum(50) default(10) +// @Param q query string true "q" Minlength(1) Maxlength(50) default("") +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 404 {object} web.APIError "Can not find ID" +// @Security ApiKeyAuth +// @Security BasicAuth +// @Security OAuth2Application[write] +// @Security OAuth2Implicit[read, admin] +// @Security OAuth2AccessCode[read] +// @Security OAuth2Password[admin] +// @Router /testapi/get-struct-array-by-string/{some_id} [get] +func GetStructArrayByString(c *gin.Context) { + //write your code +} + +// @Summary Upload file +// @Description Upload file +// @ID file.upload +// @Accept multipart/form-data +// @Produce json +// @Param file formData file true "this is a test file" +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 401 {array} string +// @Failure 404 {object} web.APIError "Can not find ID" +// @Router /file/upload [post] +func Upload(ctx *gin.Context) { + //write your code +} + +// @Summary use Anonymous field +// @Success 200 {object} web.RevValue "ok" +func AnonymousField() { + +} + +// @Summary use pet2 +// @Success 200 {object} web.Pet2 "ok" +func Pet2() { + +} + +// @Summary Use IndirectRecursiveTest +// @Success 200 {object} web.IndirectRecursiveTest +func IndirectRecursiveTest() { +} + +// @Summary Use Tags +// @Success 200 {object} web.Tags +func Tags() { +} + +// @Summary Use CrossAlias +// @Success 200 {object} web.CrossAlias +func CrossAlias() { +} + +// @Summary Use AnonymousStructArray +// @Success 200 {object} web.AnonymousStructArray +func AnonymousStructArray() { +} + +type Pet3 struct { + ID int `json:"id"` +} + +// @Success 200 {object} web.Pet5a "ok" +func GetPet5a() { + +} + +// @Success 200 {object} web.Pet5b "ok" +func GetPet5b() { + +} + +// @Success 200 {object} web.Pet5c "ok" +func GetPet5c() { + +} + +type SwagReturn []map[string]string + +// @Success 200 {object} api.SwagReturn "ok" +func GetPet6MapString() { + +} diff --git a/testdata/simple_cgo/cross/test.go b/testdata/simple_cgo/cross/test.go new file mode 100644 index 000000000..540e53f4f --- /dev/null +++ b/testdata/simple_cgo/cross/test.go @@ -0,0 +1,6 @@ +package cross + +type Cross struct { + Array []string + String string +} diff --git a/testdata/simple_cgo/web/handler.go b/testdata/simple_cgo/web/handler.go new file mode 100644 index 000000000..ece1628dc --- /dev/null +++ b/testdata/simple_cgo/web/handler.go @@ -0,0 +1,97 @@ +package web + +import ( + "time" + + "github.com/satori/go.uuid" + "github.com/shopspring/decimal" + "github.com/swaggo/swag/testdata/simple/cross" +) + +type Pet struct { + ID int `json:"id" example:"1" format:"int64" readonly:"true"` + Category struct { + ID int `json:"id" example:"1"` + Name string `json:"name" example:"category_name"` + PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" format:"url"` + SmallCategory struct { + ID int `json:"id" example:"1"` + Name string `json:"name" example:"detail_category_name" binding:"required" minLength:"4" maxLength:"16"` + PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg"` + } `json:"small_category"` + } `json:"category"` + Name string `json:"name" example:"poti" binding:"required"` + PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" binding:"required"` + Tags []Tag `json:"tags"` + Pets *[]Pet2 `json:"pets"` + Pets2 []*Pet2 `json:"pets2"` + Status string `json:"status" enums:"healthy,ill"` + Price float32 `json:"price" example:"3.25" minimum:"1.0" maximum:"1000"` + IsAlive bool `json:"is_alive" example:"true" default:"true"` + Data interface{} `json:"data"` + Hidden string `json:"-"` + UUID uuid.UUID `json:"uuid"` + Decimal decimal.Decimal `json:"decimal"` + IntArray []int `json:"int_array" example:"1,2"` + EnumArray []int `json:"enum_array" enums:"1,2,3,5,7"` +} + +type Tag struct { + ID int `json:"id" format:"int64"` + Name string `json:"name"` + Pets []Pet `json:"pets"` +} + +type Tags []*Tag + +type AnonymousStructArray []struct { + Foo string `json:"foo"` +} + +type CrossAlias cross.Cross + +type Pet2 struct { + ID int `json:"id"` + MiddleName *string `json:"middlename" extensions:"x-nullable,x-abc=def"` + DeletedAt *time.Time `json:"deleted_at"` +} + +type IndirectRecursiveTest struct { + Tags []Tag +} + +type APIError struct { + ErrorCode int + ErrorMessage string + CreatedAt time.Time +} + +type RevValueBase struct { + Status bool `json:"Status"` + + Err int32 `json:"Err,omitempty"` +} +type RevValue struct { + RevValueBase `json:"rev_value_base"` + + Data int `json:"Data"` + Cross cross.Cross `json:"cross"` + Crosses []cross.Cross `json:"crosses"` +} + +// Below we have Pet5b as base type and Pet5a and Pet5c both have Pet5b as anonymous field, inheriting it's properties +// By using these names we ensure that our test will fill if the order of parsing matters at all + +type Pet5a struct { + *Pet5b + Odd bool `json:"odd" binding:"required"` +} + +type Pet5b struct { + Name string `json:"name" binding:"required"` +} + +type Pet5c struct { + *Pet5b + Odd bool `json:"odd" binding:"required"` +} From e21ff5ddc1bf20f49c9ad0fdf5aa02c7a7b4468a Mon Sep 17 00:00:00 2001 From: Damien Date: Thu, 16 Apr 2020 16:25:41 +1100 Subject: [PATCH 5/6] test: use good api reference --- testdata/simple_cgo/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/simple_cgo/main.go b/testdata/simple_cgo/main.go index 63deacc33..13b15c02d 100644 --- a/testdata/simple_cgo/main.go +++ b/testdata/simple_cgo/main.go @@ -11,7 +11,7 @@ import "C" import ( "github.com/gin-gonic/gin" - "github.com/swaggo/swag/testdata/simple/api" + "github.com/swaggo/swag/testdata/simple_cgo/api" ) // @title Swagger Example API From 5b6f1b79ceda701f5526a89b2165648567e3d386 Mon Sep 17 00:00:00 2001 From: Damien Date: Thu, 16 Apr 2020 18:10:38 +1100 Subject: [PATCH 6/6] simplified cgo test --- testdata/simple_cgo/api/api.go | 103 +---------------------------- testdata/simple_cgo/cross/test.go | 6 -- testdata/simple_cgo/main.go | 2 - testdata/simple_cgo/web/handler.go | 97 --------------------------- 4 files changed, 3 insertions(+), 205 deletions(-) delete mode 100644 testdata/simple_cgo/cross/test.go delete mode 100644 testdata/simple_cgo/web/handler.go diff --git a/testdata/simple_cgo/api/api.go b/testdata/simple_cgo/api/api.go index ba6734d71..9de5c6ca8 100644 --- a/testdata/simple_cgo/api/api.go +++ b/testdata/simple_cgo/api/api.go @@ -10,107 +10,10 @@ import ( // @Accept json // @Produce json // @Param some_id path int true "Some ID" Format(int64) -// @Param some_id body web.Pet true "Some ID" +// @Param some_id body int true "Some ID" // @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 404 {object} web.APIError "Can not find ID" +// @Failure 400 {object} string "We need ID!!" +// @Failure 404 {object} string "Can not find ID" // @Router /testapi/get-string-by-int/{some_id} [get] func GetStringByInt(c *gin.Context) { - //write your code -} - -// @Description get struct array by ID -// @ID get-struct-array-by-string -// @Accept json -// @Produce json -// @Param some_id path string true "Some ID" -// @Param category query int true "Category" Enums(1, 2, 3) -// @Param offset query int true "Offset" Mininum(0) default(0) -// @Param limit query int true "Limit" Maxinum(50) default(10) -// @Param q query string true "q" Minlength(1) Maxlength(50) default("") -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 404 {object} web.APIError "Can not find ID" -// @Security ApiKeyAuth -// @Security BasicAuth -// @Security OAuth2Application[write] -// @Security OAuth2Implicit[read, admin] -// @Security OAuth2AccessCode[read] -// @Security OAuth2Password[admin] -// @Router /testapi/get-struct-array-by-string/{some_id} [get] -func GetStructArrayByString(c *gin.Context) { - //write your code -} - -// @Summary Upload file -// @Description Upload file -// @ID file.upload -// @Accept multipart/form-data -// @Produce json -// @Param file formData file true "this is a test file" -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 401 {array} string -// @Failure 404 {object} web.APIError "Can not find ID" -// @Router /file/upload [post] -func Upload(ctx *gin.Context) { - //write your code -} - -// @Summary use Anonymous field -// @Success 200 {object} web.RevValue "ok" -func AnonymousField() { - -} - -// @Summary use pet2 -// @Success 200 {object} web.Pet2 "ok" -func Pet2() { - -} - -// @Summary Use IndirectRecursiveTest -// @Success 200 {object} web.IndirectRecursiveTest -func IndirectRecursiveTest() { -} - -// @Summary Use Tags -// @Success 200 {object} web.Tags -func Tags() { -} - -// @Summary Use CrossAlias -// @Success 200 {object} web.CrossAlias -func CrossAlias() { -} - -// @Summary Use AnonymousStructArray -// @Success 200 {object} web.AnonymousStructArray -func AnonymousStructArray() { -} - -type Pet3 struct { - ID int `json:"id"` -} - -// @Success 200 {object} web.Pet5a "ok" -func GetPet5a() { - -} - -// @Success 200 {object} web.Pet5b "ok" -func GetPet5b() { - -} - -// @Success 200 {object} web.Pet5c "ok" -func GetPet5c() { - -} - -type SwagReturn []map[string]string - -// @Success 200 {object} api.SwagReturn "ok" -func GetPet6MapString() { - } diff --git a/testdata/simple_cgo/cross/test.go b/testdata/simple_cgo/cross/test.go deleted file mode 100644 index 540e53f4f..000000000 --- a/testdata/simple_cgo/cross/test.go +++ /dev/null @@ -1,6 +0,0 @@ -package cross - -type Cross struct { - Array []string - String string -} diff --git a/testdata/simple_cgo/main.go b/testdata/simple_cgo/main.go index 13b15c02d..3368deb68 100644 --- a/testdata/simple_cgo/main.go +++ b/testdata/simple_cgo/main.go @@ -60,7 +60,5 @@ func main() { r := gin.New() r.GET("/testapi/get-string-by-int/:some_id", api.GetStringByInt) - r.GET("/testapi/get-struct-array-by-string/:some_id", api.GetStructArrayByString) - r.POST("/testapi/upload", api.Upload) r.Run() } diff --git a/testdata/simple_cgo/web/handler.go b/testdata/simple_cgo/web/handler.go deleted file mode 100644 index ece1628dc..000000000 --- a/testdata/simple_cgo/web/handler.go +++ /dev/null @@ -1,97 +0,0 @@ -package web - -import ( - "time" - - "github.com/satori/go.uuid" - "github.com/shopspring/decimal" - "github.com/swaggo/swag/testdata/simple/cross" -) - -type Pet struct { - ID int `json:"id" example:"1" format:"int64" readonly:"true"` - Category struct { - ID int `json:"id" example:"1"` - Name string `json:"name" example:"category_name"` - PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" format:"url"` - SmallCategory struct { - ID int `json:"id" example:"1"` - Name string `json:"name" example:"detail_category_name" binding:"required" minLength:"4" maxLength:"16"` - PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg"` - } `json:"small_category"` - } `json:"category"` - Name string `json:"name" example:"poti" binding:"required"` - PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg,http://test/image/2.jpg" binding:"required"` - Tags []Tag `json:"tags"` - Pets *[]Pet2 `json:"pets"` - Pets2 []*Pet2 `json:"pets2"` - Status string `json:"status" enums:"healthy,ill"` - Price float32 `json:"price" example:"3.25" minimum:"1.0" maximum:"1000"` - IsAlive bool `json:"is_alive" example:"true" default:"true"` - Data interface{} `json:"data"` - Hidden string `json:"-"` - UUID uuid.UUID `json:"uuid"` - Decimal decimal.Decimal `json:"decimal"` - IntArray []int `json:"int_array" example:"1,2"` - EnumArray []int `json:"enum_array" enums:"1,2,3,5,7"` -} - -type Tag struct { - ID int `json:"id" format:"int64"` - Name string `json:"name"` - Pets []Pet `json:"pets"` -} - -type Tags []*Tag - -type AnonymousStructArray []struct { - Foo string `json:"foo"` -} - -type CrossAlias cross.Cross - -type Pet2 struct { - ID int `json:"id"` - MiddleName *string `json:"middlename" extensions:"x-nullable,x-abc=def"` - DeletedAt *time.Time `json:"deleted_at"` -} - -type IndirectRecursiveTest struct { - Tags []Tag -} - -type APIError struct { - ErrorCode int - ErrorMessage string - CreatedAt time.Time -} - -type RevValueBase struct { - Status bool `json:"Status"` - - Err int32 `json:"Err,omitempty"` -} -type RevValue struct { - RevValueBase `json:"rev_value_base"` - - Data int `json:"Data"` - Cross cross.Cross `json:"cross"` - Crosses []cross.Cross `json:"crosses"` -} - -// Below we have Pet5b as base type and Pet5a and Pet5c both have Pet5b as anonymous field, inheriting it's properties -// By using these names we ensure that our test will fill if the order of parsing matters at all - -type Pet5a struct { - *Pet5b - Odd bool `json:"odd" binding:"required"` -} - -type Pet5b struct { - Name string `json:"name" binding:"required"` -} - -type Pet5c struct { - *Pet5b - Odd bool `json:"odd" binding:"required"` -}