fix: cleanup tests

This commit is contained in:
Tristan Cartledge
2023-12-03 20:41:54 +00:00
parent d669ada7b6
commit 6904f4d459
7 changed files with 189 additions and 165 deletions

View File

@@ -323,10 +323,10 @@ func NewSchema(schema *base.Schema) *Schema {
// for every item, build schema async
buildSchema := func(sch lowmodel.ValueReference[*base.SchemaProxy], idx int, bChan chan buildResult) {
n := &lowmodel.NodeReference[*base.SchemaProxy]{
ValueNode: sch.GetValueNode(),
ValueNode: sch.ValueNode,
Value: sch.Value,
}
n.SetReference(sch.GetReference(), sch.GetValueNode())
n.SetReference(sch.GetReference(), sch.GetReferenceNode())
p := NewSchemaProxy(n)

View File

@@ -122,7 +122,7 @@ func (sp *SchemaProxy) GetReference() string {
func (sp *SchemaProxy) GetReferenceNode() *yaml.Node {
if sp.refStr != "" {
return nil
return utils.CreateStringNode(sp.refStr)
}
return sp.schema.GetValue().GetReferenceNode()
}

View File

@@ -779,157 +779,6 @@ func ExtractMapExtensions[PT Buildable[N], N any](
return nil, labelNode, valueNode, nil
}
// ExtractMapExtensions will extract a map of KeyReference and ValueReference from a root yaml.Node. The 'label' is
// used to locate the node to be extracted from the root node supplied. Supply a bit to decide if extensions should
// be included or not. required in some use cases.
//
// The second return value is the yaml.Node found for the 'label' and the third return value is the yaml.Node
// found for the value extracted from the label node.
func ExtractMapExtensionsOld[PT Buildable[N], N any](
ctx context.Context,
label string,
root *yaml.Node,
idx *index.SpecIndex,
extensions bool,
) (*orderedmap.Map[KeyReference[string], ValueReference[PT]], *yaml.Node, *yaml.Node, error) {
var referenceValue string
var labelNode, valueNode *yaml.Node
var circError error
root = utils.NodeAlias(root)
if rf, rl, rv := utils.IsNodeRefValue(root); rf {
// locate reference in index.
ref, fIdx, err, fCtx := LocateRefNodeWithContext(ctx, root, idx)
if ref != nil {
valueNode = ref
labelNode = rl
referenceValue = rv
ctx = fCtx
idx = fIdx
if err != nil {
circError = err
}
} else {
return nil, labelNode, valueNode, fmt.Errorf("map build failed: reference cannot be found: %s",
root.Content[1].Value)
}
} else {
_, labelNode, valueNode = utils.FindKeyNodeFull(label, root.Content)
valueNode = utils.NodeAlias(valueNode)
if valueNode != nil {
if h, _, rvt := utils.IsNodeRefValue(valueNode); h {
ref, fIdx, err, nCtx := LocateRefNodeWithContext(ctx, valueNode, idx)
if ref != nil {
valueNode = ref
referenceValue = rvt
idx = fIdx
ctx = nCtx
if err != nil {
circError = err
}
} else {
if err != nil {
return nil, labelNode, valueNode, fmt.Errorf("map build failed: reference cannot be found: %s",
err.Error())
}
}
}
}
}
if valueNode != nil {
var currentLabelNode *yaml.Node
valueMap := orderedmap.New[KeyReference[string], ValueReference[PT]]()
// TODO: Convert to datamodel.TranslatePipeline.
bChan := make(chan mappingResult[PT])
eChan := make(chan error)
buildMap := func(nctx context.Context, label *yaml.Node, value *yaml.Node, c chan mappingResult[PT], ec chan<- error, ref string, fIdx *index.SpecIndex) {
var n PT = new(N)
value = utils.NodeAlias(value)
_ = BuildModel(value, n)
err := n.Build(nctx, label, value, fIdx)
if err != nil {
ec <- err
return
}
if ref != "" {
SetReference(n, ref, nil)
}
c <- mappingResult[PT]{
k: KeyReference[string]{
KeyNode: label,
Value: label.Value,
},
v: ValueReference[PT]{
Value: n,
ValueNode: value,
// Reference: ref,
},
}
}
totalKeys := 0
for i, en := range valueNode.Content {
en = utils.NodeAlias(en)
referenceValue = ""
if i%2 == 0 {
currentLabelNode = en
continue
}
foundIndex := idx
foundContext := ctx
// check our valueNode isn't a reference still.
if h, _, refVal := utils.IsNodeRefValue(en); h {
ref, fIdx, err, nCtx := LocateRefNodeWithContext(ctx, en, idx)
if ref != nil {
en = ref
referenceValue = refVal
if fIdx != nil {
foundIndex = fIdx
}
foundContext = nCtx
if err != nil {
circError = err
}
} else {
if err != nil {
return nil, labelNode, valueNode, fmt.Errorf("flat map build failed: reference cannot be found: %s",
err.Error())
}
}
}
if !extensions {
if strings.HasPrefix(currentLabelNode.Value, "x-") {
continue // yo, don't pay any attention to extensions, not here anyway.
}
}
totalKeys++
go buildMap(foundContext, currentLabelNode, en, bChan, eChan, referenceValue, foundIndex)
}
completedKeys := 0
for completedKeys < totalKeys {
select {
case err := <-eChan:
return valueMap, labelNode, valueNode, err
case res := <-bChan:
completedKeys++
valueMap.Set(res.k, res.v)
}
}
if circError != nil && !idx.AllowCircularReferenceResolving() {
return valueMap, labelNode, valueNode, circError
}
return valueMap, labelNode, valueNode, nil
}
return nil, labelNode, valueNode, nil
}
// ExtractMap will extract a map of KeyReference and ValueReference from a root yaml.Node. The 'label' is
// used to locate the node to be extracted from the root node supplied.
//

View File

@@ -18,6 +18,7 @@ import (
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/orderedmap"
"github.com/pb33f/libopenapi/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -2063,3 +2064,45 @@ func TestArray_NotRefNotArray(t *testing.T) {
assert.Equal(t, err.Error(), "array build failed, input is not an array, line 2, column 3")
assert.Len(t, things, 0)
}
func TestHashExtensions(t *testing.T) {
type args struct {
ext *orderedmap.Map[KeyReference[string], ValueReference[*yaml.Node]]
}
tests := []struct {
name string
args args
want []string
}{
{
name: "empty",
args: args{
ext: orderedmap.New[KeyReference[string], ValueReference[*yaml.Node]](),
},
want: []string{},
},
{
name: "hashes extensions",
args: args{
ext: orderedmap.ToOrderedMap(map[KeyReference[string]]ValueReference[*yaml.Node]{
{Value: "x-burger"}: {
Value: utils.CreateStringNode("yummy"),
},
{Value: "x-car"}: {
Value: utils.CreateStringNode("ford"),
},
}),
},
want: []string{
"x-burger-2a296977a4572521773eb7e7773cc054fae3e8589511ce9bf90cec7dd93d016a",
"x-car-7d3aa6a5c79cdb0c2585daed714fa0936a18e6767b2dcc804992a90f6d0b8f5e",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
hash := HashExtensions(tt.args.ext)
assert.Equal(t, tt.want, hash)
})
}
}

View File

@@ -55,16 +55,8 @@ func (o *Map[K, V]) ToYamlNode(n NodeBuilder, l any) *yaml.Node {
for pair := First(o); pair != nil; pair = pair.Next() {
var k any = pair.Key()
if m, ok := k.(marshaler); ok { // TODO marshal inline?
k, _ = m.MarshalYAML()
}
var y any
y, ok := k.(yaml.Node)
if !ok {
y, ok = k.(*yaml.Node)
}
if ok {
b, _ := yaml.Marshal(y)
mk, _ := m.MarshalYAML()
b, _ := yaml.Marshal(mk)
k = strings.TrimSpace(string(b))
}

140
orderedmap/builder_test.go Normal file
View File

@@ -0,0 +1,140 @@
package orderedmap_test
import (
"testing"
"github.com/pb33f/libopenapi/datamodel/high"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/orderedmap"
"github.com/pb33f/libopenapi/utils"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
func TestOrderedMap_ToYamlNode(t *testing.T) {
type args struct {
om any
low any
}
tests := []struct {
name string
args args
want string
}{
{
name: "simple ordered map",
args: args{
om: orderedmap.ToOrderedMap(map[string]string{
"one": "two",
"three": "four",
}),
},
want: `one: two
three: four
`,
},
{
name: "simple ordered map with low representation",
args: args{
om: orderedmap.ToOrderedMap(map[string]string{
"one": "two",
"three": "four",
}),
low: low.NodeReference[*orderedmap.Map[*low.KeyReference[string], *low.ValueReference[string]]]{
Value: orderedmap.ToOrderedMap(map[*low.KeyReference[string]]*low.ValueReference[string]{
{Value: "one", KeyNode: utils.CreateStringNode("one")}: {Value: "two", ValueNode: utils.CreateStringNode("two")},
}),
ValueNode: utils.CreateYamlNode(orderedmap.ToOrderedMap(map[string]string{
"one": "two",
"three": "four",
})),
},
},
want: `one: two
three: four
`,
},
{
name: "ordered map with KeyReference",
args: args{
om: orderedmap.ToOrderedMap(map[*low.KeyReference[string]]string{
{
KeyNode: utils.CreateStringNode("one"),
}: "two",
{
KeyNode: utils.CreateStringNode("three"),
}: "four",
}),
},
want: `one: two
three: four
`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
nb := new(high.NodeBuilder)
node := tt.args.om.(orderedmap.MapToYamlNoder).ToYamlNode(nb, tt.args.low)
b, err := yaml.Marshal(node)
require.NoError(t, err)
require.Equal(t, tt.want, string(b))
})
}
}
type findValueUntyped interface {
FindValueUntyped(k string) any
}
func TestOrderedMap_FindValueUntyped(t *testing.T) {
type args struct {
om any
key string
}
tests := []struct {
name string
args args
want any
}{
{
name: "find value in simple ordered map",
args: args{
om: orderedmap.ToOrderedMap(map[string]string{
"one": "two",
"three": "four",
}),
key: "one",
},
want: "two",
},
{
name: "unable to find value in simple ordered map",
args: args{
om: orderedmap.ToOrderedMap(map[string]string{
"one": "two",
"three": "four",
}),
key: "five",
},
want: nil,
},
{
name: "find value in ordered map with KeyReference",
args: args{
om: orderedmap.ToOrderedMap(map[*low.KeyReference[string]]string{
{Value: "one"}: "two",
{Value: "three"}: "four",
}),
key: "three",
},
want: "four",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
value := tt.args.om.(findValueUntyped).FindValueUntyped(tt.args.key)
require.Equal(t, tt.want, value)
})
}
}

View File

@@ -157,7 +157,7 @@ func ToOrderedMap[K comparable, V any](m map[K]V) *Map[K, V] {
for k, v := range m {
om.Set(k, v)
}
return om
return SortAlpha(om)
}
// First returns map's first pair for iteration.