2023-11-03 19:15:47 +00:00
|
|
|
package merge
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
2023-12-22 13:20:45 +00:00
|
|
|
"github.com/databricks/cli/libs/dyn"
|
2024-03-25 11:01:09 +00:00
|
|
|
assert "github.com/databricks/cli/libs/dyn/dynassert"
|
2023-11-03 19:15:47 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestMergeMaps(t *testing.T) {
|
2024-07-16 11:27:27 +00:00
|
|
|
l1 := dyn.Location{File: "file1", Line: 1, Column: 2}
|
|
|
|
v1 := dyn.NewValue(map[string]dyn.Value{
|
|
|
|
"foo": dyn.NewValue("bar", []dyn.Location{l1}),
|
|
|
|
"bar": dyn.NewValue("baz", []dyn.Location{l1}),
|
|
|
|
}, []dyn.Location{l1})
|
2023-11-03 19:15:47 +00:00
|
|
|
|
2024-07-16 11:27:27 +00:00
|
|
|
l2 := dyn.Location{File: "file2", Line: 3, Column: 4}
|
|
|
|
v2 := dyn.NewValue(map[string]dyn.Value{
|
|
|
|
"bar": dyn.NewValue("qux", []dyn.Location{l2}),
|
|
|
|
"qux": dyn.NewValue("foo", []dyn.Location{l2}),
|
|
|
|
}, []dyn.Location{l2})
|
2023-11-03 19:15:47 +00:00
|
|
|
|
|
|
|
// Merge v2 into v1.
|
|
|
|
{
|
|
|
|
out, err := Merge(v1, v2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, map[string]any{
|
|
|
|
"foo": "bar",
|
|
|
|
"bar": "qux",
|
|
|
|
"qux": "foo",
|
|
|
|
}, out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l1, l2}, out.Locations())
|
|
|
|
assert.Equal(t, []dyn.Location{l2, l1}, out.Get("bar").Locations())
|
|
|
|
assert.Equal(t, []dyn.Location{l1}, out.Get("foo").Locations())
|
|
|
|
assert.Equal(t, []dyn.Location{l2}, out.Get("qux").Locations())
|
|
|
|
|
|
|
|
// Location of the merged value should be the location of v1.
|
|
|
|
assert.Equal(t, l1, out.Location())
|
|
|
|
|
|
|
|
// Value of bar is "qux" which comes from v2. This .Location() should
|
|
|
|
// return the location of v2.
|
|
|
|
assert.Equal(t, l2, out.Get("bar").Location())
|
|
|
|
|
|
|
|
// Original locations of keys that were not overwritten should be preserved.
|
|
|
|
assert.Equal(t, l1, out.Get("foo").Location())
|
|
|
|
assert.Equal(t, l2, out.Get("qux").Location())
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Merge v1 into v2.
|
|
|
|
{
|
|
|
|
out, err := Merge(v2, v1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, map[string]any{
|
|
|
|
"foo": "bar",
|
|
|
|
"bar": "baz",
|
|
|
|
"qux": "foo",
|
|
|
|
}, out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l2, l1}, out.Locations())
|
|
|
|
assert.Equal(t, []dyn.Location{l1, l2}, out.Get("bar").Locations())
|
|
|
|
assert.Equal(t, []dyn.Location{l1}, out.Get("foo").Locations())
|
|
|
|
assert.Equal(t, []dyn.Location{l2}, out.Get("qux").Locations())
|
|
|
|
|
|
|
|
// Location of the merged value should be the location of v2.
|
|
|
|
assert.Equal(t, l2, out.Location())
|
|
|
|
|
|
|
|
// Value of bar is "baz" which comes from v1. This .Location() should
|
|
|
|
// return the location of v1.
|
|
|
|
assert.Equal(t, l1, out.Get("bar").Location())
|
|
|
|
|
|
|
|
// Original locations of keys that were not overwritten should be preserved.
|
|
|
|
assert.Equal(t, l1, out.Get("foo").Location())
|
|
|
|
assert.Equal(t, l2, out.Get("qux").Location())
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
2024-07-16 11:27:27 +00:00
|
|
|
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergeMapsNil(t *testing.T) {
|
2024-07-16 11:27:27 +00:00
|
|
|
l := dyn.Location{File: "file", Line: 1, Column: 2}
|
|
|
|
v := dyn.NewValue(map[string]dyn.Value{
|
2023-12-22 13:20:45 +00:00
|
|
|
"foo": dyn.V("bar"),
|
2024-07-16 11:27:27 +00:00
|
|
|
}, []dyn.Location{l})
|
|
|
|
|
|
|
|
nilL := dyn.Location{File: "file", Line: 3, Column: 4}
|
|
|
|
nilV := dyn.NewValue(nil, []dyn.Location{nilL})
|
2023-11-03 19:15:47 +00:00
|
|
|
|
|
|
|
// Merge nil into v.
|
|
|
|
{
|
2024-07-16 11:27:27 +00:00
|
|
|
out, err := Merge(v, nilV)
|
2023-11-03 19:15:47 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, map[string]any{
|
|
|
|
"foo": "bar",
|
|
|
|
}, out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l, nilL}, out.Locations())
|
|
|
|
|
|
|
|
// Location of the non-nil value should be returned by .Location().
|
|
|
|
assert.Equal(t, l, out.Location())
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Merge v into nil.
|
|
|
|
{
|
2024-07-16 11:27:27 +00:00
|
|
|
out, err := Merge(nilV, v)
|
2023-11-03 19:15:47 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, map[string]any{
|
|
|
|
"foo": "bar",
|
|
|
|
}, out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l, nilL}, out.Locations())
|
|
|
|
|
|
|
|
// Location of the non-nil value should be returned by .Location().
|
|
|
|
assert.Equal(t, l, out.Location())
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergeMapsError(t *testing.T) {
|
2023-12-22 13:20:45 +00:00
|
|
|
v := dyn.V(map[string]dyn.Value{
|
|
|
|
"foo": dyn.V("bar"),
|
2023-11-03 19:15:47 +00:00
|
|
|
})
|
|
|
|
|
2023-12-22 13:20:45 +00:00
|
|
|
other := dyn.V("string")
|
2023-11-03 19:15:47 +00:00
|
|
|
|
|
|
|
// Merge a string into v.
|
|
|
|
{
|
|
|
|
out, err := Merge(v, other)
|
|
|
|
assert.EqualError(t, err, "cannot merge map with string")
|
2024-06-21 14:22:42 +00:00
|
|
|
assert.Equal(t, dyn.InvalidValue, out)
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergeSequences(t *testing.T) {
|
2024-07-16 11:27:27 +00:00
|
|
|
l1 := dyn.Location{File: "file1", Line: 1, Column: 2}
|
|
|
|
v1 := dyn.NewValue([]dyn.Value{
|
|
|
|
dyn.NewValue("bar", []dyn.Location{l1}),
|
|
|
|
dyn.NewValue("baz", []dyn.Location{l1}),
|
|
|
|
}, []dyn.Location{l1})
|
2023-11-03 19:15:47 +00:00
|
|
|
|
2024-07-16 11:27:27 +00:00
|
|
|
l2 := dyn.Location{File: "file2", Line: 3, Column: 4}
|
|
|
|
l3 := dyn.Location{File: "file3", Line: 5, Column: 6}
|
|
|
|
v2 := dyn.NewValue([]dyn.Value{
|
|
|
|
dyn.NewValue("qux", []dyn.Location{l2}),
|
|
|
|
dyn.NewValue("foo", []dyn.Location{l3}),
|
|
|
|
}, []dyn.Location{l2, l3})
|
2023-11-03 19:15:47 +00:00
|
|
|
|
|
|
|
// Merge v2 into v1.
|
|
|
|
{
|
|
|
|
out, err := Merge(v1, v2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, []any{
|
|
|
|
"bar",
|
|
|
|
"baz",
|
|
|
|
"qux",
|
|
|
|
"foo",
|
|
|
|
}, out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l1, l2, l3}, out.Locations())
|
|
|
|
|
|
|
|
// Location of the merged value should be the location of v1.
|
|
|
|
assert.Equal(t, l1, out.Location())
|
|
|
|
|
|
|
|
// Location of the individual values should be preserved.
|
|
|
|
assert.Equal(t, l1, out.Index(0).Location()) // "bar"
|
|
|
|
assert.Equal(t, l1, out.Index(1).Location()) // "baz"
|
|
|
|
assert.Equal(t, l2, out.Index(2).Location()) // "qux"
|
|
|
|
assert.Equal(t, l3, out.Index(3).Location()) // "foo"
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Merge v1 into v2.
|
|
|
|
{
|
|
|
|
out, err := Merge(v2, v1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, []any{
|
|
|
|
"qux",
|
|
|
|
"foo",
|
|
|
|
"bar",
|
|
|
|
"baz",
|
|
|
|
}, out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l2, l3, l1}, out.Locations())
|
|
|
|
|
|
|
|
// Location of the merged value should be the location of v2.
|
|
|
|
assert.Equal(t, l2, out.Location())
|
|
|
|
|
|
|
|
// Location of the individual values should be preserved.
|
|
|
|
assert.Equal(t, l2, out.Index(0).Location()) // "qux"
|
|
|
|
assert.Equal(t, l3, out.Index(1).Location()) // "foo"
|
|
|
|
assert.Equal(t, l1, out.Index(2).Location()) // "bar"
|
|
|
|
assert.Equal(t, l1, out.Index(3).Location()) // "baz"
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergeSequencesNil(t *testing.T) {
|
2023-12-22 13:20:45 +00:00
|
|
|
v := dyn.V([]dyn.Value{
|
|
|
|
dyn.V("bar"),
|
2023-11-03 19:15:47 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
// Merge nil into v.
|
|
|
|
{
|
2023-12-22 13:20:45 +00:00
|
|
|
out, err := Merge(v, dyn.NilValue)
|
2023-11-03 19:15:47 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, []any{
|
|
|
|
"bar",
|
|
|
|
}, out.AsAny())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge v into nil.
|
|
|
|
{
|
2023-12-22 13:20:45 +00:00
|
|
|
out, err := Merge(dyn.NilValue, v)
|
2023-11-03 19:15:47 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, []any{
|
|
|
|
"bar",
|
|
|
|
}, out.AsAny())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergeSequencesError(t *testing.T) {
|
2023-12-22 13:20:45 +00:00
|
|
|
v := dyn.V([]dyn.Value{
|
|
|
|
dyn.V("bar"),
|
2023-11-03 19:15:47 +00:00
|
|
|
})
|
|
|
|
|
2023-12-22 13:20:45 +00:00
|
|
|
other := dyn.V("string")
|
2023-11-03 19:15:47 +00:00
|
|
|
|
|
|
|
// Merge a string into v.
|
|
|
|
{
|
|
|
|
out, err := Merge(v, other)
|
|
|
|
assert.EqualError(t, err, "cannot merge sequence with string")
|
2024-06-21 14:22:42 +00:00
|
|
|
assert.Equal(t, dyn.InvalidValue, out)
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergePrimitives(t *testing.T) {
|
2024-07-16 11:27:27 +00:00
|
|
|
l1 := dyn.Location{File: "file1", Line: 1, Column: 2}
|
|
|
|
l2 := dyn.Location{File: "file2", Line: 3, Column: 4}
|
|
|
|
v1 := dyn.NewValue("bar", []dyn.Location{l1})
|
|
|
|
v2 := dyn.NewValue("baz", []dyn.Location{l2})
|
2023-11-03 19:15:47 +00:00
|
|
|
|
|
|
|
// Merge v2 into v1.
|
|
|
|
{
|
|
|
|
out, err := Merge(v1, v2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "baz", out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l2, l1}, out.Locations())
|
|
|
|
|
|
|
|
// Location of the merged value should be the location of v2, the second value.
|
|
|
|
assert.Equal(t, l2, out.Location())
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Merge v1 into v2.
|
|
|
|
{
|
|
|
|
out, err := Merge(v2, v1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "bar", out.AsAny())
|
2024-07-16 11:27:27 +00:00
|
|
|
|
|
|
|
// Locations of both values should be preserved.
|
|
|
|
assert.Equal(t, []dyn.Location{l1, l2}, out.Locations())
|
|
|
|
|
|
|
|
// Location of the merged value should be the location of v1, the second value.
|
|
|
|
assert.Equal(t, l1, out.Location())
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergePrimitivesNil(t *testing.T) {
|
2023-12-22 13:20:45 +00:00
|
|
|
v := dyn.V("bar")
|
2023-11-03 19:15:47 +00:00
|
|
|
|
|
|
|
// Merge nil into v.
|
|
|
|
{
|
2023-12-22 13:20:45 +00:00
|
|
|
out, err := Merge(v, dyn.NilValue)
|
2023-11-03 19:15:47 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "bar", out.AsAny())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge v into nil.
|
|
|
|
{
|
2023-12-22 13:20:45 +00:00
|
|
|
out, err := Merge(dyn.NilValue, v)
|
2023-11-03 19:15:47 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "bar", out.AsAny())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergePrimitivesError(t *testing.T) {
|
2023-12-22 13:20:45 +00:00
|
|
|
v := dyn.V("bar")
|
|
|
|
other := dyn.V(map[string]dyn.Value{
|
|
|
|
"foo": dyn.V("bar"),
|
2023-11-03 19:15:47 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
// Merge a map into v.
|
|
|
|
{
|
|
|
|
out, err := Merge(v, other)
|
|
|
|
assert.EqualError(t, err, "cannot merge string with map")
|
2024-06-21 14:22:42 +00:00
|
|
|
assert.Equal(t, dyn.InvalidValue, out)
|
2023-11-03 19:15:47 +00:00
|
|
|
}
|
|
|
|
}
|