Skip to content

Commit

Permalink
fix: Schema.Minimum and Schema.Maxmium are now float64
Browse files Browse the repository at this point in the history
  • Loading branch information
thrawn01 authored and daveshanley committed Jun 17, 2023
1 parent 06f6b24 commit a09916e
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 42 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
test-operation.yaml
test-operation.yaml
.idea/
24 changes: 12 additions & 12 deletions datamodel/high/base/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ type Schema struct {
SchemaTypeRef string `json:"$schema,omitempty" yaml:"$schema,omitempty"`

// In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean.
// In version 3.1, ExclusiveMaximum is an integer.
ExclusiveMaximum *DynamicValue[bool, int64] `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
// In version 3.1, ExclusiveMaximum is a number.
ExclusiveMaximum *DynamicValue[bool, float64] `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`

// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
// In version 3.1, ExclusiveMinimum is an integer.
ExclusiveMinimum *DynamicValue[bool, int64] `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
// In version 3.1, ExclusiveMinimum is a number.
ExclusiveMinimum *DynamicValue[bool, float64] `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`

// In versions 2 and 3.0, this Type is a single value, so array will only ever have one value
// in version 3.1, Type can be multiple values
Expand Down Expand Up @@ -74,9 +74,9 @@ type Schema struct {
Not *SchemaProxy `json:"not,omitempty" yaml:"not,omitempty"`
Properties map[string]*SchemaProxy `json:"properties,omitempty" yaml:"properties,omitempty"`
Title string `json:"title,omitempty" yaml:"title,omitempty"`
MultipleOf *int64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
Maximum *int64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
Minimum *int64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
MultipleOf *float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
MaxLength *int64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
MinLength *int64 `json:"minLength,omitempty" yaml:"minLength,omitempty"`
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
Expand Down Expand Up @@ -121,26 +121,26 @@ func NewSchema(schema *base.Schema) *Schema {
}
// if we're dealing with a 3.0 spec using a bool
if !schema.ExclusiveMaximum.IsEmpty() && schema.ExclusiveMaximum.Value.IsA() {
s.ExclusiveMaximum = &DynamicValue[bool, int64]{
s.ExclusiveMaximum = &DynamicValue[bool, float64]{
A: schema.ExclusiveMaximum.Value.A,
}
}
// if we're dealing with a 3.1 spec using an int
if !schema.ExclusiveMaximum.IsEmpty() && schema.ExclusiveMaximum.Value.IsB() {
s.ExclusiveMaximum = &DynamicValue[bool, int64]{
s.ExclusiveMaximum = &DynamicValue[bool, float64]{
N: 1,
B: schema.ExclusiveMaximum.Value.B,
}
}
// if we're dealing with a 3.0 spec using a bool
if !schema.ExclusiveMinimum.IsEmpty() && schema.ExclusiveMinimum.Value.IsA() {
s.ExclusiveMinimum = &DynamicValue[bool, int64]{
s.ExclusiveMinimum = &DynamicValue[bool, float64]{
A: schema.ExclusiveMinimum.Value.A,
}
}
// if we're dealing with a 3.1 spec, using an int
if !schema.ExclusiveMinimum.IsEmpty() && schema.ExclusiveMinimum.Value.IsB() {
s.ExclusiveMinimum = &DynamicValue[bool, int64]{
s.ExclusiveMinimum = &DynamicValue[bool, float64]{
N: 1,
B: schema.ExclusiveMinimum.Value.B,
}
Expand Down
42 changes: 32 additions & 10 deletions datamodel/high/base/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,8 @@ required: [cake, fish]`
assert.Nil(t, schemaProxy.GetBuildError())

assert.True(t, compiled.ExclusiveMaximum.A)
assert.Equal(t, int64(123), compiled.Properties["somethingB"].Schema().ExclusiveMinimum.B)
assert.Equal(t, int64(334), compiled.Properties["somethingB"].Schema().ExclusiveMaximum.B)
assert.Equal(t, float64(123), compiled.Properties["somethingB"].Schema().ExclusiveMinimum.B)
assert.Equal(t, float64(334), compiled.Properties["somethingB"].Schema().ExclusiveMaximum.B)
assert.Len(t, compiled.Properties["somethingB"].Schema().Properties["somethingBProp"].Schema().Type, 2)

assert.Equal(t, "nice", compiled.AdditionalProperties.(*SchemaProxy).Schema().Description)
Expand All @@ -515,7 +515,7 @@ required: [cake, fish]`
}

func TestSchemaProxy_GoLow(t *testing.T) {
const ymlComponents = `components:
const ymlComponents = `components:
schemas:
rice:
type: string
Expand Down Expand Up @@ -586,25 +586,47 @@ type: number
assert.Nil(t, highSchema.ExclusiveMaximum)
}

func TestSchemaNumberMultipleOf(t *testing.T) {
func TestSchemaNumberMultipleOfInt(t *testing.T) {
yml := `
type: number
multipleOf: 5
`
highSchema := getHighSchema(t, yml)

value := int64(5)
value := float64(5)
assert.EqualValues(t, &value, highSchema.MultipleOf)
}

func TestSchemaNumberMultipleOfFloat(t *testing.T) {
yml := `
type: number
multipleOf: 0.5
`
highSchema := getHighSchema(t, yml)

value := 0.5
assert.EqualValues(t, &value, highSchema.MultipleOf)
}

func TestSchemaNumberMinimum(t *testing.T) {
func TestSchemaNumberMinimumInt(t *testing.T) {
yml := `
type: number
minimum: 5
`
highSchema := getHighSchema(t, yml)

value := int64(5)
value := float64(5)
assert.EqualValues(t, &value, highSchema.Minimum)
}

func TestSchemaNumberMinimumFloat(t *testing.T) {
yml := `
type: number
minimum: 0.5
`
highSchema := getHighSchema(t, yml)

value := 0.5
assert.EqualValues(t, &value, highSchema.Minimum)
}

Expand All @@ -615,7 +637,7 @@ minimum: 0
`
highSchema := getHighSchema(t, yml)

value := int64(0)
value := float64(0)
assert.EqualValues(t, &value, highSchema.Minimum)
}

Expand All @@ -638,7 +660,7 @@ maximum: 5
`
highSchema := getHighSchema(t, yml)

value := int64(5)
value := float64(5)
assert.EqualValues(t, &value, highSchema.Maximum)
}

Expand All @@ -649,7 +671,7 @@ maximum: 0
`
highSchema := getHighSchema(t, yml)

value := int64(0)
value := float64(0)
assert.EqualValues(t, &value, highSchema.Maximum)
}

Expand Down
30 changes: 15 additions & 15 deletions datamodel/low/base/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ type Schema struct {
SchemaTypeRef low.NodeReference[string]

// In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean.
ExclusiveMaximum low.NodeReference[*SchemaDynamicValue[bool, int64]]
ExclusiveMaximum low.NodeReference[*SchemaDynamicValue[bool, float64]]

// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
ExclusiveMinimum low.NodeReference[*SchemaDynamicValue[bool, int64]]
ExclusiveMinimum low.NodeReference[*SchemaDynamicValue[bool, float64]]

// In versions 2 and 3.0, this Type is a single value, so array will only ever have one value
// in version 3.1, Type can be multiple values
Expand Down Expand Up @@ -94,9 +94,9 @@ type Schema struct {

// Compatible with all versions
Title low.NodeReference[string]
MultipleOf low.NodeReference[int64]
Maximum low.NodeReference[int64]
Minimum low.NodeReference[int64]
MultipleOf low.NodeReference[float64]
Maximum low.NodeReference[float64]
Minimum low.NodeReference[float64]
MaxLength low.NodeReference[int64]
MinLength low.NodeReference[int64]
Pattern low.NodeReference[string]
Expand Down Expand Up @@ -575,18 +575,18 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
if exMinValue != nil {
if utils.IsNodeBoolValue(exMinValue) {
val, _ := strconv.ParseBool(exMinValue.Value)
s.ExclusiveMinimum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
s.ExclusiveMinimum = low.NodeReference[*SchemaDynamicValue[bool, float64]]{
KeyNode: exMinLabel,
ValueNode: exMinValue,
Value: &SchemaDynamicValue[bool, int64]{N: 0, A: val},
Value: &SchemaDynamicValue[bool, float64]{N: 0, A: val},
}
}
if utils.IsNodeIntValue(exMinValue) {
val, _ := strconv.ParseInt(exMinValue.Value, 10, 64)
s.ExclusiveMinimum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
val, _ := strconv.ParseFloat(exMinValue.Value, 64)
s.ExclusiveMinimum = low.NodeReference[*SchemaDynamicValue[bool, float64]]{
KeyNode: exMinLabel,
ValueNode: exMinValue,
Value: &SchemaDynamicValue[bool, int64]{N: 1, B: val},
Value: &SchemaDynamicValue[bool, float64]{N: 1, B: val},
}
}
}
Expand All @@ -596,18 +596,18 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
if exMaxValue != nil {
if utils.IsNodeBoolValue(exMaxValue) {
val, _ := strconv.ParseBool(exMaxValue.Value)
s.ExclusiveMaximum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
s.ExclusiveMaximum = low.NodeReference[*SchemaDynamicValue[bool, float64]]{
KeyNode: exMaxLabel,
ValueNode: exMaxValue,
Value: &SchemaDynamicValue[bool, int64]{N: 0, A: val},
Value: &SchemaDynamicValue[bool, float64]{N: 0, A: val},
}
}
if utils.IsNodeIntValue(exMaxValue) {
val, _ := strconv.ParseInt(exMaxValue.Value, 10, 64)
s.ExclusiveMaximum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
val, _ := strconv.ParseFloat(exMaxValue.Value, 64)
s.ExclusiveMaximum = low.NodeReference[*SchemaDynamicValue[bool, float64]]{
KeyNode: exMaxLabel,
ValueNode: exMaxValue,
Value: &SchemaDynamicValue[bool, int64]{N: 1, B: val},
Value: &SchemaDynamicValue[bool, float64]{N: 1, B: val},
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions datamodel/low/base/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,8 @@ examples:
assert.True(t, sch.ExclusiveMinimum.Value.IsB())
assert.False(t, sch.ExclusiveMinimum.Value.IsA())
assert.True(t, sch.ExclusiveMaximum.Value.IsB())
assert.Equal(t, int64(12), sch.ExclusiveMinimum.Value.B)
assert.Equal(t, int64(13), sch.ExclusiveMaximum.Value.B)
assert.Equal(t, float64(12), sch.ExclusiveMinimum.Value.B)
assert.Equal(t, float64(13), sch.ExclusiveMaximum.Value.B)
assert.Len(t, sch.Examples.Value, 1)
assert.Equal(t, "testing", sch.Examples.Value[0].Value)
assert.Equal(t, "fish64", sch.ContentEncoding.Value)
Expand Down
4 changes: 2 additions & 2 deletions datamodel/low/model_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func SetField(field *reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) er

case reflect.TypeOf(NodeReference[float32]{}):

if utils.IsNodeFloatValue(valueNode) {
if utils.IsNodeNumberValue(valueNode) {
if field.CanSet() {
fv, _ := strconv.ParseFloat(valueNode.Value, 32)
nr := NodeReference[float32]{
Expand All @@ -227,7 +227,7 @@ func SetField(field *reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) er

case reflect.TypeOf(NodeReference[float64]{}):

if utils.IsNodeFloatValue(valueNode) {
if utils.IsNodeNumberValue(valueNode) {
if field.CanSet() {
fv, _ := strconv.ParseFloat(valueNode.Value, 64)
nr := NodeReference[float64]{
Expand Down
8 changes: 8 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,14 @@ func IsNodeFloatValue(node *yaml.Node) bool {
return node.Tag == "!!float"
}

// IsNodeNumberValue will check if a node can be parsed as a float value.
func IsNodeNumberValue(node *yaml.Node) bool {
if node == nil {
return false
}
return IsNodeIntValue(node) || IsNodeFloatValue(node)
}

// IsNodeBoolValue will check is a node is a bool
func IsNodeBoolValue(node *yaml.Node) bool {
if node == nil {
Expand Down
17 changes: 17 additions & 0 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,23 @@ func TestIsNodeFloatValue(t *testing.T) {
assert.False(t, IsNodeFloatValue(n))
}

func TestIsNodeNumberValue(t *testing.T) {
n := &yaml.Node{
Tag: "!!float",
}
assert.True(t, IsNodeNumberValue(n))
n.Tag = "!!pizza"
assert.False(t, IsNodeNumberValue(n))

n = &yaml.Node{
Tag: "!!int",
}
assert.True(t, IsNodeNumberValue(n))
n.Tag = "!!pizza"
assert.False(t, IsNodeNumberValue(n))
assert.False(t, IsNodeNumberValue(nil))
}

func TestIsNodeFloatValue_Nil(t *testing.T) {
assert.False(t, IsNodeFloatValue(nil))
}
Expand Down

0 comments on commit a09916e

Please sign in to comment.