Merge pull request #5537 from nikhiljindal/swaggie

Updating go-restful to include fix for emicklei/go-restful#185
This commit is contained in:
Brian Grant 2015-03-17 11:51:01 -07:00
commit a62673d226
9 changed files with 6843 additions and 6903 deletions

4
Godeps/Godeps.json generated
View File

@ -156,8 +156,8 @@
}, },
{ {
"ImportPath": "github.com/emicklei/go-restful", "ImportPath": "github.com/emicklei/go-restful",
"Comment": "v1.1.3-9-g49e08a0", "Comment": "v1.1.3-10-g62dc65d",
"Rev": "49e08a07d31e2dae8005f28b5360a96746cd6365" "Rev": "62dc65d6e51525418cad2bb6f292d3cf7c5e9d0a"
}, },
{ {
"ImportPath": "github.com/evanphx/json-patch", "ImportPath": "github.com/evanphx/json-patch",

View File

@ -0,0 +1,32 @@
package swagger
import "github.com/emicklei/go-restful"
type orderedRouteMap struct {
elements map[string][]restful.Route
keys []string
}
func newOrderedRouteMap() *orderedRouteMap {
return &orderedRouteMap{
elements: map[string][]restful.Route{},
keys: []string{},
}
}
func (o *orderedRouteMap) Add(key string, route restful.Route) {
routes, ok := o.elements[key]
if ok {
routes = append(routes, route)
o.elements[key] = routes
return
}
o.elements[key] = []restful.Route{route}
o.keys = append(o.keys, key)
}
func (o *orderedRouteMap) Do(block func(key string, routes []restful.Route)) {
for _, k := range o.keys {
block(k, o.elements[k])
}
}

View File

@ -0,0 +1,29 @@
package swagger
import (
"testing"
"github.com/emicklei/go-restful"
)
// go test -v -test.run TestOrderedRouteMap ...swagger
func TestOrderedRouteMap(t *testing.T) {
m := newOrderedRouteMap()
r1 := restful.Route{Path: "/r1"}
r2 := restful.Route{Path: "/r2"}
m.Add("a", r1)
m.Add("b", r2)
m.Add("b", r1)
m.Add("d", r2)
m.Add("c", r2)
order := ""
m.Do(func(k string, routes []restful.Route) {
order += k
if len(routes) == 0 {
t.Fail()
}
})
if order != "abdc" {
t.Fail()
}
}

View File

@ -1,26 +1,26 @@
package swagger package swagger
import ( import (
"encoding/json"
"fmt"
"testing" "testing"
"github.com/emicklei/go-restful" "github.com/emicklei/go-restful"
) )
// go test -v -test.run TestApi ...swagger
func TestApi(t *testing.T) {
value := Api{Path: "/", Description: "Some Path", Operations: []Operation{}}
compareJson(t, true, value, `{"path":"/","description":"Some Path"}`)
}
// go test -v -test.run TestServiceToApi ...swagger // go test -v -test.run TestServiceToApi ...swagger
func TestServiceToApi(t *testing.T) { func TestServiceToApi(t *testing.T) {
ws := new(restful.WebService) ws := new(restful.WebService)
ws.Path("/tests") ws.Path("/tests")
ws.Consumes(restful.MIME_JSON) ws.Consumes(restful.MIME_JSON)
ws.Produces(restful.MIME_XML) ws.Produces(restful.MIME_XML)
ws.Route(ws.GET("/all").To(dummy).Writes(sample{})) ws.Route(ws.GET("/a").To(dummy).Writes(sample{}))
ws.Route(ws.PUT("/b").To(dummy).Writes(sample{}))
ws.Route(ws.POST("/c").To(dummy).Writes(sample{}))
ws.Route(ws.DELETE("/d").To(dummy).Writes(sample{}))
ws.Route(ws.GET("/d").To(dummy).Writes(sample{}))
ws.Route(ws.PUT("/c").To(dummy).Writes(sample{}))
ws.Route(ws.POST("/b").To(dummy).Writes(sample{}))
ws.Route(ws.DELETE("/a").To(dummy).Writes(sample{}))
ws.ApiVersion("1.2.3") ws.ApiVersion("1.2.3")
cfg := Config{ cfg := Config{
WebServicesUrl: "http://here.com", WebServicesUrl: "http://here.com",
@ -28,12 +28,26 @@ func TestServiceToApi(t *testing.T) {
WebServices: []*restful.WebService{ws}} WebServices: []*restful.WebService{ws}}
sws := newSwaggerService(cfg) sws := newSwaggerService(cfg)
decl := sws.composeDeclaration(ws, "/tests") decl := sws.composeDeclaration(ws, "/tests")
data, err := json.MarshalIndent(decl, " ", " ") // checks
if err != nil { if decl.ApiVersion != "1.2.3" {
t.Fatal(err.Error()) t.Errorf("got %v want %v", decl.ApiVersion, "1.2.3")
}
if decl.BasePath != "http://here.com" {
t.Errorf("got %v want %v", decl.BasePath, "http://here.com")
}
if len(decl.Apis) != 4 {
t.Errorf("got %v want %v", len(decl.Apis), 4)
}
pathOrder := ""
for _, each := range decl.Apis {
pathOrder += each.Path
for _, other := range each.Operations {
pathOrder += other.Method
}
}
if pathOrder != "/tests/aGETDELETE/tests/bPUTPOST/tests/cPOSTPUT/tests/dDELETEGET" {
t.Errorf("got %v want %v", pathOrder, "see test source")
} }
// for visual inspection only
fmt.Println(string(data))
} }
func dummy(i *restful.Request, o *restful.Response) {} func dummy(i *restful.Request, o *restful.Response) {}

View File

@ -180,14 +180,13 @@ func (sws SwaggerService) composeDeclaration(ws *restful.WebService, pathPrefix
rootParams = append(rootParams, asSwaggerParameter(param.Data())) rootParams = append(rootParams, asSwaggerParameter(param.Data()))
} }
// aggregate by path // aggregate by path
pathToRoutes := map[string][]restful.Route{} pathToRoutes := newOrderedRouteMap()
for _, other := range ws.Routes() { for _, other := range ws.Routes() {
if strings.HasPrefix(other.Path, pathPrefix) { if strings.HasPrefix(other.Path, pathPrefix) {
routes := pathToRoutes[other.Path] pathToRoutes.Add(other.Path, other)
pathToRoutes[other.Path] = append(routes, other)
} }
} }
for path, routes := range pathToRoutes { pathToRoutes.Do(func(path string, routes []restful.Route) {
api := Api{Path: strings.TrimSuffix(path, "/"), Description: ws.Documentation()} api := Api{Path: strings.TrimSuffix(path, "/"), Description: ws.Documentation()}
for _, route := range routes { for _, route := range routes {
operation := Operation{ operation := Operation{
@ -217,7 +216,7 @@ func (sws SwaggerService) composeDeclaration(ws *restful.WebService, pathPrefix
api.Operations = append(api.Operations, operation) api.Operations = append(api.Operations, operation)
} }
decl.Apis = append(decl.Apis, api) decl.Apis = append(decl.Apis, api)
} })
return decl return decl
} }

View File

@ -9,8 +9,10 @@ import (
"testing" "testing"
) )
func testJsonFromStruct(t *testing.T, sample interface{}, expectedJson string) { func testJsonFromStruct(t *testing.T, sample interface{}, expectedJson string) bool {
compareJson(t, false, modelsFromStruct(sample), expectedJson) m := modelsFromStruct(sample)
data, _ := json.MarshalIndent(m, " ", " ")
return compareJson(t, string(data), expectedJson)
} }
func modelsFromStruct(sample interface{}) map[string]Model { func modelsFromStruct(sample interface{}) map[string]Model {
@ -20,32 +22,20 @@ func modelsFromStruct(sample interface{}) map[string]Model {
return models return models
} }
func compareJson(t *testing.T, flatCompare bool, value interface{}, expectedJsonAsString string) { func compareJson(t *testing.T, actualJsonAsString string, expectedJsonAsString string) bool {
var output []byte
var err error
if flatCompare {
output, err = json.Marshal(value)
} else {
output, err = json.MarshalIndent(value, " ", " ")
}
if err != nil {
t.Error(err.Error())
return
}
actual := string(output)
var actualMap map[string]interface{} var actualMap map[string]interface{}
json.Unmarshal([]byte(actualJsonAsString), &actualMap)
var expectedMap map[string]interface{} var expectedMap map[string]interface{}
json.Unmarshal(output, &actualMap)
json.Unmarshal([]byte(expectedJsonAsString), &expectedMap) json.Unmarshal([]byte(expectedJsonAsString), &expectedMap)
if !reflect.DeepEqual(actualMap, expectedMap) { if !reflect.DeepEqual(actualMap, expectedMap) {
fmt.Println("---- expected -----") fmt.Println("---- expected -----")
fmt.Println(withLineNumbers(expectedJsonAsString)) fmt.Println(withLineNumbers(expectedJsonAsString))
fmt.Println("---- actual -----") fmt.Println("---- actual -----")
fmt.Println(withLineNumbers(actual)) fmt.Println(withLineNumbers(actualJsonAsString))
fmt.Println("---- raw -----")
fmt.Println(actual)
t.Error("there are differences") t.Error("there are differences")
return false
} }
return true
} }
func indexOfNonMatchingLine(actual, expected string) int { func indexOfNonMatchingLine(actual, expected string) int {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff