mirror of https://github.com/databricks/cli.git
Rename libs/config -> libs/dyn (#1086)
## Changes The name "dynamic value", or "dyn" for short, is more descriptive than the opaque "config". Also, it conveniently does not alias with other packages in the repository, or (popular ones) elsewhere. (discussed with @andrewnester) ## Tests n/a
This commit is contained in:
parent
a1297d71fd
commit
938eb1600c
|
@ -1,76 +0,0 @@
|
||||||
package config_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPathAppend(t *testing.T) {
|
|
||||||
p := config.NewPath(config.Key("foo"))
|
|
||||||
|
|
||||||
// Single arg.
|
|
||||||
p1 := p.Append(config.Key("bar"))
|
|
||||||
assert.True(t, p1.Equal(config.NewPath(config.Key("foo"), config.Key("bar"))))
|
|
||||||
|
|
||||||
// Multiple args.
|
|
||||||
p2 := p.Append(config.Key("bar"), config.Index(1))
|
|
||||||
assert.True(t, p2.Equal(config.NewPath(config.Key("foo"), config.Key("bar"), config.Index(1))))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathJoin(t *testing.T) {
|
|
||||||
p := config.NewPath(config.Key("foo"))
|
|
||||||
|
|
||||||
// Single arg.
|
|
||||||
p1 := p.Join(config.NewPath(config.Key("bar")))
|
|
||||||
assert.True(t, p1.Equal(config.NewPath(config.Key("foo"), config.Key("bar"))))
|
|
||||||
|
|
||||||
// Multiple args.
|
|
||||||
p2 := p.Join(config.NewPath(config.Key("bar")), config.NewPath(config.Index(1)))
|
|
||||||
assert.True(t, p2.Equal(config.NewPath(config.Key("foo"), config.Key("bar"), config.Index(1))))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathEqualEmpty(t *testing.T) {
|
|
||||||
assert.True(t, config.EmptyPath.Equal(config.EmptyPath))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathEqual(t *testing.T) {
|
|
||||||
p1 := config.NewPath(config.Key("foo"), config.Index(1))
|
|
||||||
p2 := config.NewPath(config.Key("bar"), config.Index(2))
|
|
||||||
assert.False(t, p1.Equal(p2), "expected %q to not equal %q", p1, p2)
|
|
||||||
|
|
||||||
p3 := config.NewPath(config.Key("foo"), config.Index(1))
|
|
||||||
assert.True(t, p1.Equal(p3), "expected %q to equal %q", p1, p3)
|
|
||||||
|
|
||||||
p4 := config.NewPath(config.Key("foo"), config.Index(1), config.Key("bar"), config.Index(2))
|
|
||||||
assert.False(t, p1.Equal(p4), "expected %q to not equal %q", p1, p4)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathHasPrefixEmpty(t *testing.T) {
|
|
||||||
empty := config.EmptyPath
|
|
||||||
nonEmpty := config.NewPath(config.Key("foo"))
|
|
||||||
assert.True(t, empty.HasPrefix(empty))
|
|
||||||
assert.True(t, nonEmpty.HasPrefix(empty))
|
|
||||||
assert.False(t, empty.HasPrefix(nonEmpty))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathHasPrefix(t *testing.T) {
|
|
||||||
p1 := config.NewPath(config.Key("foo"), config.Index(1))
|
|
||||||
p2 := config.NewPath(config.Key("bar"), config.Index(2))
|
|
||||||
assert.False(t, p1.HasPrefix(p2), "expected %q to not have prefix %q", p1, p2)
|
|
||||||
|
|
||||||
p3 := config.NewPath(config.Key("foo"))
|
|
||||||
assert.True(t, p1.HasPrefix(p3), "expected %q to have prefix %q", p1, p3)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathString(t *testing.T) {
|
|
||||||
p1 := config.NewPath(config.Key("foo"), config.Index(1))
|
|
||||||
assert.Equal(t, "foo[1]", p1.String())
|
|
||||||
|
|
||||||
p2 := config.NewPath(config.Key("bar"), config.Index(2), config.Key("baz"))
|
|
||||||
assert.Equal(t, "bar[2].baz", p2.String())
|
|
||||||
|
|
||||||
p3 := config.NewPath(config.Key("foo"), config.Index(1), config.Key("bar"), config.Index(2), config.Key("baz"))
|
|
||||||
assert.Equal(t, "foo[1].bar[2].baz", p3.String())
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@ package diag
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Diagnostic struct {
|
type Diagnostic struct {
|
||||||
|
@ -19,7 +19,7 @@ type Diagnostic struct {
|
||||||
|
|
||||||
// Location is a source code location associated with the diagnostic message.
|
// Location is a source code location associated with the diagnostic message.
|
||||||
// It may be zero if there is no associated location.
|
// It may be zero if there is no associated location.
|
||||||
Location config.Location
|
Location dyn.Location
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorf creates a new error diagnostic.
|
// Errorf creates a new error diagnostic.
|
||||||
|
|
|
@ -3,13 +3,13 @@ package convert
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func assertFromTypedToTypedEqual[T any](t *testing.T, src T) {
|
func assertFromTypedToTypedEqual[T any](t *testing.T, src T) {
|
||||||
nv, err := FromTyped(src, config.NilValue)
|
nv, err := FromTyped(src, dyn.NilValue)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var dst T
|
var dst T
|
|
@ -3,11 +3,11 @@ package convert
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TypeError struct {
|
type TypeError struct {
|
||||||
value config.Value
|
value dyn.Value
|
||||||
msg string
|
msg string
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,18 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FromTyped converts changes made in the typed structure w.r.t. the configuration value
|
// FromTyped converts changes made in the typed structure w.r.t. the configuration value
|
||||||
// back to the configuration value, retaining existing location information where possible.
|
// back to the configuration value, retaining existing location information where possible.
|
||||||
func FromTyped(src any, ref config.Value) (config.Value, error) {
|
func FromTyped(src any, ref dyn.Value) (dyn.Value, error) {
|
||||||
srcv := reflect.ValueOf(src)
|
srcv := reflect.ValueOf(src)
|
||||||
|
|
||||||
// Dereference pointer if necessary
|
// Dereference pointer if necessary
|
||||||
for srcv.Kind() == reflect.Pointer {
|
for srcv.Kind() == reflect.Pointer {
|
||||||
if srcv.IsNil() {
|
if srcv.IsNil() {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
srcv = srcv.Elem()
|
srcv = srcv.Elem()
|
||||||
}
|
}
|
||||||
|
@ -37,53 +37,53 @@ func FromTyped(src any, ref config.Value) (config.Value, error) {
|
||||||
return fromTypedFloat(srcv, ref)
|
return fromTypedFloat(srcv, ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NilValue, fmt.Errorf("unsupported type: %s", srcv.Kind())
|
return dyn.NilValue, fmt.Errorf("unsupported type: %s", srcv.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromTypedStruct(src reflect.Value, ref config.Value) (config.Value, error) {
|
func fromTypedStruct(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
||||||
// Check that the reference value is compatible or nil.
|
// Check that the reference value is compatible or nil.
|
||||||
switch ref.Kind() {
|
switch ref.Kind() {
|
||||||
case config.KindMap, config.KindNil:
|
case dyn.KindMap, dyn.KindNil:
|
||||||
default:
|
default:
|
||||||
return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
out := make(map[string]config.Value)
|
out := make(map[string]dyn.Value)
|
||||||
info := getStructInfo(src.Type())
|
info := getStructInfo(src.Type())
|
||||||
for k, v := range info.FieldValues(src) {
|
for k, v := range info.FieldValues(src) {
|
||||||
// Convert the field taking into account the reference value (may be equal to config.NilValue).
|
// Convert the field taking into account the reference value (may be equal to config.NilValue).
|
||||||
nv, err := FromTyped(v.Interface(), ref.Get(k))
|
nv, err := FromTyped(v.Interface(), ref.Get(k))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Value{}, err
|
return dyn.Value{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if nv != config.NilValue {
|
if nv != dyn.NilValue {
|
||||||
out[k] = nv
|
out[k] = nv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the struct was equal to its zero value, emit a nil.
|
// If the struct was equal to its zero value, emit a nil.
|
||||||
if len(out) == 0 {
|
if len(out) == 0 {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, ref.Location()), nil
|
return dyn.NewValue(out, ref.Location()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromTypedMap(src reflect.Value, ref config.Value) (config.Value, error) {
|
func fromTypedMap(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
||||||
// Check that the reference value is compatible or nil.
|
// Check that the reference value is compatible or nil.
|
||||||
switch ref.Kind() {
|
switch ref.Kind() {
|
||||||
case config.KindMap, config.KindNil:
|
case dyn.KindMap, dyn.KindNil:
|
||||||
default:
|
default:
|
||||||
return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return nil if the map is nil.
|
// Return nil if the map is nil.
|
||||||
if src.IsNil() {
|
if src.IsNil() {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
out := make(map[string]config.Value)
|
out := make(map[string]dyn.Value)
|
||||||
iter := src.MapRange()
|
iter := src.MapRange()
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
k := iter.Key().String()
|
k := iter.Key().String()
|
||||||
|
@ -92,7 +92,7 @@ func fromTypedMap(src reflect.Value, ref config.Value) (config.Value, error) {
|
||||||
// Convert entry taking into account the reference value (may be equal to config.NilValue).
|
// Convert entry taking into account the reference value (may be equal to config.NilValue).
|
||||||
nv, err := FromTyped(v.Interface(), ref.Get(k))
|
nv, err := FromTyped(v.Interface(), ref.Get(k))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Value{}, err
|
return dyn.Value{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every entry is represented, even if it is a nil.
|
// Every entry is represented, even if it is a nil.
|
||||||
|
@ -100,115 +100,115 @@ func fromTypedMap(src reflect.Value, ref config.Value) (config.Value, error) {
|
||||||
out[k] = nv
|
out[k] = nv
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, ref.Location()), nil
|
return dyn.NewValue(out, ref.Location()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromTypedSlice(src reflect.Value, ref config.Value) (config.Value, error) {
|
func fromTypedSlice(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
||||||
// Check that the reference value is compatible or nil.
|
// Check that the reference value is compatible or nil.
|
||||||
switch ref.Kind() {
|
switch ref.Kind() {
|
||||||
case config.KindSequence, config.KindNil:
|
case dyn.KindSequence, dyn.KindNil:
|
||||||
default:
|
default:
|
||||||
return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return nil if the slice is nil.
|
// Return nil if the slice is nil.
|
||||||
if src.IsNil() {
|
if src.IsNil() {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
out := make([]config.Value, src.Len())
|
out := make([]dyn.Value, src.Len())
|
||||||
for i := 0; i < src.Len(); i++ {
|
for i := 0; i < src.Len(); i++ {
|
||||||
v := src.Index(i)
|
v := src.Index(i)
|
||||||
|
|
||||||
// Convert entry taking into account the reference value (may be equal to config.NilValue).
|
// Convert entry taking into account the reference value (may be equal to config.NilValue).
|
||||||
nv, err := FromTyped(v.Interface(), ref.Index(i))
|
nv, err := FromTyped(v.Interface(), ref.Index(i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.Value{}, err
|
return dyn.Value{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i] = nv
|
out[i] = nv
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, ref.Location()), nil
|
return dyn.NewValue(out, ref.Location()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromTypedString(src reflect.Value, ref config.Value) (config.Value, error) {
|
func fromTypedString(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
||||||
switch ref.Kind() {
|
switch ref.Kind() {
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
value := src.String()
|
value := src.String()
|
||||||
if value == ref.MustString() {
|
if value == ref.MustString() {
|
||||||
return ref, nil
|
return ref, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.V(value), nil
|
return dyn.V(value), nil
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
||||||
// Otherwise, we would always include all zero valued fields.
|
// Otherwise, we would always include all zero valued fields.
|
||||||
if src.IsZero() {
|
if src.IsZero() {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
return config.V(src.String()), nil
|
return dyn.V(src.String()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromTypedBool(src reflect.Value, ref config.Value) (config.Value, error) {
|
func fromTypedBool(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
||||||
switch ref.Kind() {
|
switch ref.Kind() {
|
||||||
case config.KindBool:
|
case dyn.KindBool:
|
||||||
value := src.Bool()
|
value := src.Bool()
|
||||||
if value == ref.MustBool() {
|
if value == ref.MustBool() {
|
||||||
return ref, nil
|
return ref, nil
|
||||||
}
|
}
|
||||||
return config.V(value), nil
|
return dyn.V(value), nil
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
||||||
// Otherwise, we would always include all zero valued fields.
|
// Otherwise, we would always include all zero valued fields.
|
||||||
if src.IsZero() {
|
if src.IsZero() {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
return config.V(src.Bool()), nil
|
return dyn.V(src.Bool()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromTypedInt(src reflect.Value, ref config.Value) (config.Value, error) {
|
func fromTypedInt(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
||||||
switch ref.Kind() {
|
switch ref.Kind() {
|
||||||
case config.KindInt:
|
case dyn.KindInt:
|
||||||
value := src.Int()
|
value := src.Int()
|
||||||
if value == ref.MustInt() {
|
if value == ref.MustInt() {
|
||||||
return ref, nil
|
return ref, nil
|
||||||
}
|
}
|
||||||
return config.V(value), nil
|
return dyn.V(value), nil
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
||||||
// Otherwise, we would always include all zero valued fields.
|
// Otherwise, we would always include all zero valued fields.
|
||||||
if src.IsZero() {
|
if src.IsZero() {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
return config.V(src.Int()), nil
|
return dyn.V(src.Int()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromTypedFloat(src reflect.Value, ref config.Value) (config.Value, error) {
|
func fromTypedFloat(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
||||||
switch ref.Kind() {
|
switch ref.Kind() {
|
||||||
case config.KindFloat:
|
case dyn.KindFloat:
|
||||||
value := src.Float()
|
value := src.Float()
|
||||||
if value == ref.MustFloat() {
|
if value == ref.MustFloat() {
|
||||||
return ref, nil
|
return ref, nil
|
||||||
}
|
}
|
||||||
return config.V(value), nil
|
return dyn.V(value), nil
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
// This field is not set in the reference, so we only include it if it has a non-zero value.
|
||||||
// Otherwise, we would always include all zero valued fields.
|
// Otherwise, we would always include all zero valued fields.
|
||||||
if src.IsZero() {
|
if src.IsZero() {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
return config.V(src.Float()), nil
|
return dyn.V(src.Float()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind())
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package convert
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -15,11 +15,11 @@ func TestFromTypedStructZeroFields(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
src := Tmp{}
|
src := Tmp{}
|
||||||
ref := config.NilValue
|
ref := dyn.NilValue
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NilValue, nv)
|
assert.Equal(t, dyn.NilValue, nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedStructSetFields(t *testing.T) {
|
func TestFromTypedStructSetFields(t *testing.T) {
|
||||||
|
@ -33,12 +33,12 @@ func TestFromTypedStructSetFields(t *testing.T) {
|
||||||
Bar: "bar",
|
Bar: "bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := config.NilValue
|
ref := dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(map[string]config.Value{
|
assert.Equal(t, dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("foo"),
|
"foo": dyn.V("foo"),
|
||||||
"bar": config.V("bar"),
|
"bar": dyn.V("bar"),
|
||||||
}), nv)
|
}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,45 +53,45 @@ func TestFromTypedStructSetFieldsRetainLocationIfUnchanged(t *testing.T) {
|
||||||
Bar: "qux",
|
Bar: "qux",
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := config.V(map[string]config.Value{
|
ref := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.NewValue("bar", config.Location{File: "foo"}),
|
"foo": dyn.NewValue("bar", dyn.Location{File: "foo"}),
|
||||||
"bar": config.NewValue("baz", config.Location{File: "bar"}),
|
"bar": dyn.NewValue("baz", dyn.Location{File: "bar"}),
|
||||||
})
|
})
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Assert foo has retained its location.
|
// Assert foo has retained its location.
|
||||||
assert.Equal(t, config.NewValue("bar", config.Location{File: "foo"}), nv.Get("foo"))
|
assert.Equal(t, dyn.NewValue("bar", dyn.Location{File: "foo"}), nv.Get("foo"))
|
||||||
|
|
||||||
// Assert bar lost its location (because it was overwritten).
|
// Assert bar lost its location (because it was overwritten).
|
||||||
assert.Equal(t, config.NewValue("qux", config.Location{}), nv.Get("bar"))
|
assert.Equal(t, dyn.NewValue("qux", dyn.Location{}), nv.Get("bar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedMapNil(t *testing.T) {
|
func TestFromTypedMapNil(t *testing.T) {
|
||||||
var src map[string]string = nil
|
var src map[string]string = nil
|
||||||
|
|
||||||
ref := config.V(map[string]config.Value{
|
ref := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NilValue, nv)
|
assert.Equal(t, dyn.NilValue, nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedMapEmpty(t *testing.T) {
|
func TestFromTypedMapEmpty(t *testing.T) {
|
||||||
var src = map[string]string{}
|
var src = map[string]string{}
|
||||||
|
|
||||||
ref := config.V(map[string]config.Value{
|
ref := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(map[string]config.Value{}), nv)
|
assert.Equal(t, dyn.V(map[string]dyn.Value{}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedMapNonEmpty(t *testing.T) {
|
func TestFromTypedMapNonEmpty(t *testing.T) {
|
||||||
|
@ -100,12 +100,12 @@ func TestFromTypedMapNonEmpty(t *testing.T) {
|
||||||
"bar": "bar",
|
"bar": "bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := config.NilValue
|
ref := dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(map[string]config.Value{
|
assert.Equal(t, dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("foo"),
|
"foo": dyn.V("foo"),
|
||||||
"bar": config.V("bar"),
|
"bar": dyn.V("bar"),
|
||||||
}), nv)
|
}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,19 +115,19 @@ func TestFromTypedMapNonEmptyRetainLocationIfUnchanged(t *testing.T) {
|
||||||
"bar": "qux",
|
"bar": "qux",
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := config.V(map[string]config.Value{
|
ref := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.NewValue("bar", config.Location{File: "foo"}),
|
"foo": dyn.NewValue("bar", dyn.Location{File: "foo"}),
|
||||||
"bar": config.NewValue("baz", config.Location{File: "bar"}),
|
"bar": dyn.NewValue("baz", dyn.Location{File: "bar"}),
|
||||||
})
|
})
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Assert foo has retained its location.
|
// Assert foo has retained its location.
|
||||||
assert.Equal(t, config.NewValue("bar", config.Location{File: "foo"}), nv.Get("foo"))
|
assert.Equal(t, dyn.NewValue("bar", dyn.Location{File: "foo"}), nv.Get("foo"))
|
||||||
|
|
||||||
// Assert bar lost its location (because it was overwritten).
|
// Assert bar lost its location (because it was overwritten).
|
||||||
assert.Equal(t, config.NewValue("qux", config.Location{}), nv.Get("bar"))
|
assert.Equal(t, dyn.NewValue("qux", dyn.Location{}), nv.Get("bar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedMapFieldWithZeroValue(t *testing.T) {
|
func TestFromTypedMapFieldWithZeroValue(t *testing.T) {
|
||||||
|
@ -135,38 +135,38 @@ func TestFromTypedMapFieldWithZeroValue(t *testing.T) {
|
||||||
"foo": "",
|
"foo": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := config.NilValue
|
ref := dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(map[string]config.Value{
|
assert.Equal(t, dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.NilValue,
|
"foo": dyn.NilValue,
|
||||||
}), nv)
|
}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedSliceNil(t *testing.T) {
|
func TestFromTypedSliceNil(t *testing.T) {
|
||||||
var src []string = nil
|
var src []string = nil
|
||||||
|
|
||||||
ref := config.V([]config.Value{
|
ref := dyn.V([]dyn.Value{
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
config.V("baz"),
|
dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NilValue, nv)
|
assert.Equal(t, dyn.NilValue, nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedSliceEmpty(t *testing.T) {
|
func TestFromTypedSliceEmpty(t *testing.T) {
|
||||||
var src = []string{}
|
var src = []string{}
|
||||||
|
|
||||||
ref := config.V([]config.Value{
|
ref := dyn.V([]dyn.Value{
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
config.V("baz"),
|
dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V([]config.Value{}), nv)
|
assert.Equal(t, dyn.V([]dyn.Value{}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedSliceNonEmpty(t *testing.T) {
|
func TestFromTypedSliceNonEmpty(t *testing.T) {
|
||||||
|
@ -175,12 +175,12 @@ func TestFromTypedSliceNonEmpty(t *testing.T) {
|
||||||
"bar",
|
"bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := config.NilValue
|
ref := dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V([]config.Value{
|
assert.Equal(t, dyn.V([]dyn.Value{
|
||||||
config.V("foo"),
|
dyn.V("foo"),
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
}), nv)
|
}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,205 +190,205 @@ func TestFromTypedSliceNonEmptyRetainLocationIfUnchanged(t *testing.T) {
|
||||||
"bar",
|
"bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := config.V([]config.Value{
|
ref := dyn.V([]dyn.Value{
|
||||||
config.NewValue("foo", config.Location{File: "foo"}),
|
dyn.NewValue("foo", dyn.Location{File: "foo"}),
|
||||||
config.NewValue("baz", config.Location{File: "baz"}),
|
dyn.NewValue("baz", dyn.Location{File: "baz"}),
|
||||||
})
|
})
|
||||||
|
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Assert foo has retained its location.
|
// Assert foo has retained its location.
|
||||||
assert.Equal(t, config.NewValue("foo", config.Location{File: "foo"}), nv.Index(0))
|
assert.Equal(t, dyn.NewValue("foo", dyn.Location{File: "foo"}), nv.Index(0))
|
||||||
|
|
||||||
// Assert bar lost its location (because it was overwritten).
|
// Assert bar lost its location (because it was overwritten).
|
||||||
assert.Equal(t, config.NewValue("bar", config.Location{}), nv.Index(1))
|
assert.Equal(t, dyn.NewValue("bar", dyn.Location{}), nv.Index(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedStringEmpty(t *testing.T) {
|
func TestFromTypedStringEmpty(t *testing.T) {
|
||||||
var src string
|
var src string
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NilValue, nv)
|
assert.Equal(t, dyn.NilValue, nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedStringEmptyOverwrite(t *testing.T) {
|
func TestFromTypedStringEmptyOverwrite(t *testing.T) {
|
||||||
var src string
|
var src string
|
||||||
var ref = config.V("old")
|
var ref = dyn.V("old")
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(""), nv)
|
assert.Equal(t, dyn.V(""), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedStringNonEmpty(t *testing.T) {
|
func TestFromTypedStringNonEmpty(t *testing.T) {
|
||||||
var src string = "new"
|
var src string = "new"
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V("new"), nv)
|
assert.Equal(t, dyn.V("new"), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedStringNonEmptyOverwrite(t *testing.T) {
|
func TestFromTypedStringNonEmptyOverwrite(t *testing.T) {
|
||||||
var src string = "new"
|
var src string = "new"
|
||||||
var ref = config.V("old")
|
var ref = dyn.V("old")
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V("new"), nv)
|
assert.Equal(t, dyn.V("new"), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedStringRetainsLocationsIfUnchanged(t *testing.T) {
|
func TestFromTypedStringRetainsLocationsIfUnchanged(t *testing.T) {
|
||||||
var src string = "foo"
|
var src string = "foo"
|
||||||
var ref = config.NewValue("foo", config.Location{File: "foo"})
|
var ref = dyn.NewValue("foo", dyn.Location{File: "foo"})
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NewValue("foo", config.Location{File: "foo"}), nv)
|
assert.Equal(t, dyn.NewValue("foo", dyn.Location{File: "foo"}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedStringTypeError(t *testing.T) {
|
func TestFromTypedStringTypeError(t *testing.T) {
|
||||||
var src string = "foo"
|
var src string = "foo"
|
||||||
var ref = config.V(1234)
|
var ref = dyn.V(1234)
|
||||||
_, err := FromTyped(src, ref)
|
_, err := FromTyped(src, ref)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedBoolEmpty(t *testing.T) {
|
func TestFromTypedBoolEmpty(t *testing.T) {
|
||||||
var src bool
|
var src bool
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NilValue, nv)
|
assert.Equal(t, dyn.NilValue, nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedBoolEmptyOverwrite(t *testing.T) {
|
func TestFromTypedBoolEmptyOverwrite(t *testing.T) {
|
||||||
var src bool
|
var src bool
|
||||||
var ref = config.V(true)
|
var ref = dyn.V(true)
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(false), nv)
|
assert.Equal(t, dyn.V(false), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedBoolNonEmpty(t *testing.T) {
|
func TestFromTypedBoolNonEmpty(t *testing.T) {
|
||||||
var src bool = true
|
var src bool = true
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(true), nv)
|
assert.Equal(t, dyn.V(true), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedBoolNonEmptyOverwrite(t *testing.T) {
|
func TestFromTypedBoolNonEmptyOverwrite(t *testing.T) {
|
||||||
var src bool = true
|
var src bool = true
|
||||||
var ref = config.V(false)
|
var ref = dyn.V(false)
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(true), nv)
|
assert.Equal(t, dyn.V(true), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedBoolRetainsLocationsIfUnchanged(t *testing.T) {
|
func TestFromTypedBoolRetainsLocationsIfUnchanged(t *testing.T) {
|
||||||
var src bool = true
|
var src bool = true
|
||||||
var ref = config.NewValue(true, config.Location{File: "foo"})
|
var ref = dyn.NewValue(true, dyn.Location{File: "foo"})
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NewValue(true, config.Location{File: "foo"}), nv)
|
assert.Equal(t, dyn.NewValue(true, dyn.Location{File: "foo"}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedBoolTypeError(t *testing.T) {
|
func TestFromTypedBoolTypeError(t *testing.T) {
|
||||||
var src bool = true
|
var src bool = true
|
||||||
var ref = config.V("string")
|
var ref = dyn.V("string")
|
||||||
_, err := FromTyped(src, ref)
|
_, err := FromTyped(src, ref)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedIntEmpty(t *testing.T) {
|
func TestFromTypedIntEmpty(t *testing.T) {
|
||||||
var src int
|
var src int
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NilValue, nv)
|
assert.Equal(t, dyn.NilValue, nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedIntEmptyOverwrite(t *testing.T) {
|
func TestFromTypedIntEmptyOverwrite(t *testing.T) {
|
||||||
var src int
|
var src int
|
||||||
var ref = config.V(1234)
|
var ref = dyn.V(1234)
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(int64(0)), nv)
|
assert.Equal(t, dyn.V(int64(0)), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedIntNonEmpty(t *testing.T) {
|
func TestFromTypedIntNonEmpty(t *testing.T) {
|
||||||
var src int = 1234
|
var src int = 1234
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(int64(1234)), nv)
|
assert.Equal(t, dyn.V(int64(1234)), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedIntNonEmptyOverwrite(t *testing.T) {
|
func TestFromTypedIntNonEmptyOverwrite(t *testing.T) {
|
||||||
var src int = 1234
|
var src int = 1234
|
||||||
var ref = config.V(1233)
|
var ref = dyn.V(1233)
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(int64(1234)), nv)
|
assert.Equal(t, dyn.V(int64(1234)), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedIntRetainsLocationsIfUnchanged(t *testing.T) {
|
func TestFromTypedIntRetainsLocationsIfUnchanged(t *testing.T) {
|
||||||
var src int = 1234
|
var src int = 1234
|
||||||
var ref = config.NewValue(1234, config.Location{File: "foo"})
|
var ref = dyn.NewValue(1234, dyn.Location{File: "foo"})
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NewValue(1234, config.Location{File: "foo"}), nv)
|
assert.Equal(t, dyn.NewValue(1234, dyn.Location{File: "foo"}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedIntTypeError(t *testing.T) {
|
func TestFromTypedIntTypeError(t *testing.T) {
|
||||||
var src int = 1234
|
var src int = 1234
|
||||||
var ref = config.V("string")
|
var ref = dyn.V("string")
|
||||||
_, err := FromTyped(src, ref)
|
_, err := FromTyped(src, ref)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedFloatEmpty(t *testing.T) {
|
func TestFromTypedFloatEmpty(t *testing.T) {
|
||||||
var src float64
|
var src float64
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NilValue, nv)
|
assert.Equal(t, dyn.NilValue, nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedFloatEmptyOverwrite(t *testing.T) {
|
func TestFromTypedFloatEmptyOverwrite(t *testing.T) {
|
||||||
var src float64
|
var src float64
|
||||||
var ref = config.V(1.23)
|
var ref = dyn.V(1.23)
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(0.0), nv)
|
assert.Equal(t, dyn.V(0.0), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedFloatNonEmpty(t *testing.T) {
|
func TestFromTypedFloatNonEmpty(t *testing.T) {
|
||||||
var src float64 = 1.23
|
var src float64 = 1.23
|
||||||
var ref = config.NilValue
|
var ref = dyn.NilValue
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(1.23), nv)
|
assert.Equal(t, dyn.V(1.23), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedFloatNonEmptyOverwrite(t *testing.T) {
|
func TestFromTypedFloatNonEmptyOverwrite(t *testing.T) {
|
||||||
var src float64 = 1.23
|
var src float64 = 1.23
|
||||||
var ref = config.V(1.24)
|
var ref = dyn.V(1.24)
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.V(1.23), nv)
|
assert.Equal(t, dyn.V(1.23), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedFloatRetainsLocationsIfUnchanged(t *testing.T) {
|
func TestFromTypedFloatRetainsLocationsIfUnchanged(t *testing.T) {
|
||||||
var src float64 = 1.23
|
var src float64 = 1.23
|
||||||
var ref = config.NewValue(1.23, config.Location{File: "foo"})
|
var ref = dyn.NewValue(1.23, dyn.Location{File: "foo"})
|
||||||
nv, err := FromTyped(src, ref)
|
nv, err := FromTyped(src, ref)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, config.NewValue(1.23, config.Location{File: "foo"}), nv)
|
assert.Equal(t, dyn.NewValue(1.23, dyn.Location{File: "foo"}), nv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTypedFloatTypeError(t *testing.T) {
|
func TestFromTypedFloatTypeError(t *testing.T) {
|
||||||
var src float64 = 1.23
|
var src float64 = 1.23
|
||||||
var ref = config.V("string")
|
var ref = dyn.V("string")
|
||||||
_, err := FromTyped(src, ref)
|
_, err := FromTyped(src, ref)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
|
@ -5,15 +5,15 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
|
||||||
"github.com/databricks/cli/libs/diag"
|
"github.com/databricks/cli/libs/diag"
|
||||||
|
"github.com/databricks/cli/libs/dyn"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Normalize(dst any, src config.Value) (config.Value, diag.Diagnostics) {
|
func Normalize(dst any, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
return normalizeType(reflect.TypeOf(dst), src)
|
return normalizeType(reflect.TypeOf(dst), src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeType(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeType(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
for typ.Kind() == reflect.Pointer {
|
for typ.Kind() == reflect.Pointer {
|
||||||
typ = typ.Elem()
|
typ = typ.Elem()
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,10 @@ func normalizeType(typ reflect.Type, src config.Value) (config.Value, diag.Diagn
|
||||||
return normalizeFloat(typ, src)
|
return normalizeFloat(typ, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NilValue, diag.Errorf("unsupported type: %s", typ.Kind())
|
return dyn.NilValue, diag.Errorf("unsupported type: %s", typ.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func typeMismatch(expected config.Kind, src config.Value) diag.Diagnostic {
|
func typeMismatch(expected dyn.Kind, src dyn.Value) diag.Diagnostic {
|
||||||
return diag.Diagnostic{
|
return diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: fmt.Sprintf("expected %s, found %s", expected, src.Kind()),
|
Summary: fmt.Sprintf("expected %s, found %s", expected, src.Kind()),
|
||||||
|
@ -46,12 +46,12 @@ func typeMismatch(expected config.Kind, src config.Value) diag.Diagnostic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeStruct(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeStruct(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindMap:
|
case dyn.KindMap:
|
||||||
out := make(map[string]config.Value)
|
out := make(map[string]dyn.Value)
|
||||||
info := getStructInfo(typ)
|
info := getStructInfo(typ)
|
||||||
for k, v := range src.MustMap() {
|
for k, v := range src.MustMap() {
|
||||||
index, ok := info.Fields[k]
|
index, ok := info.Fields[k]
|
||||||
|
@ -77,20 +77,20 @@ func normalizeStruct(typ reflect.Type, src config.Value) (config.Value, diag.Dia
|
||||||
out[k] = v
|
out[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, src.Location()), diags
|
return dyn.NewValue(out, src.Location()), diags
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
return src, diags
|
return src, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindMap, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindMap, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeMap(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeMap(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindMap:
|
case dyn.KindMap:
|
||||||
out := make(map[string]config.Value)
|
out := make(map[string]dyn.Value)
|
||||||
for k, v := range src.MustMap() {
|
for k, v := range src.MustMap() {
|
||||||
// Normalize the value according to the map element type.
|
// Normalize the value according to the map element type.
|
||||||
v, err := normalizeType(typ.Elem(), v)
|
v, err := normalizeType(typ.Elem(), v)
|
||||||
|
@ -105,20 +105,20 @@ func normalizeMap(typ reflect.Type, src config.Value) (config.Value, diag.Diagno
|
||||||
out[k] = v
|
out[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, src.Location()), diags
|
return dyn.NewValue(out, src.Location()), diags
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
return src, diags
|
return src, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindMap, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindMap, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeSlice(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeSlice(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindSequence:
|
case dyn.KindSequence:
|
||||||
out := make([]config.Value, 0, len(src.MustSequence()))
|
out := make([]dyn.Value, 0, len(src.MustSequence()))
|
||||||
for _, v := range src.MustSequence() {
|
for _, v := range src.MustSequence() {
|
||||||
// Normalize the value according to the slice element type.
|
// Normalize the value according to the slice element type.
|
||||||
v, err := normalizeType(typ.Elem(), v)
|
v, err := normalizeType(typ.Elem(), v)
|
||||||
|
@ -133,42 +133,42 @@ func normalizeSlice(typ reflect.Type, src config.Value) (config.Value, diag.Diag
|
||||||
out = append(out, v)
|
out = append(out, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, src.Location()), diags
|
return dyn.NewValue(out, src.Location()), diags
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
return src, diags
|
return src, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindSequence, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindSequence, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeString(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeString(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
var out string
|
var out string
|
||||||
|
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
out = src.MustString()
|
out = src.MustString()
|
||||||
case config.KindBool:
|
case dyn.KindBool:
|
||||||
out = strconv.FormatBool(src.MustBool())
|
out = strconv.FormatBool(src.MustBool())
|
||||||
case config.KindInt:
|
case dyn.KindInt:
|
||||||
out = strconv.FormatInt(src.MustInt(), 10)
|
out = strconv.FormatInt(src.MustInt(), 10)
|
||||||
case config.KindFloat:
|
case dyn.KindFloat:
|
||||||
out = strconv.FormatFloat(src.MustFloat(), 'f', -1, 64)
|
out = strconv.FormatFloat(src.MustFloat(), 'f', -1, 64)
|
||||||
default:
|
default:
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindString, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindString, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, src.Location()), diags
|
return dyn.NewValue(out, src.Location()), diags
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeBool(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeBool(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
var out bool
|
var out bool
|
||||||
|
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindBool:
|
case dyn.KindBool:
|
||||||
out = src.MustBool()
|
out = src.MustBool()
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
// See https://github.com/go-yaml/yaml/blob/f6f7691b1fdeb513f56608cd2c32c51f8194bf51/decode.go#L684-L693.
|
// See https://github.com/go-yaml/yaml/blob/f6f7691b1fdeb513f56608cd2c32c51f8194bf51/decode.go#L684-L693.
|
||||||
switch src.MustString() {
|
switch src.MustString() {
|
||||||
case "true", "y", "Y", "yes", "Yes", "YES", "on", "On", "ON":
|
case "true", "y", "Y", "yes", "Yes", "YES", "on", "On", "ON":
|
||||||
|
@ -177,59 +177,59 @@ func normalizeBool(typ reflect.Type, src config.Value) (config.Value, diag.Diagn
|
||||||
out = false
|
out = false
|
||||||
default:
|
default:
|
||||||
// Cannot interpret as a boolean.
|
// Cannot interpret as a boolean.
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindBool, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindBool, src))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindBool, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindBool, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, src.Location()), diags
|
return dyn.NewValue(out, src.Location()), diags
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeInt(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeInt(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
var out int64
|
var out int64
|
||||||
|
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindInt:
|
case dyn.KindInt:
|
||||||
out = src.MustInt()
|
out = src.MustInt()
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
var err error
|
var err error
|
||||||
out, err = strconv.ParseInt(src.MustString(), 10, 64)
|
out, err = strconv.ParseInt(src.MustString(), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, diags.Append(diag.Diagnostic{
|
return dyn.NilValue, diags.Append(diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: fmt.Sprintf("cannot parse %q as an integer", src.MustString()),
|
Summary: fmt.Sprintf("cannot parse %q as an integer", src.MustString()),
|
||||||
Location: src.Location(),
|
Location: src.Location(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindInt, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindInt, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, src.Location()), diags
|
return dyn.NewValue(out, src.Location()), diags
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeFloat(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) {
|
func normalizeFloat(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
var out float64
|
var out float64
|
||||||
|
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindFloat:
|
case dyn.KindFloat:
|
||||||
out = src.MustFloat()
|
out = src.MustFloat()
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
var err error
|
var err error
|
||||||
out, err = strconv.ParseFloat(src.MustString(), 64)
|
out, err = strconv.ParseFloat(src.MustString(), 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, diags.Append(diag.Diagnostic{
|
return dyn.NilValue, diags.Append(diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: fmt.Sprintf("cannot parse %q as a floating point number", src.MustString()),
|
Summary: fmt.Sprintf("cannot parse %q as a floating point number", src.MustString()),
|
||||||
Location: src.Location(),
|
Location: src.Location(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return config.NilValue, diags.Append(typeMismatch(config.KindFloat, src))
|
return dyn.NilValue, diags.Append(typeMismatch(dyn.KindFloat, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, src.Location()), diags
|
return dyn.NewValue(out, src.Location()), diags
|
||||||
}
|
}
|
|
@ -3,8 +3,8 @@ package convert
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
|
||||||
"github.com/databricks/cli/libs/diag"
|
"github.com/databricks/cli/libs/diag"
|
||||||
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ func TestNormalizeStruct(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var typ Tmp
|
var typ Tmp
|
||||||
vin := config.V(map[string]config.Value{
|
vin := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
|
@ -32,9 +32,9 @@ func TestNormalizeStructElementDiagnostic(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var typ Tmp
|
var typ Tmp
|
||||||
vin := config.V(map[string]config.Value{
|
vin := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V(map[string]config.Value{"an": config.V("error")}),
|
"bar": dyn.V(map[string]dyn.Value{"an": dyn.V("error")}),
|
||||||
})
|
})
|
||||||
|
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
|
@ -42,7 +42,7 @@ func TestNormalizeStructElementDiagnostic(t *testing.T) {
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: `expected string, found map`,
|
Summary: `expected string, found map`,
|
||||||
Location: config.Location{},
|
Location: dyn.Location{},
|
||||||
}, err[0])
|
}, err[0])
|
||||||
|
|
||||||
// Elements that encounter an error during normalization are dropped.
|
// Elements that encounter an error during normalization are dropped.
|
||||||
|
@ -57,9 +57,9 @@ func TestNormalizeStructUnknownField(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var typ Tmp
|
var typ Tmp
|
||||||
vin := config.V(map[string]config.Value{
|
vin := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
|
@ -82,7 +82,7 @@ func TestNormalizeStructNil(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var typ Tmp
|
var typ Tmp
|
||||||
vin := config.NilValue
|
vin := dyn.NilValue
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, vin, vout)
|
assert.Equal(t, vin, vout)
|
||||||
|
@ -94,7 +94,7 @@ func TestNormalizeStructError(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var typ Tmp
|
var typ Tmp
|
||||||
vin := config.V("string")
|
vin := dyn.V("string")
|
||||||
_, err := Normalize(typ, vin)
|
_, err := Normalize(typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -106,9 +106,9 @@ func TestNormalizeStructError(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeMap(t *testing.T) {
|
func TestNormalizeMap(t *testing.T) {
|
||||||
var typ map[string]string
|
var typ map[string]string
|
||||||
vin := config.V(map[string]config.Value{
|
vin := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
|
@ -118,9 +118,9 @@ func TestNormalizeMap(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeMapElementDiagnostic(t *testing.T) {
|
func TestNormalizeMapElementDiagnostic(t *testing.T) {
|
||||||
var typ map[string]string
|
var typ map[string]string
|
||||||
vin := config.V(map[string]config.Value{
|
vin := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V(map[string]config.Value{"an": config.V("error")}),
|
"bar": dyn.V(map[string]dyn.Value{"an": dyn.V("error")}),
|
||||||
})
|
})
|
||||||
|
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
|
@ -128,7 +128,7 @@ func TestNormalizeMapElementDiagnostic(t *testing.T) {
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: `expected string, found map`,
|
Summary: `expected string, found map`,
|
||||||
Location: config.Location{},
|
Location: dyn.Location{},
|
||||||
}, err[0])
|
}, err[0])
|
||||||
|
|
||||||
// Elements that encounter an error during normalization are dropped.
|
// Elements that encounter an error during normalization are dropped.
|
||||||
|
@ -139,7 +139,7 @@ func TestNormalizeMapElementDiagnostic(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeMapNil(t *testing.T) {
|
func TestNormalizeMapNil(t *testing.T) {
|
||||||
var typ map[string]string
|
var typ map[string]string
|
||||||
vin := config.NilValue
|
vin := dyn.NilValue
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, vin, vout)
|
assert.Equal(t, vin, vout)
|
||||||
|
@ -147,7 +147,7 @@ func TestNormalizeMapNil(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeMapError(t *testing.T) {
|
func TestNormalizeMapError(t *testing.T) {
|
||||||
var typ map[string]string
|
var typ map[string]string
|
||||||
vin := config.V("string")
|
vin := dyn.V("string")
|
||||||
_, err := Normalize(typ, vin)
|
_, err := Normalize(typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -159,9 +159,9 @@ func TestNormalizeMapError(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeSlice(t *testing.T) {
|
func TestNormalizeSlice(t *testing.T) {
|
||||||
var typ []string
|
var typ []string
|
||||||
vin := config.V([]config.Value{
|
vin := dyn.V([]dyn.Value{
|
||||||
config.V("foo"),
|
dyn.V("foo"),
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
|
@ -171,10 +171,10 @@ func TestNormalizeSlice(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeSliceElementDiagnostic(t *testing.T) {
|
func TestNormalizeSliceElementDiagnostic(t *testing.T) {
|
||||||
var typ []string
|
var typ []string
|
||||||
vin := config.V([]config.Value{
|
vin := dyn.V([]dyn.Value{
|
||||||
config.V("foo"),
|
dyn.V("foo"),
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
config.V(map[string]config.Value{"an": config.V("error")}),
|
dyn.V(map[string]dyn.Value{"an": dyn.V("error")}),
|
||||||
})
|
})
|
||||||
|
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
|
@ -182,7 +182,7 @@ func TestNormalizeSliceElementDiagnostic(t *testing.T) {
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: `expected string, found map`,
|
Summary: `expected string, found map`,
|
||||||
Location: config.Location{},
|
Location: dyn.Location{},
|
||||||
}, err[0])
|
}, err[0])
|
||||||
|
|
||||||
// Elements that encounter an error during normalization are dropped.
|
// Elements that encounter an error during normalization are dropped.
|
||||||
|
@ -191,7 +191,7 @@ func TestNormalizeSliceElementDiagnostic(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeSliceNil(t *testing.T) {
|
func TestNormalizeSliceNil(t *testing.T) {
|
||||||
var typ []string
|
var typ []string
|
||||||
vin := config.NilValue
|
vin := dyn.NilValue
|
||||||
vout, err := Normalize(typ, vin)
|
vout, err := Normalize(typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, vin, vout)
|
assert.Equal(t, vin, vout)
|
||||||
|
@ -199,7 +199,7 @@ func TestNormalizeSliceNil(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeSliceError(t *testing.T) {
|
func TestNormalizeSliceError(t *testing.T) {
|
||||||
var typ []string
|
var typ []string
|
||||||
vin := config.V("string")
|
vin := dyn.V("string")
|
||||||
_, err := Normalize(typ, vin)
|
_, err := Normalize(typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -211,7 +211,7 @@ func TestNormalizeSliceError(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeString(t *testing.T) {
|
func TestNormalizeString(t *testing.T) {
|
||||||
var typ string
|
var typ string
|
||||||
vin := config.V("string")
|
vin := dyn.V("string")
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, vin, vout)
|
assert.Equal(t, vin, vout)
|
||||||
|
@ -219,7 +219,7 @@ func TestNormalizeString(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeStringNil(t *testing.T) {
|
func TestNormalizeStringNil(t *testing.T) {
|
||||||
var typ string
|
var typ string
|
||||||
vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1})
|
vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -231,51 +231,51 @@ func TestNormalizeStringNil(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeStringFromBool(t *testing.T) {
|
func TestNormalizeStringFromBool(t *testing.T) {
|
||||||
var typ string
|
var typ string
|
||||||
vin := config.NewValue(true, config.Location{File: "file", Line: 1, Column: 1})
|
vin := dyn.NewValue(true, dyn.Location{File: "file", Line: 1, Column: 1})
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.NewValue("true", vin.Location()), vout)
|
assert.Equal(t, dyn.NewValue("true", vin.Location()), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeStringFromInt(t *testing.T) {
|
func TestNormalizeStringFromInt(t *testing.T) {
|
||||||
var typ string
|
var typ string
|
||||||
vin := config.NewValue(123, config.Location{File: "file", Line: 1, Column: 1})
|
vin := dyn.NewValue(123, dyn.Location{File: "file", Line: 1, Column: 1})
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.NewValue("123", vin.Location()), vout)
|
assert.Equal(t, dyn.NewValue("123", vin.Location()), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeStringFromFloat(t *testing.T) {
|
func TestNormalizeStringFromFloat(t *testing.T) {
|
||||||
var typ string
|
var typ string
|
||||||
vin := config.NewValue(1.20, config.Location{File: "file", Line: 1, Column: 1})
|
vin := dyn.NewValue(1.20, dyn.Location{File: "file", Line: 1, Column: 1})
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.NewValue("1.2", vin.Location()), vout)
|
assert.Equal(t, dyn.NewValue("1.2", vin.Location()), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeStringError(t *testing.T) {
|
func TestNormalizeStringError(t *testing.T) {
|
||||||
var typ string
|
var typ string
|
||||||
vin := config.V(map[string]config.Value{"an": config.V("error")})
|
vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: `expected string, found map`,
|
Summary: `expected string, found map`,
|
||||||
Location: config.Location{},
|
Location: dyn.Location{},
|
||||||
}, err[0])
|
}, err[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeBool(t *testing.T) {
|
func TestNormalizeBool(t *testing.T) {
|
||||||
var typ bool
|
var typ bool
|
||||||
vin := config.V(true)
|
vin := dyn.V(true)
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.V(true), vout)
|
assert.Equal(t, dyn.V(true), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeBoolNil(t *testing.T) {
|
func TestNormalizeBoolNil(t *testing.T) {
|
||||||
var typ bool
|
var typ bool
|
||||||
vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1})
|
vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -299,16 +299,16 @@ func TestNormalizeBoolFromString(t *testing.T) {
|
||||||
{"on", true},
|
{"on", true},
|
||||||
{"off", false},
|
{"off", false},
|
||||||
} {
|
} {
|
||||||
vin := config.V(c.Input)
|
vin := dyn.V(c.Input)
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.V(c.Output), vout)
|
assert.Equal(t, dyn.V(c.Output), vout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeBoolFromStringError(t *testing.T) {
|
func TestNormalizeBoolFromStringError(t *testing.T) {
|
||||||
var typ bool
|
var typ bool
|
||||||
vin := config.V("abc")
|
vin := dyn.V("abc")
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -320,27 +320,27 @@ func TestNormalizeBoolFromStringError(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeBoolError(t *testing.T) {
|
func TestNormalizeBoolError(t *testing.T) {
|
||||||
var typ bool
|
var typ bool
|
||||||
vin := config.V(map[string]config.Value{"an": config.V("error")})
|
vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: `expected bool, found map`,
|
Summary: `expected bool, found map`,
|
||||||
Location: config.Location{},
|
Location: dyn.Location{},
|
||||||
}, err[0])
|
}, err[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeInt(t *testing.T) {
|
func TestNormalizeInt(t *testing.T) {
|
||||||
var typ int
|
var typ int
|
||||||
vin := config.V(123)
|
vin := dyn.V(123)
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.V(int64(123)), vout)
|
assert.Equal(t, dyn.V(int64(123)), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeIntNil(t *testing.T) {
|
func TestNormalizeIntNil(t *testing.T) {
|
||||||
var typ int
|
var typ int
|
||||||
vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1})
|
vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -352,15 +352,15 @@ func TestNormalizeIntNil(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeIntFromString(t *testing.T) {
|
func TestNormalizeIntFromString(t *testing.T) {
|
||||||
var typ int
|
var typ int
|
||||||
vin := config.V("123")
|
vin := dyn.V("123")
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.V(int64(123)), vout)
|
assert.Equal(t, dyn.V(int64(123)), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeIntFromStringError(t *testing.T) {
|
func TestNormalizeIntFromStringError(t *testing.T) {
|
||||||
var typ int
|
var typ int
|
||||||
vin := config.V("abc")
|
vin := dyn.V("abc")
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -372,27 +372,27 @@ func TestNormalizeIntFromStringError(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeIntError(t *testing.T) {
|
func TestNormalizeIntError(t *testing.T) {
|
||||||
var typ int
|
var typ int
|
||||||
vin := config.V(map[string]config.Value{"an": config.V("error")})
|
vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: `expected int, found map`,
|
Summary: `expected int, found map`,
|
||||||
Location: config.Location{},
|
Location: dyn.Location{},
|
||||||
}, err[0])
|
}, err[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeFloat(t *testing.T) {
|
func TestNormalizeFloat(t *testing.T) {
|
||||||
var typ float64
|
var typ float64
|
||||||
vin := config.V(1.2)
|
vin := dyn.V(1.2)
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.V(1.2), vout)
|
assert.Equal(t, dyn.V(1.2), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeFloatNil(t *testing.T) {
|
func TestNormalizeFloatNil(t *testing.T) {
|
||||||
var typ float64
|
var typ float64
|
||||||
vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1})
|
vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -404,15 +404,15 @@ func TestNormalizeFloatNil(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeFloatFromString(t *testing.T) {
|
func TestNormalizeFloatFromString(t *testing.T) {
|
||||||
var typ float64
|
var typ float64
|
||||||
vin := config.V("1.2")
|
vin := dyn.V("1.2")
|
||||||
vout, err := Normalize(&typ, vin)
|
vout, err := Normalize(&typ, vin)
|
||||||
assert.Empty(t, err)
|
assert.Empty(t, err)
|
||||||
assert.Equal(t, config.V(1.2), vout)
|
assert.Equal(t, dyn.V(1.2), vout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeFloatFromStringError(t *testing.T) {
|
func TestNormalizeFloatFromStringError(t *testing.T) {
|
||||||
var typ float64
|
var typ float64
|
||||||
vin := config.V("abc")
|
vin := dyn.V("abc")
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
@ -424,12 +424,12 @@ func TestNormalizeFloatFromStringError(t *testing.T) {
|
||||||
|
|
||||||
func TestNormalizeFloatError(t *testing.T) {
|
func TestNormalizeFloatError(t *testing.T) {
|
||||||
var typ float64
|
var typ float64
|
||||||
vin := config.V(map[string]config.Value{"an": config.V("error")})
|
vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")})
|
||||||
_, err := Normalize(&typ, vin)
|
_, err := Normalize(&typ, vin)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
assert.Equal(t, diag.Diagnostic{
|
assert.Equal(t, diag.Diagnostic{
|
||||||
Severity: diag.Error,
|
Severity: diag.Error,
|
||||||
Summary: `expected float, found map`,
|
Summary: `expected float, found map`,
|
||||||
Location: config.Location{},
|
Location: dyn.Location{},
|
||||||
}, err[0])
|
}, err[0])
|
||||||
}
|
}
|
|
@ -5,16 +5,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
)
|
)
|
||||||
|
|
||||||
// structInfo holds the type information we need to efficiently
|
// structInfo holds the type information we need to efficiently
|
||||||
// convert data from a [config.Value] to a Go struct.
|
// convert data from a [dyn.Value] to a Go struct.
|
||||||
type structInfo struct {
|
type structInfo struct {
|
||||||
// Fields maps the JSON-name of the field to the field's index for use with [FieldByIndex].
|
// Fields maps the JSON-name of the field to the field's index for use with [FieldByIndex].
|
||||||
Fields map[string][]int
|
Fields map[string][]int
|
||||||
|
|
||||||
// ValueField maps to the field with a [config.Value].
|
// ValueField maps to the field with a [dyn.Value].
|
||||||
// The underlying type is expected to only have one of these.
|
// The underlying type is expected to only have one of these.
|
||||||
ValueField []int
|
ValueField []int
|
||||||
}
|
}
|
||||||
|
@ -74,10 +74,10 @@ func buildStructInfo(typ reflect.Type) structInfo {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this field has type [config.Value], we populate it with the source [config.Value] from [ToTyped].
|
// If this field has type [dyn.Value], we populate it with the source [dyn.Value] from [ToTyped].
|
||||||
if sf.IsExported() && sf.Type == configValueType {
|
if sf.IsExported() && sf.Type == configValueType {
|
||||||
if out.ValueField != nil {
|
if out.ValueField != nil {
|
||||||
panic("multiple config.Value fields")
|
panic("multiple dyn.Value fields")
|
||||||
}
|
}
|
||||||
out.ValueField = append(prefix, sf.Index...)
|
out.ValueField = append(prefix, sf.Index...)
|
||||||
continue
|
continue
|
||||||
|
@ -129,5 +129,5 @@ func (s *structInfo) FieldValues(v reflect.Value) map[string]reflect.Value {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type of [config.Value].
|
// Type of [dyn.Value].
|
||||||
var configValueType = reflect.TypeOf((*config.Value)(nil)).Elem()
|
var configValueType = reflect.TypeOf((*dyn.Value)(nil)).Elem()
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ func TestStructInfoValueFieldAbsent(t *testing.T) {
|
||||||
|
|
||||||
func TestStructInfoValueFieldPresent(t *testing.T) {
|
func TestStructInfoValueFieldPresent(t *testing.T) {
|
||||||
type Tmp struct {
|
type Tmp struct {
|
||||||
Foo config.Value
|
Foo dyn.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
si := getStructInfo(reflect.TypeOf(Tmp{}))
|
si := getStructInfo(reflect.TypeOf(Tmp{}))
|
||||||
|
@ -216,8 +216,8 @@ func TestStructInfoValueFieldPresent(t *testing.T) {
|
||||||
|
|
||||||
func TestStructInfoValueFieldMultiple(t *testing.T) {
|
func TestStructInfoValueFieldMultiple(t *testing.T) {
|
||||||
type Tmp struct {
|
type Tmp struct {
|
||||||
Foo config.Value
|
Foo dyn.Value
|
||||||
Bar config.Value
|
Bar dyn.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Panics(t, func() {
|
assert.Panics(t, func() {
|
|
@ -5,17 +5,17 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ToTyped(dst any, src config.Value) error {
|
func ToTyped(dst any, src dyn.Value) error {
|
||||||
dstv := reflect.ValueOf(dst)
|
dstv := reflect.ValueOf(dst)
|
||||||
|
|
||||||
// Dereference pointer if necessary
|
// Dereference pointer if necessary
|
||||||
for dstv.Kind() == reflect.Pointer {
|
for dstv.Kind() == reflect.Pointer {
|
||||||
// If the source value is nil and the destination is a settable pointer,
|
// If the source value is nil and the destination is a settable pointer,
|
||||||
// set the destination to nil. Also see `end_to_end_test.go`.
|
// set the destination to nil. Also see `end_to_end_test.go`.
|
||||||
if dstv.CanSet() && src == config.NilValue {
|
if dstv.CanSet() && src == dyn.NilValue {
|
||||||
dstv.SetZero()
|
dstv.SetZero()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,9 @@ func ToTyped(dst any, src config.Value) error {
|
||||||
return fmt.Errorf("unsupported type: %s", dstv.Kind())
|
return fmt.Errorf("unsupported type: %s", dstv.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTypedStruct(dst reflect.Value, src config.Value) error {
|
func toTypedStruct(dst reflect.Value, src dyn.Value) error {
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindMap:
|
case dyn.KindMap:
|
||||||
info := getStructInfo(dst.Type())
|
info := getStructInfo(dst.Type())
|
||||||
for k, v := range src.MustMap() {
|
for k, v := range src.MustMap() {
|
||||||
index, ok := info.Fields[k]
|
index, ok := info.Fields[k]
|
||||||
|
@ -83,14 +83,14 @@ func toTypedStruct(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate field(s) for [config.Value], if any.
|
// Populate field(s) for [dyn.Value], if any.
|
||||||
if info.ValueField != nil {
|
if info.ValueField != nil {
|
||||||
vv := dst.FieldByIndex(info.ValueField)
|
vv := dst.FieldByIndex(info.ValueField)
|
||||||
vv.Set(reflect.ValueOf(src))
|
vv.Set(reflect.ValueOf(src))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
dst.SetZero()
|
dst.SetZero()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -101,9 +101,9 @@ func toTypedStruct(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTypedMap(dst reflect.Value, src config.Value) error {
|
func toTypedMap(dst reflect.Value, src dyn.Value) error {
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindMap:
|
case dyn.KindMap:
|
||||||
m := src.MustMap()
|
m := src.MustMap()
|
||||||
|
|
||||||
// Always overwrite.
|
// Always overwrite.
|
||||||
|
@ -118,7 +118,7 @@ func toTypedMap(dst reflect.Value, src config.Value) error {
|
||||||
dst.SetMapIndex(kv, vv.Elem())
|
dst.SetMapIndex(kv, vv.Elem())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
dst.SetZero()
|
dst.SetZero()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -129,9 +129,9 @@ func toTypedMap(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTypedSlice(dst reflect.Value, src config.Value) error {
|
func toTypedSlice(dst reflect.Value, src dyn.Value) error {
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindSequence:
|
case dyn.KindSequence:
|
||||||
seq := src.MustSequence()
|
seq := src.MustSequence()
|
||||||
|
|
||||||
// Always overwrite.
|
// Always overwrite.
|
||||||
|
@ -143,7 +143,7 @@ func toTypedSlice(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case config.KindNil:
|
case dyn.KindNil:
|
||||||
dst.SetZero()
|
dst.SetZero()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -154,18 +154,18 @@ func toTypedSlice(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTypedString(dst reflect.Value, src config.Value) error {
|
func toTypedString(dst reflect.Value, src dyn.Value) error {
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
dst.SetString(src.MustString())
|
dst.SetString(src.MustString())
|
||||||
return nil
|
return nil
|
||||||
case config.KindBool:
|
case dyn.KindBool:
|
||||||
dst.SetString(strconv.FormatBool(src.MustBool()))
|
dst.SetString(strconv.FormatBool(src.MustBool()))
|
||||||
return nil
|
return nil
|
||||||
case config.KindInt:
|
case dyn.KindInt:
|
||||||
dst.SetString(strconv.FormatInt(src.MustInt(), 10))
|
dst.SetString(strconv.FormatInt(src.MustInt(), 10))
|
||||||
return nil
|
return nil
|
||||||
case config.KindFloat:
|
case dyn.KindFloat:
|
||||||
dst.SetString(strconv.FormatFloat(src.MustFloat(), 'f', -1, 64))
|
dst.SetString(strconv.FormatFloat(src.MustFloat(), 'f', -1, 64))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -176,12 +176,12 @@ func toTypedString(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTypedBool(dst reflect.Value, src config.Value) error {
|
func toTypedBool(dst reflect.Value, src dyn.Value) error {
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindBool:
|
case dyn.KindBool:
|
||||||
dst.SetBool(src.MustBool())
|
dst.SetBool(src.MustBool())
|
||||||
return nil
|
return nil
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
// See https://github.com/go-yaml/yaml/blob/f6f7691b1fdeb513f56608cd2c32c51f8194bf51/decode.go#L684-L693.
|
// See https://github.com/go-yaml/yaml/blob/f6f7691b1fdeb513f56608cd2c32c51f8194bf51/decode.go#L684-L693.
|
||||||
switch src.MustString() {
|
switch src.MustString() {
|
||||||
case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON":
|
case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON":
|
||||||
|
@ -199,12 +199,12 @@ func toTypedBool(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTypedInt(dst reflect.Value, src config.Value) error {
|
func toTypedInt(dst reflect.Value, src dyn.Value) error {
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindInt:
|
case dyn.KindInt:
|
||||||
dst.SetInt(src.MustInt())
|
dst.SetInt(src.MustInt())
|
||||||
return nil
|
return nil
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
if i64, err := strconv.ParseInt(src.MustString(), 10, 64); err == nil {
|
if i64, err := strconv.ParseInt(src.MustString(), 10, 64); err == nil {
|
||||||
dst.SetInt(i64)
|
dst.SetInt(i64)
|
||||||
return nil
|
return nil
|
||||||
|
@ -217,12 +217,12 @@ func toTypedInt(dst reflect.Value, src config.Value) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTypedFloat(dst reflect.Value, src config.Value) error {
|
func toTypedFloat(dst reflect.Value, src dyn.Value) error {
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case config.KindFloat:
|
case dyn.KindFloat:
|
||||||
dst.SetFloat(src.MustFloat())
|
dst.SetFloat(src.MustFloat())
|
||||||
return nil
|
return nil
|
||||||
case config.KindString:
|
case dyn.KindString:
|
||||||
if f64, err := strconv.ParseFloat(src.MustString(), 64); err == nil {
|
if f64, err := strconv.ParseFloat(src.MustString(), 64); err == nil {
|
||||||
dst.SetFloat(f64)
|
dst.SetFloat(f64)
|
||||||
return nil
|
return nil
|
|
@ -3,7 +3,7 @@ package convert
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -21,9 +21,9 @@ func TestToTypedStruct(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var out Tmp
|
var out Tmp
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -48,9 +48,9 @@ func TestToTypedStructOverwrite(t *testing.T) {
|
||||||
Foo: "baz",
|
Foo: "baz",
|
||||||
Bar: "qux",
|
Bar: "qux",
|
||||||
}
|
}
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -74,9 +74,9 @@ func TestToTypedStructAnonymousByValue(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var out Tmp
|
var out Tmp
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -100,9 +100,9 @@ func TestToTypedStructAnonymousByPointer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var out Tmp
|
var out Tmp
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -117,7 +117,7 @@ func TestToTypedStructNil(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var out = Tmp{}
|
var out = Tmp{}
|
||||||
err := ToTyped(&out, config.NilValue)
|
err := ToTyped(&out, dyn.NilValue)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, Tmp{}, out)
|
assert.Equal(t, Tmp{}, out)
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ func TestToTypedStructNilOverwrite(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var out = Tmp{"bar"}
|
var out = Tmp{"bar"}
|
||||||
err := ToTyped(&out, config.NilValue)
|
err := ToTyped(&out, dyn.NilValue)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, Tmp{}, out)
|
assert.Equal(t, Tmp{}, out)
|
||||||
}
|
}
|
||||||
|
@ -137,12 +137,12 @@ func TestToTypedStructWithValueField(t *testing.T) {
|
||||||
type Tmp struct {
|
type Tmp struct {
|
||||||
Foo string `json:"foo"`
|
Foo string `json:"foo"`
|
||||||
|
|
||||||
ConfigValue config.Value
|
ConfigValue dyn.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
var out Tmp
|
var out Tmp
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -154,8 +154,8 @@ func TestToTypedStructWithValueField(t *testing.T) {
|
||||||
func TestToTypedMap(t *testing.T) {
|
func TestToTypedMap(t *testing.T) {
|
||||||
var out = map[string]string{}
|
var out = map[string]string{}
|
||||||
|
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"key": config.V("value"),
|
"key": dyn.V("value"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -169,8 +169,8 @@ func TestToTypedMapOverwrite(t *testing.T) {
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"bar": config.V("qux"),
|
"bar": dyn.V("qux"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -182,8 +182,8 @@ func TestToTypedMapOverwrite(t *testing.T) {
|
||||||
func TestToTypedMapWithPointerElement(t *testing.T) {
|
func TestToTypedMapWithPointerElement(t *testing.T) {
|
||||||
var out map[string]*string
|
var out map[string]*string
|
||||||
|
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"key": config.V("value"),
|
"key": dyn.V("value"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -194,7 +194,7 @@ func TestToTypedMapWithPointerElement(t *testing.T) {
|
||||||
|
|
||||||
func TestToTypedMapNil(t *testing.T) {
|
func TestToTypedMapNil(t *testing.T) {
|
||||||
var out = map[string]string{}
|
var out = map[string]string{}
|
||||||
err := ToTyped(&out, config.NilValue)
|
err := ToTyped(&out, dyn.NilValue)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Nil(t, out)
|
assert.Nil(t, out)
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ func TestToTypedMapNilOverwrite(t *testing.T) {
|
||||||
var out = map[string]string{
|
var out = map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
}
|
}
|
||||||
err := ToTyped(&out, config.NilValue)
|
err := ToTyped(&out, dyn.NilValue)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Nil(t, out)
|
assert.Nil(t, out)
|
||||||
}
|
}
|
||||||
|
@ -211,9 +211,9 @@ func TestToTypedMapNilOverwrite(t *testing.T) {
|
||||||
func TestToTypedSlice(t *testing.T) {
|
func TestToTypedSlice(t *testing.T) {
|
||||||
var out []string
|
var out []string
|
||||||
|
|
||||||
v := config.V([]config.Value{
|
v := dyn.V([]dyn.Value{
|
||||||
config.V("foo"),
|
dyn.V("foo"),
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -226,9 +226,9 @@ func TestToTypedSlice(t *testing.T) {
|
||||||
func TestToTypedSliceOverwrite(t *testing.T) {
|
func TestToTypedSliceOverwrite(t *testing.T) {
|
||||||
var out = []string{"qux"}
|
var out = []string{"qux"}
|
||||||
|
|
||||||
v := config.V([]config.Value{
|
v := dyn.V([]dyn.Value{
|
||||||
config.V("foo"),
|
dyn.V("foo"),
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -241,9 +241,9 @@ func TestToTypedSliceOverwrite(t *testing.T) {
|
||||||
func TestToTypedSliceWithPointerElement(t *testing.T) {
|
func TestToTypedSliceWithPointerElement(t *testing.T) {
|
||||||
var out []*string
|
var out []*string
|
||||||
|
|
||||||
v := config.V([]config.Value{
|
v := dyn.V([]dyn.Value{
|
||||||
config.V("foo"),
|
dyn.V("foo"),
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ToTyped(&out, v)
|
err := ToTyped(&out, v)
|
||||||
|
@ -255,63 +255,63 @@ func TestToTypedSliceWithPointerElement(t *testing.T) {
|
||||||
|
|
||||||
func TestToTypedSliceNil(t *testing.T) {
|
func TestToTypedSliceNil(t *testing.T) {
|
||||||
var out []string
|
var out []string
|
||||||
err := ToTyped(&out, config.NilValue)
|
err := ToTyped(&out, dyn.NilValue)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Nil(t, out)
|
assert.Nil(t, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedSliceNilOverwrite(t *testing.T) {
|
func TestToTypedSliceNilOverwrite(t *testing.T) {
|
||||||
var out = []string{"foo"}
|
var out = []string{"foo"}
|
||||||
err := ToTyped(&out, config.NilValue)
|
err := ToTyped(&out, dyn.NilValue)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Nil(t, out)
|
assert.Nil(t, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedString(t *testing.T) {
|
func TestToTypedString(t *testing.T) {
|
||||||
var out string
|
var out string
|
||||||
err := ToTyped(&out, config.V("foo"))
|
err := ToTyped(&out, dyn.V("foo"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "foo", out)
|
assert.Equal(t, "foo", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedStringOverwrite(t *testing.T) {
|
func TestToTypedStringOverwrite(t *testing.T) {
|
||||||
var out string = "bar"
|
var out string = "bar"
|
||||||
err := ToTyped(&out, config.V("foo"))
|
err := ToTyped(&out, dyn.V("foo"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "foo", out)
|
assert.Equal(t, "foo", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedStringFromBool(t *testing.T) {
|
func TestToTypedStringFromBool(t *testing.T) {
|
||||||
var out string
|
var out string
|
||||||
err := ToTyped(&out, config.V(true))
|
err := ToTyped(&out, dyn.V(true))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "true", out)
|
assert.Equal(t, "true", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedStringFromInt(t *testing.T) {
|
func TestToTypedStringFromInt(t *testing.T) {
|
||||||
var out string
|
var out string
|
||||||
err := ToTyped(&out, config.V(123))
|
err := ToTyped(&out, dyn.V(123))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "123", out)
|
assert.Equal(t, "123", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedStringFromFloat(t *testing.T) {
|
func TestToTypedStringFromFloat(t *testing.T) {
|
||||||
var out string
|
var out string
|
||||||
err := ToTyped(&out, config.V(1.2))
|
err := ToTyped(&out, dyn.V(1.2))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "1.2", out)
|
assert.Equal(t, "1.2", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedBool(t *testing.T) {
|
func TestToTypedBool(t *testing.T) {
|
||||||
var out bool
|
var out bool
|
||||||
err := ToTyped(&out, config.V(true))
|
err := ToTyped(&out, dyn.V(true))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, out)
|
assert.Equal(t, true, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedBoolOverwrite(t *testing.T) {
|
func TestToTypedBoolOverwrite(t *testing.T) {
|
||||||
var out bool = true
|
var out bool = true
|
||||||
err := ToTyped(&out, config.V(false))
|
err := ToTyped(&out, dyn.V(false))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, false, out)
|
assert.Equal(t, false, out)
|
||||||
}
|
}
|
||||||
|
@ -321,128 +321,128 @@ func TestToTypedBoolFromString(t *testing.T) {
|
||||||
|
|
||||||
// True-ish
|
// True-ish
|
||||||
for _, v := range []string{"y", "yes", "on"} {
|
for _, v := range []string{"y", "yes", "on"} {
|
||||||
err := ToTyped(&out, config.V(v))
|
err := ToTyped(&out, dyn.V(v))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, out)
|
assert.Equal(t, true, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// False-ish
|
// False-ish
|
||||||
for _, v := range []string{"n", "no", "off"} {
|
for _, v := range []string{"n", "no", "off"} {
|
||||||
err := ToTyped(&out, config.V(v))
|
err := ToTyped(&out, dyn.V(v))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, false, out)
|
assert.Equal(t, false, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
err := ToTyped(&out, config.V("${var.foo}"))
|
err := ToTyped(&out, dyn.V("${var.foo}"))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedInt(t *testing.T) {
|
func TestToTypedInt(t *testing.T) {
|
||||||
var out int
|
var out int
|
||||||
err := ToTyped(&out, config.V(1234))
|
err := ToTyped(&out, dyn.V(1234))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int(1234), out)
|
assert.Equal(t, int(1234), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedInt32(t *testing.T) {
|
func TestToTypedInt32(t *testing.T) {
|
||||||
var out32 int32
|
var out32 int32
|
||||||
err := ToTyped(&out32, config.V(1235))
|
err := ToTyped(&out32, dyn.V(1235))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int32(1235), out32)
|
assert.Equal(t, int32(1235), out32)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedInt64(t *testing.T) {
|
func TestToTypedInt64(t *testing.T) {
|
||||||
var out64 int64
|
var out64 int64
|
||||||
err := ToTyped(&out64, config.V(1236))
|
err := ToTyped(&out64, dyn.V(1236))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int64(1236), out64)
|
assert.Equal(t, int64(1236), out64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedIntOverwrite(t *testing.T) {
|
func TestToTypedIntOverwrite(t *testing.T) {
|
||||||
var out int = 123
|
var out int = 123
|
||||||
err := ToTyped(&out, config.V(1234))
|
err := ToTyped(&out, dyn.V(1234))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int(1234), out)
|
assert.Equal(t, int(1234), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedInt32Overwrite(t *testing.T) {
|
func TestToTypedInt32Overwrite(t *testing.T) {
|
||||||
var out32 int32 = 123
|
var out32 int32 = 123
|
||||||
err := ToTyped(&out32, config.V(1234))
|
err := ToTyped(&out32, dyn.V(1234))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int32(1234), out32)
|
assert.Equal(t, int32(1234), out32)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedInt64Overwrite(t *testing.T) {
|
func TestToTypedInt64Overwrite(t *testing.T) {
|
||||||
var out64 int64 = 123
|
var out64 int64 = 123
|
||||||
err := ToTyped(&out64, config.V(1234))
|
err := ToTyped(&out64, dyn.V(1234))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int64(1234), out64)
|
assert.Equal(t, int64(1234), out64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedIntFromStringError(t *testing.T) {
|
func TestToTypedIntFromStringError(t *testing.T) {
|
||||||
var out int
|
var out int
|
||||||
err := ToTyped(&out, config.V("abc"))
|
err := ToTyped(&out, dyn.V("abc"))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedIntFromStringInt(t *testing.T) {
|
func TestToTypedIntFromStringInt(t *testing.T) {
|
||||||
var out int
|
var out int
|
||||||
err := ToTyped(&out, config.V("123"))
|
err := ToTyped(&out, dyn.V("123"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int(123), out)
|
assert.Equal(t, int(123), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat32(t *testing.T) {
|
func TestToTypedFloat32(t *testing.T) {
|
||||||
var out float32
|
var out float32
|
||||||
err := ToTyped(&out, config.V(float32(1.0)))
|
err := ToTyped(&out, dyn.V(float32(1.0)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, float32(1.0), out)
|
assert.Equal(t, float32(1.0), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat64(t *testing.T) {
|
func TestToTypedFloat64(t *testing.T) {
|
||||||
var out float64
|
var out float64
|
||||||
err := ToTyped(&out, config.V(float64(1.0)))
|
err := ToTyped(&out, dyn.V(float64(1.0)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, float64(1.0), out)
|
assert.Equal(t, float64(1.0), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat32Overwrite(t *testing.T) {
|
func TestToTypedFloat32Overwrite(t *testing.T) {
|
||||||
var out float32 = 1.0
|
var out float32 = 1.0
|
||||||
err := ToTyped(&out, config.V(float32(2.0)))
|
err := ToTyped(&out, dyn.V(float32(2.0)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, float32(2.0), out)
|
assert.Equal(t, float32(2.0), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat64Overwrite(t *testing.T) {
|
func TestToTypedFloat64Overwrite(t *testing.T) {
|
||||||
var out float64 = 1.0
|
var out float64 = 1.0
|
||||||
err := ToTyped(&out, config.V(float64(2.0)))
|
err := ToTyped(&out, dyn.V(float64(2.0)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, float64(2.0), out)
|
assert.Equal(t, float64(2.0), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat32FromStringError(t *testing.T) {
|
func TestToTypedFloat32FromStringError(t *testing.T) {
|
||||||
var out float32
|
var out float32
|
||||||
err := ToTyped(&out, config.V("abc"))
|
err := ToTyped(&out, dyn.V("abc"))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat64FromStringError(t *testing.T) {
|
func TestToTypedFloat64FromStringError(t *testing.T) {
|
||||||
var out float64
|
var out float64
|
||||||
err := ToTyped(&out, config.V("abc"))
|
err := ToTyped(&out, dyn.V("abc"))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat32FromString(t *testing.T) {
|
func TestToTypedFloat32FromString(t *testing.T) {
|
||||||
var out float32
|
var out float32
|
||||||
err := ToTyped(&out, config.V("1.2"))
|
err := ToTyped(&out, dyn.V("1.2"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, float32(1.2), out)
|
assert.Equal(t, float32(1.2), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToTypedFloat64FromString(t *testing.T) {
|
func TestToTypedFloat64FromString(t *testing.T) {
|
||||||
var out float64
|
var out float64
|
||||||
err := ToTyped(&out, config.V("1.2"))
|
err := ToTyped(&out, dyn.V("1.2"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, float64(1.2), out)
|
assert.Equal(t, float64(1.2), out)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package config
|
package dyn
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package config
|
package dyn
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package config_test
|
package dyn_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLocation(t *testing.T) {
|
func TestLocation(t *testing.T) {
|
||||||
loc := config.Location{File: "file", Line: 1, Column: 2}
|
loc := dyn.Location{File: "file", Line: 1, Column: 2}
|
||||||
assert.Equal(t, "file:1:2", loc.String())
|
assert.Equal(t, "file:1:2", loc.String())
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package merge
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Merge recursively merges the specified values.
|
// Merge recursively merges the specified values.
|
||||||
|
@ -12,46 +12,46 @@ import (
|
||||||
// * Merging x with nil or nil with x always yields x.
|
// * Merging x with nil or nil with x always yields x.
|
||||||
// * Merging maps a and b means entries from map b take precedence.
|
// * Merging maps a and b means entries from map b take precedence.
|
||||||
// * Merging sequences a and b means concatenating them.
|
// * Merging sequences a and b means concatenating them.
|
||||||
func Merge(a, b config.Value) (config.Value, error) {
|
func Merge(a, b dyn.Value) (dyn.Value, error) {
|
||||||
return merge(a, b)
|
return merge(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func merge(a, b config.Value) (config.Value, error) {
|
func merge(a, b dyn.Value) (dyn.Value, error) {
|
||||||
ak := a.Kind()
|
ak := a.Kind()
|
||||||
bk := b.Kind()
|
bk := b.Kind()
|
||||||
|
|
||||||
// If a is nil, return b.
|
// If a is nil, return b.
|
||||||
if ak == config.KindNil {
|
if ak == dyn.KindNil {
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If b is nil, return a.
|
// If b is nil, return a.
|
||||||
if bk == config.KindNil {
|
if bk == dyn.KindNil {
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the appropriate merge function based on the kind of a and b.
|
// Call the appropriate merge function based on the kind of a and b.
|
||||||
switch ak {
|
switch ak {
|
||||||
case config.KindMap:
|
case dyn.KindMap:
|
||||||
if bk != config.KindMap {
|
if bk != dyn.KindMap {
|
||||||
return config.NilValue, fmt.Errorf("cannot merge map with %s", bk)
|
return dyn.NilValue, fmt.Errorf("cannot merge map with %s", bk)
|
||||||
}
|
}
|
||||||
return mergeMap(a, b)
|
return mergeMap(a, b)
|
||||||
case config.KindSequence:
|
case dyn.KindSequence:
|
||||||
if bk != config.KindSequence {
|
if bk != dyn.KindSequence {
|
||||||
return config.NilValue, fmt.Errorf("cannot merge sequence with %s", bk)
|
return dyn.NilValue, fmt.Errorf("cannot merge sequence with %s", bk)
|
||||||
}
|
}
|
||||||
return mergeSequence(a, b)
|
return mergeSequence(a, b)
|
||||||
default:
|
default:
|
||||||
if ak != bk {
|
if ak != bk {
|
||||||
return config.NilValue, fmt.Errorf("cannot merge %s with %s", ak, bk)
|
return dyn.NilValue, fmt.Errorf("cannot merge %s with %s", ak, bk)
|
||||||
}
|
}
|
||||||
return mergePrimitive(a, b)
|
return mergePrimitive(a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeMap(a, b config.Value) (config.Value, error) {
|
func mergeMap(a, b dyn.Value) (dyn.Value, error) {
|
||||||
out := make(map[string]config.Value)
|
out := make(map[string]dyn.Value)
|
||||||
am := a.MustMap()
|
am := a.MustMap()
|
||||||
bm := b.MustMap()
|
bm := b.MustMap()
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ func mergeMap(a, b config.Value) (config.Value, error) {
|
||||||
// If the key already exists, merge the values.
|
// If the key already exists, merge the values.
|
||||||
merged, err := merge(out[k], v)
|
merged, err := merge(out[k], v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, err
|
return dyn.NilValue, err
|
||||||
}
|
}
|
||||||
out[k] = merged
|
out[k] = merged
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,23 +76,23 @@ func mergeMap(a, b config.Value) (config.Value, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve the location of the first value.
|
// Preserve the location of the first value.
|
||||||
return config.NewValue(out, a.Location()), nil
|
return dyn.NewValue(out, a.Location()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeSequence(a, b config.Value) (config.Value, error) {
|
func mergeSequence(a, b dyn.Value) (dyn.Value, error) {
|
||||||
as := a.MustSequence()
|
as := a.MustSequence()
|
||||||
bs := b.MustSequence()
|
bs := b.MustSequence()
|
||||||
|
|
||||||
// Merging sequences means concatenating them.
|
// Merging sequences means concatenating them.
|
||||||
out := make([]config.Value, len(as)+len(bs))
|
out := make([]dyn.Value, len(as)+len(bs))
|
||||||
copy(out[:], as)
|
copy(out[:], as)
|
||||||
copy(out[len(as):], bs)
|
copy(out[len(as):], bs)
|
||||||
|
|
||||||
// Preserve the location of the first value.
|
// Preserve the location of the first value.
|
||||||
return config.NewValue(out, a.Location()), nil
|
return dyn.NewValue(out, a.Location()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergePrimitive(a, b config.Value) (config.Value, error) {
|
func mergePrimitive(a, b dyn.Value) (dyn.Value, error) {
|
||||||
// Merging primitive values means using the incoming value.
|
// Merging primitive values means using the incoming value.
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
|
@ -3,19 +3,19 @@ package merge
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMergeMaps(t *testing.T) {
|
func TestMergeMaps(t *testing.T) {
|
||||||
v1 := config.V(map[string]config.Value{
|
v1 := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
"bar": config.V("baz"),
|
"bar": dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
v2 := config.V(map[string]config.Value{
|
v2 := dyn.V(map[string]dyn.Value{
|
||||||
"bar": config.V("qux"),
|
"bar": dyn.V("qux"),
|
||||||
"qux": config.V("foo"),
|
"qux": dyn.V("foo"),
|
||||||
})
|
})
|
||||||
|
|
||||||
// Merge v2 into v1.
|
// Merge v2 into v1.
|
||||||
|
@ -42,13 +42,13 @@ func TestMergeMaps(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeMapsNil(t *testing.T) {
|
func TestMergeMapsNil(t *testing.T) {
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
// Merge nil into v.
|
// Merge nil into v.
|
||||||
{
|
{
|
||||||
out, err := Merge(v, config.NilValue)
|
out, err := Merge(v, dyn.NilValue)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, map[string]any{
|
assert.Equal(t, map[string]any{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
|
@ -57,7 +57,7 @@ func TestMergeMapsNil(t *testing.T) {
|
||||||
|
|
||||||
// Merge v into nil.
|
// Merge v into nil.
|
||||||
{
|
{
|
||||||
out, err := Merge(config.NilValue, v)
|
out, err := Merge(dyn.NilValue, v)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, map[string]any{
|
assert.Equal(t, map[string]any{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
|
@ -66,29 +66,29 @@ func TestMergeMapsNil(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeMapsError(t *testing.T) {
|
func TestMergeMapsError(t *testing.T) {
|
||||||
v := config.V(map[string]config.Value{
|
v := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
other := config.V("string")
|
other := dyn.V("string")
|
||||||
|
|
||||||
// Merge a string into v.
|
// Merge a string into v.
|
||||||
{
|
{
|
||||||
out, err := Merge(v, other)
|
out, err := Merge(v, other)
|
||||||
assert.EqualError(t, err, "cannot merge map with string")
|
assert.EqualError(t, err, "cannot merge map with string")
|
||||||
assert.Equal(t, config.NilValue, out)
|
assert.Equal(t, dyn.NilValue, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeSequences(t *testing.T) {
|
func TestMergeSequences(t *testing.T) {
|
||||||
v1 := config.V([]config.Value{
|
v1 := dyn.V([]dyn.Value{
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
config.V("baz"),
|
dyn.V("baz"),
|
||||||
})
|
})
|
||||||
|
|
||||||
v2 := config.V([]config.Value{
|
v2 := dyn.V([]dyn.Value{
|
||||||
config.V("qux"),
|
dyn.V("qux"),
|
||||||
config.V("foo"),
|
dyn.V("foo"),
|
||||||
})
|
})
|
||||||
|
|
||||||
// Merge v2 into v1.
|
// Merge v2 into v1.
|
||||||
|
@ -117,13 +117,13 @@ func TestMergeSequences(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeSequencesNil(t *testing.T) {
|
func TestMergeSequencesNil(t *testing.T) {
|
||||||
v := config.V([]config.Value{
|
v := dyn.V([]dyn.Value{
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
// Merge nil into v.
|
// Merge nil into v.
|
||||||
{
|
{
|
||||||
out, err := Merge(v, config.NilValue)
|
out, err := Merge(v, dyn.NilValue)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, []any{
|
assert.Equal(t, []any{
|
||||||
"bar",
|
"bar",
|
||||||
|
@ -132,7 +132,7 @@ func TestMergeSequencesNil(t *testing.T) {
|
||||||
|
|
||||||
// Merge v into nil.
|
// Merge v into nil.
|
||||||
{
|
{
|
||||||
out, err := Merge(config.NilValue, v)
|
out, err := Merge(dyn.NilValue, v)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, []any{
|
assert.Equal(t, []any{
|
||||||
"bar",
|
"bar",
|
||||||
|
@ -141,23 +141,23 @@ func TestMergeSequencesNil(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeSequencesError(t *testing.T) {
|
func TestMergeSequencesError(t *testing.T) {
|
||||||
v := config.V([]config.Value{
|
v := dyn.V([]dyn.Value{
|
||||||
config.V("bar"),
|
dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
other := config.V("string")
|
other := dyn.V("string")
|
||||||
|
|
||||||
// Merge a string into v.
|
// Merge a string into v.
|
||||||
{
|
{
|
||||||
out, err := Merge(v, other)
|
out, err := Merge(v, other)
|
||||||
assert.EqualError(t, err, "cannot merge sequence with string")
|
assert.EqualError(t, err, "cannot merge sequence with string")
|
||||||
assert.Equal(t, config.NilValue, out)
|
assert.Equal(t, dyn.NilValue, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergePrimitives(t *testing.T) {
|
func TestMergePrimitives(t *testing.T) {
|
||||||
v1 := config.V("bar")
|
v1 := dyn.V("bar")
|
||||||
v2 := config.V("baz")
|
v2 := dyn.V("baz")
|
||||||
|
|
||||||
// Merge v2 into v1.
|
// Merge v2 into v1.
|
||||||
{
|
{
|
||||||
|
@ -175,33 +175,33 @@ func TestMergePrimitives(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergePrimitivesNil(t *testing.T) {
|
func TestMergePrimitivesNil(t *testing.T) {
|
||||||
v := config.V("bar")
|
v := dyn.V("bar")
|
||||||
|
|
||||||
// Merge nil into v.
|
// Merge nil into v.
|
||||||
{
|
{
|
||||||
out, err := Merge(v, config.NilValue)
|
out, err := Merge(v, dyn.NilValue)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "bar", out.AsAny())
|
assert.Equal(t, "bar", out.AsAny())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge v into nil.
|
// Merge v into nil.
|
||||||
{
|
{
|
||||||
out, err := Merge(config.NilValue, v)
|
out, err := Merge(dyn.NilValue, v)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "bar", out.AsAny())
|
assert.Equal(t, "bar", out.AsAny())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergePrimitivesError(t *testing.T) {
|
func TestMergePrimitivesError(t *testing.T) {
|
||||||
v := config.V("bar")
|
v := dyn.V("bar")
|
||||||
other := config.V(map[string]config.Value{
|
other := dyn.V(map[string]dyn.Value{
|
||||||
"foo": config.V("bar"),
|
"foo": dyn.V("bar"),
|
||||||
})
|
})
|
||||||
|
|
||||||
// Merge a map into v.
|
// Merge a map into v.
|
||||||
{
|
{
|
||||||
out, err := Merge(v, other)
|
out, err := Merge(v, other)
|
||||||
assert.EqualError(t, err, "cannot merge string with map")
|
assert.EqualError(t, err, "cannot merge string with map")
|
||||||
assert.Equal(t, config.NilValue, out)
|
assert.Equal(t, dyn.NilValue, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package config
|
package dyn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
|
@ -1,4 +1,4 @@
|
||||||
package config
|
package dyn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,10 +1,10 @@
|
||||||
package config_test
|
package dyn_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/databricks/cli/libs/config"
|
. "github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package dyn_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/databricks/cli/libs/dyn"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPathAppend(t *testing.T) {
|
||||||
|
p := dyn.NewPath(dyn.Key("foo"))
|
||||||
|
|
||||||
|
// Single arg.
|
||||||
|
p1 := p.Append(dyn.Key("bar"))
|
||||||
|
assert.True(t, p1.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar"))))
|
||||||
|
|
||||||
|
// Multiple args.
|
||||||
|
p2 := p.Append(dyn.Key("bar"), dyn.Index(1))
|
||||||
|
assert.True(t, p2.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar"), dyn.Index(1))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPathJoin(t *testing.T) {
|
||||||
|
p := dyn.NewPath(dyn.Key("foo"))
|
||||||
|
|
||||||
|
// Single arg.
|
||||||
|
p1 := p.Join(dyn.NewPath(dyn.Key("bar")))
|
||||||
|
assert.True(t, p1.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar"))))
|
||||||
|
|
||||||
|
// Multiple args.
|
||||||
|
p2 := p.Join(dyn.NewPath(dyn.Key("bar")), dyn.NewPath(dyn.Index(1)))
|
||||||
|
assert.True(t, p2.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar"), dyn.Index(1))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPathEqualEmpty(t *testing.T) {
|
||||||
|
assert.True(t, dyn.EmptyPath.Equal(dyn.EmptyPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPathEqual(t *testing.T) {
|
||||||
|
p1 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1))
|
||||||
|
p2 := dyn.NewPath(dyn.Key("bar"), dyn.Index(2))
|
||||||
|
assert.False(t, p1.Equal(p2), "expected %q to not equal %q", p1, p2)
|
||||||
|
|
||||||
|
p3 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1))
|
||||||
|
assert.True(t, p1.Equal(p3), "expected %q to equal %q", p1, p3)
|
||||||
|
|
||||||
|
p4 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1), dyn.Key("bar"), dyn.Index(2))
|
||||||
|
assert.False(t, p1.Equal(p4), "expected %q to not equal %q", p1, p4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPathHasPrefixEmpty(t *testing.T) {
|
||||||
|
empty := dyn.EmptyPath
|
||||||
|
nonEmpty := dyn.NewPath(dyn.Key("foo"))
|
||||||
|
assert.True(t, empty.HasPrefix(empty))
|
||||||
|
assert.True(t, nonEmpty.HasPrefix(empty))
|
||||||
|
assert.False(t, empty.HasPrefix(nonEmpty))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPathHasPrefix(t *testing.T) {
|
||||||
|
p1 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1))
|
||||||
|
p2 := dyn.NewPath(dyn.Key("bar"), dyn.Index(2))
|
||||||
|
assert.False(t, p1.HasPrefix(p2), "expected %q to not have prefix %q", p1, p2)
|
||||||
|
|
||||||
|
p3 := dyn.NewPath(dyn.Key("foo"))
|
||||||
|
assert.True(t, p1.HasPrefix(p3), "expected %q to have prefix %q", p1, p3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPathString(t *testing.T) {
|
||||||
|
p1 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1))
|
||||||
|
assert.Equal(t, "foo[1]", p1.String())
|
||||||
|
|
||||||
|
p2 := dyn.NewPath(dyn.Key("bar"), dyn.Index(2), dyn.Key("baz"))
|
||||||
|
assert.Equal(t, "bar[2].baz", p2.String())
|
||||||
|
|
||||||
|
p3 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1), dyn.Key("bar"), dyn.Index(2), dyn.Key("baz"))
|
||||||
|
assert.Equal(t, "foo[1].bar[2].baz", p3.String())
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package config
|
package dyn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,35 +1,35 @@
|
||||||
package config_test
|
package dyn_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValueIsAnchor(t *testing.T) {
|
func TestValueIsAnchor(t *testing.T) {
|
||||||
var zero config.Value
|
var zero dyn.Value
|
||||||
assert.False(t, zero.IsAnchor())
|
assert.False(t, zero.IsAnchor())
|
||||||
mark := zero.MarkAnchor()
|
mark := zero.MarkAnchor()
|
||||||
assert.True(t, mark.IsAnchor())
|
assert.True(t, mark.IsAnchor())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValueAsMap(t *testing.T) {
|
func TestValueAsMap(t *testing.T) {
|
||||||
var zeroValue config.Value
|
var zeroValue dyn.Value
|
||||||
m, ok := zeroValue.AsMap()
|
m, ok := zeroValue.AsMap()
|
||||||
assert.False(t, ok)
|
assert.False(t, ok)
|
||||||
assert.Nil(t, m)
|
assert.Nil(t, m)
|
||||||
|
|
||||||
var intValue = config.NewValue(1, config.Location{})
|
var intValue = dyn.NewValue(1, dyn.Location{})
|
||||||
m, ok = intValue.AsMap()
|
m, ok = intValue.AsMap()
|
||||||
assert.False(t, ok)
|
assert.False(t, ok)
|
||||||
assert.Nil(t, m)
|
assert.Nil(t, m)
|
||||||
|
|
||||||
var mapValue = config.NewValue(
|
var mapValue = dyn.NewValue(
|
||||||
map[string]config.Value{
|
map[string]dyn.Value{
|
||||||
"key": config.NewValue("value", config.Location{File: "file", Line: 1, Column: 2}),
|
"key": dyn.NewValue("value", dyn.Location{File: "file", Line: 1, Column: 2}),
|
||||||
},
|
},
|
||||||
config.Location{File: "file", Line: 1, Column: 2},
|
dyn.Location{File: "file", Line: 1, Column: 2},
|
||||||
)
|
)
|
||||||
m, ok = mapValue.AsMap()
|
m, ok = mapValue.AsMap()
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
@ -37,8 +37,8 @@ func TestValueAsMap(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValueIsValid(t *testing.T) {
|
func TestValueIsValid(t *testing.T) {
|
||||||
var zeroValue config.Value
|
var zeroValue dyn.Value
|
||||||
assert.False(t, zeroValue.IsValid())
|
assert.False(t, zeroValue.IsValid())
|
||||||
var intValue = config.NewValue(1, config.Location{})
|
var intValue = dyn.NewValue(1, dyn.Location{})
|
||||||
assert.True(t, intValue.IsValid())
|
assert.True(t, intValue.IsValid())
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package config
|
package dyn
|
||||||
|
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package config_test
|
package dyn_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/databricks/cli/libs/config"
|
. "github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ type loader struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorf(loc config.Location, format string, args ...interface{}) error {
|
func errorf(loc dyn.Location, format string, args ...interface{}) error {
|
||||||
return fmt.Errorf("yaml (%s): %s", loc, fmt.Sprintf(format, args...))
|
return fmt.Errorf("yaml (%s): %s", loc, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,22 +25,22 @@ func newLoader(path string) *loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *loader) location(node *yaml.Node) config.Location {
|
func (d *loader) location(node *yaml.Node) dyn.Location {
|
||||||
return config.Location{
|
return dyn.Location{
|
||||||
File: d.path,
|
File: d.path,
|
||||||
Line: node.Line,
|
Line: node.Line,
|
||||||
Column: node.Column,
|
Column: node.Column,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *loader) load(node *yaml.Node) (config.Value, error) {
|
func (d *loader) load(node *yaml.Node) (dyn.Value, error) {
|
||||||
loc := config.Location{
|
loc := dyn.Location{
|
||||||
File: d.path,
|
File: d.path,
|
||||||
Line: node.Line,
|
Line: node.Line,
|
||||||
Column: node.Column,
|
Column: node.Column,
|
||||||
}
|
}
|
||||||
|
|
||||||
var value config.Value
|
var value dyn.Value
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
|
@ -55,7 +55,7 @@ func (d *loader) load(node *yaml.Node) (config.Value, error) {
|
||||||
case yaml.AliasNode:
|
case yaml.AliasNode:
|
||||||
value, err = d.loadAlias(node, loc)
|
value, err = d.loadAlias(node, loc)
|
||||||
default:
|
default:
|
||||||
return config.NilValue, errorf(loc, "unknown node kind: %v", node.Kind)
|
return dyn.NilValue, errorf(loc, "unknown node kind: %v", node.Kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -71,35 +71,35 @@ func (d *loader) load(node *yaml.Node) (config.Value, error) {
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *loader) loadDocument(node *yaml.Node, loc config.Location) (config.Value, error) {
|
func (d *loader) loadDocument(node *yaml.Node, loc dyn.Location) (dyn.Value, error) {
|
||||||
return d.load(node.Content[0])
|
return d.load(node.Content[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *loader) loadSequence(node *yaml.Node, loc config.Location) (config.Value, error) {
|
func (d *loader) loadSequence(node *yaml.Node, loc dyn.Location) (dyn.Value, error) {
|
||||||
acc := make([]config.Value, len(node.Content))
|
acc := make([]dyn.Value, len(node.Content))
|
||||||
for i, n := range node.Content {
|
for i, n := range node.Content {
|
||||||
v, err := d.load(n)
|
v, err := d.load(n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, err
|
return dyn.NilValue, err
|
||||||
}
|
}
|
||||||
|
|
||||||
acc[i] = v
|
acc[i] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(acc, loc), nil
|
return dyn.NewValue(acc, loc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *loader) loadMapping(node *yaml.Node, loc config.Location) (config.Value, error) {
|
func (d *loader) loadMapping(node *yaml.Node, loc dyn.Location) (dyn.Value, error) {
|
||||||
var merge *yaml.Node
|
var merge *yaml.Node
|
||||||
|
|
||||||
acc := make(map[string]config.Value)
|
acc := make(map[string]dyn.Value)
|
||||||
for i := 0; i < len(node.Content); i += 2 {
|
for i := 0; i < len(node.Content); i += 2 {
|
||||||
key := node.Content[i]
|
key := node.Content[i]
|
||||||
val := node.Content[i+1]
|
val := node.Content[i+1]
|
||||||
|
|
||||||
// Assert that keys are strings
|
// Assert that keys are strings
|
||||||
if key.Kind != yaml.ScalarNode {
|
if key.Kind != yaml.ScalarNode {
|
||||||
return config.NilValue, errorf(loc, "key is not a scalar")
|
return dyn.NilValue, errorf(loc, "key is not a scalar")
|
||||||
}
|
}
|
||||||
|
|
||||||
st := key.ShortTag()
|
st := key.ShortTag()
|
||||||
|
@ -113,19 +113,19 @@ func (d *loader) loadMapping(node *yaml.Node, loc config.Location) (config.Value
|
||||||
merge = val
|
merge = val
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
return config.NilValue, errorf(loc, "invalid key tag: %v", st)
|
return dyn.NilValue, errorf(loc, "invalid key tag: %v", st)
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := d.load(val)
|
v, err := d.load(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, err
|
return dyn.NilValue, err
|
||||||
}
|
}
|
||||||
|
|
||||||
acc[key.Value] = v
|
acc[key.Value] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
if merge == nil {
|
if merge == nil {
|
||||||
return config.NewValue(acc, loc), nil
|
return dyn.NewValue(acc, loc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build location for the merge node.
|
// Build location for the merge node.
|
||||||
|
@ -141,68 +141,68 @@ func (d *loader) loadMapping(node *yaml.Node, loc config.Location) (config.Value
|
||||||
case yaml.AliasNode:
|
case yaml.AliasNode:
|
||||||
mnodes = []*yaml.Node{merge}
|
mnodes = []*yaml.Node{merge}
|
||||||
default:
|
default:
|
||||||
return config.NilValue, merr
|
return dyn.NilValue, merr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a sequence of values to merge.
|
// Build a sequence of values to merge.
|
||||||
// The entries that we already accumulated have precedence.
|
// The entries that we already accumulated have precedence.
|
||||||
var seq []map[string]config.Value
|
var seq []map[string]dyn.Value
|
||||||
for _, n := range mnodes {
|
for _, n := range mnodes {
|
||||||
v, err := d.load(n)
|
v, err := d.load(n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, err
|
return dyn.NilValue, err
|
||||||
}
|
}
|
||||||
m, ok := v.AsMap()
|
m, ok := v.AsMap()
|
||||||
if !ok {
|
if !ok {
|
||||||
return config.NilValue, merr
|
return dyn.NilValue, merr
|
||||||
}
|
}
|
||||||
seq = append(seq, m)
|
seq = append(seq, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the accumulated entries to the sequence.
|
// Append the accumulated entries to the sequence.
|
||||||
seq = append(seq, acc)
|
seq = append(seq, acc)
|
||||||
out := make(map[string]config.Value)
|
out := make(map[string]dyn.Value)
|
||||||
for _, m := range seq {
|
for _, m := range seq {
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
out[k] = v
|
out[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.NewValue(out, loc), nil
|
return dyn.NewValue(out, loc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *loader) loadScalar(node *yaml.Node, loc config.Location) (config.Value, error) {
|
func (d *loader) loadScalar(node *yaml.Node, loc dyn.Location) (dyn.Value, error) {
|
||||||
st := node.ShortTag()
|
st := node.ShortTag()
|
||||||
switch st {
|
switch st {
|
||||||
case "!!str":
|
case "!!str":
|
||||||
return config.NewValue(node.Value, loc), nil
|
return dyn.NewValue(node.Value, loc), nil
|
||||||
case "!!bool":
|
case "!!bool":
|
||||||
switch strings.ToLower(node.Value) {
|
switch strings.ToLower(node.Value) {
|
||||||
case "true":
|
case "true":
|
||||||
return config.NewValue(true, loc), nil
|
return dyn.NewValue(true, loc), nil
|
||||||
case "false":
|
case "false":
|
||||||
return config.NewValue(false, loc), nil
|
return dyn.NewValue(false, loc), nil
|
||||||
default:
|
default:
|
||||||
return config.NilValue, errorf(loc, "invalid bool value: %v", node.Value)
|
return dyn.NilValue, errorf(loc, "invalid bool value: %v", node.Value)
|
||||||
}
|
}
|
||||||
case "!!int":
|
case "!!int":
|
||||||
i64, err := strconv.ParseInt(node.Value, 10, 64)
|
i64, err := strconv.ParseInt(node.Value, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, errorf(loc, "invalid int value: %v", node.Value)
|
return dyn.NilValue, errorf(loc, "invalid int value: %v", node.Value)
|
||||||
}
|
}
|
||||||
// Use regular int type instead of int64 if possible.
|
// Use regular int type instead of int64 if possible.
|
||||||
if i64 >= math.MinInt32 && i64 <= math.MaxInt32 {
|
if i64 >= math.MinInt32 && i64 <= math.MaxInt32 {
|
||||||
return config.NewValue(int(i64), loc), nil
|
return dyn.NewValue(int(i64), loc), nil
|
||||||
}
|
}
|
||||||
return config.NewValue(i64, loc), nil
|
return dyn.NewValue(i64, loc), nil
|
||||||
case "!!float":
|
case "!!float":
|
||||||
f64, err := strconv.ParseFloat(node.Value, 64)
|
f64, err := strconv.ParseFloat(node.Value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config.NilValue, errorf(loc, "invalid float value: %v", node.Value)
|
return dyn.NilValue, errorf(loc, "invalid float value: %v", node.Value)
|
||||||
}
|
}
|
||||||
return config.NewValue(f64, loc), nil
|
return dyn.NewValue(f64, loc), nil
|
||||||
case "!!null":
|
case "!!null":
|
||||||
return config.NewValue(nil, loc), nil
|
return dyn.NewValue(nil, loc), nil
|
||||||
case "!!timestamp":
|
case "!!timestamp":
|
||||||
// Try a couple of layouts
|
// Try a couple of layouts
|
||||||
for _, layout := range []string{
|
for _, layout := range []string{
|
||||||
|
@ -213,15 +213,15 @@ func (d *loader) loadScalar(node *yaml.Node, loc config.Location) (config.Value,
|
||||||
} {
|
} {
|
||||||
t, terr := time.Parse(layout, node.Value)
|
t, terr := time.Parse(layout, node.Value)
|
||||||
if terr == nil {
|
if terr == nil {
|
||||||
return config.NewValue(t, loc), nil
|
return dyn.NewValue(t, loc), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return config.NilValue, errorf(loc, "invalid timestamp value: %v", node.Value)
|
return dyn.NilValue, errorf(loc, "invalid timestamp value: %v", node.Value)
|
||||||
default:
|
default:
|
||||||
return config.NilValue, errorf(loc, "unknown tag: %v", st)
|
return dyn.NilValue, errorf(loc, "unknown tag: %v", st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *loader) loadAlias(node *yaml.Node, loc config.Location) (config.Value, error) {
|
func (d *loader) loadAlias(node *yaml.Node, loc dyn.Location) (dyn.Value, error) {
|
||||||
return d.load(node.Alias)
|
return d.load(node.Alias)
|
||||||
}
|
}
|
|
@ -3,19 +3,19 @@ package yamlloader
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadYAML(path string, r io.Reader) (config.Value, error) {
|
func LoadYAML(path string, r io.Reader) (dyn.Value, error) {
|
||||||
var node yaml.Node
|
var node yaml.Node
|
||||||
dec := yaml.NewDecoder(r)
|
dec := yaml.NewDecoder(r)
|
||||||
err := dec.Decode(&node)
|
err := dec.Decode(&node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return config.NilValue, nil
|
return dyn.NilValue, nil
|
||||||
}
|
}
|
||||||
return config.NilValue, err
|
return dyn.NilValue, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return newLoader(path).load(&node)
|
return newLoader(path).load(&node)
|
|
@ -3,14 +3,14 @@ package yamlloader_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestYAMLAnchor01(t *testing.T) {
|
func TestYAMLAnchor01(t *testing.T) {
|
||||||
file := "testdata/anchor_01.yml"
|
file := "testdata/anchor_01.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
assert.True(t, self.Get("defaults").IsAnchor())
|
assert.True(t, self.Get("defaults").IsAnchor())
|
||||||
assert.False(t, self.Get("shirt1").IsAnchor())
|
assert.False(t, self.Get("shirt1").IsAnchor())
|
||||||
|
@ -18,31 +18,31 @@ func TestYAMLAnchor01(t *testing.T) {
|
||||||
|
|
||||||
pattern := self.Get("shirt1").Get("pattern")
|
pattern := self.Get("shirt1").Get("pattern")
|
||||||
assert.Equal(t, "striped", pattern.AsAny())
|
assert.Equal(t, "striped", pattern.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 8, Column: 12}, pattern.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 8, Column: 12}, pattern.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestYAMLAnchor02(t *testing.T) {
|
func TestYAMLAnchor02(t *testing.T) {
|
||||||
file := "testdata/anchor_02.yml"
|
file := "testdata/anchor_02.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
color := self.Get("shirt").Get("color")
|
color := self.Get("shirt").Get("color")
|
||||||
assert.Equal(t, "red", color.AsAny())
|
assert.Equal(t, "red", color.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 4, Column: 10}, color.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 4, Column: 10}, color.Location())
|
||||||
|
|
||||||
primary := self.Get("shirt").Get("primary")
|
primary := self.Get("shirt").Get("primary")
|
||||||
assert.Equal(t, "cotton", primary.AsAny())
|
assert.Equal(t, "cotton", primary.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 8, Column: 12}, primary.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 8, Column: 12}, primary.Location())
|
||||||
|
|
||||||
pattern := self.Get("shirt").Get("pattern")
|
pattern := self.Get("shirt").Get("pattern")
|
||||||
assert.Equal(t, "striped", pattern.AsAny())
|
assert.Equal(t, "striped", pattern.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 13, Column: 12}, pattern.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 13, Column: 12}, pattern.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestYAMLAnchor03(t *testing.T) {
|
func TestYAMLAnchor03(t *testing.T) {
|
||||||
file := "testdata/anchor_03.yml"
|
file := "testdata/anchor_03.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
// Assert the override took place.
|
// Assert the override took place.
|
||||||
blue := self.Get("shirt").Get("color")
|
blue := self.Get("shirt").Get("color")
|
||||||
|
@ -55,63 +55,63 @@ func TestYAMLAnchor03(t *testing.T) {
|
||||||
func TestYAMLAnchor04(t *testing.T) {
|
func TestYAMLAnchor04(t *testing.T) {
|
||||||
file := "testdata/anchor_04.yml"
|
file := "testdata/anchor_04.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
p1 := self.Get("person1").Get("address").Get("city")
|
p1 := self.Get("person1").Get("address").Get("city")
|
||||||
assert.Equal(t, "San Francisco", p1.AsAny())
|
assert.Equal(t, "San Francisco", p1.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 4, Column: 9}, p1.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 4, Column: 9}, p1.Location())
|
||||||
|
|
||||||
p2 := self.Get("person2").Get("address").Get("city")
|
p2 := self.Get("person2").Get("address").Get("city")
|
||||||
assert.Equal(t, "Los Angeles", p2.AsAny())
|
assert.Equal(t, "Los Angeles", p2.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 16, Column: 11}, p2.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 16, Column: 11}, p2.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestYAMLAnchor05(t *testing.T) {
|
func TestYAMLAnchor05(t *testing.T) {
|
||||||
file := "testdata/anchor_05.yml"
|
file := "testdata/anchor_05.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
features := self.Get("phone1").Get("features")
|
features := self.Get("phone1").Get("features")
|
||||||
assert.Equal(t, "wifi", features.Index(0).AsAny())
|
assert.Equal(t, "wifi", features.Index(0).AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 4, Column: 5}, features.Index(0).Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 4, Column: 5}, features.Index(0).Location())
|
||||||
assert.Equal(t, "bluetooth", features.Index(1).AsAny())
|
assert.Equal(t, "bluetooth", features.Index(1).AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 5, Column: 5}, features.Index(1).Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 5, Column: 5}, features.Index(1).Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestYAMLAnchor06(t *testing.T) {
|
func TestYAMLAnchor06(t *testing.T) {
|
||||||
file := "testdata/anchor_06.yml"
|
file := "testdata/anchor_06.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
greeting := self.Get("greeting1")
|
greeting := self.Get("greeting1")
|
||||||
assert.Equal(t, "Hello, World!", greeting.AsAny())
|
assert.Equal(t, "Hello, World!", greeting.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 2, Column: 16}, greeting.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 2, Column: 16}, greeting.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestYAMLAnchor07(t *testing.T) {
|
func TestYAMLAnchor07(t *testing.T) {
|
||||||
file := "testdata/anchor_07.yml"
|
file := "testdata/anchor_07.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
name := self.Get("person1").Get("name")
|
name := self.Get("person1").Get("name")
|
||||||
assert.Equal(t, "Alice", name.AsAny())
|
assert.Equal(t, "Alice", name.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 5, Column: 9}, name.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 5, Column: 9}, name.Location())
|
||||||
|
|
||||||
age := self.Get("person1").Get("age")
|
age := self.Get("person1").Get("age")
|
||||||
assert.Equal(t, 25, age.AsAny())
|
assert.Equal(t, 25, age.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 2, Column: 13}, age.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 2, Column: 13}, age.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestYAMLAnchor08(t *testing.T) {
|
func TestYAMLAnchor08(t *testing.T) {
|
||||||
file := "testdata/anchor_08.yml"
|
file := "testdata/anchor_08.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
username := self.Get("user1").Get("username")
|
username := self.Get("user1").Get("username")
|
||||||
assert.Equal(t, "user1", username.AsAny())
|
assert.Equal(t, "user1", username.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 5, Column: 13}, username.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 5, Column: 13}, username.Location())
|
||||||
|
|
||||||
active := self.Get("user1").Get("active")
|
active := self.Get("user1").Get("active")
|
||||||
assert.Equal(t, true, active.AsAny())
|
assert.Equal(t, true, active.AsAny())
|
||||||
assert.Equal(t, config.Location{File: file, Line: 2, Column: 11}, active.Location())
|
assert.Equal(t, dyn.Location{File: file, Line: 2, Column: 11}, active.Location())
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config/yamlloader"
|
"github.com/databricks/cli/libs/dyn/yamlloader"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
|
@ -3,14 +3,14 @@ package yamlloader_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestYAMLMix01(t *testing.T) {
|
func TestYAMLMix01(t *testing.T) {
|
||||||
file := "testdata/mix_01.yml"
|
file := "testdata/mix_01.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
assert.True(t, self.Get("base_address").IsAnchor())
|
assert.True(t, self.Get("base_address").IsAnchor())
|
||||||
assert.False(t, self.Get("office_address").IsAnchor())
|
assert.False(t, self.Get("office_address").IsAnchor())
|
||||||
|
@ -19,7 +19,7 @@ func TestYAMLMix01(t *testing.T) {
|
||||||
func TestYAMLMix02(t *testing.T) {
|
func TestYAMLMix02(t *testing.T) {
|
||||||
file := "testdata/mix_02.yml"
|
file := "testdata/mix_02.yml"
|
||||||
self := loadYAML(t, file)
|
self := loadYAML(t, file)
|
||||||
assert.NotEqual(t, config.NilValue, self)
|
assert.NotEqual(t, dyn.NilValue, self)
|
||||||
|
|
||||||
assert.True(t, self.Get("base_colors").IsAnchor())
|
assert.True(t, self.Get("base_colors").IsAnchor())
|
||||||
assert.False(t, self.Get("theme").IsAnchor())
|
assert.False(t, self.Get("theme").IsAnchor())
|
|
@ -5,14 +5,14 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/config"
|
"github.com/databricks/cli/libs/dyn"
|
||||||
"github.com/databricks/cli/libs/config/yamlloader"
|
"github.com/databricks/cli/libs/dyn/yamlloader"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadYAML(t *testing.T, path string) config.Value {
|
func loadYAML(t *testing.T, path string) dyn.Value {
|
||||||
input, err := os.ReadFile(path)
|
input, err := os.ReadFile(path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -31,5 +31,5 @@ func loadYAML(t *testing.T, path string) config.Value {
|
||||||
|
|
||||||
func TestYAMLEmpty(t *testing.T) {
|
func TestYAMLEmpty(t *testing.T) {
|
||||||
self := loadYAML(t, "testdata/empty.yml")
|
self := loadYAML(t, "testdata/empty.yml")
|
||||||
assert.Equal(t, config.NilValue, self)
|
assert.Equal(t, dyn.NilValue, self)
|
||||||
}
|
}
|
Loading…
Reference in New Issue