mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
Adding in some mock examples
Noticed that I had missed something in the burgershop. Now that we can ‘see’ the spec, it’s going to open up a whole ton of new capabilities. Signed-off-by: Quobix <dave@quobix.com>
This commit is contained in:
@@ -216,7 +216,7 @@ func TestNewDocument_Components_Schemas(t *testing.T) {
|
|||||||
|
|
||||||
f := h.Components.Schemas["Fries"]
|
f := h.Components.Schemas["Fries"]
|
||||||
assert.Equal(t, "salt", f.Schema().Properties["seasoning"].Schema().Items.A.Schema().Example)
|
assert.Equal(t, "salt", f.Schema().Properties["seasoning"].Schema().Items.A.Schema().Example)
|
||||||
assert.Len(t, f.Schema().Properties["favoriteDrink"].Schema().Properties["drinkType"].Schema().Enum, 2)
|
assert.Len(t, f.Schema().Properties["favoriteDrink"].Schema().Properties["drinkType"].Schema().Enum, 1)
|
||||||
|
|
||||||
d := h.Components.Schemas["Drink"]
|
d := h.Components.Schemas["Drink"]
|
||||||
assert.Len(t, d.Schema().Required, 2)
|
assert.Len(t, d.Schema().Required, 2)
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ func ExampleCompareDocuments_openAPI() {
|
|||||||
// Print out some interesting stats about the OpenAPI document changes.
|
// Print out some interesting stats about the OpenAPI document changes.
|
||||||
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
||||||
documentChanges.TotalChanges(), documentChanges.TotalBreakingChanges(), len(schemaChanges))
|
documentChanges.TotalChanges(), documentChanges.TotalBreakingChanges(), len(schemaChanges))
|
||||||
//Output: There are 72 changes, of which 17 are breaking. 5 schemas have changes.
|
//Output: There are 75 changes, of which 19 are breaking. 6 schemas have changes.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
|
|||||||
for i := 0; i < num; i++ {
|
for i := 0; i < num; i++ {
|
||||||
fieldName := v.Type().Field(i).Name
|
fieldName := v.Type().Field(i).Name
|
||||||
switch fieldName {
|
switch fieldName {
|
||||||
case Schema:
|
|
||||||
fieldCount++
|
|
||||||
case Example:
|
case Example:
|
||||||
fieldCount++
|
fieldCount++
|
||||||
case Examples:
|
case Examples:
|
||||||
@@ -54,12 +52,12 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
mockReady := false
|
mockReady := false
|
||||||
// check if all fields are present, if so, we can generate a mock
|
// check if all fields are present, if so, we can generate a mock
|
||||||
if fieldCount == 3 {
|
if fieldCount == 2 {
|
||||||
mockReady = true
|
mockReady = true
|
||||||
}
|
}
|
||||||
if !mockReady {
|
if !mockReady {
|
||||||
return nil, fmt.Errorf("mockable struct only contains %d of the required "+
|
return nil, fmt.Errorf("mockable struct only contains %d of the required "+
|
||||||
"fields (%s, %s, %s)", fieldCount, Schema, Example, Examples)
|
"fields (%s, %s)", fieldCount, Example, Examples)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the value has an example, try and render it out as is.
|
// if the value has an example, try and render it out as is.
|
||||||
@@ -70,29 +68,49 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if there is no example, but there are multi-examples.
|
// if there is no example, but there are multi-examples.
|
||||||
examplesValue := v.FieldByName(Examples).Interface()
|
examples := v.FieldByName(Examples)
|
||||||
if examplesValue != nil {
|
examplesValue := examples.Interface()
|
||||||
|
if examplesValue != nil && !examples.IsNil() {
|
||||||
|
|
||||||
// cast examples to map[string]interface{}
|
// cast examples to map[string]interface{}
|
||||||
examples := examplesValue.(map[string]*highbase.Example)
|
examplesMap := examplesValue.(map[string]*highbase.Example)
|
||||||
|
|
||||||
// if the name is not empty, try and find the example by name
|
// if the name is not empty, try and find the example by name
|
||||||
for k, exp := range examples {
|
for k, exp := range examplesMap {
|
||||||
if k == name {
|
if k == name {
|
||||||
return mg.renderMock(exp.Value), nil
|
return mg.renderMock(exp.Value), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the name is empty, just return the first example
|
// if the name is empty, just return the first example
|
||||||
for _, exp := range examples {
|
for _, exp := range examplesMap {
|
||||||
return mg.renderMock(exp.Value), nil
|
return mg.renderMock(exp.Value), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no examples? no problem, we can try and generate a mock from the schema.
|
// no examples? no problem, we can try and generate a mock from the schema.
|
||||||
schemaValue := v.FieldByName(Schema).Interface().(*highbase.SchemaProxy)
|
// check if this is a SchemaProxy, if not, then see if it has a Schema, if not, then we can't generate a mock.
|
||||||
|
var schemaValue *highbase.Schema
|
||||||
|
switch reflect.TypeOf(mock) {
|
||||||
|
case reflect.TypeOf(&highbase.SchemaProxy{}):
|
||||||
|
schemaValue = mock.(*highbase.SchemaProxy).Schema()
|
||||||
|
case reflect.TypeOf(&highbase.Schema{}):
|
||||||
|
schemaValue = mock.(*highbase.Schema)
|
||||||
|
default:
|
||||||
|
if sv, ok := v.FieldByName(Schema).Interface().(*highbase.Schema); ok {
|
||||||
|
if sv != nil {
|
||||||
|
schemaValue = sv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sv, ok := v.FieldByName(Schema).Interface().(*highbase.SchemaProxy); ok {
|
||||||
|
if sv != nil {
|
||||||
|
schemaValue = sv.Schema()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if schemaValue != nil {
|
if schemaValue != nil {
|
||||||
renderMap := mg.renderer.RenderSchema(schemaValue.Schema())
|
renderMap := mg.renderer.RenderSchema(schemaValue)
|
||||||
if renderMap != nil {
|
if renderMap != nil {
|
||||||
return mg.renderMock(renderMap), nil
|
return mg.renderMock(renderMap), nil
|
||||||
}
|
}
|
||||||
|
|||||||
128
renderer/mock_generator_examples_test.go
Normal file
128
renderer/mock_generator_examples_test.go
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
// Copyright 2023 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package renderer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pb33f/libopenapi"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleMockGenerator_generateBurgerMock_yaml() {
|
||||||
|
|
||||||
|
// create a new YAML mock generator
|
||||||
|
mg := NewMockGenerator(MockYAML)
|
||||||
|
|
||||||
|
burgerShop, _ := os.ReadFile("../test_specs/burgershop.openapi.yaml")
|
||||||
|
|
||||||
|
// create a new document from specification and build a v3 model.
|
||||||
|
document, _ := libopenapi.NewDocument(burgerShop)
|
||||||
|
v3Model, _ := document.BuildV3Model()
|
||||||
|
|
||||||
|
// create a mock of the Burger model
|
||||||
|
burgerModel := v3Model.Model.Components.Schemas["Burger"]
|
||||||
|
burger := burgerModel.Schema()
|
||||||
|
mock, err := mg.GenerateMock(burger, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(mock))
|
||||||
|
// Output: name: Big Mac
|
||||||
|
//numPatties: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMockGenerator_generateFriesMock_json() {
|
||||||
|
|
||||||
|
// create a new YAML mock generator
|
||||||
|
mg := NewMockGenerator(MockJSON)
|
||||||
|
|
||||||
|
burgerShop, _ := os.ReadFile("../test_specs/burgershop.openapi.yaml")
|
||||||
|
|
||||||
|
// create a new document from specification and build a v3 model.
|
||||||
|
document, _ := libopenapi.NewDocument(burgerShop)
|
||||||
|
v3Model, _ := document.BuildV3Model()
|
||||||
|
|
||||||
|
// create a mock of the Fries model
|
||||||
|
friesModel := v3Model.Model.Components.Schemas["Fries"]
|
||||||
|
fries := friesModel.Schema()
|
||||||
|
mock, err := mg.GenerateMock(fries, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(mock))
|
||||||
|
// Output: {"favoriteDrink":{"drinkType":"coke","size":"M"},"potatoShape":"Crispy Shoestring"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMockGenerator_generateRequestMock_json() {
|
||||||
|
|
||||||
|
// create a new YAML mock generator
|
||||||
|
mg := NewMockGenerator(MockJSON)
|
||||||
|
|
||||||
|
burgerShop, _ := os.ReadFile("../test_specs/burgershop.openapi.yaml")
|
||||||
|
|
||||||
|
// create a new document from specification and build a v3 model.
|
||||||
|
document, _ := libopenapi.NewDocument(burgerShop)
|
||||||
|
v3Model, _ := document.BuildV3Model()
|
||||||
|
|
||||||
|
// create a mock of the burger request model, extracted from the operation directly.
|
||||||
|
burgerRequestModel := v3Model.Model.Paths.PathItems["/burgers"].Post.RequestBody.Content["application/json"]
|
||||||
|
|
||||||
|
// use the 'cakeBurger' example to generate a mock
|
||||||
|
mock, err := mg.GenerateMock(burgerRequestModel, "cakeBurger")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(mock))
|
||||||
|
// Output: {"name":"Chocolate Cake Burger","numPatties":5}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMockGenerator_generateResponseMock_json() {
|
||||||
|
|
||||||
|
mg := NewMockGenerator(MockJSON)
|
||||||
|
// create a new YAML mock generator
|
||||||
|
|
||||||
|
burgerShop, _ := os.ReadFile("../test_specs/burgershop.openapi.yaml")
|
||||||
|
|
||||||
|
// create a new document from specification and build a v3 model.
|
||||||
|
document, _ := libopenapi.NewDocument(burgerShop)
|
||||||
|
v3Model, _ := document.BuildV3Model()
|
||||||
|
|
||||||
|
// create a mock of the burger response model, extracted from the operation directly.
|
||||||
|
burgerResponseModel := v3Model.Model.Paths.PathItems["/burgers"].Post.Responses.Codes["200"].Content["application/json"]
|
||||||
|
|
||||||
|
// use the 'filetOFish' example to generate a mock
|
||||||
|
mock, err := mg.GenerateMock(burgerResponseModel, "filetOFish")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(mock))
|
||||||
|
// Output: {"name":"Filet-O-Fish","numPatties":1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleMockGenerator_generatePolymorphicMock_json() {
|
||||||
|
|
||||||
|
mg := NewMockGenerator(MockJSON)
|
||||||
|
// create a new YAML mock generator
|
||||||
|
|
||||||
|
burgerShop, _ := os.ReadFile("../test_specs/burgershop.openapi.yaml")
|
||||||
|
|
||||||
|
// create a new document from specification and build a v3 model.
|
||||||
|
document, _ := libopenapi.NewDocument(burgerShop)
|
||||||
|
v3Model, _ := document.BuildV3Model()
|
||||||
|
|
||||||
|
// create a mock of the SomePayload component, which uses polymorphism (incorrectly)
|
||||||
|
payloadModel := v3Model.Model.Components.Schemas["SomePayload"]
|
||||||
|
payload := payloadModel.Schema()
|
||||||
|
mock, err := mg.GenerateMock(payload, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(mock))
|
||||||
|
// Output: {"drinkType":"coke","size":"M"}
|
||||||
|
}
|
||||||
@@ -503,10 +503,10 @@ components:
|
|||||||
ice:
|
ice:
|
||||||
type: boolean
|
type: boolean
|
||||||
drinkType:
|
drinkType:
|
||||||
|
type: string
|
||||||
description: select from coke or sprite
|
description: select from coke or sprite
|
||||||
enum:
|
enum:
|
||||||
- coke
|
- coke
|
||||||
- sprite
|
|
||||||
size:
|
size:
|
||||||
type: string
|
type: string
|
||||||
description: what size man? S/M/L
|
description: what size man? S/M/L
|
||||||
@@ -517,7 +517,7 @@ components:
|
|||||||
mapping:
|
mapping:
|
||||||
drink: some value
|
drink: some value
|
||||||
SomePayload:
|
SomePayload:
|
||||||
type: string
|
type: object
|
||||||
description: some kind of payload for something.
|
description: some kind of payload for something.
|
||||||
xml:
|
xml:
|
||||||
name: is html programming? yes.
|
name: is html programming? yes.
|
||||||
|
|||||||
@@ -33,6 +33,6 @@ func TestCreateSummary_OverallReport(t *testing.T) {
|
|||||||
assert.Equal(t, 2, report.ChangeReport[v3.ServersLabel].Total)
|
assert.Equal(t, 2, report.ChangeReport[v3.ServersLabel].Total)
|
||||||
assert.Equal(t, 1, report.ChangeReport[v3.ServersLabel].Breaking)
|
assert.Equal(t, 1, report.ChangeReport[v3.ServersLabel].Breaking)
|
||||||
assert.Equal(t, 1, report.ChangeReport[v3.SecurityLabel].Total)
|
assert.Equal(t, 1, report.ChangeReport[v3.SecurityLabel].Total)
|
||||||
assert.Equal(t, 17, report.ChangeReport[v3.ComponentsLabel].Total)
|
assert.Equal(t, 20, report.ChangeReport[v3.ComponentsLabel].Total)
|
||||||
assert.Equal(t, 6, report.ChangeReport[v3.ComponentsLabel].Breaking)
|
assert.Equal(t, 8, report.ChangeReport[v3.ComponentsLabel].Breaking)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ func TestCompareOpenAPIDocuments(t *testing.T) {
|
|||||||
modDoc, _ := v3.CreateDocument(infoMod)
|
modDoc, _ := v3.CreateDocument(infoMod)
|
||||||
|
|
||||||
changes := CompareOpenAPIDocuments(origDoc, modDoc)
|
changes := CompareOpenAPIDocuments(origDoc, modDoc)
|
||||||
assert.Equal(t, 72, changes.TotalChanges())
|
assert.Equal(t, 75, changes.TotalChanges())
|
||||||
assert.Equal(t, 17, changes.TotalBreakingChanges())
|
assert.Equal(t, 19, changes.TotalBreakingChanges())
|
||||||
//out, _ := json.MarshalIndent(changes, "", " ")
|
//out, _ := json.MarshalIndent(changes, "", " ")
|
||||||
//_ = ioutil.WriteFile("outputv3.json", out, 0776)
|
//_ = ioutil.WriteFile("outputv3.json", out, 0776)
|
||||||
}
|
}
|
||||||
@@ -149,5 +149,5 @@ func ExampleCompareOpenAPIDocuments() {
|
|||||||
// Print out some interesting stats.
|
// Print out some interesting stats.
|
||||||
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
||||||
changes.TotalChanges(), changes.TotalBreakingChanges(), len(schemaChanges))
|
changes.TotalChanges(), changes.TotalBreakingChanges(), len(schemaChanges))
|
||||||
//Output: There are 72 changes, of which 17 are breaking. 5 schemas have changes.
|
//Output: There are 75 changes, of which 19 are breaking. 6 schemas have changes.
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user