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"]
|
||||
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"]
|
||||
assert.Len(t, d.Schema().Required, 2)
|
||||
|
||||
@@ -321,7 +321,7 @@ func ExampleCompareDocuments_openAPI() {
|
||||
// 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.",
|
||||
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++ {
|
||||
fieldName := v.Type().Field(i).Name
|
||||
switch fieldName {
|
||||
case Schema:
|
||||
fieldCount++
|
||||
case Example:
|
||||
fieldCount++
|
||||
case Examples:
|
||||
@@ -54,12 +52,12 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
|
||||
}
|
||||
mockReady := false
|
||||
// check if all fields are present, if so, we can generate a mock
|
||||
if fieldCount == 3 {
|
||||
if fieldCount == 2 {
|
||||
mockReady = true
|
||||
}
|
||||
if !mockReady {
|
||||
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.
|
||||
@@ -70,29 +68,49 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
|
||||
}
|
||||
|
||||
// if there is no example, but there are multi-examples.
|
||||
examplesValue := v.FieldByName(Examples).Interface()
|
||||
if examplesValue != nil {
|
||||
examples := v.FieldByName(Examples)
|
||||
examplesValue := examples.Interface()
|
||||
if examplesValue != nil && !examples.IsNil() {
|
||||
|
||||
// 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
|
||||
for k, exp := range examples {
|
||||
for k, exp := range examplesMap {
|
||||
if k == name {
|
||||
return mg.renderMock(exp.Value), nil
|
||||
}
|
||||
}
|
||||
|
||||
// if the name is empty, just return the first example
|
||||
for _, exp := range examples {
|
||||
for _, exp := range examplesMap {
|
||||
return mg.renderMock(exp.Value), nil
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
renderMap := mg.renderer.RenderSchema(schemaValue.Schema())
|
||||
renderMap := mg.renderer.RenderSchema(schemaValue)
|
||||
if 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:
|
||||
type: boolean
|
||||
drinkType:
|
||||
type: string
|
||||
description: select from coke or sprite
|
||||
enum:
|
||||
- coke
|
||||
- sprite
|
||||
size:
|
||||
type: string
|
||||
description: what size man? S/M/L
|
||||
@@ -517,7 +517,7 @@ components:
|
||||
mapping:
|
||||
drink: some value
|
||||
SomePayload:
|
||||
type: string
|
||||
type: object
|
||||
description: some kind of payload for something.
|
||||
xml:
|
||||
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, 1, report.ChangeReport[v3.ServersLabel].Breaking)
|
||||
assert.Equal(t, 1, report.ChangeReport[v3.SecurityLabel].Total)
|
||||
assert.Equal(t, 17, report.ChangeReport[v3.ComponentsLabel].Total)
|
||||
assert.Equal(t, 6, report.ChangeReport[v3.ComponentsLabel].Breaking)
|
||||
assert.Equal(t, 20, report.ChangeReport[v3.ComponentsLabel].Total)
|
||||
assert.Equal(t, 8, report.ChangeReport[v3.ComponentsLabel].Breaking)
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ func TestCompareOpenAPIDocuments(t *testing.T) {
|
||||
modDoc, _ := v3.CreateDocument(infoMod)
|
||||
|
||||
changes := CompareOpenAPIDocuments(origDoc, modDoc)
|
||||
assert.Equal(t, 72, changes.TotalChanges())
|
||||
assert.Equal(t, 17, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 75, changes.TotalChanges())
|
||||
assert.Equal(t, 19, changes.TotalBreakingChanges())
|
||||
//out, _ := json.MarshalIndent(changes, "", " ")
|
||||
//_ = ioutil.WriteFile("outputv3.json", out, 0776)
|
||||
}
|
||||
@@ -149,5 +149,5 @@ func ExampleCompareOpenAPIDocuments() {
|
||||
// Print out some interesting stats.
|
||||
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
||||
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