2019-11-23 03:52:29 +00:00
|
|
|
package yqlib
|
2015-09-28 01:39:16 +00:00
|
|
|
|
2019-12-09 02:44:53 +00:00
|
|
|
// import (
|
|
|
|
// "fmt"
|
|
|
|
// "sort"
|
|
|
|
// "testing"
|
|
|
|
|
|
|
|
// "github.com/mikefarah/yq/v2/test"
|
|
|
|
// logging "gopkg.in/op/go-logging.v1"
|
|
|
|
// )
|
|
|
|
|
|
|
|
// func TestDataNavigator(t *testing.T) {
|
|
|
|
// var log = logging.MustGetLogger("yq")
|
|
|
|
// subject := NewDataNavigator(log)
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_simple", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"b", "c"})
|
|
|
|
// test.AssertResult(t, 2, got)
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_numberKey", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// 200: things
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"200"})
|
|
|
|
// test.AssertResult(t, "things", got)
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_splat", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// mapSplat:
|
|
|
|
// item1: things
|
|
|
|
// item2: whatever
|
|
|
|
// otherThing: cat
|
|
|
|
// `)
|
|
|
|
// res, _ := subject.ReadChildValue(data, []string{"mapSplat", "*"})
|
|
|
|
// test.AssertResult(t, "[things whatever cat]", fmt.Sprintf("%v", res))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_prefixSplat", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// mapSplat:
|
|
|
|
// item1: things
|
|
|
|
// item2: whatever
|
|
|
|
// otherThing: cat
|
|
|
|
// `)
|
|
|
|
// res, _ := subject.ReadChildValue(data, []string{"mapSplat", "item*"})
|
|
|
|
// test.AssertResult(t, "[things whatever]", fmt.Sprintf("%v", res))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_deep_splat", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// mapSplatDeep:
|
|
|
|
// item1:
|
|
|
|
// cats: bananas
|
|
|
|
// item2:
|
|
|
|
// cats: apples
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// res, _ := subject.ReadChildValue(data, []string{"mapSplatDeep", "*", "cats"})
|
|
|
|
// result := res.([]interface{})
|
|
|
|
// var actual = []string{result[0].(string), result[1].(string)}
|
|
|
|
// sort.Strings(actual)
|
|
|
|
// test.AssertResult(t, "[apples bananas]", fmt.Sprintf("%v", actual))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_key_doesnt_exist", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"b", "x", "f", "c"})
|
|
|
|
// test.AssertResult(t, nil, got)
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_recurse_against_string", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// a: cat
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"a", "b"})
|
|
|
|
// test.AssertResult(t, nil, got)
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_with_array", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// d:
|
|
|
|
// - 3
|
|
|
|
// - 4
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"b", "d", "1"})
|
|
|
|
// test.AssertResult(t, 4, got)
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_with_array_and_bad_index", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// d:
|
|
|
|
// - 3
|
|
|
|
// - 4
|
|
|
|
// `)
|
|
|
|
// _, err := subject.ReadChildValue(data, []string{"b", "d", "x"})
|
|
|
|
// if err == nil {
|
|
|
|
// t.Fatal("Expected error due to invalid path")
|
|
|
|
// }
|
|
|
|
// expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
|
|
|
// test.AssertResult(t, expectedOutput, err.Error())
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_with_mapsplat_array_and_bad_index", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// d:
|
|
|
|
// e:
|
|
|
|
// - 3
|
|
|
|
// - 4
|
|
|
|
// f:
|
|
|
|
// - 1
|
|
|
|
// - 2
|
|
|
|
// `)
|
|
|
|
// _, err := subject.ReadChildValue(data, []string{"b", "d", "*", "x"})
|
|
|
|
// if err == nil {
|
|
|
|
// t.Fatal("Expected error due to invalid path")
|
|
|
|
// }
|
|
|
|
// expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
|
|
|
// test.AssertResult(t, expectedOutput, err.Error())
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_with_arraysplat_map_array_and_bad_index", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// d:
|
|
|
|
// - names:
|
|
|
|
// - fred
|
|
|
|
// - smith
|
|
|
|
// - names:
|
|
|
|
// - sam
|
|
|
|
// - bo
|
|
|
|
// `)
|
|
|
|
// _, err := subject.ReadChildValue(data, []string{"b", "d", "*", "names", "x"})
|
|
|
|
// if err == nil {
|
|
|
|
// t.Fatal("Expected error due to invalid path")
|
|
|
|
// }
|
|
|
|
// expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
|
|
|
// test.AssertResult(t, expectedOutput, err.Error())
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_with_array_out_of_bounds", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// d:
|
|
|
|
// - 3
|
|
|
|
// - 4
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"b", "d", "3"})
|
|
|
|
// test.AssertResult(t, nil, got)
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_with_array_out_of_bounds_by_1", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// ---
|
|
|
|
// b:
|
|
|
|
// d:
|
|
|
|
// - 3
|
|
|
|
// - 4
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"b", "d", "2"})
|
|
|
|
// test.AssertResult(t, nil, got)
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestReadMap_with_array_splat", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// e:
|
|
|
|
// -
|
|
|
|
// name: Fred
|
|
|
|
// thing: cat
|
|
|
|
// -
|
|
|
|
// name: Sam
|
|
|
|
// thing: dog
|
|
|
|
// `)
|
|
|
|
// got, _ := subject.ReadChildValue(data, []string{"e", "*", "name"})
|
|
|
|
// test.AssertResult(t, "[Fred Sam]", fmt.Sprintf("%v", got))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_really_simple", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b: 2
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b"}, "4")
|
|
|
|
// test.AssertResult(t, "[{b 4}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_simple", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "c"}, "4")
|
|
|
|
// test.AssertResult(t, "[{b [{c 4}]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_new", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "d"}, "4")
|
|
|
|
// test.AssertResult(t, "[{b [{c 2} {d 4}]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_new_deep", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "d", "f"}, "4")
|
|
|
|
// test.AssertResult(t, "[{b [{c 2} {d [{f 4}]}]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_array", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// - aa
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "0"}, "bb")
|
|
|
|
|
|
|
|
// test.AssertResult(t, "[{b [bb]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_new_array", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "0"}, "4")
|
|
|
|
// test.AssertResult(t, "[{b [{c 2} {0 4}]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_new_array_deep", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// a: apple
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "+", "c"}, "4")
|
|
|
|
// test.AssertResult(t, "[{a apple} {b [[{c 4}]]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_new_map_array_deep", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "d", "+"}, "4")
|
|
|
|
// test.AssertResult(t, "[{b [{c 2} {d [4]}]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_add_to_array", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// - aa
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b", "1"}, "bb")
|
|
|
|
// test.AssertResult(t, "[{b [aa bb]}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWrite_with_no_tail", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// c: 2
|
|
|
|
// `)
|
|
|
|
// updated := subject.UpdatedChildValue(data, []string{"b"}, "4")
|
|
|
|
|
|
|
|
// test.AssertResult(t, "[{b 4}]", fmt.Sprintf("%v", updated))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWriteMap_no_paths", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b: 5
|
|
|
|
// `)
|
|
|
|
// var new = test.ParseData(`
|
|
|
|
// c: 4
|
|
|
|
// `)
|
|
|
|
// result := subject.UpdatedChildValue(data, []string{}, new)
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", new), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestWriteArray_no_paths", func(t *testing.T) {
|
|
|
|
// var data = make([]interface{}, 1)
|
|
|
|
// data[0] = "mike"
|
|
|
|
// var new = test.ParseData(`
|
|
|
|
// c: 4
|
|
|
|
// `)
|
|
|
|
// result := subject.UpdatedChildValue(data, []string{}, new)
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", new), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestDelete_MapItem", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// a: 123
|
|
|
|
// b: 456
|
|
|
|
// `)
|
|
|
|
// var expected = test.ParseData(`
|
|
|
|
// b: 456
|
|
|
|
// `)
|
|
|
|
|
|
|
|
// result, _ := subject.DeleteChildValue(data, []string{"a"})
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// // Ensure deleting an index into a string does nothing
|
|
|
|
// t.Run("TestDelete_index_to_string", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// a: mystring
|
|
|
|
// `)
|
|
|
|
// result, _ := subject.DeleteChildValue(data, []string{"a", "0"})
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestDelete_list_index", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// a: [3, 4]
|
|
|
|
// `)
|
|
|
|
// var expected = test.ParseData(`
|
|
|
|
// a: [3]
|
|
|
|
// `)
|
|
|
|
// result, _ := subject.DeleteChildValue(data, []string{"a", "1"})
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestDelete_list_index_beyond_bounds", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// a: [3, 4]
|
|
|
|
// `)
|
|
|
|
// result, _ := subject.DeleteChildValue(data, []string{"a", "5"})
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestDelete_list_index_out_of_bounds_by_1", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// a: [3, 4]
|
|
|
|
// `)
|
|
|
|
// result, _ := subject.DeleteChildValue(data, []string{"a", "2"})
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestDelete_no_paths", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// a: [3, 4]
|
|
|
|
// b:
|
|
|
|
// - name: test
|
|
|
|
// `)
|
|
|
|
// result, _ := subject.DeleteChildValue(data, []string{})
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// t.Run("TestDelete_array_map_item", func(t *testing.T) {
|
|
|
|
// var data = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// - name: fred
|
|
|
|
// value: blah
|
|
|
|
// - name: john
|
|
|
|
// value: test
|
|
|
|
// `)
|
|
|
|
// var expected = test.ParseData(`
|
|
|
|
// b:
|
|
|
|
// - value: blah
|
|
|
|
// - name: john
|
|
|
|
// value: test
|
|
|
|
// `)
|
|
|
|
// result, _ := subject.DeleteChildValue(data, []string{"b", "0", "name"})
|
|
|
|
// test.AssertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result))
|
|
|
|
// })
|
|
|
|
// }
|