From 0a459e938dc9a38fa481e54832babad2f2015921 Mon Sep 17 00:00:00 2001 From: RiyaJohn Date: Thu, 16 Apr 2020 14:15:33 +0530 Subject: [PATCH 1/7] add float to test case to check leading zeroes in exponent parts --- example-crlf.toml | 1 + example.toml | 1 + parser_test.go | 2 ++ tomltree_write_test.go | 1 + 4 files changed, 5 insertions(+) diff --git a/example-crlf.toml b/example-crlf.toml index 12950a1..780d9c6 100644 --- a/example-crlf.toml +++ b/example-crlf.toml @@ -27,3 +27,4 @@ enabled = true [clients] data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it +score = 4e-08 # to make sure leading zeroes in exponent parts of floats are supported \ No newline at end of file diff --git a/example.toml b/example.toml index 3d902f2..f45bf88 100644 --- a/example.toml +++ b/example.toml @@ -27,3 +27,4 @@ enabled = true [clients] data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it +score = 4e-08 # to make sure leading zeroes in exponent parts of floats are supported \ No newline at end of file diff --git a/parser_test.go b/parser_test.go index a2ec3aa..65d11b0 100644 --- a/parser_test.go +++ b/parser_test.go @@ -783,6 +783,7 @@ func TestParseFile(t *testing.T) { []string{"gamma", "delta"}, []int64{1, 2}, }, + "score": 4e-08, }, }) } @@ -819,6 +820,7 @@ func TestParseFileCRLF(t *testing.T) { []string{"gamma", "delta"}, []int64{1, 2}, }, + "score": 4e-08, }, }) } diff --git a/tomltree_write_test.go b/tomltree_write_test.go index 4c6540b..efbe885 100644 --- a/tomltree_write_test.go +++ b/tomltree_write_test.go @@ -236,6 +236,7 @@ func TestTreeWriteToMapExampleFile(t *testing.T) { []interface{}{"gamma", "delta"}, []interface{}{int64(1), int64(2)}, }, + "score": 4e-08, }, } testMaps(t, tree.ToMap(), expected) From 5060c72d94abf595f2e5d327a104277416d37081 Mon Sep 17 00:00:00 2001 From: RiyaJohn Date: Fri, 17 Apr 2020 16:09:08 +0530 Subject: [PATCH 2/7] add testcase for query pkg --- query/parser_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/query/parser_test.go b/query/parser_test.go index 312f51a..af93276 100644 --- a/query/parser_test.go +++ b/query/parser_test.go @@ -407,7 +407,10 @@ func TestQueryFilterFn(t *testing.T) { assertQueryPositions(t, string(buff), "$..[?(float)]", - []interface{}{ // no float values in document + []interface{}{ + queryTestNode{ + 4e-08, toml.Position{30, 1}, + }, }) tv, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z") @@ -460,6 +463,7 @@ func TestQueryFilterFn(t *testing.T) { []interface{}{"gamma", "delta"}, []interface{}{int64(1), int64(2)}, }, + "score": 4e-08, }, toml.Position{28, 1}, }, }) From 71c324cf7b4cca08510e31463e0a68ea43ddd8fa Mon Sep 17 00:00:00 2001 From: RiyaJohn Date: Mon, 27 Apr 2020 12:06:33 +0530 Subject: [PATCH 3/7] add getArray logic --- toml.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/toml.go b/toml.go index f4d5687..7a580c9 100644 --- a/toml.go +++ b/toml.go @@ -115,12 +115,59 @@ func (t *Tree) GetPath(keys []string) interface{} { // branch based on final node type switch node := subtree.values[keys[len(keys)-1]].(type) { case *tomlValue: - return node.value + switch n := node.value.(type) { + case []interface{}: + return getArray(n) + default: + return node.value + } default: return node } } +// if homogeneous array, then return array type obj. as resp. over []interface{} +func getArray(n []interface{}) interface{} { + var str []string + var i32 []int32 + var i64 []int64 + var i []int + var f32 []float32 + var f64 []float64 + for _, value := range n { + switch v := value.(type) { + case string: + str = append(str, v) + case int32: + i32 = append(i32, v) + case int64: + i64 = append(i64, v) + case int: + i = append(i, v) + case float32: + f32 = append(f32, v) + case float64: + f64 = append(f64, v) + default: + return n + } + } + if len(str) == len(n) { + return str + } else if len(i32) == len(n) { + return i32 + } else if len(i64) == len(n) { + return i64 + } else if len(i) == len(n) { + return i + } else if len(f32) == len(n) { + return f32 + } else if len(f64) == len(n) { + return f64 + } + return n +} + // GetPosition returns the position of the given key. func (t *Tree) GetPosition(key string) Position { if key == "" { From bcacc71a18be4b36b52baf6d10a95513f94dc7b2 Mon Sep 17 00:00:00 2001 From: RiyaJohn Date: Mon, 18 May 2020 15:26:15 +0530 Subject: [PATCH 4/7] feat: add GetArray() with testcases --- toml.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++++---- toml_test.go | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 5 deletions(-) diff --git a/toml.go b/toml.go index 7a580c9..fdc74d8 100644 --- a/toml.go +++ b/toml.go @@ -90,6 +90,52 @@ func (t *Tree) Get(key string) interface{} { // GetPath returns the element in the tree indicated by 'keys'. // If keys is of length zero, the current tree is returned. func (t *Tree) GetPath(keys []string) interface{} { + if len(keys) == 0 { + return t + } + subtree := t + for _, intermediateKey := range keys[:len(keys)-1] { + value, exists := subtree.values[intermediateKey] + if !exists { + return nil + } + switch node := value.(type) { + case *Tree: + subtree = node + case []*Tree: + // go to most recent element + if len(node) == 0 { + return nil + } + subtree = node[len(node)-1] + default: + return nil // cannot navigate through other node types + } + } + // branch based on final node type + switch node := subtree.values[keys[len(keys)-1]].(type) { + case *tomlValue: + return node.value + default: + return node + } +} + +// GetArray returns the value at key in the Tree. +// It returns []string, []int64, etc type if key has homogeneous lists +// Key is a dot-separated path (e.g. a.b.c) without single/double quoted strings. +// Returns nil if the path does not exist in the tree. +// If keys is of length zero, the current tree is returned. +func (t *Tree) GetArray(key string) interface{} { + if key == "" { + return t + } + return t.GetArrayPath(strings.Split(key, ".")) +} + +// GetArrayPath returns the element in the tree indicated by 'keys'. +// If keys is of length zero, the current tree is returned. +func (t *Tree) GetArrayPath(keys []string) interface{} { if len(keys) == 0 { return t } @@ -126,18 +172,22 @@ func (t *Tree) GetPath(keys []string) interface{} { } } -// if homogeneous array, then return array type obj. as resp. over []interface{} +// if homogeneous array, then return slice type object over []interface{} func getArray(n []interface{}) interface{} { - var str []string + var s []string + var b []byte var i32 []int32 var i64 []int64 var i []int var f32 []float32 var f64 []float64 + var bl []bool for _, value := range n { switch v := value.(type) { case string: - str = append(str, v) + s = append(s, v) + case byte: + b = append(b, v) case int32: i32 = append(i32, v) case int64: @@ -148,12 +198,16 @@ func getArray(n []interface{}) interface{} { f32 = append(f32, v) case float64: f64 = append(f64, v) + case bool: + bl = append(bl, v) default: return n } } - if len(str) == len(n) { - return str + if len(s) == len(n) { + return s + } else if len(b) == len(n) { + return b } else if len(i32) == len(n) { return i32 } else if len(i64) == len(n) { @@ -164,6 +218,8 @@ func getArray(n []interface{}) interface{} { return f32 } else if len(f64) == len(n) { return f64 + } else if len(bl) == len(n) { + return bl } return n } diff --git a/toml_test.go b/toml_test.go index 81c3954..ce3cf1c 100644 --- a/toml_test.go +++ b/toml_test.go @@ -3,6 +3,7 @@ package toml import ( + "reflect" "testing" ) @@ -39,6 +40,27 @@ func TestTomlGet(t *testing.T) { } } +func TestTomlGetArray(t *testing.T) { + tree, _ := Load(` + [test] + key = ["one", "two"] + `) + + if tree.GetArray("") != tree { + t.Errorf("GetArray should return the tree itself when given an empty path") + } + + expect := []string{"one", "two"} + actual := tree.GetArray("test.key").([]string) + if !reflect.DeepEqual(actual, expect) { + t.Errorf("GetArray should return the []string value") + } + + if tree.GetArray(`\`) != nil { + t.Errorf("should return nil when the key is malformed") + } +} + func TestTomlGetDefault(t *testing.T) { tree, _ := Load(` [test] @@ -148,6 +170,32 @@ func TestTomlGetPath(t *testing.T) { } } +func TestTomlGetArrayPath(t *testing.T) { + node := newTree() + //TODO: set other node data + + for idx, item := range []struct { + Path []string + Expected *Tree + }{ + { // empty path test + []string{}, + node, + }, + } { + result := node.GetArrayPath(item.Path) + if result != item.Expected { + t.Errorf("GetArrayPath[%d] %v - expected %v, got %v instead.", idx, item.Path, item.Expected, result) + } + } + + tree, _ := Load("[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6") + if tree.GetArrayPath([]string{"whatever"}) != nil { + t.Error("GetArrayPath should return nil when the key does not exist") + } + +} + func TestTomlFromMap(t *testing.T) { simpleMap := map[string]interface{}{"hello": 42} tree, err := TreeFromMap(simpleMap) From 100799f7b7bc20c1bc4ecf65b70e8347557fc3c1 Mon Sep 17 00:00:00 2001 From: RiyaJohn Date: Mon, 18 May 2020 16:13:17 +0530 Subject: [PATCH 5/7] add testcase for bool --- toml_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/toml_test.go b/toml_test.go index ce3cf1c..45279a3 100644 --- a/toml_test.go +++ b/toml_test.go @@ -44,6 +44,7 @@ func TestTomlGetArray(t *testing.T) { tree, _ := Load(` [test] key = ["one", "two"] + key2 = [true, false, false] `) if tree.GetArray("") != tree { @@ -56,6 +57,12 @@ func TestTomlGetArray(t *testing.T) { t.Errorf("GetArray should return the []string value") } + expect2 := []bool{true, false, false} + actual2 := tree.GetArray("test.key2").([]bool) + if !reflect.DeepEqual(actual2, expect2) { + t.Errorf("GetArray should return the []string value") + } + if tree.GetArray(`\`) != nil { t.Errorf("should return nil when the key is malformed") } From 2d866e3faea6feaa8842ce61d2f2f2fba819c8c8 Mon Sep 17 00:00:00 2001 From: RiyaJohn Date: Thu, 21 May 2020 22:50:23 +0530 Subject: [PATCH 6/7] fix: rm int, int32, float32 --- toml.go | 15 --------------- toml_test.go | 9 ++++++++- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/toml.go b/toml.go index d2a6e3e..1c16655 100644 --- a/toml.go +++ b/toml.go @@ -177,10 +177,7 @@ func (t *Tree) GetArrayPath(keys []string) interface{} { func getArray(n []interface{}) interface{} { var s []string var b []byte - var i32 []int32 var i64 []int64 - var i []int - var f32 []float32 var f64 []float64 var bl []bool for _, value := range n { @@ -189,14 +186,8 @@ func getArray(n []interface{}) interface{} { s = append(s, v) case byte: b = append(b, v) - case int32: - i32 = append(i32, v) case int64: i64 = append(i64, v) - case int: - i = append(i, v) - case float32: - f32 = append(f32, v) case float64: f64 = append(f64, v) case bool: @@ -209,14 +200,8 @@ func getArray(n []interface{}) interface{} { return s } else if len(b) == len(n) { return b - } else if len(i32) == len(n) { - return i32 } else if len(i64) == len(n) { return i64 - } else if len(i) == len(n) { - return i - } else if len(f32) == len(n) { - return f32 } else if len(f64) == len(n) { return f64 } else if len(bl) == len(n) { diff --git a/toml_test.go b/toml_test.go index 45279a3..c2efdcd 100644 --- a/toml_test.go +++ b/toml_test.go @@ -45,6 +45,7 @@ func TestTomlGetArray(t *testing.T) { [test] key = ["one", "two"] key2 = [true, false, false] + key3 = [1.5,2.5] `) if tree.GetArray("") != tree { @@ -60,7 +61,13 @@ func TestTomlGetArray(t *testing.T) { expect2 := []bool{true, false, false} actual2 := tree.GetArray("test.key2").([]bool) if !reflect.DeepEqual(actual2, expect2) { - t.Errorf("GetArray should return the []string value") + t.Errorf("GetArray should return the []bool value") + } + + expect3 := []float64{1.5,2.5} + actual3 := tree.GetArray("test.key3").([]float64) + if !reflect.DeepEqual(actual3, expect3) { + t.Errorf("GetArray should return the []float64 value") } if tree.GetArray(`\`) != nil { From db62263e3ec25ece24301bb2a2b64a7602fac532 Mon Sep 17 00:00:00 2001 From: Thomas Pelletier Date: Mon, 1 Jun 2020 10:16:36 -0400 Subject: [PATCH 7/7] Added exta tests for GetArrayPath --- toml.go | 5 ----- toml_test.go | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/toml.go b/toml.go index 1c16655..2b138d1 100644 --- a/toml.go +++ b/toml.go @@ -176,7 +176,6 @@ func (t *Tree) GetArrayPath(keys []string) interface{} { // if homogeneous array, then return slice type object over []interface{} func getArray(n []interface{}) interface{} { var s []string - var b []byte var i64 []int64 var f64 []float64 var bl []bool @@ -184,8 +183,6 @@ func getArray(n []interface{}) interface{} { switch v := value.(type) { case string: s = append(s, v) - case byte: - b = append(b, v) case int64: i64 = append(i64, v) case float64: @@ -198,8 +195,6 @@ func getArray(n []interface{}) interface{} { } if len(s) == len(n) { return s - } else if len(b) == len(n) { - return b } else if len(i64) == len(n) { return i64 } else if len(f64) == len(n) { diff --git a/toml_test.go b/toml_test.go index c2efdcd..0c7b6d3 100644 --- a/toml_test.go +++ b/toml_test.go @@ -64,7 +64,7 @@ func TestTomlGetArray(t *testing.T) { t.Errorf("GetArray should return the []bool value") } - expect3 := []float64{1.5,2.5} + expect3 := []float64{1.5, 2.5} actual3 := tree.GetArray("test.key3").([]float64) if !reflect.DeepEqual(actual3, expect3) { t.Errorf("GetArray should return the []float64 value") @@ -185,22 +185,41 @@ func TestTomlGetPath(t *testing.T) { } func TestTomlGetArrayPath(t *testing.T) { - node := newTree() - //TODO: set other node data - for idx, item := range []struct { - Path []string - Expected *Tree + Name string + Path []string + Make func() (tree *Tree, expected interface{}) }{ - { // empty path test - []string{}, - node, + { + Name: "empty", + Path: []string{}, + Make: func() (tree *Tree, expected interface{}) { + tree = newTree() + expected = tree + return + }, + }, + { + Name: "int64", + Path: []string{"a"}, + Make: func() (tree *Tree, expected interface{}) { + var err error + tree, err = Load(`a = [1,2,3]`) + if err != nil { + panic(err) + } + expected = []int64{1, 2, 3} + return + }, }, } { - result := node.GetArrayPath(item.Path) - if result != item.Expected { - t.Errorf("GetArrayPath[%d] %v - expected %v, got %v instead.", idx, item.Path, item.Expected, result) - } + t.Run(item.Name, func(t *testing.T) { + tree, expected := item.Make() + result := tree.GetArrayPath(item.Path) + if !reflect.DeepEqual(result, expected) { + t.Errorf("GetArrayPath[%d] %v - expected %#v, got %#v instead.", idx, item.Path, expected, result) + } + }) } tree, _ := Load("[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6")