From 1d5e09bd39e130cea81ed9cd47a33bf16d10019f Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Wed, 17 May 2023 14:26:35 +0200 Subject: [PATCH] correct validateType to use reflection and added test for it --- libs/template/schema.go | 8 +++- libs/template/schema_test.go | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/libs/template/schema.go b/libs/template/schema.go index 7b3bcc2f..b5fb35aa 100644 --- a/libs/template/schema.go +++ b/libs/template/schema.go @@ -3,6 +3,8 @@ package template import ( "fmt" "reflect" + + "golang.org/x/exp/slices" ) type Schema map[string]FieldInfo @@ -71,11 +73,13 @@ func validateType(v any, fieldType FieldType) error { return fmt.Errorf("expected type string, but value is %#v", v) } case FieldTypeInt: - if _, ok := v.(int); !ok { + if !slices.Contains([]reflect.Kind{reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64}, + reflect.TypeOf(v).Kind()) { return fmt.Errorf("expected type integer, but value is %#v", v) } case FieldTypeFloat: - if _, ok := v.(float64); !ok { + if !slices.Contains([]reflect.Kind{reflect.Float32, reflect.Float64}, + reflect.TypeOf(v).Kind()) { return fmt.Errorf("expected type float, but value is %#v", v) } case FieldTypeBoolean: diff --git a/libs/template/schema_test.go b/libs/template/schema_test.go index cbb007ac..ad1a69c5 100644 --- a/libs/template/schema_test.go +++ b/libs/template/schema_test.go @@ -89,3 +89,82 @@ func TestTemplateSchemaCastFloatToIntFailsForUnknownTypes(t *testing.T) { err = schema.CastFloatToInt(config) assert.ErrorContains(t, err, "bar is not defined as an input parameter for the template") } + +func TestTemplateSchemaCastFloatToIntFailsWhenWithNonIntValues(t *testing.T) { + // define schema for config + schemaJson := `{ + "foo": { + "type": "integer" + } + }` + var schema Schema + err := json.Unmarshal([]byte(schemaJson), &schema) + require.NoError(t, err) + + // define the config + configJson := `{ + "foo": 1.1 + }` + var config map[string]any + err = json.Unmarshal([]byte(configJson), &config) + require.NoError(t, err) + + err = schema.CastFloatToInt(config) + assert.ErrorContains(t, err, "expected foo to have integer value but it is 1.1") +} + +func TestTemplateSchemaValidateType(t *testing.T) { + // assert validation passing + err := validateType(int(0), FieldTypeInt) + assert.NoError(t, err) + + err = validateType(int32(1), FieldTypeInt) + assert.NoError(t, err) + + err = validateType(int64(1), FieldTypeInt) + assert.NoError(t, err) + + err = validateType(float32(1.1), FieldTypeFloat) + assert.NoError(t, err) + + err = validateType(float64(1.2), FieldTypeFloat) + assert.NoError(t, err) + + err = validateType(false, FieldTypeBoolean) + assert.NoError(t, err) + + err = validateType("abc", FieldTypeString) + assert.NoError(t, err) + + // assert validation failing for integers + err = validateType(float64(1.2), FieldTypeInt) + assert.ErrorContains(t, err, "expected type integer, but value is 1.2") + err = validateType(true, FieldTypeInt) + assert.ErrorContains(t, err, "expected type integer, but value is true") + err = validateType("abc", FieldTypeInt) + assert.ErrorContains(t, err, "expected type integer, but value is \"abc\"") + + // assert validation failing for floats + err = validateType(int(1), FieldTypeFloat) + assert.ErrorContains(t, err, "expected type float, but value is 1") + err = validateType(true, FieldTypeFloat) + assert.ErrorContains(t, err, "expected type float, but value is true") + err = validateType("abc", FieldTypeFloat) + assert.ErrorContains(t, err, "expected type float, but value is \"abc\"") + + // assert validation failing for boolean + err = validateType(int(1), FieldTypeBoolean) + assert.ErrorContains(t, err, "expected type boolean, but value is 1") + err = validateType(float64(1), FieldTypeBoolean) + assert.ErrorContains(t, err, "expected type boolean, but value is 1") + err = validateType("abc", FieldTypeBoolean) + assert.ErrorContains(t, err, "expected type boolean, but value is \"abc\"") + + // assert validation failing for string + err = validateType(int(1), FieldTypeString) + assert.ErrorContains(t, err, "expected type string, but value is 1") + err = validateType(float64(1), FieldTypeString) + assert.ErrorContains(t, err, "expected type string, but value is 1") + err = validateType(false, FieldTypeString) + assert.ErrorContains(t, err, "expected type string, but value is false") +}