mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 12:37:49 +00:00
fix: fixed tests after merge
This commit is contained in:
@@ -6,6 +6,7 @@ package base
|
|||||||
import (
|
import (
|
||||||
low2 "github.com/pb33f/libopenapi/datamodel/high"
|
low2 "github.com/pb33f/libopenapi/datamodel/high"
|
||||||
low "github.com/pb33f/libopenapi/datamodel/low/base"
|
low "github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,8 +20,8 @@ import (
|
|||||||
//
|
//
|
||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
||||||
type Discriminator struct {
|
type Discriminator struct {
|
||||||
PropertyName string `json:"propertyName,omitempty" yaml:"propertyName,omitempty"`
|
PropertyName string `json:"propertyName,omitempty" yaml:"propertyName,omitempty"`
|
||||||
Mapping map[string]string `json:"mapping,omitempty" yaml:"mapping,omitempty"`
|
Mapping orderedmap.Map[string, string] `json:"mapping,omitempty" yaml:"mapping,omitempty"`
|
||||||
low *low.Discriminator
|
low *low.Discriminator
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,9 +30,9 @@ func NewDiscriminator(disc *low.Discriminator) *Discriminator {
|
|||||||
d := new(Discriminator)
|
d := new(Discriminator)
|
||||||
d.low = disc
|
d.low = disc
|
||||||
d.PropertyName = disc.PropertyName.Value
|
d.PropertyName = disc.PropertyName.Value
|
||||||
mapping := make(map[string]string)
|
mapping := orderedmap.New[string, string]()
|
||||||
for k, v := range disc.Mapping.Value {
|
for pair := disc.Mapping.Value.First(); pair != nil; pair = pair.Next() {
|
||||||
mapping[k.Value] = v.Value
|
mapping.Set(pair.Key().Value, pair.Value().Value)
|
||||||
}
|
}
|
||||||
d.Mapping = mapping
|
d.Mapping = mapping
|
||||||
return d
|
return d
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ package base
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
|
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
|
||||||
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
|
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewDiscriminator(t *testing.T) {
|
func TestNewDiscriminator(t *testing.T) {
|
||||||
|
|
||||||
var cNode yaml.Node
|
var cNode yaml.Node
|
||||||
|
|
||||||
yml := `propertyName: coffee
|
yml := `propertyName: coffee
|
||||||
@@ -31,17 +31,15 @@ mapping:
|
|||||||
highDiscriminator := NewDiscriminator(&lowDiscriminator)
|
highDiscriminator := NewDiscriminator(&lowDiscriminator)
|
||||||
|
|
||||||
assert.Equal(t, "coffee", highDiscriminator.PropertyName)
|
assert.Equal(t, "coffee", highDiscriminator.PropertyName)
|
||||||
assert.Equal(t, "in the morning", highDiscriminator.Mapping["fogCleaner"])
|
assert.Equal(t, "in the morning", highDiscriminator.Mapping.GetOrZero("fogCleaner"))
|
||||||
assert.Equal(t, 3, highDiscriminator.GoLow().FindMappingValue("fogCleaner").ValueNode.Line)
|
assert.Equal(t, 3, highDiscriminator.GoLow().FindMappingValue("fogCleaner").ValueNode.Line)
|
||||||
|
|
||||||
// render the example as YAML
|
// render the example as YAML
|
||||||
rendered, _ := highDiscriminator.Render()
|
rendered, _ := highDiscriminator.Render()
|
||||||
assert.Equal(t, strings.TrimSpace(string(rendered)), yml)
|
assert.Equal(t, strings.TrimSpace(string(rendered)), yml)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleNewDiscriminator() {
|
func ExampleNewDiscriminator() {
|
||||||
|
|
||||||
// create a yaml representation of a discriminator (can be JSON, doesn't matter)
|
// create a yaml representation of a discriminator (can be JSON, doesn't matter)
|
||||||
yml := `propertyName: coffee
|
yml := `propertyName: coffee
|
||||||
mapping:
|
mapping:
|
||||||
@@ -59,6 +57,6 @@ mapping:
|
|||||||
highDiscriminator := NewDiscriminator(&lowDiscriminator)
|
highDiscriminator := NewDiscriminator(&lowDiscriminator)
|
||||||
|
|
||||||
// print out a mapping defined for the discriminator.
|
// print out a mapping defined for the discriminator.
|
||||||
fmt.Print(highDiscriminator.Mapping["coffee"])
|
fmt.Print(highDiscriminator.Mapping.GetOrZero("coffee"))
|
||||||
// Output: in the morning
|
// Output: in the morning
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ package base
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
|
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDynamicValue_Render_A(t *testing.T) {
|
func TestDynamicValue_Render_A(t *testing.T) {
|
||||||
@@ -57,7 +58,6 @@ func TestDynamicValue_Render_Float64(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDynamicValue_Render_Ptr(t *testing.T) {
|
func TestDynamicValue_Render_Ptr(t *testing.T) {
|
||||||
|
|
||||||
type cake struct {
|
type cake struct {
|
||||||
Cake string
|
Cake string
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,6 @@ func TestDynamicValue_Render_Ptr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDynamicValue_Render_PtrRenderable(t *testing.T) {
|
func TestDynamicValue_Render_PtrRenderable(t *testing.T) {
|
||||||
|
|
||||||
tag := &Tag{
|
tag := &Tag{
|
||||||
Name: "cake",
|
Name: "cake",
|
||||||
}
|
}
|
||||||
@@ -79,7 +78,6 @@ func TestDynamicValue_Render_PtrRenderable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDynamicValue_RenderInline(t *testing.T) {
|
func TestDynamicValue_RenderInline(t *testing.T) {
|
||||||
|
|
||||||
tag := &Tag{
|
tag := &Tag{
|
||||||
Name: "cake",
|
Name: "cake",
|
||||||
}
|
}
|
||||||
@@ -90,7 +88,6 @@ func TestDynamicValue_RenderInline(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDynamicValue_MarshalYAMLInline(t *testing.T) {
|
func TestDynamicValue_MarshalYAMLInline(t *testing.T) {
|
||||||
|
|
||||||
const ymlComponents = `components:
|
const ymlComponents = `components:
|
||||||
schemas:
|
schemas:
|
||||||
rice:
|
rice:
|
||||||
@@ -130,11 +127,10 @@ func TestDynamicValue_MarshalYAMLInline(t *testing.T) {
|
|||||||
|
|
||||||
// convert node into yaml
|
// convert node into yaml
|
||||||
bits, _ := yaml.Marshal(rend)
|
bits, _ := yaml.Marshal(rend)
|
||||||
assert.Equal(t, "properties:\n rice:\n type: array\n items:\n type: string", strings.TrimSpace(string(bits)))
|
assert.Equal(t, "properties:\n rice:\n $ref: '#/components/schemas/rice'", strings.TrimSpace(string(bits)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDynamicValue_MarshalYAMLInline_Error(t *testing.T) {
|
func TestDynamicValue_MarshalYAMLInline_Error(t *testing.T) {
|
||||||
|
|
||||||
const ymlComponents = `components:
|
const ymlComponents = `components:
|
||||||
schemas:
|
schemas:
|
||||||
rice:
|
rice:
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ func TestNewDocument_Components_Schemas(t *testing.T) {
|
|||||||
assert.Len(t, d.Schema().Required, 2)
|
assert.Len(t, d.Schema().Required, 2)
|
||||||
assert.True(t, d.Schema().AdditionalProperties.B)
|
assert.True(t, d.Schema().AdditionalProperties.B)
|
||||||
assert.Equal(t, "drinkType", d.Schema().Discriminator.PropertyName)
|
assert.Equal(t, "drinkType", d.Schema().Discriminator.PropertyName)
|
||||||
assert.Equal(t, "some value", d.Schema().Discriminator.Mapping["drink"])
|
assert.Equal(t, "some value", d.Schema().Discriminator.Mapping.GetOrZero("drink"))
|
||||||
assert.Equal(t, 516, d.Schema().Discriminator.GoLow().PropertyName.ValueNode.Line)
|
assert.Equal(t, 516, d.Schema().Discriminator.GoLow().PropertyName.ValueNode.Line)
|
||||||
assert.Equal(t, 23, d.Schema().Discriminator.GoLow().PropertyName.ValueNode.Column)
|
assert.Equal(t, 23, d.Schema().Discriminator.GoLow().PropertyName.ValueNode.Column)
|
||||||
|
|
||||||
@@ -300,8 +300,8 @@ func TestNewDocument_Components_SecuritySchemes(t *testing.T) {
|
|||||||
assert.Equal(t, "an oAuth security scheme", oAuth.Description)
|
assert.Equal(t, "an oAuth security scheme", oAuth.Description)
|
||||||
assert.Equal(t, 375, oAuth.GoLow().Description.ValueNode.Line)
|
assert.Equal(t, 375, oAuth.GoLow().Description.ValueNode.Line)
|
||||||
assert.Equal(t, 20, oAuth.GoLow().Description.ValueNode.Column)
|
assert.Equal(t, 20, oAuth.GoLow().Description.ValueNode.Column)
|
||||||
assert.Equal(t, 2, len(oAuth.Flows.Implicit.Scopes))
|
assert.Equal(t, 2, oAuth.Flows.Implicit.Scopes.Len())
|
||||||
assert.Equal(t, "read all burgers", oAuth.Flows.Implicit.Scopes["read:burgers"])
|
assert.Equal(t, "read all burgers", oAuth.Flows.Implicit.Scopes.GetOrZero("read:burgers"))
|
||||||
assert.Equal(t, "https://pb33f.io/oauth", oAuth.Flows.AuthorizationCode.AuthorizationUrl)
|
assert.Equal(t, "https://pb33f.io/oauth", oAuth.Flows.AuthorizationCode.AuthorizationUrl)
|
||||||
|
|
||||||
// check the lowness is low.
|
// check the lowness is low.
|
||||||
@@ -553,7 +553,7 @@ func TestCircularReferencesDoc(t *testing.T) {
|
|||||||
lDoc, err := lowv3.CreateDocumentFromConfig(info, datamodel.NewDocumentConfiguration())
|
lDoc, err := lowv3.CreateDocumentFromConfig(info, datamodel.NewDocumentConfiguration())
|
||||||
assert.Len(t, utils.UnwrapErrors(err), 3)
|
assert.Len(t, utils.UnwrapErrors(err), 3)
|
||||||
d := NewDocument(lDoc)
|
d := NewDocument(lDoc)
|
||||||
assert.Len(t, d.Components.Schemas, 9)
|
assert.Equal(t, 9, d.Components.Schemas.Len())
|
||||||
assert.Len(t, d.Index.GetCircularReferences(), 3)
|
assert.Len(t, d.Index.GetCircularReferences(), 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package v3
|
|||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/high"
|
"github.com/pb33f/libopenapi/datamodel/high"
|
||||||
low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,8 +16,7 @@ type OAuthFlow struct {
|
|||||||
AuthorizationUrl string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
|
AuthorizationUrl string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
|
||||||
TokenUrl string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
|
TokenUrl string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
|
||||||
RefreshUrl string `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
|
RefreshUrl string `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
|
||||||
// FIXME: Scopes must be converted to orderedmap.Map. Fix unmarshaling issue causing omitted `scopes` stanza on parsing.
|
Scopes orderedmap.Map[string, string] `json:"scopes,omitempty" yaml:"scopes,omitempty"`
|
||||||
Scopes map[string]string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
|
|
||||||
Extensions map[string]any `json:"-" yaml:"-"`
|
Extensions map[string]any `json:"-" yaml:"-"`
|
||||||
low *low.OAuthFlow
|
low *low.OAuthFlow
|
||||||
}
|
}
|
||||||
@@ -28,9 +28,9 @@ func NewOAuthFlow(flow *low.OAuthFlow) *OAuthFlow {
|
|||||||
o.TokenUrl = flow.TokenUrl.Value
|
o.TokenUrl = flow.TokenUrl.Value
|
||||||
o.AuthorizationUrl = flow.AuthorizationUrl.Value
|
o.AuthorizationUrl = flow.AuthorizationUrl.Value
|
||||||
o.RefreshUrl = flow.RefreshUrl.Value
|
o.RefreshUrl = flow.RefreshUrl.Value
|
||||||
scopes := map[string]string{}
|
scopes := orderedmap.New[string, string]()
|
||||||
for k, v := range flow.Scopes.Value {
|
for pair := flow.Scopes.Value.First(); pair != nil; pair = pair.Next() {
|
||||||
scopes[k.Value] = v.Value
|
scopes.Set(pair.Key().Value, pair.Value().Value)
|
||||||
}
|
}
|
||||||
o.Scopes = scopes
|
o.Scopes = scopes
|
||||||
o.Extensions = high.ExtractExtensions(flow.Extensions)
|
o.Extensions = high.ExtractExtensions(flow.Extensions)
|
||||||
|
|||||||
@@ -7,19 +7,20 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestOAuthFlow_MarshalYAML(t *testing.T) {
|
func TestOAuthFlow_MarshalYAML(t *testing.T) {
|
||||||
|
scopes := orderedmap.New[string, string]()
|
||||||
|
scopes.Set("chicken", "nuggets")
|
||||||
|
scopes.Set("beefy", "soup")
|
||||||
|
|
||||||
oflow := &OAuthFlow{
|
oflow := &OAuthFlow{
|
||||||
AuthorizationUrl: "https://pb33f.io",
|
AuthorizationUrl: "https://pb33f.io",
|
||||||
TokenUrl: "https://pb33f.io/token",
|
TokenUrl: "https://pb33f.io/token",
|
||||||
RefreshUrl: "https://pb33f.io/refresh",
|
RefreshUrl: "https://pb33f.io/refresh",
|
||||||
Scopes: map[string]string{
|
Scopes: scopes,
|
||||||
"chicken": "nuggets",
|
|
||||||
"beefy": "soup",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rend, _ := oflow.Render()
|
rend, _ := oflow.Render()
|
||||||
@@ -45,5 +46,4 @@ x-burgers: why not?`
|
|||||||
|
|
||||||
rend, _ = oflow.Render()
|
rend, _ = oflow.Render()
|
||||||
assert.Equal(t, desired, strings.TrimSpace(string(rend)))
|
assert.Equal(t, desired, strings.TrimSpace(string(rend)))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNewOAuthFlows(t *testing.T) {
|
func TestNewOAuthFlows(t *testing.T) {
|
||||||
|
|
||||||
yml := `implicit:
|
yml := `implicit:
|
||||||
authorizationUrl: https://pb33f.io/oauth/implicit
|
authorizationUrl: https://pb33f.io/oauth/implicit
|
||||||
scopes:
|
scopes:
|
||||||
@@ -49,10 +48,10 @@ clientCredentials:
|
|||||||
|
|
||||||
r := NewOAuthFlows(&n)
|
r := NewOAuthFlows(&n)
|
||||||
|
|
||||||
assert.Len(t, r.Implicit.Scopes, 2)
|
assert.Equal(t, 2, r.Implicit.Scopes.Len())
|
||||||
assert.Len(t, r.AuthorizationCode.Scopes, 2)
|
assert.Equal(t, 2, r.AuthorizationCode.Scopes.Len())
|
||||||
assert.Len(t, r.Password.Scopes, 2)
|
assert.Equal(t, 2, r.Password.Scopes.Len())
|
||||||
assert.Len(t, r.ClientCredentials.Scopes, 2)
|
assert.Equal(t, 2, r.ClientCredentials.Scopes.Len())
|
||||||
assert.Equal(t, 2, r.GoLow().Implicit.Value.AuthorizationUrl.KeyNode.Line)
|
assert.Equal(t, 2, r.GoLow().Implicit.Value.AuthorizationUrl.KeyNode.Line)
|
||||||
|
|
||||||
// now render it back out, and it should be identical!
|
// now render it back out, and it should be identical!
|
||||||
@@ -83,8 +82,7 @@ clientCredentials:
|
|||||||
CHIP:CHOP: microwave a sock`
|
CHIP:CHOP: microwave a sock`
|
||||||
|
|
||||||
// now modify it and render it back out, and it should be identical!
|
// now modify it and render it back out, and it should be identical!
|
||||||
r.ClientCredentials.Scopes["CHIP:CHOP"] = "microwave a sock"
|
r.ClientCredentials.Scopes.Set("CHIP:CHOP", "microwave a sock")
|
||||||
rBytes, _ = r.Render()
|
rBytes, _ = r.Render()
|
||||||
assert.Equal(t, modified, strings.TrimSpace(string(rBytes)))
|
assert.Equal(t, modified, strings.TrimSpace(string(rBytes)))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ package base
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Discriminator is only used by OpenAPI 3+ documents, it represents a polymorphic discriminator used for schemas
|
// Discriminator is only used by OpenAPI 3+ documents, it represents a polymorphic discriminator used for schemas
|
||||||
@@ -21,14 +22,15 @@ import (
|
|||||||
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
// v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object
|
||||||
type Discriminator struct {
|
type Discriminator struct {
|
||||||
PropertyName low.NodeReference[string]
|
PropertyName low.NodeReference[string]
|
||||||
Mapping low.NodeReference[map[low.KeyReference[string]]low.ValueReference[string]]
|
Mapping low.NodeReference[orderedmap.Map[low.KeyReference[string], low.ValueReference[string]]]
|
||||||
low.Reference
|
low.Reference
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindMappingValue will return a ValueReference containing the string mapping value
|
// FindMappingValue will return a ValueReference containing the string mapping value
|
||||||
func (d *Discriminator) FindMappingValue(key string) *low.ValueReference[string] {
|
func (d *Discriminator) FindMappingValue(key string) *low.ValueReference[string] {
|
||||||
for k, v := range d.Mapping.Value {
|
for pair := d.Mapping.Value.First(); pair != nil; pair = pair.Next() {
|
||||||
if k.Value == key {
|
if pair.Key().Value == key {
|
||||||
|
v := pair.Value()
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,20 +39,15 @@ func (d *Discriminator) FindMappingValue(key string) *low.ValueReference[string]
|
|||||||
|
|
||||||
// Hash will return a consistent SHA256 Hash of the Discriminator object
|
// Hash will return a consistent SHA256 Hash of the Discriminator object
|
||||||
func (d *Discriminator) Hash() [32]byte {
|
func (d *Discriminator) Hash() [32]byte {
|
||||||
|
|
||||||
// calculate a hash from every property.
|
// calculate a hash from every property.
|
||||||
var f []string
|
var f []string
|
||||||
if d.PropertyName.Value != "" {
|
if d.PropertyName.Value != "" {
|
||||||
f = append(f, d.PropertyName.Value)
|
f = append(f, d.PropertyName.Value)
|
||||||
}
|
}
|
||||||
propertyKeys := make([]string, 0, len(d.Mapping.Value))
|
|
||||||
for i := range d.Mapping.Value {
|
for pair := orderedmap.First(d.Mapping.Value); pair != nil; pair = pair.Next() {
|
||||||
propertyKeys = append(propertyKeys, i.Value)
|
f = append(f, pair.Value().Value)
|
||||||
}
|
|
||||||
sort.Strings(propertyKeys)
|
|
||||||
for k := range propertyKeys {
|
|
||||||
prop := d.FindMappingValue(propertyKeys[k])
|
|
||||||
f = append(f, prop.Value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -549,7 +549,6 @@ func (s *Schema) Build(ctx context.Context, root *yaml.Node, idx *index.SpecInde
|
|||||||
// determine exclusive minimum type, bool (3.0) or int (3.1)
|
// determine exclusive minimum type, bool (3.0) or int (3.1)
|
||||||
_, exMinLabel, exMinValue := utils.FindKeyNodeFullTop(ExclusiveMinimumLabel, root.Content)
|
_, exMinLabel, exMinValue := utils.FindKeyNodeFullTop(ExclusiveMinimumLabel, root.Content)
|
||||||
if exMinValue != nil {
|
if exMinValue != nil {
|
||||||
|
|
||||||
// if there is an index, determine if this a 3.0 or 3.1 schema
|
// if there is an index, determine if this a 3.0 or 3.1 schema
|
||||||
if idx != nil {
|
if idx != nil {
|
||||||
if idx.GetConfig().SpecInfo.VersionNumeric == 3.1 {
|
if idx.GetConfig().SpecInfo.VersionNumeric == 3.1 {
|
||||||
@@ -593,7 +592,6 @@ func (s *Schema) Build(ctx context.Context, root *yaml.Node, idx *index.SpecInde
|
|||||||
// determine exclusive maximum type, bool (3.0) or int (3.1)
|
// determine exclusive maximum type, bool (3.0) or int (3.1)
|
||||||
_, exMaxLabel, exMaxValue := utils.FindKeyNodeFullTop(ExclusiveMaximumLabel, root.Content)
|
_, exMaxLabel, exMaxValue := utils.FindKeyNodeFullTop(ExclusiveMaximumLabel, root.Content)
|
||||||
if exMaxValue != nil {
|
if exMaxValue != nil {
|
||||||
|
|
||||||
// if there is an index, determine if this a 3.0 or 3.1 schema
|
// if there is an index, determine if this a 3.0 or 3.1 schema
|
||||||
if idx != nil {
|
if idx != nil {
|
||||||
if idx.GetConfig().SpecInfo.VersionNumeric == 3.1 {
|
if idx.GetConfig().SpecInfo.VersionNumeric == 3.1 {
|
||||||
@@ -1038,62 +1036,40 @@ func (s *Schema) Build(ctx context.Context, root *yaml.Node, idx *index.SpecInde
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildPropertyMap(ctx context.Context, root *yaml.Node, idx *index.SpecIndex, label string) (*low.NodeReference[orderedmap.Map[low.KeyReference[string], low.ValueReference[*SchemaProxy]]], error) {
|
func buildPropertyMap(ctx context.Context, root *yaml.Node, idx *index.SpecIndex, label string) (*low.NodeReference[orderedmap.Map[low.KeyReference[string], low.ValueReference[*SchemaProxy]]], error) {
|
||||||
// for property, build in a new thread!
|
|
||||||
bChan := make(chan schemaProxyBuildResult)
|
|
||||||
|
|
||||||
buildProperty := func(ctx context.Context, label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult, isRef bool,
|
|
||||||
refString string,
|
|
||||||
) {
|
|
||||||
c <- schemaProxyBuildResult{
|
|
||||||
k: low.KeyReference[string]{
|
|
||||||
KeyNode: label,
|
|
||||||
Value: label.Value,
|
|
||||||
},
|
|
||||||
v: low.ValueReference[*SchemaProxy]{
|
|
||||||
Value: &SchemaProxy{ctx: ctx, kn: label, vn: value, idx: idx, isReference: isRef, referenceLookup: refString},
|
|
||||||
ValueNode: value,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, propLabel, propsNode := utils.FindKeyNodeFullTop(label, root.Content)
|
_, propLabel, propsNode := utils.FindKeyNodeFullTop(label, root.Content)
|
||||||
if propsNode != nil {
|
if propsNode != nil {
|
||||||
propertyMap := orderedmap.New[low.KeyReference[string], low.ValueReference[*SchemaProxy]]()
|
propertyMap := orderedmap.New[low.KeyReference[string], low.ValueReference[*SchemaProxy]]()
|
||||||
var currentProp *yaml.Node
|
var currentProp *yaml.Node
|
||||||
totalProps := 0
|
|
||||||
for i, prop := range propsNode.Content {
|
for i, prop := range propsNode.Content {
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
currentProp = prop
|
currentProp = prop
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
foundCtx := ctx
|
|
||||||
// check our prop isn't reference
|
// check our prop isn't reference
|
||||||
isRef := false
|
isRef := false
|
||||||
refString := ""
|
refString := ""
|
||||||
if h, _, l := utils.IsNodeRefValue(prop); h {
|
if h, _, l := utils.IsNodeRefValue(prop); h {
|
||||||
ref, _, _, fctx := low.LocateRefNodeWithContext(ctx, prop, idx)
|
ref, _, _, _ := low.LocateRefNodeWithContext(ctx, prop, idx)
|
||||||
if ref != nil {
|
if ref != nil {
|
||||||
isRef = true
|
isRef = true
|
||||||
prop = ref
|
prop = ref
|
||||||
refString = l
|
refString = l
|
||||||
foundCtx = fctx
|
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("schema properties build failed: cannot find reference %s, line %d, col %d",
|
return nil, fmt.Errorf("schema properties build failed: cannot find reference %s, line %d, col %d",
|
||||||
prop.Content[1].Value, prop.Content[1].Line, prop.Content[1].Column)
|
prop.Content[1].Value, prop.Content[1].Line, prop.Content[1].Column)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
totalProps++
|
|
||||||
go buildProperty(foundCtx, currentProp, prop, bChan, isRef, refString)
|
propertyMap.Set(low.KeyReference[string]{
|
||||||
}
|
KeyNode: currentProp,
|
||||||
completedProps := 0
|
Value: currentProp.Value,
|
||||||
for completedProps < totalProps {
|
}, low.ValueReference[*SchemaProxy]{
|
||||||
select {
|
Value: &SchemaProxy{ctx: ctx, kn: currentProp, vn: prop, idx: idx, isReference: isRef, referenceLookup: refString},
|
||||||
case res := <-bChan:
|
ValueNode: prop,
|
||||||
completedProps++
|
})
|
||||||
propertyMap.Set(res.k, res.v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &low.NodeReference[orderedmap.Map[low.KeyReference[string], low.ValueReference[*SchemaProxy]]]{
|
return &low.NodeReference[orderedmap.Map[low.KeyReference[string], low.ValueReference[*SchemaProxy]]]{
|
||||||
Value: propertyMap,
|
Value: propertyMap,
|
||||||
KeyNode: propLabel,
|
KeyNode: propLabel,
|
||||||
@@ -1280,7 +1256,7 @@ func ExtractSchema(ctx context.Context, root *yaml.Node, idx *index.SpecIndex) (
|
|||||||
schNode = ref
|
schNode = ref
|
||||||
if foundIdx != nil {
|
if foundIdx != nil {
|
||||||
// TODO: check on this
|
// TODO: check on this
|
||||||
//idx = foundIdx
|
// idx = foundIdx
|
||||||
}
|
}
|
||||||
ctx = nCtx
|
ctx = nCtx
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -389,25 +390,25 @@ func SetField(field *reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) er
|
|||||||
field.Set(reflect.ValueOf(ref))
|
field.Set(reflect.ValueOf(ref))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.TypeOf(NodeReference[map[KeyReference[string]]ValueReference[string]]{}):
|
case reflect.TypeOf(NodeReference[orderedmap.Map[KeyReference[string], ValueReference[string]]]{}):
|
||||||
if utils.IsNodeMap(valueNode) {
|
if utils.IsNodeMap(valueNode) {
|
||||||
if field.CanSet() {
|
if field.CanSet() {
|
||||||
items := make(map[KeyReference[string]]ValueReference[string])
|
items := orderedmap.New[KeyReference[string], ValueReference[string]]()
|
||||||
var cf *yaml.Node
|
var cf *yaml.Node
|
||||||
for i, sliceItem := range valueNode.Content {
|
for i, sliceItem := range valueNode.Content {
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
cf = sliceItem
|
cf = sliceItem
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
items[KeyReference[string]{
|
items.Set(KeyReference[string]{
|
||||||
Value: cf.Value,
|
Value: cf.Value,
|
||||||
KeyNode: cf,
|
KeyNode: cf,
|
||||||
}] = ValueReference[string]{
|
}, ValueReference[string]{
|
||||||
Value: sliceItem.Value,
|
Value: sliceItem.Value,
|
||||||
ValueNode: sliceItem,
|
ValueNode: sliceItem,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
ref := NodeReference[map[KeyReference[string]]ValueReference[string]]{
|
ref := NodeReference[orderedmap.Map[KeyReference[string], ValueReference[string]]]{
|
||||||
Value: items,
|
Value: items,
|
||||||
KeyNode: keyNode,
|
KeyNode: keyNode,
|
||||||
ValueNode: valueNode,
|
ValueNode: valueNode,
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package low
|
package low
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type hotdog struct {
|
type hotdog struct {
|
||||||
@@ -27,11 +29,10 @@ type hotdog struct {
|
|||||||
LotsOfUnknowns []NodeReference[any]
|
LotsOfUnknowns []NodeReference[any]
|
||||||
Where map[string]NodeReference[any]
|
Where map[string]NodeReference[any]
|
||||||
There map[string]NodeReference[string]
|
There map[string]NodeReference[string]
|
||||||
AllTheThings NodeReference[map[KeyReference[string]]ValueReference[string]]
|
AllTheThings NodeReference[orderedmap.Map[KeyReference[string], ValueReference[string]]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildModel_Mismatch(t *testing.T) {
|
func TestBuildModel_Mismatch(t *testing.T) {
|
||||||
|
|
||||||
yml := `crisps: are tasty`
|
yml := `crisps: are tasty`
|
||||||
|
|
||||||
var rootNode yaml.Node
|
var rootNode yaml.Node
|
||||||
@@ -42,11 +43,9 @@ func TestBuildModel_Mismatch(t *testing.T) {
|
|||||||
cErr := BuildModel(&rootNode, &hd)
|
cErr := BuildModel(&rootNode, &hd)
|
||||||
assert.NoError(t, cErr)
|
assert.NoError(t, cErr)
|
||||||
assert.Empty(t, hd.Name)
|
assert.Empty(t, hd.Name)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildModel(t *testing.T) {
|
func TestBuildModel(t *testing.T) {
|
||||||
|
|
||||||
yml := `name: yummy
|
yml := `name: yummy
|
||||||
valueName: yammy
|
valueName: yammy
|
||||||
beef: true
|
beef: true
|
||||||
@@ -135,19 +134,18 @@ allTheThings:
|
|||||||
assert.Equal(t, 324938249028.98234892374892374923874823974, hd.Mustard.Value)
|
assert.Equal(t, 324938249028.98234892374892374923874823974, hd.Mustard.Value)
|
||||||
|
|
||||||
allTheThings := hd.AllTheThings.Value
|
allTheThings := hd.AllTheThings.Value
|
||||||
for i := range allTheThings {
|
for pair := allTheThings.First(); pair != nil; pair = pair.Next() {
|
||||||
if i.Value == "beer" {
|
if pair.Key().Value == "beer" {
|
||||||
assert.Equal(t, "isGood", allTheThings[i].Value)
|
assert.Equal(t, "isGood", pair.Value().Value)
|
||||||
}
|
}
|
||||||
if i.Value == "cake" {
|
if pair.Key().Value == "cake" {
|
||||||
assert.Equal(t, "isNice", allTheThings[i].Value)
|
assert.Equal(t, "isNice", pair.Value().Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert.NoError(t, cErr)
|
assert.NoError(t, cErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildModel_UseCopyNotRef(t *testing.T) {
|
func TestBuildModel_UseCopyNotRef(t *testing.T) {
|
||||||
|
|
||||||
yml := `cake: -99999`
|
yml := `cake: -99999`
|
||||||
|
|
||||||
var rootNode yaml.Node
|
var rootNode yaml.Node
|
||||||
@@ -158,11 +156,9 @@ func TestBuildModel_UseCopyNotRef(t *testing.T) {
|
|||||||
cErr := BuildModel(&rootNode, hd)
|
cErr := BuildModel(&rootNode, hd)
|
||||||
assert.Error(t, cErr)
|
assert.Error(t, cErr)
|
||||||
assert.Empty(t, hd.Name)
|
assert.Empty(t, hd.Name)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildModel_UseUnsupportedPrimitive(t *testing.T) {
|
func TestBuildModel_UseUnsupportedPrimitive(t *testing.T) {
|
||||||
|
|
||||||
type notSupported struct {
|
type notSupported struct {
|
||||||
cake string
|
cake string
|
||||||
}
|
}
|
||||||
@@ -176,11 +172,9 @@ func TestBuildModel_UseUnsupportedPrimitive(t *testing.T) {
|
|||||||
cErr := BuildModel(rootNode.Content[0], &ns)
|
cErr := BuildModel(rootNode.Content[0], &ns)
|
||||||
assert.Error(t, cErr)
|
assert.Error(t, cErr)
|
||||||
assert.Empty(t, ns.cake)
|
assert.Empty(t, ns.cake)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildModel_UsingInternalConstructs(t *testing.T) {
|
func TestBuildModel_UsingInternalConstructs(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Extensions NodeReference[string]
|
Extensions NodeReference[string]
|
||||||
PathItems NodeReference[string]
|
PathItems NodeReference[string]
|
||||||
@@ -208,7 +202,6 @@ thing: yeah`
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetField_NodeRefAny_Error(t *testing.T) {
|
func TestSetField_NodeRefAny_Error(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing []NodeReference[any]
|
Thing []NodeReference[any]
|
||||||
}
|
}
|
||||||
@@ -224,11 +217,9 @@ func TestSetField_NodeRefAny_Error(t *testing.T) {
|
|||||||
|
|
||||||
try := BuildModel(rootNode.Content[0], ins)
|
try := BuildModel(rootNode.Content[0], ins)
|
||||||
assert.Error(t, try)
|
assert.Error(t, try)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetField_MapHelperWrapped(t *testing.T) {
|
func TestSetField_MapHelperWrapped(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing KeyReference[map[KeyReference[string]]ValueReference[string]]
|
Thing KeyReference[map[KeyReference[string]]ValueReference[string]]
|
||||||
}
|
}
|
||||||
@@ -249,7 +240,6 @@ func TestSetField_MapHelperWrapped(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetField_MapHelper(t *testing.T) {
|
func TestSetField_MapHelper(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing map[KeyReference[string]]ValueReference[string]
|
Thing map[KeyReference[string]]ValueReference[string]
|
||||||
}
|
}
|
||||||
@@ -270,7 +260,6 @@ func TestSetField_MapHelper(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetField_ArrayHelper(t *testing.T) {
|
func TestSetField_ArrayHelper(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing NodeReference[[]ValueReference[string]]
|
Thing NodeReference[[]ValueReference[string]]
|
||||||
}
|
}
|
||||||
@@ -291,7 +280,6 @@ func TestSetField_ArrayHelper(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetField_Enum_Helper(t *testing.T) {
|
func TestSetField_Enum_Helper(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing NodeReference[[]ValueReference[any]]
|
Thing NodeReference[[]ValueReference[any]]
|
||||||
}
|
}
|
||||||
@@ -312,7 +300,6 @@ func TestSetField_Enum_Helper(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetField_Default_Helper(t *testing.T) {
|
func TestSetField_Default_Helper(t *testing.T) {
|
||||||
|
|
||||||
type cake struct {
|
type cake struct {
|
||||||
thing int
|
thing int
|
||||||
}
|
}
|
||||||
@@ -336,7 +323,6 @@ func TestSetField_Default_Helper(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestHandleSlicesOfInts(t *testing.T) {
|
func TestHandleSlicesOfInts(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing NodeReference[[]ValueReference[any]]
|
Thing NodeReference[[]ValueReference[any]]
|
||||||
}
|
}
|
||||||
@@ -377,7 +363,6 @@ func TestHandleSlicesOfBools(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetField_Ignore(t *testing.T) {
|
func TestSetField_Ignore(t *testing.T) {
|
||||||
|
|
||||||
type Complex struct {
|
type Complex struct {
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
@@ -401,7 +386,6 @@ func TestSetField_Ignore(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildModelAsync(t *testing.T) {
|
func TestBuildModelAsync(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing KeyReference[map[KeyReference[string]]ValueReference[string]]
|
Thing KeyReference[map[KeyReference[string]]ValueReference[string]]
|
||||||
}
|
}
|
||||||
@@ -422,11 +406,9 @@ func TestBuildModelAsync(t *testing.T) {
|
|||||||
BuildModelAsync(rootNode.Content[0], ins, &wg, &errors)
|
BuildModelAsync(rootNode.Content[0], ins, &wg, &errors)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
assert.Len(t, ins.Thing.Value, 3)
|
assert.Len(t, ins.Thing.Value, 3)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildModelAsync_Error(t *testing.T) {
|
func TestBuildModelAsync_Error(t *testing.T) {
|
||||||
|
|
||||||
type internal struct {
|
type internal struct {
|
||||||
Thing []NodeReference[any]
|
Thing []NodeReference[any]
|
||||||
}
|
}
|
||||||
@@ -447,5 +429,4 @@ func TestBuildModelAsync_Error(t *testing.T) {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
assert.Len(t, errors, 1)
|
assert.Len(t, errors, 1)
|
||||||
assert.Len(t, ins.Thing, 0)
|
assert.Len(t, ins.Thing, 0)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pb33f/libopenapi/index"
|
|
||||||
"github.com/pb33f/libopenapi/utils"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel"
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
"github.com/pb33f/libopenapi/orderedmap"
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -525,7 +526,7 @@ func TestCreateDocument_Components_Schemas(t *testing.T) {
|
|||||||
|
|
||||||
components := doc.Components.Value
|
components := doc.Components.Value
|
||||||
assert.NotNil(t, components)
|
assert.NotNil(t, components)
|
||||||
assert.Len(t, components.Schemas.Value, 6)
|
assert.Equal(t, 6, components.Schemas.Value.Len())
|
||||||
|
|
||||||
burger := components.FindSchema("Burger").Value
|
burger := components.FindSchema("Burger").Value
|
||||||
assert.NotNil(t, burger)
|
assert.NotNil(t, burger)
|
||||||
@@ -539,7 +540,7 @@ func TestCreateDocument_Components_Schemas(t *testing.T) {
|
|||||||
fries := components.FindSchema("Fries")
|
fries := components.FindSchema("Fries")
|
||||||
assert.NotNil(t, fries.Value)
|
assert.NotNil(t, fries.Value)
|
||||||
|
|
||||||
assert.Len(t, fries.Value.Schema().Properties.Value, 3)
|
assert.Equal(t, 3, fries.Value.Schema().Properties.Value.Len())
|
||||||
p := fries.Value.Schema().FindProperty("favoriteDrink")
|
p := fries.Value.Schema().FindProperty("favoriteDrink")
|
||||||
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
||||||
p.Value.Schema().Description.Value)
|
p.Value.Schema().Description.Value)
|
||||||
@@ -549,7 +550,7 @@ func TestCreateDocument_Components_SecuritySchemes(t *testing.T) {
|
|||||||
initTest()
|
initTest()
|
||||||
components := doc.Components.Value
|
components := doc.Components.Value
|
||||||
securitySchemes := components.SecuritySchemes.Value
|
securitySchemes := components.SecuritySchemes.Value
|
||||||
assert.Len(t, securitySchemes, 3)
|
assert.Equal(t, 3, securitySchemes.Len())
|
||||||
|
|
||||||
apiKey := components.FindSecurityScheme("APIKeyScheme").Value
|
apiKey := components.FindSecurityScheme("APIKeyScheme").Value
|
||||||
assert.NotNil(t, apiKey)
|
assert.NotNil(t, apiKey)
|
||||||
@@ -577,19 +578,19 @@ func TestCreateDocument_Components_Responses(t *testing.T) {
|
|||||||
initTest()
|
initTest()
|
||||||
components := doc.Components.Value
|
components := doc.Components.Value
|
||||||
responses := components.Responses.Value
|
responses := components.Responses.Value
|
||||||
assert.Len(t, responses, 1)
|
assert.Equal(t, 1, responses.Len())
|
||||||
|
|
||||||
dressingResponse := components.FindResponse("DressingResponse")
|
dressingResponse := components.FindResponse("DressingResponse")
|
||||||
assert.NotNil(t, dressingResponse.Value)
|
assert.NotNil(t, dressingResponse.Value)
|
||||||
assert.Equal(t, "all the dressings for a burger.", dressingResponse.Value.Description.Value)
|
assert.Equal(t, "all the dressings for a burger.", dressingResponse.Value.Description.Value)
|
||||||
assert.Len(t, dressingResponse.Value.Content.Value, 1)
|
assert.Equal(t, 1, dressingResponse.Value.Content.Value.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateDocument_Components_Examples(t *testing.T) {
|
func TestCreateDocument_Components_Examples(t *testing.T) {
|
||||||
initTest()
|
initTest()
|
||||||
components := doc.Components.Value
|
components := doc.Components.Value
|
||||||
examples := components.Examples.Value
|
examples := components.Examples.Value
|
||||||
assert.Len(t, examples, 1)
|
assert.Equal(t, 1, examples.Len())
|
||||||
|
|
||||||
quarterPounder := components.FindExample("QuarterPounder")
|
quarterPounder := components.FindExample("QuarterPounder")
|
||||||
assert.NotNil(t, quarterPounder.Value)
|
assert.NotNil(t, quarterPounder.Value)
|
||||||
@@ -601,19 +602,19 @@ func TestCreateDocument_Components_RequestBodies(t *testing.T) {
|
|||||||
initTest()
|
initTest()
|
||||||
components := doc.Components.Value
|
components := doc.Components.Value
|
||||||
requestBodies := components.RequestBodies.Value
|
requestBodies := components.RequestBodies.Value
|
||||||
assert.Len(t, requestBodies, 1)
|
assert.Equal(t, 1, requestBodies.Len())
|
||||||
|
|
||||||
burgerRequest := components.FindRequestBody("BurgerRequest")
|
burgerRequest := components.FindRequestBody("BurgerRequest")
|
||||||
assert.NotNil(t, burgerRequest.Value)
|
assert.NotNil(t, burgerRequest.Value)
|
||||||
assert.Equal(t, "Give us the new burger!", burgerRequest.Value.Description.Value)
|
assert.Equal(t, "Give us the new burger!", burgerRequest.Value.Description.Value)
|
||||||
assert.Len(t, burgerRequest.Value.Content.Value, 1)
|
assert.Equal(t, 1, burgerRequest.Value.Content.Value.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateDocument_Components_Headers(t *testing.T) {
|
func TestCreateDocument_Components_Headers(t *testing.T) {
|
||||||
initTest()
|
initTest()
|
||||||
components := doc.Components.Value
|
components := doc.Components.Value
|
||||||
headers := components.Headers.Value
|
headers := components.Headers.Value
|
||||||
assert.Len(t, headers, 1)
|
assert.Equal(t, 1, headers.Len())
|
||||||
|
|
||||||
useOil := components.FindHeader("UseOil")
|
useOil := components.FindHeader("UseOil")
|
||||||
assert.NotNil(t, useOil.Value)
|
assert.NotNil(t, useOil.Value)
|
||||||
@@ -625,7 +626,7 @@ func TestCreateDocument_Components_Links(t *testing.T) {
|
|||||||
initTest()
|
initTest()
|
||||||
components := doc.Components.Value
|
components := doc.Components.Value
|
||||||
links := components.Links.Value
|
links := components.Links.Value
|
||||||
assert.Len(t, links, 2)
|
assert.Equal(t, 2, links.Len())
|
||||||
|
|
||||||
locateBurger := components.FindLink("LocateBurger")
|
locateBurger := components.FindLink("LocateBurger")
|
||||||
assert.NotNil(t, locateBurger.Value)
|
assert.NotNil(t, locateBurger.Value)
|
||||||
@@ -646,11 +647,11 @@ func TestCreateDocument_Doc_Security(t *testing.T) {
|
|||||||
func TestCreateDocument_Callbacks(t *testing.T) {
|
func TestCreateDocument_Callbacks(t *testing.T) {
|
||||||
initTest()
|
initTest()
|
||||||
callbacks := doc.Components.Value.Callbacks.Value
|
callbacks := doc.Components.Value.Callbacks.Value
|
||||||
assert.Len(t, callbacks, 1)
|
assert.Equal(t, 1, callbacks.Len())
|
||||||
|
|
||||||
bCallback := doc.Components.Value.FindCallback("BurgerCallback")
|
bCallback := doc.Components.Value.FindCallback("BurgerCallback")
|
||||||
assert.NotNil(t, bCallback.Value)
|
assert.NotNil(t, bCallback.Value)
|
||||||
assert.Len(t, callbacks, 1)
|
assert.Equal(t, 1, callbacks.Len())
|
||||||
|
|
||||||
exp := bCallback.Value.FindExpression("{$request.query.queryUrl}")
|
exp := bCallback.Value.FindExpression("{$request.query.queryUrl}")
|
||||||
assert.NotNil(t, exp.Value)
|
assert.NotNil(t, exp.Value)
|
||||||
@@ -791,7 +792,6 @@ func TestCreateDocument_YamlAnchor(t *testing.T) {
|
|||||||
|
|
||||||
// build low-level document model
|
// build low-level document model
|
||||||
document, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{})
|
document, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error: %s\n", err.Error())
|
fmt.Printf("error: %s\n", err.Error())
|
||||||
panic("cannot build document")
|
panic("cannot build document")
|
||||||
@@ -851,7 +851,6 @@ func ExampleCreateDocument() {
|
|||||||
|
|
||||||
// build low-level document model
|
// build low-level document model
|
||||||
document, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{})
|
document, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error: %s\n", err.Error())
|
fmt.Printf("error: %s\n", err.Error())
|
||||||
panic("cannot build document")
|
panic("cannot build document")
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHeader_Build(t *testing.T) {
|
func TestHeader_Build(t *testing.T) {
|
||||||
@@ -168,7 +170,6 @@ func TestHeader_Build_Fail_Content(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEncoding_Hash_n_Grab(t *testing.T) {
|
func TestEncoding_Hash_n_Grab(t *testing.T) {
|
||||||
|
|
||||||
yml := `description: heady
|
yml := `description: heady
|
||||||
required: true
|
required: true
|
||||||
deprecated: true
|
deprecated: true
|
||||||
@@ -241,7 +242,6 @@ schema:
|
|||||||
sch := n.GetSchema().Value.(*base.SchemaProxy).Schema()
|
sch := n.GetSchema().Value.(*base.SchemaProxy).Schema()
|
||||||
assert.Len(t, sch.Type.Value.B, 2) // using multiple types for 3.1 testing.
|
assert.Len(t, sch.Type.Value.B, 2) // using multiple types for 3.1 testing.
|
||||||
assert.Equal(t, "what a good puppy", n.GetExample().Value)
|
assert.Equal(t, "what a good puppy", n.GetExample().Value)
|
||||||
assert.Len(t, n.GetExamples().Value, 1)
|
assert.Equal(t, 1, orderedmap.Cast[low.KeyReference[string], low.ValueReference[*base.Example]](n.GetExamples().Value).Len())
|
||||||
assert.Len(t, n.GetContent().Value.(map[low.KeyReference[string]]low.ValueReference[*MediaType]), 1)
|
assert.Equal(t, 1, orderedmap.Cast[low.KeyReference[string], low.ValueReference[*MediaType]](n.GetContent().Value).Len())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMediaType_Build(t *testing.T) {
|
func TestMediaType_Build(t *testing.T) {
|
||||||
@@ -42,7 +43,7 @@ x-rock: and roll`
|
|||||||
assert.Equal(t, "why?", n.FindExample("what").Value.Value.Value)
|
assert.Equal(t, "why?", n.FindExample("what").Value.Value.Value)
|
||||||
assert.Equal(t, "there?", n.FindExample("where").Value.Value.Value)
|
assert.Equal(t, "there?", n.FindExample("where").Value.Value.Value)
|
||||||
assert.True(t, n.FindPropertyEncoding("chicken").Value.Explode.Value)
|
assert.True(t, n.FindPropertyEncoding("chicken").Value.Explode.Value)
|
||||||
assert.Len(t, n.GetAllExamples(), 2)
|
assert.Equal(t, n.GetAllExamples().Len(), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMediaType_Build_Fail_Schema(t *testing.T) {
|
func TestMediaType_Build_Fail_Schema(t *testing.T) {
|
||||||
@@ -76,7 +77,6 @@ func TestMediaType_Build_Fail_Examples(t *testing.T) {
|
|||||||
|
|
||||||
err = n.Build(context.Background(), nil, idxNode.Content[0], idx)
|
err = n.Build(context.Background(), nil, idxNode.Content[0], idx)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMediaType_Build_Fail_Encoding(t *testing.T) {
|
func TestMediaType_Build_Fail_Encoding(t *testing.T) {
|
||||||
@@ -97,7 +97,6 @@ func TestMediaType_Build_Fail_Encoding(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMediaType_Hash(t *testing.T) {
|
func TestMediaType_Hash(t *testing.T) {
|
||||||
|
|
||||||
yml := `schema:
|
yml := `schema:
|
||||||
type: string
|
type: string
|
||||||
example: a thing
|
example: a thing
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -97,7 +98,7 @@ type OAuthFlow struct {
|
|||||||
AuthorizationUrl low.NodeReference[string]
|
AuthorizationUrl low.NodeReference[string]
|
||||||
TokenUrl low.NodeReference[string]
|
TokenUrl low.NodeReference[string]
|
||||||
RefreshUrl low.NodeReference[string]
|
RefreshUrl low.NodeReference[string]
|
||||||
Scopes low.NodeReference[map[low.KeyReference[string]]low.ValueReference[string]]
|
Scopes low.NodeReference[orderedmap.Map[low.KeyReference[string], low.ValueReference[string]]]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
*low.Reference
|
*low.Reference
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,7 @@ func (o *OAuthFlow) GetExtensions() map[low.KeyReference[string]]low.ValueRefere
|
|||||||
|
|
||||||
// FindScope attempts to locate a scope using a specified name.
|
// FindScope attempts to locate a scope using a specified name.
|
||||||
func (o *OAuthFlow) FindScope(scope string) *low.ValueReference[string] {
|
func (o *OAuthFlow) FindScope(scope string) *low.ValueReference[string] {
|
||||||
return low.FindItemInMap[string](scope, o.Scopes.Value)
|
return low.FindItemInOrderedMap[string](scope, o.Scopes.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindExtension attempts to locate an extension with a specified key
|
// FindExtension attempts to locate an extension with a specified key
|
||||||
@@ -136,10 +137,10 @@ func (o *OAuthFlow) Hash() [32]byte {
|
|||||||
if !o.RefreshUrl.IsEmpty() {
|
if !o.RefreshUrl.IsEmpty() {
|
||||||
f = append(f, o.RefreshUrl.Value)
|
f = append(f, o.RefreshUrl.Value)
|
||||||
}
|
}
|
||||||
keys := make([]string, len(o.Scopes.Value))
|
keys := make([]string, orderedmap.Len(o.Scopes.Value))
|
||||||
z := 0
|
z := 0
|
||||||
for k, v := range o.Scopes.Value {
|
for pair := orderedmap.First(o.Scopes.Value); pair != nil; pair = pair.Next() {
|
||||||
keys[z] = fmt.Sprintf("%s-%s", k.Value, sha256.Sum256([]byte(fmt.Sprint(v.Value))))
|
keys[z] = fmt.Sprintf("%s-%s", pair.Key().Value, sha256.Sum256([]byte(fmt.Sprint(pair.Value().Value))))
|
||||||
z++
|
z++
|
||||||
}
|
}
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestOperation_Build(t *testing.T) {
|
func TestOperation_Build(t *testing.T) {
|
||||||
|
|
||||||
yml := `tags:
|
yml := `tags:
|
||||||
- meddy
|
- meddy
|
||||||
- maddy
|
- maddy
|
||||||
@@ -61,9 +61,9 @@ servers:
|
|||||||
assert.Equal(t, "beefyBeef", n.OperationId.Value)
|
assert.Equal(t, "beefyBeef", n.OperationId.Value)
|
||||||
assert.Len(t, n.Parameters.Value, 2)
|
assert.Len(t, n.Parameters.Value, 2)
|
||||||
assert.Equal(t, "a requestBody", n.RequestBody.Value.Description.Value)
|
assert.Equal(t, "a requestBody", n.RequestBody.Value.Description.Value)
|
||||||
assert.Len(t, n.Responses.Value.Codes, 1)
|
assert.Equal(t, 1, n.Responses.Value.Codes.Len())
|
||||||
assert.Equal(t, "an OK response", n.Responses.Value.FindResponseByCode("200").Value.Description.Value)
|
assert.Equal(t, "an OK response", n.Responses.Value.FindResponseByCode("200").Value.Description.Value)
|
||||||
assert.Len(t, n.Callbacks.Value, 1)
|
assert.Equal(t, 1, n.Callbacks.Value.Len())
|
||||||
assert.Equal(t, "a nice callback",
|
assert.Equal(t, "a nice callback",
|
||||||
n.FindCallback("niceCallback").Value.FindExpression("ohISee").Value.Description.Value)
|
n.FindCallback("niceCallback").Value.FindExpression("ohISee").Value.Description.Value)
|
||||||
assert.True(t, n.Deprecated.Value)
|
assert.True(t, n.Deprecated.Value)
|
||||||
@@ -76,7 +76,6 @@ servers:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Build_FailDocs(t *testing.T) {
|
func TestOperation_Build_FailDocs(t *testing.T) {
|
||||||
|
|
||||||
yml := `externalDocs:
|
yml := `externalDocs:
|
||||||
$ref: #borked`
|
$ref: #borked`
|
||||||
|
|
||||||
@@ -93,7 +92,6 @@ func TestOperation_Build_FailDocs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Build_FailParams(t *testing.T) {
|
func TestOperation_Build_FailParams(t *testing.T) {
|
||||||
|
|
||||||
yml := `parameters:
|
yml := `parameters:
|
||||||
$ref: #borked`
|
$ref: #borked`
|
||||||
|
|
||||||
@@ -110,7 +108,6 @@ func TestOperation_Build_FailParams(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Build_FailRequestBody(t *testing.T) {
|
func TestOperation_Build_FailRequestBody(t *testing.T) {
|
||||||
|
|
||||||
yml := `requestBody:
|
yml := `requestBody:
|
||||||
$ref: #borked`
|
$ref: #borked`
|
||||||
|
|
||||||
@@ -127,7 +124,6 @@ func TestOperation_Build_FailRequestBody(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Build_FailResponses(t *testing.T) {
|
func TestOperation_Build_FailResponses(t *testing.T) {
|
||||||
|
|
||||||
yml := `responses:
|
yml := `responses:
|
||||||
$ref: #borked`
|
$ref: #borked`
|
||||||
|
|
||||||
@@ -144,7 +140,6 @@ func TestOperation_Build_FailResponses(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Build_FailCallbacks(t *testing.T) {
|
func TestOperation_Build_FailCallbacks(t *testing.T) {
|
||||||
|
|
||||||
yml := `callbacks:
|
yml := `callbacks:
|
||||||
$ref: #borked`
|
$ref: #borked`
|
||||||
|
|
||||||
@@ -161,7 +156,6 @@ func TestOperation_Build_FailCallbacks(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Build_FailSecurity(t *testing.T) {
|
func TestOperation_Build_FailSecurity(t *testing.T) {
|
||||||
|
|
||||||
yml := `security:
|
yml := `security:
|
||||||
$ref: #borked`
|
$ref: #borked`
|
||||||
|
|
||||||
@@ -178,7 +172,6 @@ func TestOperation_Build_FailSecurity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Build_FailServers(t *testing.T) {
|
func TestOperation_Build_FailServers(t *testing.T) {
|
||||||
|
|
||||||
yml := `servers:
|
yml := `servers:
|
||||||
$ref: #borked`
|
$ref: #borked`
|
||||||
|
|
||||||
@@ -195,7 +188,6 @@ func TestOperation_Build_FailServers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_Hash_n_Grab(t *testing.T) {
|
func TestOperation_Hash_n_Grab(t *testing.T) {
|
||||||
|
|
||||||
yml := `tags:
|
yml := `tags:
|
||||||
- nice
|
- nice
|
||||||
- rice
|
- rice
|
||||||
@@ -282,14 +274,12 @@ x-mint: sweet`
|
|||||||
assert.True(t, n.GetDeprecated().Value)
|
assert.True(t, n.GetDeprecated().Value)
|
||||||
assert.Len(t, n.GetExtensions(), 1)
|
assert.Len(t, n.GetExtensions(), 1)
|
||||||
assert.Len(t, n.GetServers().Value.([]low.ValueReference[*Server]), 1)
|
assert.Len(t, n.GetServers().Value.([]low.ValueReference[*Server]), 1)
|
||||||
assert.Len(t, n.GetCallbacks().Value, 1)
|
assert.Equal(t, 1, n.GetCallbacks().Value.Len())
|
||||||
assert.Len(t, n.GetResponses().Value.(*Responses).Codes, 1)
|
assert.Equal(t, 1, n.GetResponses().Value.(*Responses).Codes.Len())
|
||||||
assert.Nil(t, n.FindSecurityRequirement("I do not exist"))
|
assert.Nil(t, n.FindSecurityRequirement("I do not exist"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOperation_EmptySecurity(t *testing.T) {
|
func TestOperation_EmptySecurity(t *testing.T) {
|
||||||
|
|
||||||
yml := `
|
yml := `
|
||||||
security: []`
|
security: []`
|
||||||
|
|
||||||
@@ -305,5 +295,4 @@ security: []`
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Len(t, n.Security.Value, 0)
|
assert.Len(t, n.Security.Value, 0)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParameter_Build(t *testing.T) {
|
func TestParameter_Build(t *testing.T) {
|
||||||
@@ -172,7 +174,6 @@ func TestParameter_Build_Fail_Content(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParameter_Hash_n_grab(t *testing.T) {
|
func TestParameter_Hash_n_grab(t *testing.T) {
|
||||||
|
|
||||||
yml := `description: michelle, meddy and maddy
|
yml := `description: michelle, meddy and maddy
|
||||||
required: true
|
required: true
|
||||||
deprecated: false
|
deprecated: false
|
||||||
@@ -275,11 +276,11 @@ content:
|
|||||||
assert.True(t, n.GetRequired().Value)
|
assert.True(t, n.GetRequired().Value)
|
||||||
assert.False(t, n.GetDeprecated().Value)
|
assert.False(t, n.GetDeprecated().Value)
|
||||||
assert.False(t, n.GetAllowEmptyValue().Value)
|
assert.False(t, n.GetAllowEmptyValue().Value)
|
||||||
assert.Len(t, n.GetSchema().Value.(*base.SchemaProxy).Schema().Properties.Value, 3)
|
assert.Equal(t, 3, n.GetSchema().Value.(*base.SchemaProxy).Schema().Properties.Value.Len())
|
||||||
assert.Equal(t, "beautiful", n.GetStyle().Value)
|
assert.Equal(t, "beautiful", n.GetStyle().Value)
|
||||||
assert.True(t, n.GetAllowReserved().Value)
|
assert.True(t, n.GetAllowReserved().Value)
|
||||||
assert.True(t, n.GetExplode().Value)
|
assert.True(t, n.GetExplode().Value)
|
||||||
assert.NotNil(t, n.GetExample().Value)
|
assert.NotNil(t, n.GetExample().Value)
|
||||||
assert.Len(t, n.GetExamples().Value.(map[low.KeyReference[string]]low.ValueReference[*base.Example]), 2)
|
assert.Equal(t, 2, orderedmap.Cast[low.KeyReference[string], low.ValueReference[*base.Example]](n.GetExamples().Value).Len())
|
||||||
assert.Len(t, n.GetContent().Value.(map[low.KeyReference[string]]low.ValueReference[*MediaType]), 1)
|
assert.Equal(t, 1, orderedmap.Cast[low.KeyReference[string], low.ValueReference[*MediaType]](n.GetContent().Value).Len())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSecurityRequirement_Build(t *testing.T) {
|
func TestSecurityRequirement_Build(t *testing.T) {
|
||||||
@@ -29,7 +30,7 @@ func TestSecurityRequirement_Build(t *testing.T) {
|
|||||||
err = n.Build(context.Background(), nil, idxNode.Content[0], idx)
|
err = n.Build(context.Background(), nil, idxNode.Content[0], idx)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, n.Requirements.Value, 1)
|
assert.Equal(t, 1, n.Requirements.Value.Len())
|
||||||
assert.Equal(t, "read:me", n.FindRequirement("something")[0].Value)
|
assert.Equal(t, "read:me", n.FindRequirement("something")[0].Value)
|
||||||
assert.Equal(t, "write:me", n.FindRequirement("something")[1].Value)
|
assert.Equal(t, "write:me", n.FindRequirement("something")[1].Value)
|
||||||
assert.Nil(t, n.FindRequirement("none"))
|
assert.Nil(t, n.FindRequirement("none"))
|
||||||
@@ -72,7 +73,6 @@ x-milk: please`
|
|||||||
assert.Equal(t, "please", n.FindExtension("x-milk").Value)
|
assert.Equal(t, "please", n.FindExtension("x-milk").Value)
|
||||||
assert.Equal(t, "https://pb33f.io", n.Flows.Value.Implicit.Value.TokenUrl.Value)
|
assert.Equal(t, "https://pb33f.io", n.Flows.Value.Implicit.Value.TokenUrl.Value)
|
||||||
assert.Len(t, n.GetExtensions(), 1)
|
assert.Len(t, n.GetExtensions(), 1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSecurityScheme_Build_Fail(t *testing.T) {
|
func TestSecurityScheme_Build_Fail(t *testing.T) {
|
||||||
|
|||||||
@@ -5,15 +5,16 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestServer_Build(t *testing.T) {
|
func TestServer_Build(t *testing.T) {
|
||||||
|
|
||||||
yml := `x-coffee: hot
|
yml := `x-coffee: hot
|
||||||
url: https://pb33f.io
|
url: https://pb33f.io
|
||||||
description: high quality software for developers.
|
description: high quality software for developers.
|
||||||
@@ -48,11 +49,9 @@ variables:
|
|||||||
low.GenerateHashString(s.Value))
|
low.GenerateHashString(s.Value))
|
||||||
|
|
||||||
assert.Len(t, n.GetExtensions(), 1)
|
assert.Len(t, n.GetExtensions(), 1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_Build_NoVars(t *testing.T) {
|
func TestServer_Build_NoVars(t *testing.T) {
|
||||||
|
|
||||||
yml := `url: https://pb33f.io
|
yml := `url: https://pb33f.io
|
||||||
description: high quality software for developers.`
|
description: high quality software for developers.`
|
||||||
|
|
||||||
@@ -68,6 +67,5 @@ description: high quality software for developers.`
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "https://pb33f.io", n.URL.Value)
|
assert.Equal(t, "https://pb33f.io", n.URL.Value)
|
||||||
assert.Equal(t, "high quality software for developers.", n.Description.Value)
|
assert.Equal(t, "high quality software for developers.", n.Description.Value)
|
||||||
assert.Len(t, n.Variables.Value, 0)
|
assert.Equal(t, 0, orderedmap.Len(n.Variables.Value))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,9 +42,11 @@ type wrapPair[K comparable, V any] struct {
|
|||||||
*wk8orderedmap.Pair[K, V]
|
*wk8orderedmap.Pair[K, V]
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionFunc[K comparable, V any] func(Pair[K, V]) error
|
type (
|
||||||
type TranslateFunc[IN any, OUT any] func(IN) (OUT, error)
|
ActionFunc[K comparable, V any] func(Pair[K, V]) error
|
||||||
type ResultFunc[V any] func(V) error
|
TranslateFunc[IN any, OUT any] func(IN) (OUT, error)
|
||||||
|
ResultFunc[V any] func(V) error
|
||||||
|
)
|
||||||
|
|
||||||
// New creates an ordered map generic object.
|
// New creates an ordered map generic object.
|
||||||
func New[K comparable, V any]() Map[K, V] {
|
func New[K comparable, V any]() Map[K, V] {
|
||||||
@@ -63,6 +65,10 @@ func (o *wrapOrderedMap[K, V]) GetOrZero(k K) V {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *wrapOrderedMap[K, V]) First() Pair[K, V] {
|
func (o *wrapOrderedMap[K, V]) First() Pair[K, V] {
|
||||||
|
if o == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
pair := o.OrderedMap.Oldest()
|
pair := o.OrderedMap.Oldest()
|
||||||
if pair == nil {
|
if pair == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -76,7 +82,7 @@ func (o *wrapOrderedMap[K, V]) First() Pair[K, V] {
|
|||||||
func NewPair[K comparable, V any](key K, value V) Pair[K, V] {
|
func NewPair[K comparable, V any](key K, value V) Pair[K, V] {
|
||||||
return &wrapPair[K, V]{
|
return &wrapPair[K, V]{
|
||||||
Pair: &wk8orderedmap.Pair[K, V]{
|
Pair: &wk8orderedmap.Pair[K, V]{
|
||||||
Key: key,
|
Key: key,
|
||||||
Value: value,
|
Value: value,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -174,6 +180,20 @@ func First[K comparable, V any](m Map[K, V]) Pair[K, V] {
|
|||||||
return m.First()
|
return m.First()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cast converts `any` to `Map`.
|
||||||
|
func Cast[K comparable, V any](v any) Map[K, V] {
|
||||||
|
if v == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
m, ok := v.(*wrapOrderedMap[K, V])
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
type jobStatus[T any] struct {
|
type jobStatus[T any] struct {
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
result T
|
result T
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ var changeMutex sync.Mutex
|
|||||||
// CreateChange is a generic function that will create a Change of type T, populate all properties if set, and then
|
// CreateChange is a generic function that will create a Change of type T, populate all properties if set, and then
|
||||||
// add a pointer to Change[T] in the slice of Change pointers provided
|
// add a pointer to Change[T] in the slice of Change pointers provided
|
||||||
func CreateChange(changes *[]*Change, changeType int, property string, leftValueNode, rightValueNode *yaml.Node,
|
func CreateChange(changes *[]*Change, changeType int, property string, leftValueNode, rightValueNode *yaml.Node,
|
||||||
breaking bool, originalObject, newObject any) *[]*Change {
|
breaking bool, originalObject, newObject any,
|
||||||
|
) *[]*Change {
|
||||||
// create a new context for the left and right nodes.
|
// create a new context for the left and right nodes.
|
||||||
ctx := CreateContext(leftValueNode, rightValueNode)
|
ctx := CreateContext(leftValueNode, rightValueNode)
|
||||||
c := &Change{
|
c := &Change{
|
||||||
@@ -71,7 +71,8 @@ func CreateContext(l, r *yaml.Node) *ChangeContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func FlattenLowLevelMap[T any](
|
func FlattenLowLevelMap[T any](
|
||||||
lowMap map[low.KeyReference[string]]low.ValueReference[T]) map[string]*low.ValueReference[T] {
|
lowMap map[low.KeyReference[string]]low.ValueReference[T],
|
||||||
|
) map[string]*low.ValueReference[T] {
|
||||||
flat := make(map[string]*low.ValueReference[T])
|
flat := make(map[string]*low.ValueReference[T])
|
||||||
for i := range lowMap {
|
for i := range lowMap {
|
||||||
l := lowMap[i]
|
l := lowMap[i]
|
||||||
@@ -80,6 +81,19 @@ func FlattenLowLevelMap[T any](
|
|||||||
return flat
|
return flat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FlattenLowLevelOrderedMap[T any](
|
||||||
|
lowMap orderedmap.Map[low.KeyReference[string], low.ValueReference[T]],
|
||||||
|
) map[string]*low.ValueReference[T] {
|
||||||
|
flat := make(map[string]*low.ValueReference[T])
|
||||||
|
|
||||||
|
for pair := orderedmap.First(lowMap); pair != nil; pair = pair.Next() {
|
||||||
|
k := pair.Key()
|
||||||
|
l := pair.Value()
|
||||||
|
flat[k.Value] = &l
|
||||||
|
}
|
||||||
|
return flat
|
||||||
|
}
|
||||||
|
|
||||||
// CountBreakingChanges counts the number of changes in a slice that are breaking
|
// CountBreakingChanges counts the number of changes in a slice that are breaking
|
||||||
func CountBreakingChanges(changes []*Change) int {
|
func CountBreakingChanges(changes []*Change) int {
|
||||||
b := 0
|
b := 0
|
||||||
@@ -99,7 +113,8 @@ func CountBreakingChanges(changes []*Change) int {
|
|||||||
// properties like descriptions, summaries and other non-binding values, so a breakingRemove value can be tuned for
|
// properties like descriptions, summaries and other non-binding values, so a breakingRemove value can be tuned for
|
||||||
// these circumstances.
|
// these circumstances.
|
||||||
func CheckForObjectAdditionOrRemoval[T any](l, r map[string]*low.ValueReference[T], label string, changes *[]*Change,
|
func CheckForObjectAdditionOrRemoval[T any](l, r map[string]*low.ValueReference[T], label string, changes *[]*Change,
|
||||||
breakingAdd, breakingRemove bool) {
|
breakingAdd, breakingRemove bool,
|
||||||
|
) {
|
||||||
var left, right T
|
var left, right T
|
||||||
if CheckSpecificObjectRemoved(l, r, label) {
|
if CheckSpecificObjectRemoved(l, r, label) {
|
||||||
left = l[label].GetValue()
|
left = l[label].GetValue()
|
||||||
@@ -129,7 +144,6 @@ func CheckSpecificObjectAdded[T any](l, r map[string]*T, label string) bool {
|
|||||||
// CheckPropertyAdditionOrRemoval
|
// CheckPropertyAdditionOrRemoval
|
||||||
// CheckForModification
|
// CheckForModification
|
||||||
func CheckProperties(properties []*PropertyCheck) {
|
func CheckProperties(properties []*PropertyCheck) {
|
||||||
|
|
||||||
// todo: make this async to really speed things up.
|
// todo: make this async to really speed things up.
|
||||||
for _, n := range properties {
|
for _, n := range properties {
|
||||||
CheckPropertyAdditionOrRemoval(n.LeftNode, n.RightNode, n.Label, n.Changes, n.Breaking, n.Original, n.New)
|
CheckPropertyAdditionOrRemoval(n.LeftNode, n.RightNode, n.Label, n.Changes, n.Breaking, n.Original, n.New)
|
||||||
@@ -139,7 +153,8 @@ func CheckProperties(properties []*PropertyCheck) {
|
|||||||
|
|
||||||
// CheckPropertyAdditionOrRemoval will run both CheckForRemoval (first) and CheckForAddition (second)
|
// CheckPropertyAdditionOrRemoval will run both CheckForRemoval (first) and CheckForAddition (second)
|
||||||
func CheckPropertyAdditionOrRemoval[T any](l, r *yaml.Node,
|
func CheckPropertyAdditionOrRemoval[T any](l, r *yaml.Node,
|
||||||
label string, changes *[]*Change, breaking bool, orig, new T) {
|
label string, changes *[]*Change, breaking bool, orig, new T,
|
||||||
|
) {
|
||||||
CheckForRemoval[T](l, r, label, changes, breaking, orig, new)
|
CheckForRemoval[T](l, r, label, changes, breaking, orig, new)
|
||||||
CheckForAddition[T](l, r, label, changes, breaking, orig, new)
|
CheckForAddition[T](l, r, label, changes, breaking, orig, new)
|
||||||
}
|
}
|
||||||
@@ -238,12 +253,14 @@ func CheckForModification[T any](l, r *yaml.Node, label string, changes *[]*Chan
|
|||||||
// CheckMapForChanges checks a left and right low level map for any additions, subtractions or modifications to
|
// CheckMapForChanges checks a left and right low level map for any additions, subtractions or modifications to
|
||||||
// values. The compareFunc argument should reference the correct comparison function for the generic type.
|
// values. The compareFunc argument should reference the correct comparison function for the generic type.
|
||||||
func CheckMapForChanges[T any, R any](expLeft, expRight orderedmap.Map[low.KeyReference[string], low.ValueReference[T]],
|
func CheckMapForChanges[T any, R any](expLeft, expRight orderedmap.Map[low.KeyReference[string], low.ValueReference[T]],
|
||||||
changes *[]*Change, label string, compareFunc func(l, r T) R) map[string]R {
|
changes *[]*Change, label string, compareFunc func(l, r T) R,
|
||||||
|
) map[string]R {
|
||||||
return CheckMapForChangesWithComp(expLeft, expRight, changes, label, compareFunc, true)
|
return CheckMapForChangesWithComp(expLeft, expRight, changes, label, compareFunc, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckMapForAdditionRemoval[T any](expLeft, expRight orderedmap.Map[low.KeyReference[string], low.ValueReference[T]],
|
func CheckMapForAdditionRemoval[T any](expLeft, expRight orderedmap.Map[low.KeyReference[string], low.ValueReference[T]],
|
||||||
changes *[]*Change, label string) any {
|
changes *[]*Change, label string,
|
||||||
|
) any {
|
||||||
// do nothing
|
// do nothing
|
||||||
doNothing := func(l, r T) any {
|
doNothing := func(l, r T) any {
|
||||||
return nil
|
return nil
|
||||||
@@ -266,8 +283,8 @@ func CheckMapForAdditionRemoval[T any](expLeft, expRight orderedmap.Map[low.KeyR
|
|||||||
// values. The compareFunc argument should reference the correct comparison function for the generic type. The compare
|
// values. The compareFunc argument should reference the correct comparison function for the generic type. The compare
|
||||||
// bit determines if the comparison should be run or not.
|
// bit determines if the comparison should be run or not.
|
||||||
func CheckMapForChangesWithComp[T any, R any](expLeft, expRight orderedmap.Map[low.KeyReference[string], low.ValueReference[T]],
|
func CheckMapForChangesWithComp[T any, R any](expLeft, expRight orderedmap.Map[low.KeyReference[string], low.ValueReference[T]],
|
||||||
changes *[]*Change, label string, compareFunc func(l, r T) R, compare bool) map[string]R {
|
changes *[]*Change, label string, compareFunc func(l, r T) R, compare bool,
|
||||||
|
) map[string]R {
|
||||||
// stop concurrent threads screwing up changes.
|
// stop concurrent threads screwing up changes.
|
||||||
var chLock sync.Mutex
|
var chLock sync.Mutex
|
||||||
|
|
||||||
@@ -331,7 +348,7 @@ func CheckMapForChangesWithComp[T any, R any](expLeft, expRight orderedmap.Map[l
|
|||||||
go checkLeft(k, doneChan, lHashes, rHashes, lValues, rValues)
|
go checkLeft(k, doneChan, lHashes, rHashes, lValues, rValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
//check right example hashes
|
// check right example hashes
|
||||||
for k := range rHashes {
|
for k := range rHashes {
|
||||||
count++
|
count++
|
||||||
go checkRightValue(k, doneChan, lHashes, rValues, changes, label, &chLock)
|
go checkRightValue(k, doneChan, lHashes, rValues, changes, label, &chLock)
|
||||||
@@ -349,8 +366,8 @@ func CheckMapForChangesWithComp[T any, R any](expLeft, expRight orderedmap.Map[l
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkRightValue[T any](k string, doneChan chan bool, f map[string]string, p map[string]low.ValueReference[T],
|
func checkRightValue[T any](k string, doneChan chan bool, f map[string]string, p map[string]low.ValueReference[T],
|
||||||
changes *[]*Change, label string, lock *sync.Mutex) {
|
changes *[]*Change, label string, lock *sync.Mutex,
|
||||||
|
) {
|
||||||
lhash := f[k]
|
lhash := f[k]
|
||||||
if lhash == "" {
|
if lhash == "" {
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
@@ -367,7 +384,8 @@ func checkRightValue[T any](k string, doneChan chan bool, f map[string]string, p
|
|||||||
|
|
||||||
// ExtractStringValueSliceChanges will compare two low level string slices for changes.
|
// ExtractStringValueSliceChanges will compare two low level string slices for changes.
|
||||||
func ExtractStringValueSliceChanges(lParam, rParam []low.ValueReference[string],
|
func ExtractStringValueSliceChanges(lParam, rParam []low.ValueReference[string],
|
||||||
changes *[]*Change, label string, breaking bool) {
|
changes *[]*Change, label string, breaking bool,
|
||||||
|
) {
|
||||||
lKeys := make([]string, len(lParam))
|
lKeys := make([]string, len(lParam))
|
||||||
rKeys := make([]string, len(rParam))
|
rKeys := make([]string, len(rParam))
|
||||||
lValues := make(map[string]low.ValueReference[string])
|
lValues := make(map[string]low.ValueReference[string])
|
||||||
@@ -404,7 +422,8 @@ func ExtractStringValueSliceChanges(lParam, rParam []low.ValueReference[string],
|
|||||||
|
|
||||||
// ExtractRawValueSliceChanges will compare two low level interface{} slices for changes.
|
// ExtractRawValueSliceChanges will compare two low level interface{} slices for changes.
|
||||||
func ExtractRawValueSliceChanges(lParam, rParam []low.ValueReference[any],
|
func ExtractRawValueSliceChanges(lParam, rParam []low.ValueReference[any],
|
||||||
changes *[]*Change, label string, breaking bool) {
|
changes *[]*Change, label string, breaking bool,
|
||||||
|
) {
|
||||||
lKeys := make([]string, len(lParam))
|
lKeys := make([]string, len(lParam))
|
||||||
rKeys := make([]string, len(rParam))
|
rKeys := make([]string, len(rParam))
|
||||||
lValues := make(map[string]low.ValueReference[any])
|
lValues := make(map[string]low.ValueReference[any])
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ func CompareDiscriminator(l, r *base.Discriminator) *DiscriminatorChanges {
|
|||||||
CheckProperties(props)
|
CheckProperties(props)
|
||||||
|
|
||||||
// flatten maps
|
// flatten maps
|
||||||
lMap := FlattenLowLevelMap[string](l.Mapping.Value)
|
lMap := FlattenLowLevelOrderedMap[string](l.Mapping.Value)
|
||||||
rMap := FlattenLowLevelMap[string](r.Mapping.Value)
|
rMap := FlattenLowLevelOrderedMap[string](r.Mapping.Value)
|
||||||
|
|
||||||
// check for removals, modifications and moves
|
// check for removals, modifications and moves
|
||||||
for i := range lMap {
|
for i := range lMap {
|
||||||
@@ -92,5 +92,4 @@ func CompareDiscriminator(l, r *base.Discriminator) *DiscriminatorChanges {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return dc
|
return dc
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package model
|
|||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
|
"github.com/pb33f/libopenapi/orderedmap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OAuthFlowsChanges represents changes found between two OpenAPI OAuthFlows objects.
|
// OAuthFlowsChanges represents changes found between two OpenAPI OAuthFlows objects.
|
||||||
@@ -228,26 +229,26 @@ func CompareOAuthFlow(l, r *v3.OAuthFlow) *OAuthFlowChanges {
|
|||||||
|
|
||||||
CheckProperties(props)
|
CheckProperties(props)
|
||||||
|
|
||||||
for k, v := range l.Scopes.Value {
|
for pair := orderedmap.First(l.Scopes.Value); pair != nil; pair = pair.Next() {
|
||||||
if r != nil && r.FindScope(k.Value) == nil {
|
if r != nil && r.FindScope(pair.Key().Value) == nil {
|
||||||
CreateChange(&changes, ObjectRemoved, v3.Scopes,
|
CreateChange(&changes, ObjectRemoved, v3.Scopes,
|
||||||
v.ValueNode, nil, true,
|
pair.Value().ValueNode, nil, true,
|
||||||
k.Value, nil)
|
pair.Key().Value, nil)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if r != nil && r.FindScope(k.Value) != nil {
|
if r != nil && r.FindScope(pair.Key().Value) != nil {
|
||||||
if v.Value != r.FindScope(k.Value).Value {
|
if pair.Value().Value != r.FindScope(pair.Key().Value).Value {
|
||||||
CreateChange(&changes, Modified, v3.Scopes,
|
CreateChange(&changes, Modified, v3.Scopes,
|
||||||
v.ValueNode, r.FindScope(k.Value).ValueNode, true,
|
pair.Value().ValueNode, r.FindScope(pair.Key().Value).ValueNode, true,
|
||||||
v.Value, r.FindScope(k.Value).Value)
|
pair.Value().Value, r.FindScope(pair.Key().Value).Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for k, v := range r.Scopes.Value {
|
for pair := orderedmap.First(r.Scopes.Value); pair != nil; pair = pair.Next() {
|
||||||
if l != nil && l.FindScope(k.Value) == nil {
|
if l != nil && l.FindScope(pair.Key().Value) == nil {
|
||||||
CreateChange(&changes, ObjectAdded, v3.Scopes,
|
CreateChange(&changes, ObjectAdded, v3.Scopes,
|
||||||
nil, v.ValueNode, false,
|
nil, pair.Value().ValueNode, false,
|
||||||
nil, k.Value)
|
nil, pair.Key().Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
oa := new(OAuthFlowChanges)
|
oa := new(OAuthFlowChanges)
|
||||||
|
|||||||
Reference in New Issue
Block a user