Skip to content

Commit

Permalink
Updated the project's README and godocs
Browse files Browse the repository at this point in the history
* removed golangci badge
* made it explicit the repo won't support swagger 3
* added some missing godoc comments
* run gofmt
* reworked one complex unit test for readability

* closes #21

Signed-off-by: Frederic BIDON <[email protected]>
  • Loading branch information
fredbi committed Nov 26, 2020
1 parent d0486ac commit 9afb06a
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 49 deletions.
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/go-openapi/spec?status.svg)](http://godoc.org/github.com/go-openapi/spec)
[![GolangCI](https://golangci.com/badges/github.com/go-openapi/spec.svg)](https://golangci.com)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/spec)](https://goreportcard.com/report/github.com/go-openapi/spec)

The object model for OpenAPI specification documents.

Currently supports Swagger 2.0.
### FAQ

* What does this do?

> 1. This package knows how to marshal and unmarshal Swagger API specifications into a golang object model
> 2. It knows how to resolve $ref and expand them to make a single root documment
* How does it play with the rest of the go-openapi packages ?

> 1. This package is a the core of the go-openapi suite of packages and [code generator](https://github.com/go-swagger/go-swagger)
> 2. There is [spec loading package](https://github.com/go-openapi/loads) to fetch specs as JSON or YAML from local or remote locations
> 3. There is [spec validation package](https://github.com/go-openapi/validate) built on top of it
> 4. There is [spec analysis package](https://github.com/go-openapi/analysis) built on top of it, to analyze, flatten, fix and merge spec documents
* Does this library support OpenAPI 3?

> No.
> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0).
> There is no plan to make it evolve toward supporting OpenAPI 3.x.
> 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
6 changes: 3 additions & 3 deletions bindata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions contact_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,22 @@ type ContactInfo struct {
VendorExtensible
}

// ContactInfoProps hold the properties of a ContactInfo object
type ContactInfoProps struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
Email string `json:"email,omitempty"`
}

// UnmarshalJSON hydrates ContactInfo from json
func (c *ContactInfo) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &c.ContactInfoProps); err != nil {
return err
}
return json.Unmarshal(data, &c.VendorExtensible)
}

// MarshalJSON produces ContactInfo as json
func (c ContactInfo) MarshalJSON() ([]byte, error) {
b1, err := json.Marshal(c.ContactInfoProps)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions license.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,21 @@ type License struct {
VendorExtensible
}

// LicenseProps holds the properties of a License object
type LicenseProps struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
}

// UnmarshalJSON hydrates License from json
func (l *License) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &l.LicenseProps); err != nil {
return err
}
return json.Unmarshal(data, &l.VendorExtensible)
}

// MarshalJSON produces License as json
func (l License) MarshalJSON() ([]byte, error) {
b1, err := json.Marshal(l.LicenseProps)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ import (
"sort"
)

// OrderSchemaItem holds a named schema (e.g. from a property of an object)
type OrderSchemaItem struct {
Name string
Schema
}

// OrderSchemaItems is a sortable slice of named schemas.
// The ordering is defined by the x-order schema extension.
type OrderSchemaItems []OrderSchemaItem

// MarshalJSON produces a json object with keys defined by the name schemas
// of the OrderSchemaItems slice, keeping the original order of the slice.
func (items OrderSchemaItems) MarshalJSON() ([]byte, error) {
buf := bytes.NewBuffer(nil)
buf.WriteString("{")
Expand Down Expand Up @@ -60,8 +65,11 @@ func (items OrderSchemaItems) Less(i, j int) (ret bool) {
return items[i].Name < items[j].Name
}

// SchemaProperties is a map representing the properties of a Schema object.
// It knows how to transform its keys into an ordered slice.
type SchemaProperties map[string]Schema

// ToOrderedSchemaItems transforms the map of properties into a sortable slice
func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems {
items := make(OrderSchemaItems, 0, len(properties))
for k, v := range properties {
Expand All @@ -74,6 +82,7 @@ func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems {
return items
}

// MarshalJSON produces properties as json, keeping their order.
func (properties SchemaProperties) MarshalJSON() ([]byte, error) {
if properties == nil {
return []byte("null"), nil
Expand Down
97 changes: 53 additions & 44 deletions spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,25 +72,8 @@ func Test_Issue1429(t *testing.T) {
// assert well expanded
require.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture")

for _, pi := range sp.Paths.Paths {
for _, param := range pi.Get.Parameters {
if assert.NotNilf(t, param.Schema, "expected param schema not to be nil") {
// all param fixtures are body param with schema
// all $ref expanded
assert.Equal(t, "", param.Schema.Ref.String())
}
}
for code, response := range pi.Get.Responses.StatusCodeResponses {
// all response fixtures are with StatusCodeResponses, but 200
if code == 200 {
assert.Nilf(t, response.Schema, "expected response schema to be nil")
continue
}
if assert.NotNilf(t, response.Schema, "expected response schema not to be nil") {
assert.Equal(t, "", response.Schema.Ref.String())
}
}
}
assertPaths1429(t, sp)

for _, def := range sp.Definitions {
assert.Equal(t, "", def.Ref.String())
}
Expand All @@ -103,48 +86,74 @@ func Test_Issue1429(t *testing.T) {
// assert well resolved
require.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture")

assertPaths1429SkipSchema(t, sp)

for _, def := range sp.Definitions {
assert.Contains(t, def.Ref.String(), "responses.yaml#/")
}
}

func assertPaths1429(t testing.TB, sp *spec.Swagger) {
for _, pi := range sp.Paths.Paths {
for _, param := range pi.Get.Parameters {
if assert.NotNilf(t, param.Schema, "expected param schema not to be nil") {
// all param fixtures are body param with schema
if param.Name == "plainRequest" {
// this one is expanded
assert.Equal(t, "", param.Schema.Ref.String())
continue
}
if param.Name == "nestedBody" {
// this one is local
assert.Truef(t, strings.HasPrefix(param.Schema.Ref.String(), "#/definitions/"),
"expected rooted definitions $ref, got: %s", param.Schema.Ref.String())
continue
}
if param.Name == "remoteRequest" {
assert.Contains(t, param.Schema.Ref.String(), "remote/remote.yaml#/")
continue
}
assert.Contains(t, param.Schema.Ref.String(), "responses.yaml#/")
}
require.NotNilf(t, param.Schema, "expected param schema not to be nil")
// all param fixtures are body param with schema
// all $ref expanded
assert.Equal(t, "", param.Schema.Ref.String())
}

for code, response := range pi.Get.Responses.StatusCodeResponses {
// all response fixtures are with StatusCodeResponses, but 200
if code == 200 {
assert.Nilf(t, response.Schema, "expected response schema to be nil")
continue
}
if code == 204 {
assert.Contains(t, response.Schema.Ref.String(), "remote/remote.yaml#/")
require.NotNilf(t, response.Schema, "expected response schema not to be nil")
assert.Equal(t, "", response.Schema.Ref.String())
}
}
}

func assertPaths1429SkipSchema(t testing.TB, sp *spec.Swagger) {
for _, pi := range sp.Paths.Paths {
for _, param := range pi.Get.Parameters {
require.NotNilf(t, param.Schema, "expected param schema not to be nil")

// all param fixtures are body param with schema
switch param.Name {
case "plainRequest":
// this one is expanded
assert.Equal(t, "", param.Schema.Ref.String())
continue
case "nestedBody":
// this one is local
assert.Truef(t, strings.HasPrefix(param.Schema.Ref.String(), "#/definitions/"),
"expected rooted definitions $ref, got: %s", param.Schema.Ref.String())
continue
case "remoteRequest":
assert.Contains(t, param.Schema.Ref.String(), "remote/remote.yaml#/")
continue
}
if code == 404 {
assert.Contains(t, param.Schema.Ref.String(), "responses.yaml#/")

}

for code, response := range pi.Get.Responses.StatusCodeResponses {
// all response fixtures are with StatusCodeResponses, but 200
switch code {
case 200:
assert.Nilf(t, response.Schema, "expected response schema to be nil")
continue
case 204:
assert.Contains(t, response.Schema.Ref.String(), "remote/remote.yaml#/")
continue
case 404:
assert.Equal(t, "", response.Schema.Ref.String())
continue
}
assert.Containsf(t, response.Schema.Ref.String(), "responses.yaml#/", "expected remote ref at resp. %d", code)
}
}
for _, def := range sp.Definitions {
assert.Contains(t, def.Ref.String(), "responses.yaml#/")
}
}

func Test_MoreLocalExpansion(t *testing.T) {
Expand Down

0 comments on commit 9afb06a

Please sign in to comment.