Additional properties now supported.

This commit is contained in:
Dave Shanley
2022-08-05 13:20:29 -04:00
parent bdb9aa7c41
commit 4bb6a9ad49
3 changed files with 42 additions and 10 deletions

View File

@@ -5,18 +5,20 @@ import (
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils" "github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"strconv"
"sync" "sync"
) )
const ( const (
PropertiesLabel = "properties" PropertiesLabel = "properties"
ExampleLabel = "example" AdditionalPropertiesLabel = "additionalProperties"
ItemsLabel = "items" ExampleLabel = "example"
AllOfLabel = "allOf" ItemsLabel = "items"
AnyOfLabel = "anyOf" AllOfLabel = "allOf"
OneOfLabel = "oneOf" AnyOfLabel = "anyOf"
NotLabel = "not" OneOfLabel = "oneOf"
DiscriminatorLabel = "discriminator" NotLabel = "not"
DiscriminatorLabel = "discriminator"
) )
type Schema struct { type Schema struct {
@@ -84,6 +86,20 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex, level int) error {
s.Example = low.NodeReference[any]{Value: expNode.Value, KeyNode: expLabel, ValueNode: expNode} s.Example = low.NodeReference[any]{Value: expNode.Value, KeyNode: expLabel, ValueNode: expNode}
} }
_, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content)
if addPNode != nil {
if utils.IsNodeMap(addPNode) {
var props map[string]interface{}
addPNode.Decode(&props)
s.AdditionalProperties = low.NodeReference[any]{Value: props, KeyNode: addPLabel, ValueNode: addPNode}
}
if utils.IsNodeBoolValue(addPNode) {
b, _ := strconv.ParseBool(addPNode.Value)
s.AdditionalProperties = low.NodeReference[any]{Value: b, KeyNode: addPLabel, ValueNode: addPNode}
}
}
// handle discriminator if set. // handle discriminator if set.
_, discLabel, discNode := utils.FindKeyNodeFull(DiscriminatorLabel, root.Content) _, discLabel, discNode := utils.FindKeyNodeFull(DiscriminatorLabel, root.Content)
if discNode != nil { if discNode != nil {

View File

@@ -87,7 +87,11 @@ properties:
somethingBProp: somethingBProp:
type: string type: string
description: something b subprop description: something b subprop
example: picnics are nice.` example: picnics are nice.
additionalProperties:
why: yes
thatIs: true
additionalProperties: true`
var rootNode yaml.Node var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(testSpec), &rootNode) mErr := yaml.Unmarshal([]byte(testSpec), &rootNode)
@@ -100,12 +104,22 @@ properties:
schErr := sch.Build(rootNode.Content[0], nil, 0) schErr := sch.Build(rootNode.Content[0], nil, 0)
assert.NoError(t, schErr) assert.NoError(t, schErr)
assert.Equal(t, "something object", sch.Description.Value) assert.Equal(t, "something object", sch.Description.Value)
assert.True(t, sch.AdditionalProperties.Value.(bool))
assert.Len(t, sch.Properties, 2)
v := sch.FindProperty("somethingB")
assert.NotNil(t, v.Value.AdditionalProperties.Value)
var addProps map[string]interface{}
v.Value.AdditionalProperties.ValueNode.Decode(&addProps)
assert.Equal(t, "yes", addProps["why"])
assert.Equal(t, true, addProps["thatIs"])
// check polymorphic values allOf // check polymorphic values allOf
assert.Equal(t, "an allof thing", sch.AllOf[0].Value.Description.Value) assert.Equal(t, "an allof thing", sch.AllOf[0].Value.Description.Value)
assert.Len(t, sch.AllOf[0].Value.Properties, 2) assert.Len(t, sch.AllOf[0].Value.Properties, 2)
v := sch.AllOf[0].Value.FindProperty("allOfA") v = sch.AllOf[0].Value.FindProperty("allOfA")
assert.NotNil(t, v) assert.NotNil(t, v)
assert.Equal(t, "allOfA description", v.Value.Description.Value) assert.Equal(t, "allOfA description", v.Value.Description.Value)
assert.Equal(t, "allOfAExp", v.Value.Example.Value) assert.Equal(t, "allOfAExp", v.Value.Example.Value)

View File

@@ -244,6 +244,8 @@ func FindKeyNodeFull(key string, nodes []*yaml.Node) (keyNode *yaml.Node, labelN
if i%2 == 0 && key == v.Value { if i%2 == 0 && key == v.Value {
return v, nodes[i], nodes[i+1] // next node is what we need. return v, nodes[i], nodes[i+1] // next node is what we need.
} }
}
for _, v := range nodes {
for x, j := range v.Content { for x, j := range v.Content {
if key == j.Value { if key == j.Value {
if IsNodeMap(v) { if IsNodeMap(v) {