Files
libopenapi/datamodel/low/extraction_functions_test.go
quobix 8717b3cd33 An enormous amount of surgery on the low level model.
Every `Build()` method now requires a `context.Context`. This is so the rolodex knows where to resolve from when locating relative links. Without knowing where we are, there is no way to resolve anything. This new mechanism allows the model to recurse across as many files as required to locate references, without loosing track of where we are in the process.

Signed-off-by: quobix <dave@quobix.com>
2023-10-23 15:04:34 -04:00

1680 lines
40 KiB
Go

// Copyright 2022-2023 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package low
import (
"crypto/sha256"
"fmt"
"strings"
"testing"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)
func TestFindItemInMap(t *testing.T) {
v := make(map[KeyReference[string]]ValueReference[string])
v[KeyReference[string]{
Value: "pizza",
}] = ValueReference[string]{
Value: "pie",
}
assert.Equal(t, "pie", FindItemInMap("pizza", v).Value)
}
func TestFindItemInMap_WrongCase(t *testing.T) {
v := make(map[KeyReference[string]]ValueReference[string])
v[KeyReference[string]{
Value: "pizza",
}] = ValueReference[string]{
Value: "pie",
}
assert.Equal(t, "pie", FindItemInMap("PIZZA", v).Value)
}
func TestFindItemInMap_Error(t *testing.T) {
v := make(map[KeyReference[string]]ValueReference[string])
v[KeyReference[string]{
Value: "pizza",
}] = ValueReference[string]{
Value: "pie",
}
assert.Nil(t, FindItemInMap("nuggets", v))
}
func TestLocateRefNode(t *testing.T) {
yml := `components:
schemas:
cake:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `$ref: '#/components/schemas/cake'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
located, _ := LocateRefNode(cNode.Content[0], idx)
assert.NotNil(t, located)
}
func TestLocateRefNode_BadNode(t *testing.T) {
yml := `components:
schemas:
cake:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `yes: mate` // useless.
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
located, err := LocateRefNode(cNode.Content[0], idx)
// should both be empty.
assert.Nil(t, located)
assert.Nil(t, err)
}
func TestLocateRefNode_Path(t *testing.T) {
yml := `paths:
/burger/time:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `$ref: '#/paths/~1burger~1time'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
located, _ := LocateRefNode(cNode.Content[0], idx)
assert.NotNil(t, located)
}
func TestLocateRefNode_Path_NotFound(t *testing.T) {
yml := `paths:
/burger/time:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `$ref: '#/paths/~1burger~1time-somethingsomethingdarkside-somethingsomethingcomplete'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
located, err := LocateRefNode(cNode.Content[0], idx)
assert.Nil(t, located)
assert.Error(t, err)
}
type pizza struct {
Description NodeReference[string]
}
func (p *pizza) Build(_, _ *yaml.Node, _ *index.SpecIndex) error {
return nil
}
func TestExtractObject(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `tags:
description: hello pizza`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err := ExtractObject[*pizza]("tags", &cNode, idx)
assert.NoError(t, err)
assert.NotNil(t, tag)
assert.Equal(t, "hello pizza", tag.Value.Description.Value)
}
func TestExtractObject_Ref(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hello pizza`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `tags:
$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err := ExtractObject[*pizza]("tags", &cNode, idx)
assert.NoError(t, err)
assert.NotNil(t, tag)
assert.Equal(t, "hello pizza", tag.Value.Description.Value)
}
func TestExtractObject_DoubleRef(t *testing.T) {
yml := `components:
schemas:
cake:
description: cake time!
pizza:
$ref: '#/components/schemas/cake'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `tags:
$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err := ExtractObject[*pizza]("tags", &cNode, idx)
assert.NoError(t, err)
assert.NotNil(t, tag)
assert.Equal(t, "cake time!", tag.Value.Description.Value)
}
func TestExtractObject_DoubleRef_Circular(t *testing.T) {
yml := `components:
schemas:
loopy:
$ref: '#/components/schemas/cake'
cake:
$ref: '#/components/schemas/loopy'
pizza:
$ref: '#/components/schemas/cake'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
// circular references are detected by the resolver, so lets run it!
resolv := index.NewResolver(idx)
assert.Len(t, resolv.CheckForCircularReferences(), 1)
yml = `tags:
$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err := ExtractObject[*pizza]("tags", &cNode, idx)
assert.Error(t, err)
assert.Equal(t, "cake -> loopy -> cake", idx.GetCircularReferences()[0].GenerateJourneyPath())
}
func TestExtractObject_DoubleRef_Circular_Fail(t *testing.T) {
yml := `components:
schemas:
loopy:
$ref: '#/components/schemas/cake'
cake:
$ref: '#/components/schemas/loopy'
pizza:
$ref: '#/components/schemas/cake'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
// circular references are detected by the resolver, so lets run it!
resolv := index.NewResolver(idx)
assert.Len(t, resolv.CheckForCircularReferences(), 1)
yml = `tags:
$ref: #BORK`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err := ExtractObject[*pizza]("tags", &cNode, idx)
assert.Error(t, err)
}
func TestExtractObject_DoubleRef_Circular_Direct(t *testing.T) {
yml := `components:
schemas:
loopy:
$ref: '#/components/schemas/cake'
cake:
$ref: '#/components/schemas/loopy'
pizza:
$ref: '#/components/schemas/cake'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
// circular references are detected by the resolver, so lets run it!
resolv := index.NewResolver(idx)
assert.Len(t, resolv.CheckForCircularReferences(), 1)
yml = `$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err := ExtractObject[*pizza]("tags", cNode.Content[0], idx)
assert.Error(t, err)
assert.Equal(t, "cake -> loopy -> cake", idx.GetCircularReferences()[0].GenerateJourneyPath())
}
func TestExtractObject_DoubleRef_Circular_Direct_Fail(t *testing.T) {
yml := `components:
schemas:
loopy:
$ref: '#/components/schemas/cake'
cake:
$ref: '#/components/schemas/loopy'
pizza:
$ref: '#/components/schemas/cake'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
// circular references are detected by the resolver, so lets run it!
resolv := index.NewResolver(idx)
assert.Len(t, resolv.CheckForCircularReferences(), 1)
yml = `$ref: '#/components/schemas/why-did-westworld-have-to-end-so-poorly-ffs'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err := ExtractObject[*pizza]("tags", cNode.Content[0], idx)
assert.Error(t, err)
}
type test_borked struct {
DontWork int
}
func (t test_borked) Build(_, root *yaml.Node, idx *index.SpecIndex) error {
return fmt.Errorf("I am always going to fail, every thing")
}
type test_noGood struct {
DontWork int
}
func (t *test_noGood) Build(_, root *yaml.Node, idx *index.SpecIndex) error {
return fmt.Errorf("I am always going to fail a core build")
}
type test_almostGood struct {
AlmostWork NodeReference[int]
}
func (t *test_almostGood) Build(_, root *yaml.Node, idx *index.SpecIndex) error {
return fmt.Errorf("I am always going to fail a build out")
}
type test_Good struct {
AlmostWork NodeReference[int]
}
func (t *test_Good) Build(_, root *yaml.Node, idx *index.SpecIndex) error {
return nil
}
func TestExtractObject_BadLowLevelModel(t *testing.T) {
yml := `components:
schemas:
hey:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `thing:
dontWork: 123`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err := ExtractObject[*test_noGood]("thing", &cNode, idx)
assert.Error(t, err)
}
func TestExtractObject_BadBuild(t *testing.T) {
yml := `components:
schemas:
hey:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `thing:
dontWork: 123`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err := ExtractObject[*test_almostGood]("thing", &cNode, idx)
assert.Error(t, err)
}
func TestExtractObject_BadLabel(t *testing.T) {
yml := `components:
schemas:
hey:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `thing:
dontWork: 123`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
res, err := ExtractObject[*test_almostGood]("ding", &cNode, idx)
assert.Nil(t, res.Value)
assert.NoError(t, err)
}
func TestExtractObject_PathIsCircular(t *testing.T) {
// first we need an index.
yml := `paths:
'/something/here':
post:
$ref: '#/paths/~1something~1there/post'
'/something/there':
post:
$ref: '#/paths/~1something~1here/post'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `thing:
$ref: '#/paths/~1something~1here/post'`
var rootNode yaml.Node
mErr = yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
res, err := ExtractObject[*test_Good]("thing", &rootNode, idx)
assert.NotNil(t, res.Value)
assert.Error(t, err) // circular error would have been thrown.
}
func TestExtractObject_PathIsCircular_IgnoreErrors(t *testing.T) {
// first we need an index.
yml := `paths:
'/something/here':
post:
$ref: '#/paths/~1something~1there/post'
'/something/there':
post:
$ref: '#/paths/~1something~1here/post'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
// disable circular ref checking.
idx.SetAllowCircularReferenceResolving(true)
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `thing:
$ref: '#/paths/~1something~1here/post'`
var rootNode yaml.Node
mErr = yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
res, err := ExtractObject[*test_Good]("thing", &rootNode, idx)
assert.NotNil(t, res.Value)
assert.NoError(t, err) // circular error would have been thrown, but we're ignoring them.
}
func TestExtractObjectRaw(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `description: hello pizza`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err, _, _ := ExtractObjectRaw[*pizza](nil, cNode.Content[0], idx)
assert.NoError(t, err)
assert.NotNil(t, tag)
assert.Equal(t, "hello pizza", tag.Description.Value)
}
func TestExtractObjectRaw_With_Ref(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err, isRef, rv := ExtractObjectRaw[*pizza](nil, cNode.Content[0], idx)
assert.NoError(t, err)
assert.NotNil(t, tag)
assert.Equal(t, "hello", tag.Description.Value)
assert.True(t, isRef)
assert.Equal(t, "#/components/schemas/pizza", rv)
}
func TestExtractObjectRaw_Ref_Circular(t *testing.T) {
yml := `components:
schemas:
pizza:
$ref: '#/components/schemas/pie'
pie:
$ref: '#/components/schemas/pizza'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err, _, _ := ExtractObjectRaw[*pizza](nil, cNode.Content[0], idx)
assert.Error(t, err)
assert.NotNil(t, tag)
}
func TestExtractObjectRaw_RefBroken(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hey!`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `$ref: '#/components/schemas/lost-in-space'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err, _, _ := ExtractObjectRaw[*pizza](nil, cNode.Content[0], idx)
assert.Error(t, err)
assert.Nil(t, tag)
}
func TestExtractObjectRaw_Ref_NonBuildable(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hey!`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `dontWork: 1'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err, _, _ := ExtractObjectRaw[*test_noGood](nil, cNode.Content[0], idx)
assert.Error(t, err)
}
func TestExtractObjectRaw_Ref_AlmostBuildable(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hey!`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `almostWork: 1'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
_, err, _, _ := ExtractObjectRaw[*test_almostGood](nil, cNode.Content[0], idx)
assert.Error(t, err)
}
func TestExtractArray(t *testing.T) {
yml := `components:
schemas:
pizza:
description: hello`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `things:
- description: one
- description: two
- description: three`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*pizza]("things", cNode.Content[0], idx)
assert.NoError(t, err)
assert.NotNil(t, things)
assert.Equal(t, "one", things[0].Value.Description.Value)
assert.Equal(t, "two", things[1].Value.Description.Value)
assert.Equal(t, "three", things[2].Value.Description.Value)
}
func TestExtractArray_Ref(t *testing.T) {
yml := `components:
schemas:
things:
- description: one
- description: two
- description: three`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `$ref: '#/components/schemas/things'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*pizza]("things", cNode.Content[0], idx)
assert.NoError(t, err)
assert.NotNil(t, things)
assert.Equal(t, "one", things[0].Value.Description.Value)
assert.Equal(t, "two", things[1].Value.Description.Value)
assert.Equal(t, "three", things[2].Value.Description.Value)
}
func TestExtractArray_Ref_Unbuildable(t *testing.T) {
yml := `components:
schemas:
things:
- description: one
- description: two
- description: three`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `$ref: '#/components/schemas/things'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*test_noGood]("", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractArray_Ref_Circular(t *testing.T) {
yml := `components:
schemas:
thongs:
$ref: '#/components/schemas/things'
things:
$ref: '#/components/schemas/thongs'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `$ref: '#/components/schemas/things'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*test_Good]("", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractArray_Ref_Bad(t *testing.T) {
yml := `components:
schemas:
thongs:
$ref: '#/components/schemas/things'
things:
$ref: '#/components/schemas/thongs'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `$ref: '#/components/schemas/let-us-eat-cake'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*test_Good]("", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractArray_Ref_Nested(t *testing.T) {
yml := `components:
schemas:
thongs:
$ref: '#/components/schemas/things'
things:
$ref: '#/components/schemas/thongs'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `limes:
$ref: '#/components/schemas/let-us-eat-cake'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*test_Good]("limes", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractArray_Ref_Nested_Circular(t *testing.T) {
yml := `components:
schemas:
thongs:
$ref: '#/components/schemas/things'
things:
$ref: '#/components/schemas/thongs'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `limes:
- $ref: '#/components/schemas/things'`
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*test_Good]("limes", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 1)
}
func TestExtractArray_Ref_Nested_BadRef(t *testing.T) {
yml := `components:
schemas:
thongs:
allOf:
- $ref: '#/components/schemas/things'
things:
oneOf:
- type: string`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `limes:
- $ref: '#/components/schemas/thangs'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractArray[*test_Good]("limes", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractArray_Ref_Nested_CircularFlat(t *testing.T) {
yml := `components:
schemas:
thongs:
$ref: '#/components/schemas/things'
things:
$ref: '#/components/schemas/thongs'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `limes:
$ref: '#/components/schemas/things'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractArray[*test_Good]("limes", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractArray_BadBuild(t *testing.T) {
yml := `components:
schemas:
thongs:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `limes:
- dontWork: 1`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractArray[*test_noGood]("limes", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractExample_String(t *testing.T) {
yml := `hi`
var e yaml.Node
_ = yaml.Unmarshal([]byte(yml), &e)
exp := ExtractExample(e.Content[0], e.Content[0])
assert.NotNil(t, exp.Value)
assert.Equal(t, "hi", exp.Value)
}
func TestExtractExample_Map(t *testing.T) {
yml := `one: two`
var e yaml.Node
_ = yaml.Unmarshal([]byte(yml), &e)
exp := ExtractExample(e.Content[0], e.Content[0])
assert.NotNil(t, exp.Value)
if n, ok := exp.Value.(map[string]interface{}); ok {
assert.Equal(t, "two", n["one"])
} else {
panic("example unpacked incorrectly.")
}
}
func TestExtractExample_Array(t *testing.T) {
yml := `- hello`
var e yaml.Node
_ = yaml.Unmarshal([]byte(yml), &e)
exp := ExtractExample(e.Content[0], e.Content[0])
assert.NotNil(t, exp.Value)
if n, ok := exp.Value.([]interface{}); ok {
assert.Equal(t, "hello", n[0])
} else {
panic("example unpacked incorrectly.")
}
}
func TestExtractMapFlatNoLookup(t *testing.T) {
yml := `components:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
description: two`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookup[*test_Good](cNode.Content[0], idx)
assert.NoError(t, err)
assert.Len(t, things, 1)
}
func TestExtractMap_NoLookupWithExtensions(t *testing.T) {
yml := `components:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
x-choo: choo`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookupExtensions[*test_Good](cNode.Content[0], idx, true)
assert.NoError(t, err)
assert.Len(t, things, 2)
for k, v := range things {
if k.Value == "x-hey" {
continue
}
assert.Equal(t, "one", k.Value)
assert.Len(t, v.ValueNode.Content, 2)
}
}
func TestExtractMap_NoLookupWithExtensions_UsingMerge(t *testing.T) {
yml := `components:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-yeah: &yeah
night: fun
x-hey: you
one:
x-choo: choo
<<: *yeah`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookupExtensions[*test_Good](cNode.Content[0], idx, true)
assert.NoError(t, err)
assert.Len(t, things, 4)
}
func TestExtractMap_NoLookupWithoutExtensions(t *testing.T) {
yml := `components:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
x-choo: choo`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookupExtensions[*test_Good](cNode.Content[0], idx, false)
assert.NoError(t, err)
assert.Len(t, things, 1)
for k := range things {
assert.Equal(t, "one", k.Value)
}
}
func TestExtractMap_WithExtensions(t *testing.T) {
yml := `components:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
x-choo: choo`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMapExtensions[*test_Good]("one", cNode.Content[0], idx, true)
assert.NoError(t, err)
assert.Len(t, things, 1)
}
func TestExtractMap_WithoutExtensions(t *testing.T) {
yml := `components:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
x-choo: choo`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMapExtensions[*test_Good]("one", cNode.Content[0], idx, false)
assert.NoError(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlatNoLookup_Ref(t *testing.T) {
yml := `components:
schemas:
pizza:
description: tasty!`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookup[*test_Good](cNode.Content[0], idx)
assert.NoError(t, err)
assert.Len(t, things, 1)
}
func TestExtractMapFlatNoLookup_Ref_Bad(t *testing.T) {
yml := `components:
schemas:
pizza:
description: tasty!`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
$ref: '#/components/schemas/no-where-out-there'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookup[*test_Good](cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlatNoLookup_Ref_Circular(t *testing.T) {
yml := `components:
schemas:
thongs:
$ref: '#/components/schemas/things'
things:
$ref: '#/components/schemas/thongs'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `x-hey: you
one:
$ref: '#/components/schemas/things'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookup[*test_Good](cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 1)
}
func TestExtractMapFlatNoLookup_Ref_BadBuild(t *testing.T) {
yml := `components:
schemas:
pizza:
dontWork: 1`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
hello:
$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookup[*test_noGood](cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlatNoLookup_Ref_AlmostBuild(t *testing.T) {
yml := `components:
schemas:
pizza:
description: tasty!`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
$ref: '#/components/schemas/pizza'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, err := ExtractMapNoLookup[*test_almostGood](cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlat(t *testing.T) {
yml := `components:`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
description: two`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.NoError(t, err)
assert.Len(t, things, 1)
}
func TestExtractMapFlat_Ref(t *testing.T) {
yml := `components:
schemas:
stank:
things:
almostWork: 99`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `x-hey: you
one:
$ref: '#/components/schemas/stank'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.NoError(t, err)
assert.Len(t, things, 1)
for k := range things {
assert.Equal(t, 99, things[k].Value.AlmostWork.Value)
}
}
func TestExtractMapFlat_DoubleRef(t *testing.T) {
yml := `components:
schemas:
stank:
almostWork: 99`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `one:
nice:
$ref: '#/components/schemas/stank'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.NoError(t, err)
assert.Len(t, things, 1)
for k := range things {
assert.Equal(t, 99, things[k].Value.AlmostWork.Value)
}
}
func TestExtractMapFlat_DoubleRef_Error(t *testing.T) {
yml := `components:
schemas:
stank:
things:
almostWork: 99`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `one:
nice:
$ref: '#/components/schemas/stank'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_almostGood]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlat_DoubleRef_Error_NotFound(t *testing.T) {
yml := `components:
schemas:
stank:
things:
almostWork: 99`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `one:
nice:
$ref: '#/components/schemas/stanky-panky'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_almostGood]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlat_DoubleRef_Circles(t *testing.T) {
yml := `components:
schemas:
stonk:
$ref: '#/components/schemas/stank'
stank:
$ref: '#/components/schemas/stonk'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `one:
nice:
$ref: '#/components/schemas/stank'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 1)
}
func TestExtractMapFlat_Ref_Error(t *testing.T) {
yml := `components:
schemas:
stank:
x-smells: bad
things:
almostWork: 99`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `one:
$ref: '#/components/schemas/stank'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_almostGood]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlat_Ref_Circ_Error(t *testing.T) {
yml := `components:
schemas:
stink:
$ref: '#/components/schemas/stank'
stank:
$ref: '#/components/schemas/stink'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `$ref: '#/components/schemas/stank'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 1)
}
func TestExtractMapFlat_Ref_Nested_Circ_Error(t *testing.T) {
yml := `components:
schemas:
stink:
$ref: '#/components/schemas/stank'
stank:
$ref: '#/components/schemas/stink'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `one:
$ref: '#/components/schemas/stank'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 1)
}
func TestExtractMapFlat_Ref_Nested_Error(t *testing.T) {
yml := `components:
schemas:
stink:
$ref: '#/components/schemas/stank'
stank:
$ref: '#/components/schemas/none'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `one:
$ref: '#/components/schemas/somewhere-else'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlat_BadKey_Ref_Nested_Error(t *testing.T) {
yml := `components:
schemas:
stink:
$ref: '#/components/schemas/stank'
stank:
$ref: '#/components/schemas/none'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
yml = `one:
$ref: '#/components/schemas/somewhere-else'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("not-even-there", cNode.Content[0], idx)
assert.NoError(t, err)
assert.Len(t, things, 0)
}
func TestExtractMapFlat_Ref_Bad(t *testing.T) {
yml := `components:
schemas:
stink:
$ref: '#/components/schemas/stank'
stank:
$ref: '#/components/schemas/none'`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig())
resolve := index.NewResolver(idx)
errs := resolve.CheckForCircularReferences()
assert.Len(t, errs, 1)
yml = `$ref: '#/components/schemas/somewhere-else'`
var cNode yaml.Node
e := yaml.Unmarshal([]byte(yml), &cNode)
assert.NoError(t, e)
things, _, _, err := ExtractMap[*test_Good]("one", cNode.Content[0], idx)
assert.Error(t, err)
assert.Len(t, things, 0)
}
func TestExtractExtensions(t *testing.T) {
yml := `x-bing: ding
x-bong: 1
x-ling: true
x-long: 0.99
x-fish:
woo: yeah
x-tacos: [1,2,3]`
var idxNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &idxNode)
r := ExtractExtensions(idxNode.Content[0])
assert.Len(t, r, 6)
for i := range r {
switch i.Value {
case "x-bing":
assert.Equal(t, "ding", r[i].Value)
case "x-bong":
assert.Equal(t, int64(1), r[i].Value)
case "x-ling":
assert.Equal(t, true, r[i].Value)
case "x-long":
assert.Equal(t, 0.99, r[i].Value)
case "x-fish":
if a, ok := r[i].Value.(map[string]interface{}); ok {
assert.Equal(t, "yeah", a["woo"])
} else {
panic("should not fail casting")
}
case "x-tacos":
assert.Len(t, r[i].Value, 3)
}
}
}
type test_fresh struct {
val string
thang *bool
}
func (f test_fresh) Hash() [32]byte {
var data []string
if f.val != "" {
data = append(data, f.val)
}
if f.thang != nil {
data = append(data, fmt.Sprintf("%v", *f.thang))
}
return sha256.Sum256([]byte(strings.Join(data, "|")))
}
func TestAreEqual(t *testing.T) {
assert.True(t, AreEqual(test_fresh{val: "hello"}, test_fresh{val: "hello"}))
assert.False(t, AreEqual(test_fresh{val: "hello"}, test_fresh{val: "goodbye"}))
assert.False(t, AreEqual(nil, nil))
}
func TestGenerateHashString(t *testing.T) {
assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
GenerateHashString(test_fresh{val: "hello"}))
assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
GenerateHashString("hello"))
assert.Equal(t, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
GenerateHashString(""))
assert.Equal(t, "",
GenerateHashString(nil))
}
func TestGenerateHashString_Pointer(t *testing.T) {
val := true
assert.Equal(t, "b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b",
GenerateHashString(test_fresh{thang: &val}))
assert.Equal(t, "b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b",
GenerateHashString(&val))
}
func TestSetReference(t *testing.T) {
type testObj struct {
*Reference
}
n := testObj{Reference: &Reference{}}
SetReference(&n, "#/pigeon/street")
assert.Equal(t, "#/pigeon/street", n.GetReference())
}
func TestSetReference_nil(t *testing.T) {
type testObj struct {
*Reference
}
n := testObj{Reference: &Reference{}}
SetReference(nil, "#/pigeon/street")
assert.NotEqual(t, "#/pigeon/street", n.GetReference())
}