Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.16.12 #315

Merged
merged 13 commits into from
Aug 5, 2024
2 changes: 1 addition & 1 deletion bundler/bundler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ components:
assert.ErrorIs(t, unwrap[0], ErrInvalidModel)
unwrapNext := utils.UnwrapErrors(unwrap[1])
require.Len(t, unwrapNext, 2)
assert.Equal(t, "component 'bork' does not exist in the specification", unwrapNext[0].Error())
assert.Equal(t, "component `bork` does not exist in the specification", unwrapNext[0].Error())
assert.Equal(t, "cannot resolve reference `bork`, it's missing: $bork [5:7]", unwrapNext[1].Error())

logEntries := strings.Split(byteBuf.String(), "\n")
Expand Down
8 changes: 8 additions & 0 deletions datamodel/high/base/schema_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ func CreateSchemaProxyRef(ref string) *SchemaProxy {
return &SchemaProxy{refStr: ref, lock: &sync.Mutex{}}
}

// GetValueNode returns the value node of the SchemaProxy.
func (sp *SchemaProxy) GetValueNode() *yaml.Node {
if sp.schema != nil {
return sp.schema.ValueNode
}
return nil
}

// Schema will create a new Schema instance using NewSchema from the low-level SchemaProxy backing this high-level one.
// If there is a problem building the Schema, then this method will return nil. Use GetBuildError to gain access
// to that building error.
Expand Down
14 changes: 14 additions & 0 deletions datamodel/high/base/schema_proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ func TestCreateSchemaProxy(t *testing.T) {
sp := CreateSchemaProxy(&Schema{Description: "iAmASchema"})
assert.Equal(t, "iAmASchema", sp.rendered.Description)
assert.False(t, sp.IsReference())
assert.Nil(t, sp.GetValueNode())
}

func TestCreateSchemaProxy_NoNilValue(t *testing.T) {
sp := CreateSchemaProxy(&Schema{Description: "iAmASchema"})
sp.Schema()

// jerry rig the test.
nodeRef := low.NodeReference[*lowbase.SchemaProxy]{}
nodeRef.ValueNode = &yaml.Node{}
sp.schema = &nodeRef

assert.Equal(t, "iAmASchema", sp.rendered.Description)
assert.NotNil(t, sp.GetValueNode())
}

func TestCreateSchemaProxyRef(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion datamodel/high/node_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, entry *nodes.NodeEntry) *ya
lr := lut.(low.IsReferenced)
ut := reflect.ValueOf(lr)
if !ut.IsNil() {
if lut.(low.IsReferenced).IsReference() {
if lr != nil && lr.IsReference() {
if !n.Resolve {
valueNode = n.renderReference(lut.(low.IsReferenced))
break
Expand Down
5 changes: 5 additions & 0 deletions datamodel/high/v3/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ func (d *Document) GoLow() *low.Document {
return d.low
}

// GoLowUntyped returns the low-level Document that was used to create the high level one, however, it's untyped.
func (d *Document) GoLowUntyped() any {
return d.low
}

// Render will return a YAML representation of the Document object as a byte slice.
func (d *Document) Render() ([]byte, error) {
return yaml.Marshal(d)
Expand Down
1 change: 1 addition & 0 deletions datamodel/high/v3/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func TestNewDocument_Info(t *testing.T) {
assert.Equal(t, "1.2", highDoc.Info.Version)
assert.Equal(t, "https://pb33f.io/schema", highDoc.JsonSchemaDialect)

assert.NotNil(t, highDoc.GoLowUntyped())
wentLow := highDoc.GoLow()
assert.Equal(t, 1, wentLow.Version.ValueNode.Line)
assert.Equal(t, 3, wentLow.Info.Value.Title.KeyNode.Line)
Expand Down
6 changes: 3 additions & 3 deletions datamodel/low/base/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ type Contact struct {
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
low.NodeMap
}

// Build is not implemented for Contact (there is nothing to build).
func (c *Contact) Build(_ context.Context, keyNode, root *yaml.Node, _ *index.SpecIndex) error {
func (c *Contact) Build(ctx context.Context, keyNode, root *yaml.Node, _ *index.SpecIndex) error {
c.KeyNode = keyNode
c.RootNode = root
c.Reference = new(low.Reference)
// not implemented.
c.Nodes = low.ExtractNodes(ctx, root)
return nil
}

Expand Down
30 changes: 30 additions & 0 deletions datamodel/low/base/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023-2024 Princess Beef Heavy Industries, LLC / Dave Shanley
// https://pb33f.io

package base

import (
"golang.org/x/net/context"
"sync"
)

// ModelContext is a struct that holds various persistent data structures for the model
// that passes through the entire model building process.
type ModelContext struct {
SchemaCache *sync.Map
}

// GetModelContext will return the ModelContext from a context.Context object
// if it is available, otherwise it will return nil.
func GetModelContext(ctx context.Context) *ModelContext {
if ctx == nil {
return nil
}
if ctx.Value("modelCtx") == nil {
return nil
}
if c, ok := ctx.Value("modelCtx").(*ModelContext); ok {
return c
}
return nil
}
23 changes: 23 additions & 0 deletions datamodel/low/base/context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2023-2024 Princess Beef Heavy Industries, LLC / Dave Shanley
// https://pb33f.io

package base

import (
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
"testing"
)

func TestGetModelContext(t *testing.T) {

assert.Nil(t, GetModelContext(nil))
assert.Nil(t, GetModelContext(context.Background()))

ctx := context.WithValue(context.Background(), "modelCtx", &ModelContext{})
assert.NotNil(t, GetModelContext(ctx))

ctx = context.WithValue(context.Background(), "modelCtx", "wrong")
assert.Nil(t, GetModelContext(ctx))

}
14 changes: 14 additions & 0 deletions datamodel/low/base/discriminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package base

import (
"crypto/sha256"
"gopkg.in/yaml.v3"
"strings"

"github.com/pb33f/libopenapi/datamodel/low"
Expand All @@ -23,7 +24,20 @@ import (
type Discriminator struct {
PropertyName low.NodeReference[string]
Mapping low.NodeReference[*orderedmap.Map[low.KeyReference[string], low.ValueReference[string]]]
KeyNode *yaml.Node
RootNode *yaml.Node
low.Reference
low.NodeMap
}

// GetRootNode will return the root yaml node of the Discriminator object
func (d *Discriminator) GetRootNode() *yaml.Node {
return d.RootNode
}

// GetKeyNode will return the key yaml node of the Discriminator object
func (d *Discriminator) GetKeyNode() *yaml.Node {
return d.KeyNode
}

// FindMappingValue will return a ValueReference containing the string mapping value
Expand Down
5 changes: 5 additions & 0 deletions datamodel/low/base/discriminator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ propertyName: freshCakes`
var rDoc Discriminator
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
lDoc.RootNode = &lNode
lDoc.KeyNode = &rNode

assert.Equal(t, lDoc.Hash(), rDoc.Hash())
assert.NotNil(t, lDoc.GetRootNode())
assert.NotNil(t, lDoc.GetKeyNode())

}
13 changes: 12 additions & 1 deletion datamodel/low/base/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Example struct {
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
low.NodeMap
}

// FindExtension returns a ValueReference containing the extension value, if found.
Expand Down Expand Up @@ -67,12 +68,13 @@ func (ex *Example) Hash() [32]byte {
}

// Build extracts extensions and example value
func (ex *Example) Build(_ context.Context, keyNode, root *yaml.Node, _ *index.SpecIndex) error {
func (ex *Example) Build(ctx context.Context, keyNode, root *yaml.Node, _ *index.SpecIndex) error {
ex.KeyNode = keyNode
root = utils.NodeAlias(root)
ex.RootNode = root
utils.CheckForMergeNodes(root)
ex.Reference = new(low.Reference)
ex.Nodes = low.ExtractNodes(ctx, root)
ex.Extensions = low.ExtractExtensions(root)
_, ln, vn := utils.FindKeyNodeFull(ValueLabel, root.Content)

Expand All @@ -82,6 +84,15 @@ func (ex *Example) Build(_ context.Context, keyNode, root *yaml.Node, _ *index.S
KeyNode: ln,
ValueNode: vn,
}

// extract nodes for all value nodes down the tree.
expChildNodes := low.ExtractNodesRecursive(ctx, vn)
expChildNodes.Range(func(k, v interface{}) bool {
if arr, ko := v.([]*yaml.Node); ko {
ex.Nodes.Store(k, arr)
}
return true
})
return nil
}
return nil
Expand Down
4 changes: 3 additions & 1 deletion datamodel/low/base/external_doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type ExternalDoc struct {
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
low.NodeMap
}

// FindExtension returns a ValueReference containing the extension value, if found.
Expand All @@ -46,12 +47,13 @@ func (ex *ExternalDoc) GetKeyNode() *yaml.Node {
}

// Build will extract extensions from the ExternalDoc instance.
func (ex *ExternalDoc) Build(_ context.Context, keyNode, root *yaml.Node, idx *index.SpecIndex) error {
func (ex *ExternalDoc) Build(ctx context.Context, keyNode, root *yaml.Node, idx *index.SpecIndex) error {
ex.KeyNode = keyNode
root = utils.NodeAlias(root)
ex.RootNode = root
utils.CheckForMergeNodes(root)
ex.Reference = new(low.Reference)
ex.Nodes = low.ExtractNodes(ctx, root)
ex.Extensions = low.ExtractExtensions(root)
return nil
}
Expand Down
2 changes: 2 additions & 0 deletions datamodel/low/base/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Info struct {
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
low.NodeMap
}

// FindExtension attempts to locate an extension with the supplied key
Expand Down Expand Up @@ -64,6 +65,7 @@ func (i *Info) Build(ctx context.Context, keyNode, root *yaml.Node, idx *index.S
i.RootNode = root
utils.CheckForMergeNodes(root)
i.Reference = new(low.Reference)
i.Nodes = low.ExtractNodes(ctx, root)
i.Extensions = low.ExtractExtensions(root)

// extract contact
Expand Down
3 changes: 3 additions & 0 deletions datamodel/low/base/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type License struct {
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
low.NodeMap
}

// Build out a license, complain if both a URL and identifier are present as they are mutually exclusive
Expand All @@ -34,6 +35,8 @@ func (l *License) Build(ctx context.Context, keyNode, root *yaml.Node, idx *inde
l.RootNode = root
utils.CheckForMergeNodes(root)
l.Reference = new(low.Reference)
no := low.ExtractNodes(ctx, root)
l.Nodes = no
if l.URL.Value != "" && l.Identifier.Value != "" {
return fmt.Errorf("license cannot have both a URL and an identifier, they are mutually exclusive")
}
Expand Down
Loading
Loading