databricks-cli/libs/template/schema_test.go

275 lines
7.4 KiB
Go
Raw Normal View History

package template
import (
"encoding/json"
"testing"
"github.com/databricks/cli/libs/jsonschema"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func testSchema(t *testing.T) *jsonschema.Schema {
schemaJson := `{
"properties": {
"int_val": {
"type": "integer"
},
"float_val": {
"type": "number"
},
"bool_val": {
"type": "boolean"
},
"string_val": {
"type": "string"
}
}
}`
var jsonSchema jsonschema.Schema
err := json.Unmarshal([]byte(schemaJson), &jsonSchema)
require.NoError(t, err)
return &jsonSchema
}
func TestTemplateSchemaIsInteger(t *testing.T) {
assert.False(t, isIntegerValue(1.1))
assert.False(t, isIntegerValue(0.1))
assert.False(t, isIntegerValue(-0.1))
assert.True(t, isIntegerValue(-1.0))
assert.True(t, isIntegerValue(0.0))
assert.True(t, isIntegerValue(2.0))
}
func TestTemplateSchemaCastFloatToInt(t *testing.T) {
// define schema for config
jsonSchema := testSchema(t)
// define the config
configJson := `{
"int_val": 1,
"float_val": 2,
"bool_val": true,
"string_val": "main hoon na"
}`
var config map[string]any
err := json.Unmarshal([]byte(configJson), &config)
require.NoError(t, err)
// assert types before casting, checking that the integer was indeed loaded
// as a floating point
assert.IsType(t, float64(0), config["int_val"])
assert.IsType(t, float64(0), config["float_val"])
assert.IsType(t, true, config["bool_val"])
assert.IsType(t, "abc", config["string_val"])
err = castFloatConfigValuesToInt(config, jsonSchema)
require.NoError(t, err)
// assert type after casting, that the float value was converted to an integer
// for int_val.
assert.IsType(t, int(0), config["int_val"])
assert.IsType(t, float64(0), config["float_val"])
assert.IsType(t, true, config["bool_val"])
assert.IsType(t, "abc", config["string_val"])
}
func TestTemplateSchemaCastFloatToIntFailsForUnknownTypes(t *testing.T) {
// define schema for config
schemaJson := `{
"properties": {
"foo": {
"type": "integer"
}
}
}`
var jsonSchema jsonschema.Schema
err := json.Unmarshal([]byte(schemaJson), &jsonSchema)
require.NoError(t, err)
// define the config
configJson := `{
"bar": true
}`
var config map[string]any
err = json.Unmarshal([]byte(configJson), &config)
require.NoError(t, err)
err = castFloatConfigValuesToInt(config, &jsonSchema)
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 := `{
"properties": {
"foo": {
"type": "integer"
}
}
}`
var jsonSchema jsonschema.Schema
err := json.Unmarshal([]byte(schemaJson), &jsonSchema)
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 = castFloatConfigValuesToInt(config, &jsonSchema)
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), jsonschema.IntegerType)
assert.NoError(t, err)
err = validateType(int32(1), jsonschema.IntegerType)
assert.NoError(t, err)
err = validateType(int64(1), jsonschema.IntegerType)
assert.NoError(t, err)
err = validateType(float32(1.1), jsonschema.NumberType)
assert.NoError(t, err)
err = validateType(float64(1.2), jsonschema.NumberType)
assert.NoError(t, err)
err = validateType(int(1), jsonschema.NumberType)
assert.NoError(t, err)
err = validateType(false, jsonschema.BooleanType)
assert.NoError(t, err)
err = validateType("abc", jsonschema.StringType)
assert.NoError(t, err)
// assert validation failing for integers
err = validateType(float64(1.2), jsonschema.IntegerType)
assert.ErrorContains(t, err, "expected type integer, but value is 1.2")
err = validateType(true, jsonschema.IntegerType)
assert.ErrorContains(t, err, "expected type integer, but value is true")
err = validateType("abc", jsonschema.IntegerType)
assert.ErrorContains(t, err, "expected type integer, but value is \"abc\"")
// assert validation failing for floats
err = validateType(true, jsonschema.NumberType)
assert.ErrorContains(t, err, "expected type float, but value is true")
err = validateType("abc", jsonschema.NumberType)
assert.ErrorContains(t, err, "expected type float, but value is \"abc\"")
// assert validation failing for boolean
err = validateType(int(1), jsonschema.BooleanType)
assert.ErrorContains(t, err, "expected type boolean, but value is 1")
err = validateType(float64(1), jsonschema.BooleanType)
assert.ErrorContains(t, err, "expected type boolean, but value is 1")
err = validateType("abc", jsonschema.BooleanType)
assert.ErrorContains(t, err, "expected type boolean, but value is \"abc\"")
// assert validation failing for string
err = validateType(int(1), jsonschema.StringType)
assert.ErrorContains(t, err, "expected type string, but value is 1")
err = validateType(float64(1), jsonschema.StringType)
assert.ErrorContains(t, err, "expected type string, but value is 1")
err = validateType(false, jsonschema.StringType)
assert.ErrorContains(t, err, "expected type string, but value is false")
}
func TestTemplateSchemaValidateConfig(t *testing.T) {
// define schema for config
jsonSchema := testSchema(t)
// define the config
config := map[string]any{
"int_val": 1,
"float_val": 1.1,
"bool_val": true,
"string_val": "abc",
}
err := validateConfigValueTypes(config, jsonSchema)
assert.NoError(t, err)
}
func TestTemplateSchemaValidateConfigFailsForUnknownField(t *testing.T) {
// define schema for config
jsonSchema := testSchema(t)
// define the config
config := map[string]any{
"foo": 1,
"float_val": 1.1,
"bool_val": true,
"string_val": "abc",
}
err := validateConfigValueTypes(config, jsonSchema)
assert.ErrorContains(t, err, "foo is not defined as an input parameter for the template")
}
func TestTemplateSchemaValidateConfigFailsForWhenIncorrectTypes(t *testing.T) {
// define schema for config
jsonSchema := testSchema(t)
// define the config
config := map[string]any{
"int_val": 1,
"float_val": 1.1,
"bool_val": "true",
"string_val": "abc",
}
err := validateConfigValueTypes(config, jsonSchema)
assert.ErrorContains(t, err, "incorrect type for bool_val. expected type boolean, but value is \"true\"")
}
func TestTemplateSchemaValidateConfigFailsForWhenMissingInputParams(t *testing.T) {
// define schema for config
schemaJson := `{
"properties": {
"int_val": {
"type": "integer"
},
"string_val": {
"type": "string"
}
}
}`
var jsonSchema jsonschema.Schema
err := json.Unmarshal([]byte(schemaJson), &jsonSchema)
require.NoError(t, err)
// define the config
config := map[string]any{
"int_val": 1,
}
err = assignDefaultConfigValues(config, &jsonSchema)
assert.ErrorContains(t, err, "input parameter string_val is not defined in config")
}
func TestTemplateDefaultAssignment(t *testing.T) {
// define schema for config
schemaJson := `{
"properties": {
"foo": {
"type": "integer",
"default": 1
}
}
}`
var jsonSchema jsonschema.Schema
err := json.Unmarshal([]byte(schemaJson), &jsonSchema)
require.NoError(t, err)
// define the config
config := map[string]any{}
err = assignDefaultConfigValues(config, &jsonSchema)
assert.NoError(t, err)
assert.Equal(t, 1.0, config["foo"])
}