Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 26 additions & 25 deletions renderer/mock_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ package renderer
import (
"encoding/json"
"fmt"
"reflect"
"strconv"

highbase "github.com/pb33f/libopenapi/datamodel/high/base"
"github.com/pb33f/libopenapi/orderedmap"
"go.yaml.in/yaml/v4"
"reflect"
"strconv"
)

const (
Expand Down Expand Up @@ -107,7 +106,25 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
"fields (%s, %s)", fieldCount, Example, Examples)
}

// if the value has an example, try and render it out as is.
var fallbackExample *highbase.Example = nil
// trying to find a named example
examples := v.FieldByName(Examples)
examplesValue := examples.Interface()
if examplesValue != nil && !examples.IsNil() {

// cast examples to *orderedmap.Map[string, *highbase.Example]
examplesMap := examplesValue.(*orderedmap.Map[string, *highbase.Example])
if examplesMap.Len() > 0 {
if example, ok := examplesMap.Get(name); ok {
return mg.renderMock(example.Value), nil
} else {
//take the first example from the list
fallbackExample = examplesMap.Oldest().Value
}
}
}

// looking for an inline example
f := v.FieldByName(Example)
if !f.IsNil() {
// Pointer/Interface Shenanigans
Expand All @@ -120,30 +137,14 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
}
}
if ex != nil {
// try and serialize the example value
// try and serialize the example value (very hacky since ex can be anything)
return mg.renderMock(ex), nil
}
}

// if there is no example, but there are multi-examples.
examples := v.FieldByName(Examples)
examplesValue := examples.Interface()
if examplesValue != nil && !examples.IsNil() {

// cast examples to *orderedmap.Map[string, *highbase.Example]
examplesMap := examplesValue.(*orderedmap.Map[string, *highbase.Example])

// if the name is not empty, try and find the example by name
for k, exp := range examplesMap.FromOldest() {
if k == name {
return mg.renderMock(exp.Value), nil
}
}

// if the name is empty, just return the first example
for exp := range examplesMap.ValuesFromOldest() {
return mg.renderMock(exp.Value), nil
}
// rendering fallback if it's not nil
if fallbackExample != nil {
return mg.renderMock(fallbackExample.Value), nil
}

// no examples? no problem, we can try and generate a mock from the schema.
Expand All @@ -167,7 +168,7 @@ func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {

if schemaValue != nil {

// now lets check the schema for `Examples` and `Example` fields.
// now let's check the schema for `Examples` and `Example` fields.
if schemaValue.Examples != nil {
if name != "" {
// try and convert the example to an integer
Expand Down
74 changes: 74 additions & 0 deletions renderer/mock_generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,3 +523,77 @@ properties:
// It should be different from the first two
assert.NotEqual(t, string(mock1), string(mock3))
}

func TestMockGenerator_GenerateMock_PickNamedExample(t *testing.T) {
mg := NewMockGenerator(YAML)

type mockable struct {
Example *base.Example
Examples *orderedmap.Map[string, *base.Example]
}

inlineExample := &base.Example{
Value: utils.CreateStringNode("inline example"),
}
examples := orderedmap.New[string, *base.Example]()
examples.Set("exampleOne", &base.Example{
Value: utils.CreateStringNode("example 1"),
})

mock, err := mg.GenerateMock(&mockable{
Example: inlineExample,
Examples: examples,
}, "exampleOne")
assert.NoError(t, err)
assert.Equal(t, "example 1", strings.TrimSpace(string(mock)))
}

func TestMockGenerator_GenerateMock_PickOldestExample(t *testing.T) {
mg := NewMockGenerator(YAML)

type mockable struct {
Example any
Examples *orderedmap.Map[string, *base.Example]
}

examples := orderedmap.New[string, *base.Example]()
examples.Set("exampleOne", &base.Example{
Value: utils.CreateStringNode("example 1"),
})
examples.Set("exampleTwo", &base.Example{
Value: utils.CreateStringNode("example 2"),
})

mock, err := mg.GenerateMock(&mockable{
Examples: examples,
}, "nonexisting example")
assert.NoError(t, err)
assert.Equal(t, "example 1", strings.TrimSpace(string(mock)))
}

func TestMockGenerator_GenerateMock_GetInline(t *testing.T) {
mg := NewMockGenerator(YAML)

type mockable struct {
Example any
Examples *orderedmap.Map[string, *base.Example]
}
inlineExample := &yaml.Node{
Kind: yaml.ScalarNode,
Value: "inline example",
}
examples := orderedmap.New[string, *base.Example]()
examples.Set("exampleOne", &base.Example{
Value: utils.CreateStringNode("example 1"),
})
examples.Set("exampleTwo", &base.Example{
Value: utils.CreateStringNode("example 2"),
})

mock, err := mg.GenerateMock(&mockable{
Example: inlineExample,
Examples: examples,
}, "nonexisting example")
assert.NoError(t, err)
assert.Equal(t, "inline example", strings.TrimSpace(string(mock)))
}