fix: Schema.Minimum and Schema.Maxmium are now float64

This commit is contained in:
Derrick J. Wippler
2023-05-30 11:42:41 -05:00
committed by quobix
parent 06f6b243a8
commit a09916eb67
8 changed files with 90 additions and 42 deletions

3
.gitignore vendored
View File

@@ -1 +1,2 @@
test-operation.yaml
test-operation.yaml
.idea/

View File

@@ -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
@@ -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"`
@@ -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,
}

View File

@@ -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)
@@ -515,7 +515,7 @@ required: [cake, fish]`
}
func TestSchemaProxy_GoLow(t *testing.T) {
const ymlComponents = `components:
const ymlComponents = `components:
schemas:
rice:
type: string
@@ -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 TestSchemaNumberMinimum(t *testing.T) {
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 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)
}
@@ -615,7 +637,7 @@ minimum: 0
`
highSchema := getHighSchema(t, yml)
value := int64(0)
value := float64(0)
assert.EqualValues(t, &value, highSchema.Minimum)
}
@@ -638,7 +660,7 @@ maximum: 5
`
highSchema := getHighSchema(t, yml)
value := int64(5)
value := float64(5)
assert.EqualValues(t, &value, highSchema.Maximum)
}
@@ -649,7 +671,7 @@ maximum: 0
`
highSchema := getHighSchema(t, yml)
value := int64(0)
value := float64(0)
assert.EqualValues(t, &value, highSchema.Maximum)
}

View File

@@ -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
@@ -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]
@@ -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},
}
}
}
@@ -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},
}
}
}

View File

@@ -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)

View File

@@ -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]{
@@ -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]{

View File

@@ -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 {

View File

@@ -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))
}