diff options
author | Christopher Speller <crspeller@gmail.com> | 2017-05-17 16:51:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-17 16:51:25 -0400 |
commit | d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26 (patch) | |
tree | dbde13123c6add150448f7b75753ac022d862475 /vendor/github.com/pelletier/go-toml | |
parent | cd23b8139a9463b67e3096744321f6f4eb0ca40a (diff) | |
download | chat-d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26.tar.gz chat-d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26.tar.bz2 chat-d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26.zip |
Upgrading server dependancies (#6431)
Diffstat (limited to 'vendor/github.com/pelletier/go-toml')
28 files changed, 855 insertions, 702 deletions
diff --git a/vendor/github.com/pelletier/go-toml/README.md b/vendor/github.com/pelletier/go-toml/README.md index b8137e022..8279102b1 100644 --- a/vendor/github.com/pelletier/go-toml/README.md +++ b/vendor/github.com/pelletier/go-toml/README.md @@ -16,9 +16,9 @@ This library supports TOML version Go-toml provides the following features for using data parsed from TOML documents: * Load TOML documents from files and string data -* Easily navigate TOML structure using TomlTree +* Easily navigate TOML structure using Tree * Line & column position data for all parsed elements -* Query support similar to JSON-Path +* [Query support similar to JSON-Path](query/) * Syntax errors contain line and column numbers Go-toml is designed to help cover use-cases not covered by reflection-based TOML parsing: @@ -61,7 +61,7 @@ if err != nil { password := config.Get("postgres.password").(string) // or using an intermediate object - configTree := config.Get("postgres").(*toml.TomlTree) + configTree := config.Get("postgres").(*toml.Tree) user = configTree.Get("user").(string) password = configTree.Get("password").(string) fmt.Println("User is ", user, ". Password is ", password) diff --git a/vendor/github.com/pelletier/go-toml/clean.sh b/vendor/github.com/pelletier/go-toml/clean.sh deleted file mode 100755 index 44d49d936..000000000 --- a/vendor/github.com/pelletier/go-toml/clean.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# fail out of the script if anything here fails -set -e - -# clear out stuff generated by test.sh -rm -rf src test_program_bin toml-test diff --git a/vendor/github.com/pelletier/go-toml/cmd/test_program.go b/vendor/github.com/pelletier/go-toml/cmd/test_program.go index 58293446b..73077f614 100644 --- a/vendor/github.com/pelletier/go-toml/cmd/test_program.go +++ b/vendor/github.com/pelletier/go-toml/cmd/test_program.go @@ -41,16 +41,16 @@ func translate(tomlData interface{}) interface{} { typed[k] = translate(v) } return typed - case *toml.TomlTree: + case *toml.Tree: return translate(*orig) - case toml.TomlTree: + case toml.Tree: keys := orig.Keys() typed := make(map[string]interface{}, len(keys)) for _, k := range keys { typed[k] = translate(orig.GetPath([]string{k})) } return typed - case []*toml.TomlTree: + case []*toml.Tree: typed := make([]map[string]interface{}, len(orig)) for i, v := range orig { typed[i] = translate(v).(map[string]interface{}) diff --git a/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go b/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go index 7e9dc467e..8bfe46210 100644 --- a/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go +++ b/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go @@ -57,7 +57,7 @@ func reader(r io.Reader) (string, error) { return mapToJSON(tree) } -func mapToJSON(tree *toml.TomlTree) (string, error) { +func mapToJSON(tree *toml.Tree) (string, error) { treeMap := tree.ToMap() bytes, err := json.MarshalIndent(treeMap, "", " ") if err != nil { diff --git a/vendor/github.com/pelletier/go-toml/doc.go b/vendor/github.com/pelletier/go-toml/doc.go index 9156b736f..cfa5e4abe 100644 --- a/vendor/github.com/pelletier/go-toml/doc.go +++ b/vendor/github.com/pelletier/go-toml/doc.go @@ -13,14 +13,14 @@ // // load TOML data stored in a string // tree, err := toml.Load(stringContainingTomlData) // -// Either way, the result is a TomlTree object that can be used to navigate the +// Either way, the result is a Tree object that can be used to navigate the // structure and data within the original document. // // -// Getting data from the TomlTree +// Getting data from the Tree // // After parsing TOML data with Load() or LoadFile(), use the Has() and Get() -// methods on the returned TomlTree, to find your way through the document data. +// methods on the returned Tree, to find your way through the document data. // // if tree.Has("foo") { // fmt.Println("foo is:", tree.Get("foo")) @@ -50,11 +50,11 @@ // tree.GetPath([]string{"foo","bar","baz"}) // // Note that this is distinct from the heavyweight query syntax supported by -// TomlTree.Query() and the Query() struct (see below). +// Tree.Query() and the Query() struct (see below). // // Position Support // -// Each element within the TomlTree is stored with position metadata, which is +// Each element within the Tree is stored with position metadata, which is // invaluable for providing semantic feedback to a user. This helps in // situations where the TOML file parses correctly, but contains data that is // not correct for the application. In such cases, an error message can be @@ -75,176 +75,10 @@ // return fmt.Errorf("%v: Expected 'bar' element", tree.GetPosition("")) // } // -// Query Support +// JSONPath-like queries // -// The TOML query path implementation is based loosely on the JSONPath specification: -// http://goessner.net/articles/JsonPath/ -// -// The idea behind a query path is to allow quick access to any element, or set -// of elements within TOML document, with a single expression. -// -// result, err := tree.Query("$.foo.bar.baz") -// -// This is roughly equivalent to: -// -// next := tree.Get("foo") -// if next != nil { -// next = next.Get("bar") -// if next != nil { -// next = next.Get("baz") -// } -// } -// result := next -// -// err is nil if any parsing exception occurs. -// -// If no node in the tree matches the query, result will simply contain an empty list of -// items. -// -// As illustrated above, the query path is much more efficient, especially since -// the structure of the TOML file can vary. Rather than making assumptions about -// a document's structure, a query allows the programmer to make structured -// requests into the document, and get zero or more values as a result. -// -// The syntax of a query begins with a root token, followed by any number -// sub-expressions: -// -// $ -// Root of the TOML tree. This must always come first. -// .name -// Selects child of this node, where 'name' is a TOML key -// name. -// ['name'] -// Selects child of this node, where 'name' is a string -// containing a TOML key name. -// [index] -// Selcts child array element at 'index'. -// ..expr -// Recursively selects all children, filtered by an a union, -// index, or slice expression. -// ..* -// Recursive selection of all nodes at this point in the -// tree. -// .* -// Selects all children of the current node. -// [expr,expr] -// Union operator - a logical 'or' grouping of two or more -// sub-expressions: index, key name, or filter. -// [start:end:step] -// Slice operator - selects array elements from start to -// end-1, at the given step. All three arguments are -// optional. -// [?(filter)] -// Named filter expression - the function 'filter' is -// used to filter children at this node. -// -// Query Indexes And Slices -// -// Index expressions perform no bounds checking, and will contribute no -// values to the result set if the provided index or index range is invalid. -// Negative indexes represent values from the end of the array, counting backwards. -// -// // select the last index of the array named 'foo' -// tree.Query("$.foo[-1]") -// -// Slice expressions are supported, by using ':' to separate a start/end index pair. -// -// // select up to the first five elements in the array -// tree.Query("$.foo[0:5]") -// -// Slice expressions also allow negative indexes for the start and stop -// arguments. -// -// // select all array elements. -// tree.Query("$.foo[0:-1]") -// -// Slice expressions may have an optional stride/step parameter: -// -// // select every other element -// tree.Query("$.foo[0:-1:2]") -// -// Slice start and end parameters are also optional: -// -// // these are all equivalent and select all the values in the array -// tree.Query("$.foo[:]") -// tree.Query("$.foo[0:]") -// tree.Query("$.foo[:-1]") -// tree.Query("$.foo[0:-1:]") -// tree.Query("$.foo[::1]") -// tree.Query("$.foo[0::1]") -// tree.Query("$.foo[:-1:1]") -// tree.Query("$.foo[0:-1:1]") -// -// Query Filters -// -// Query filters are used within a Union [,] or single Filter [] expression. -// A filter only allows nodes that qualify through to the next expression, -// and/or into the result set. -// -// // returns children of foo that are permitted by the 'bar' filter. -// tree.Query("$.foo[?(bar)]") -// -// There are several filters provided with the library: -// -// tree -// Allows nodes of type TomlTree. -// int -// Allows nodes of type int64. -// float -// Allows nodes of type float64. -// string -// Allows nodes of type string. -// time -// Allows nodes of type time.Time. -// bool -// Allows nodes of type bool. -// -// Query Results -// -// An executed query returns a QueryResult object. This contains the nodes -// in the TOML tree that qualify the query expression. Position information -// is also available for each value in the set. -// -// // display the results of a query -// results := tree.Query("$.foo.bar.baz") -// for idx, value := results.Values() { -// fmt.Println("%v: %v", results.Positions()[idx], value) -// } -// -// Compiled Queries -// -// Queries may be executed directly on a TomlTree object, or compiled ahead -// of time and executed discretely. The former is more convienent, but has the -// penalty of having to recompile the query expression each time. -// -// // basic query -// results := tree.Query("$.foo.bar.baz") -// -// // compiled query -// query := toml.CompileQuery("$.foo.bar.baz") -// results := query.Execute(tree) -// -// // run the compiled query again on a different tree -// moreResults := query.Execute(anotherTree) -// -// User Defined Query Filters -// -// Filter expressions may also be user defined by using the SetFilter() -// function on the Query object. The function must return true/false, which -// signifies if the passed node is kept or discarded, respectively. -// -// // create a query that references a user-defined filter -// query, _ := CompileQuery("$[?(bazOnly)]") -// -// // define the filter, and assign it to the query -// query.SetFilter("bazOnly", func(node interface{}) bool{ -// if tree, ok := node.(*TomlTree); ok { -// return tree.Has("baz") -// } -// return false // reject all other node types -// }) -// -// // run the query -// query.Execute(tree) +// The package github.com/pelletier/go-toml/query implements a system +// similar to JSONPath to quickly retrive elements of a TOML document using a +// single expression. See the package documentation for more information. // package toml diff --git a/vendor/github.com/pelletier/go-toml/doc_test.go b/vendor/github.com/pelletier/go-toml/doc_test.go index 69452415a..31b4f40b5 100644 --- a/vendor/github.com/pelletier/go-toml/doc_test.go +++ b/vendor/github.com/pelletier/go-toml/doc_test.go @@ -6,52 +6,6 @@ import ( "fmt" ) -func ExampleNodeFilterFn_filterExample() { - tree, _ := Load(` - [struct_one] - foo = "foo" - bar = "bar" - - [struct_two] - baz = "baz" - gorf = "gorf" - `) - - // create a query that references a user-defined-filter - query, _ := CompileQuery("$[?(bazOnly)]") - - // define the filter, and assign it to the query - query.SetFilter("bazOnly", func(node interface{}) bool { - if tree, ok := node.(*TomlTree); ok { - return tree.Has("baz") - } - return false // reject all other node types - }) - - // results contain only the 'struct_two' TomlTree - query.Execute(tree) -} - -func ExampleQuery_queryExample() { - config, _ := Load(` - [[book]] - title = "The Stand" - author = "Stephen King" - [[book]] - title = "For Whom the Bell Tolls" - author = "Ernest Hemmingway" - [[book]] - title = "Neuromancer" - author = "William Gibson" - `) - - // find and print all the authors in the document - authors, _ := config.Query("$.book.author") - for _, name := range authors.Values() { - fmt.Println(name) - } -} - func Example_comprehensiveExample() { config, err := LoadFile("config.toml") @@ -63,7 +17,7 @@ func Example_comprehensiveExample() { password := config.Get("postgres.password").(string) // or using an intermediate object - configTree := config.Get("postgres").(*TomlTree) + configTree := config.Get("postgres").(*Tree) user = configTree.Get("user").(string) password = configTree.Get("password").(string) fmt.Println("User is ", user, ". Password is ", password) @@ -71,11 +25,5 @@ func Example_comprehensiveExample() { // show where elements are in the file fmt.Printf("User position: %v\n", configTree.GetPosition("user")) fmt.Printf("Password position: %v\n", configTree.GetPosition("password")) - - // use a query to gather elements without walking the tree - results, _ := config.Query("$..[user,password]") - for ii, item := range results.Values() { - fmt.Printf("Query result %d: %v\n", ii, item) - } } } diff --git a/vendor/github.com/pelletier/go-toml/marshal.go b/vendor/github.com/pelletier/go-toml/marshal.go index a1d701046..358425aea 100644 --- a/vendor/github.com/pelletier/go-toml/marshal.go +++ b/vendor/github.com/pelletier/go-toml/marshal.go @@ -1,6 +1,7 @@ package toml import ( + "bytes" "errors" "fmt" "reflect" @@ -9,14 +10,14 @@ import ( ) /* -TomlTree structural types and corresponding marshal types +Tree structural types and corresponding marshal types ------------------------------------------------------------------------------- -*TomlTree (*)struct, (*)map[string]interface{} -[]*TomlTree (*)[](*)struct, (*)[](*)map[string]interface{} +*Tree (*)struct, (*)map[string]interface{} +[]*Tree (*)[](*)struct, (*)[](*)map[string]interface{} []interface{} (as interface{}) (*)[]primitive, (*)[]([]interface{}) interface{} (*)primitive -TomlTree primitive types and corresponding marshal types +Tree primitive types and corresponding marshal types ----------------------------------------------------------- uint64 uint, uint8-uint64, pointers to same int64 int, int8-uint64, pointers to same @@ -35,7 +36,7 @@ type tomlOpts struct { var timeType = reflect.TypeOf(time.Time{}) var marshalerType = reflect.TypeOf(new(Marshaler)).Elem() -// Check if the given marshall type maps to a TomlTree primitive +// Check if the given marshall type maps to a Tree primitive func isPrimitive(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Ptr: @@ -57,7 +58,7 @@ func isPrimitive(mtype reflect.Type) bool { } } -// Check if the given marshall type maps to a TomlTree slice +// Check if the given marshall type maps to a Tree slice func isTreeSlice(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Slice: @@ -67,7 +68,7 @@ func isTreeSlice(mtype reflect.Type) bool { } } -// Check if the given marshall type maps to a non-TomlTree slice +// Check if the given marshall type maps to a non-Tree slice func isOtherSlice(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Ptr: @@ -79,7 +80,7 @@ func isOtherSlice(mtype reflect.Type) bool { } } -// Check if the given marshall type maps to a TomlTree +// Check if the given marshall type maps to a Tree func isTree(mtype reflect.Type) bool { switch mtype.Kind() { case reflect.Map: @@ -133,11 +134,11 @@ func Marshal(v interface{}) ([]byte, error) { } // Convert given marshal struct or map value to toml tree -func valueToTree(mtype reflect.Type, mval reflect.Value) (*TomlTree, error) { +func valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) { if mtype.Kind() == reflect.Ptr { return valueToTree(mtype.Elem(), mval.Elem()) } - tval := newTomlTree() + tval := newTree() switch mtype.Kind() { case reflect.Struct: for i := 0; i < mtype.NumField(); i++ { @@ -165,8 +166,8 @@ func valueToTree(mtype reflect.Type, mval reflect.Value) (*TomlTree, error) { } // Convert given marshal slice to slice of Toml trees -func valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*TomlTree, error) { - tval := make([]*TomlTree, mval.Len(), mval.Len()) +func valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) { + tval := make([]*Tree, mval.Len(), mval.Len()) for i := 0; i < mval.Len(); i++ { val, err := valueToTree(mtype.Elem(), mval.Index(i)) if err != nil { @@ -224,34 +225,38 @@ func valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) { } } -/* -Unmarshal parses the TOML-encoded data and stores the result in the value -pointed to by v. Behavior is similar to the Go json encoder, except that there -is no concept of an Unmarshaler interface or UnmarshalTOML function for -sub-structs, and currently only definite types can be unmarshaled to (i.e. no -`interface{}`). -*/ -func Unmarshal(data []byte, v interface{}) error { +// Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v. +// Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for +// sub-structs, and only definite types can be unmarshaled. +func (t *Tree) Unmarshal(v interface{}) error { mtype := reflect.TypeOf(v) if mtype.Kind() != reflect.Ptr || mtype.Elem().Kind() != reflect.Struct { return errors.New("Only a pointer to struct can be unmarshaled from TOML") } - t, err := Load(string(data)) + sval, err := valueFromTree(mtype.Elem(), t) if err != nil { return err } + reflect.ValueOf(v).Elem().Set(sval) + return nil +} - sval, err := valueFromTree(mtype.Elem(), t) +// Unmarshal parses the TOML-encoded data and stores the result in the value +// pointed to by v. Behavior is similar to the Go json encoder, except that there +// is no concept of an Unmarshaler interface or UnmarshalTOML function for +// sub-structs, and currently only definite types can be unmarshaled to (i.e. no +// `interface{}`). +func Unmarshal(data []byte, v interface{}) error { + t, err := LoadReader(bytes.NewReader(data)) if err != nil { return err } - reflect.ValueOf(v).Elem().Set(sval) - return nil + return t.Unmarshal(v) } // Convert toml tree to marshal struct or map, using marshal type -func valueFromTree(mtype reflect.Type, tval *TomlTree) (reflect.Value, error) { +func valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) { if mtype.Kind() == reflect.Ptr { return unwrapPointer(mtype, tval) } @@ -290,7 +295,7 @@ func valueFromTree(mtype reflect.Type, tval *TomlTree) (reflect.Value, error) { } // Convert toml value to marshal struct/map slice, using marshal type -func valueFromTreeSlice(mtype reflect.Type, tval []*TomlTree) (reflect.Value, error) { +func valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) { mval := reflect.MakeSlice(mtype, len(tval), len(tval)) for i := 0; i < len(tval); i++ { val, err := valueFromTree(mtype.Elem(), tval[i]) @@ -322,9 +327,9 @@ func valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error) } switch { case isTree(mtype): - return valueFromTree(mtype, tval.(*TomlTree)) + return valueFromTree(mtype, tval.(*Tree)) case isTreeSlice(mtype): - return valueFromTreeSlice(mtype, tval.([]*TomlTree)) + return valueFromTreeSlice(mtype, tval.([]*Tree)) case isOtherSlice(mtype): return valueFromOtherSlice(mtype, tval.([]interface{})) default: diff --git a/vendor/github.com/pelletier/go-toml/marshal_test.go b/vendor/github.com/pelletier/go-toml/marshal_test.go index 891222e9b..dbfc7c1d1 100644 --- a/vendor/github.com/pelletier/go-toml/marshal_test.go +++ b/vendor/github.com/pelletier/go-toml/marshal_test.go @@ -177,6 +177,23 @@ func TestDocUnmarshal(t *testing.T) { } } +func TestDocPartialUnmarshal(t *testing.T) { + result := testDocSubs{} + + tree, _ := LoadFile("marshal_test.toml") + subTree := tree.Get("subdoc").(*Tree) + err := subTree.Unmarshal(&result) + expected := docData.Subdocs + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(result, expected) { + resStr, _ := json.MarshalIndent(result, "", " ") + expStr, _ := json.MarshalIndent(expected, "", " ") + t.Errorf("Bad partial unmartial: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr) + } +} + type tomlTypeCheckTest struct { name string item interface{} diff --git a/vendor/github.com/pelletier/go-toml/parser.go b/vendor/github.com/pelletier/go-toml/parser.go index 20e90a3ed..64eb0e587 100644 --- a/vendor/github.com/pelletier/go-toml/parser.go +++ b/vendor/github.com/pelletier/go-toml/parser.go @@ -14,7 +14,7 @@ import ( type tomlParser struct { flow chan token - tree *TomlTree + tree *Tree tokensBuffer []token currentTable []string seenTableKeys []string @@ -106,18 +106,18 @@ func (p *tomlParser) parseGroupArray() tomlParserStateFn { } p.tree.createSubTree(keys[:len(keys)-1], startToken.Position) // create parent entries destTree := p.tree.GetPath(keys) - var array []*TomlTree + var array []*Tree if destTree == nil { - array = make([]*TomlTree, 0) - } else if target, ok := destTree.([]*TomlTree); ok && target != nil { - array = destTree.([]*TomlTree) + array = make([]*Tree, 0) + } else if target, ok := destTree.([]*Tree); ok && target != nil { + array = destTree.([]*Tree) } else { p.raiseError(key, "key %s is already assigned and not of type table array", key) } p.currentTable = keys // add a new tree to the end of the table array - newTree := newTomlTree() + newTree := newTree() newTree.position = startToken.Position array = append(array, newTree) p.tree.SetPath(p.currentTable, array) @@ -183,11 +183,11 @@ func (p *tomlParser) parseAssign() tomlParserStateFn { } // find the table to assign, looking out for arrays of tables - var targetNode *TomlTree + var targetNode *Tree switch node := p.tree.GetPath(tableKey).(type) { - case []*TomlTree: + case []*Tree: targetNode = node[len(node)-1] - case *TomlTree: + case *Tree: targetNode = node default: p.raiseError(key, "Unknown table type for path: %s", @@ -212,7 +212,7 @@ func (p *tomlParser) parseAssign() tomlParserStateFn { var toInsert interface{} switch value.(type) { - case *TomlTree, []*TomlTree: + case *Tree, []*Tree: toInsert = value default: toInsert = &tomlValue{value, key.Position} @@ -289,8 +289,8 @@ func tokenIsComma(t *token) bool { return t != nil && t.typ == tokenComma } -func (p *tomlParser) parseInlineTable() *TomlTree { - tree := newTomlTree() +func (p *tomlParser) parseInlineTable() *Tree { + tree := newTree() var previous *token Loop: for { @@ -360,22 +360,22 @@ func (p *tomlParser) parseArray() interface{} { p.getToken() } } - // An array of TomlTrees is actually an array of inline + // An array of Trees is actually an array of inline // tables, which is a shorthand for a table array. If the - // array was not converted from []interface{} to []*TomlTree, + // array was not converted from []interface{} to []*Tree, // the two notations would not be equivalent. - if arrayType == reflect.TypeOf(newTomlTree()) { - tomlArray := make([]*TomlTree, len(array)) + if arrayType == reflect.TypeOf(newTree()) { + tomlArray := make([]*Tree, len(array)) for i, v := range array { - tomlArray[i] = v.(*TomlTree) + tomlArray[i] = v.(*Tree) } return tomlArray } return array } -func parseToml(flow chan token) *TomlTree { - result := newTomlTree() +func parseToml(flow chan token) *Tree { + result := newTree() result.position = Position{1, 1} parser := &tomlParser{ flow: flow, diff --git a/vendor/github.com/pelletier/go-toml/parser_test.go b/vendor/github.com/pelletier/go-toml/parser_test.go index 58aae203a..508cb65f0 100644 --- a/vendor/github.com/pelletier/go-toml/parser_test.go +++ b/vendor/github.com/pelletier/go-toml/parser_test.go @@ -9,7 +9,7 @@ import ( "github.com/davecgh/go-spew/spew" ) -func assertSubTree(t *testing.T, path []string, tree *TomlTree, err error, ref map[string]interface{}) { +func assertSubTree(t *testing.T, path []string, tree *Tree, err error, ref map[string]interface{}) { if err != nil { t.Error("Non-nil error:", err.Error()) return @@ -20,12 +20,12 @@ func assertSubTree(t *testing.T, path []string, tree *TomlTree, err error, ref m // NOTE: directly access key instead of resolve by path // NOTE: see TestSpecialKV switch node := tree.GetPath([]string{k}).(type) { - case []*TomlTree: + case []*Tree: t.Log("\tcomparing key", nextPath, "by array iteration") for idx, item := range node { assertSubTree(t, nextPath, item, err, v.([]map[string]interface{})[idx]) } - case *TomlTree: + case *Tree: t.Log("\tcomparing key", nextPath, "by subtree assestion") assertSubTree(t, nextPath, node, err, v.(map[string]interface{})) default: @@ -37,14 +37,14 @@ func assertSubTree(t *testing.T, path []string, tree *TomlTree, err error, ref m } } -func assertTree(t *testing.T, tree *TomlTree, err error, ref map[string]interface{}) { +func assertTree(t *testing.T, tree *Tree, err error, ref map[string]interface{}) { t.Log("Asserting tree:\n", spew.Sdump(tree)) assertSubTree(t, []string{}, tree, err, ref) t.Log("Finished tree assertion.") } func TestCreateSubTree(t *testing.T) { - tree := newTomlTree() + tree := newTree() tree.createSubTree([]string{"a", "b", "c"}, Position{}) tree.Set("a.b.c", 42) if tree.Get("a.b.c") != 42 { diff --git a/vendor/github.com/pelletier/go-toml/query/doc.go b/vendor/github.com/pelletier/go-toml/query/doc.go new file mode 100644 index 000000000..f999fc965 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/query/doc.go @@ -0,0 +1,175 @@ +// Package query performs JSONPath-like queries on a TOML document. +// +// The query path implementation is based loosely on the JSONPath specification: +// http://goessner.net/articles/JsonPath/. +// +// The idea behind a query path is to allow quick access to any element, or set +// of elements within TOML document, with a single expression. +// +// result, err := query.CompileAndExecute("$.foo.bar.baz", tree) +// +// This is roughly equivalent to: +// +// next := tree.Get("foo") +// if next != nil { +// next = next.Get("bar") +// if next != nil { +// next = next.Get("baz") +// } +// } +// result := next +// +// err is nil if any parsing exception occurs. +// +// If no node in the tree matches the query, result will simply contain an empty list of +// items. +// +// As illustrated above, the query path is much more efficient, especially since +// the structure of the TOML file can vary. Rather than making assumptions about +// a document's structure, a query allows the programmer to make structured +// requests into the document, and get zero or more values as a result. +// +// Query syntax +// +// The syntax of a query begins with a root token, followed by any number +// sub-expressions: +// +// $ +// Root of the TOML tree. This must always come first. +// .name +// Selects child of this node, where 'name' is a TOML key +// name. +// ['name'] +// Selects child of this node, where 'name' is a string +// containing a TOML key name. +// [index] +// Selcts child array element at 'index'. +// ..expr +// Recursively selects all children, filtered by an a union, +// index, or slice expression. +// ..* +// Recursive selection of all nodes at this point in the +// tree. +// .* +// Selects all children of the current node. +// [expr,expr] +// Union operator - a logical 'or' grouping of two or more +// sub-expressions: index, key name, or filter. +// [start:end:step] +// Slice operator - selects array elements from start to +// end-1, at the given step. All three arguments are +// optional. +// [?(filter)] +// Named filter expression - the function 'filter' is +// used to filter children at this node. +// +// Query Indexes And Slices +// +// Index expressions perform no bounds checking, and will contribute no +// values to the result set if the provided index or index range is invalid. +// Negative indexes represent values from the end of the array, counting backwards. +// +// // select the last index of the array named 'foo' +// query.CompileAndExecute("$.foo[-1]", tree) +// +// Slice expressions are supported, by using ':' to separate a start/end index pair. +// +// // select up to the first five elements in the array +// query.CompileAndExecute("$.foo[0:5]", tree) +// +// Slice expressions also allow negative indexes for the start and stop +// arguments. +// +// // select all array elements. +// query.CompileAndExecute("$.foo[0:-1]", tree) +// +// Slice expressions may have an optional stride/step parameter: +// +// // select every other element +// query.CompileAndExecute("$.foo[0:-1:2]", tree) +// +// Slice start and end parameters are also optional: +// +// // these are all equivalent and select all the values in the array +// query.CompileAndExecute("$.foo[:]", tree) +// query.CompileAndExecute("$.foo[0:]", tree) +// query.CompileAndExecute("$.foo[:-1]", tree) +// query.CompileAndExecute("$.foo[0:-1:]", tree) +// query.CompileAndExecute("$.foo[::1]", tree) +// query.CompileAndExecute("$.foo[0::1]", tree) +// query.CompileAndExecute("$.foo[:-1:1]", tree) +// query.CompileAndExecute("$.foo[0:-1:1]", tree) +// +// Query Filters +// +// Query filters are used within a Union [,] or single Filter [] expression. +// A filter only allows nodes that qualify through to the next expression, +// and/or into the result set. +// +// // returns children of foo that are permitted by the 'bar' filter. +// query.CompileAndExecute("$.foo[?(bar)]", tree) +// +// There are several filters provided with the library: +// +// tree +// Allows nodes of type Tree. +// int +// Allows nodes of type int64. +// float +// Allows nodes of type float64. +// string +// Allows nodes of type string. +// time +// Allows nodes of type time.Time. +// bool +// Allows nodes of type bool. +// +// Query Results +// +// An executed query returns a Result object. This contains the nodes +// in the TOML tree that qualify the query expression. Position information +// is also available for each value in the set. +// +// // display the results of a query +// results := query.CompileAndExecute("$.foo.bar.baz", tree) +// for idx, value := results.Values() { +// fmt.Println("%v: %v", results.Positions()[idx], value) +// } +// +// Compiled Queries +// +// Queries may be executed directly on a Tree object, or compiled ahead +// of time and executed discretely. The former is more convienent, but has the +// penalty of having to recompile the query expression each time. +// +// // basic query +// results := query.CompileAndExecute("$.foo.bar.baz", tree) +// +// // compiled query +// query, err := toml.Compile("$.foo.bar.baz") +// results := query.Execute(tree) +// +// // run the compiled query again on a different tree +// moreResults := query.Execute(anotherTree) +// +// User Defined Query Filters +// +// Filter expressions may also be user defined by using the SetFilter() +// function on the Query object. The function must return true/false, which +// signifies if the passed node is kept or discarded, respectively. +// +// // create a query that references a user-defined filter +// query, _ := query.Compile("$[?(bazOnly)]") +// +// // define the filter, and assign it to the query +// query.SetFilter("bazOnly", func(node interface{}) bool{ +// if tree, ok := node.(*Tree); ok { +// return tree.Has("baz") +// } +// return false // reject all other node types +// }) +// +// // run the query +// query.Execute(tree) +// +package query diff --git a/vendor/github.com/pelletier/go-toml/querylexer.go b/vendor/github.com/pelletier/go-toml/query/lexer.go index 960681d0f..6336d52cd 100644 --- a/vendor/github.com/pelletier/go-toml/querylexer.go +++ b/vendor/github.com/pelletier/go-toml/query/lexer.go @@ -3,13 +3,14 @@ // Written using the principles developed by Rob Pike in // http://www.youtube.com/watch?v=HxaD_trXwRE -package toml +package query import ( "fmt" "strconv" "strings" "unicode/utf8" + "github.com/pelletier/go-toml" ) // Lexer state function @@ -54,7 +55,7 @@ func (l *queryLexer) nextStart() { func (l *queryLexer) emit(t tokenType) { l.tokens <- token{ - Position: Position{l.line, l.col}, + Position: toml.Position{Line:l.line, Col:l.col}, typ: t, val: l.input[l.start:l.pos], } @@ -63,7 +64,7 @@ func (l *queryLexer) emit(t tokenType) { func (l *queryLexer) emitWithValue(t tokenType, value string) { l.tokens <- token{ - Position: Position{l.line, l.col}, + Position: toml.Position{Line:l.line, Col:l.col}, typ: t, val: value, } @@ -91,7 +92,7 @@ func (l *queryLexer) backup() { func (l *queryLexer) errorf(format string, args ...interface{}) queryLexStateFn { l.tokens <- token{ - Position: Position{l.line, l.col}, + Position: toml.Position{Line:l.line, Col:l.col}, typ: tokenError, val: fmt.Sprintf(format, args...), } diff --git a/vendor/github.com/pelletier/go-toml/querylexer_test.go b/vendor/github.com/pelletier/go-toml/query/lexer_test.go index 2d0803ff7..e2b733a34 100644 --- a/vendor/github.com/pelletier/go-toml/querylexer_test.go +++ b/vendor/github.com/pelletier/go-toml/query/lexer_test.go @@ -1,7 +1,8 @@ -package toml +package query import ( "testing" + "github.com/pelletier/go-toml" ) func testQLFlow(t *testing.T, input string, expectedFlow []token) { @@ -36,143 +37,143 @@ func testQLFlow(t *testing.T, input string, expectedFlow []token) { func TestLexSpecialChars(t *testing.T) { testQLFlow(t, " .$[]..()?*", []token{ - {Position{1, 2}, tokenDot, "."}, - {Position{1, 3}, tokenDollar, "$"}, - {Position{1, 4}, tokenLeftBracket, "["}, - {Position{1, 5}, tokenRightBracket, "]"}, - {Position{1, 6}, tokenDotDot, ".."}, - {Position{1, 8}, tokenLeftParen, "("}, - {Position{1, 9}, tokenRightParen, ")"}, - {Position{1, 10}, tokenQuestion, "?"}, - {Position{1, 11}, tokenStar, "*"}, - {Position{1, 12}, tokenEOF, ""}, + {toml.Position{1, 2}, tokenDot, "."}, + {toml.Position{1, 3}, tokenDollar, "$"}, + {toml.Position{1, 4}, tokenLeftBracket, "["}, + {toml.Position{1, 5}, tokenRightBracket, "]"}, + {toml.Position{1, 6}, tokenDotDot, ".."}, + {toml.Position{1, 8}, tokenLeftParen, "("}, + {toml.Position{1, 9}, tokenRightParen, ")"}, + {toml.Position{1, 10}, tokenQuestion, "?"}, + {toml.Position{1, 11}, tokenStar, "*"}, + {toml.Position{1, 12}, tokenEOF, ""}, }) } func TestLexString(t *testing.T) { testQLFlow(t, "'foo\n'", []token{ - {Position{1, 2}, tokenString, "foo\n"}, - {Position{2, 2}, tokenEOF, ""}, + {toml.Position{1, 2}, tokenString, "foo\n"}, + {toml.Position{2, 2}, tokenEOF, ""}, }) } func TestLexDoubleString(t *testing.T) { testQLFlow(t, `"bar"`, []token{ - {Position{1, 2}, tokenString, "bar"}, - {Position{1, 6}, tokenEOF, ""}, + {toml.Position{1, 2}, tokenString, "bar"}, + {toml.Position{1, 6}, tokenEOF, ""}, }) } func TestLexStringEscapes(t *testing.T) { testQLFlow(t, `"foo \" \' \b \f \/ \t \r \\ \u03A9 \U00012345 \n bar"`, []token{ - {Position{1, 2}, tokenString, "foo \" ' \b \f / \t \r \\ \u03A9 \U00012345 \n bar"}, - {Position{1, 55}, tokenEOF, ""}, + {toml.Position{1, 2}, tokenString, "foo \" ' \b \f / \t \r \\ \u03A9 \U00012345 \n bar"}, + {toml.Position{1, 55}, tokenEOF, ""}, }) } func TestLexStringUnfinishedUnicode4(t *testing.T) { testQLFlow(t, `"\u000"`, []token{ - {Position{1, 2}, tokenError, "unfinished unicode escape"}, + {toml.Position{1, 2}, tokenError, "unfinished unicode escape"}, }) } func TestLexStringUnfinishedUnicode8(t *testing.T) { testQLFlow(t, `"\U0000"`, []token{ - {Position{1, 2}, tokenError, "unfinished unicode escape"}, + {toml.Position{1, 2}, tokenError, "unfinished unicode escape"}, }) } func TestLexStringInvalidEscape(t *testing.T) { testQLFlow(t, `"\x"`, []token{ - {Position{1, 2}, tokenError, "invalid escape sequence: \\x"}, + {toml.Position{1, 2}, tokenError, "invalid escape sequence: \\x"}, }) } func TestLexStringUnfinished(t *testing.T) { testQLFlow(t, `"bar`, []token{ - {Position{1, 2}, tokenError, "unclosed string"}, + {toml.Position{1, 2}, tokenError, "unclosed string"}, }) } func TestLexKey(t *testing.T) { testQLFlow(t, "foo", []token{ - {Position{1, 1}, tokenKey, "foo"}, - {Position{1, 4}, tokenEOF, ""}, + {toml.Position{1, 1}, tokenKey, "foo"}, + {toml.Position{1, 4}, tokenEOF, ""}, }) } func TestLexRecurse(t *testing.T) { testQLFlow(t, "$..*", []token{ - {Position{1, 1}, tokenDollar, "$"}, - {Position{1, 2}, tokenDotDot, ".."}, - {Position{1, 4}, tokenStar, "*"}, - {Position{1, 5}, tokenEOF, ""}, + {toml.Position{1, 1}, tokenDollar, "$"}, + {toml.Position{1, 2}, tokenDotDot, ".."}, + {toml.Position{1, 4}, tokenStar, "*"}, + {toml.Position{1, 5}, tokenEOF, ""}, }) } func TestLexBracketKey(t *testing.T) { testQLFlow(t, "$[foo]", []token{ - {Position{1, 1}, tokenDollar, "$"}, - {Position{1, 2}, tokenLeftBracket, "["}, - {Position{1, 3}, tokenKey, "foo"}, - {Position{1, 6}, tokenRightBracket, "]"}, - {Position{1, 7}, tokenEOF, ""}, + {toml.Position{1, 1}, tokenDollar, "$"}, + {toml.Position{1, 2}, tokenLeftBracket, "["}, + {toml.Position{1, 3}, tokenKey, "foo"}, + {toml.Position{1, 6}, tokenRightBracket, "]"}, + {toml.Position{1, 7}, tokenEOF, ""}, }) } func TestLexSpace(t *testing.T) { testQLFlow(t, "foo bar baz", []token{ - {Position{1, 1}, tokenKey, "foo"}, - {Position{1, 5}, tokenKey, "bar"}, - {Position{1, 9}, tokenKey, "baz"}, - {Position{1, 12}, tokenEOF, ""}, + {toml.Position{1, 1}, tokenKey, "foo"}, + {toml.Position{1, 5}, tokenKey, "bar"}, + {toml.Position{1, 9}, tokenKey, "baz"}, + {toml.Position{1, 12}, tokenEOF, ""}, }) } func TestLexInteger(t *testing.T) { testQLFlow(t, "100 +200 -300", []token{ - {Position{1, 1}, tokenInteger, "100"}, - {Position{1, 5}, tokenInteger, "+200"}, - {Position{1, 10}, tokenInteger, "-300"}, - {Position{1, 14}, tokenEOF, ""}, + {toml.Position{1, 1}, tokenInteger, "100"}, + {toml.Position{1, 5}, tokenInteger, "+200"}, + {toml.Position{1, 10}, tokenInteger, "-300"}, + {toml.Position{1, 14}, tokenEOF, ""}, }) } func TestLexFloat(t *testing.T) { testQLFlow(t, "100.0 +200.0 -300.0", []token{ - {Position{1, 1}, tokenFloat, "100.0"}, - {Position{1, 7}, tokenFloat, "+200.0"}, - {Position{1, 14}, tokenFloat, "-300.0"}, - {Position{1, 20}, tokenEOF, ""}, + {toml.Position{1, 1}, tokenFloat, "100.0"}, + {toml.Position{1, 7}, tokenFloat, "+200.0"}, + {toml.Position{1, 14}, tokenFloat, "-300.0"}, + {toml.Position{1, 20}, tokenEOF, ""}, }) } func TestLexFloatWithMultipleDots(t *testing.T) { testQLFlow(t, "4.2.", []token{ - {Position{1, 1}, tokenError, "cannot have two dots in one float"}, + {toml.Position{1, 1}, tokenError, "cannot have two dots in one float"}, }) } func TestLexFloatLeadingDot(t *testing.T) { testQLFlow(t, "+.1", []token{ - {Position{1, 1}, tokenError, "cannot start float with a dot"}, + {toml.Position{1, 1}, tokenError, "cannot start float with a dot"}, }) } func TestLexFloatWithTrailingDot(t *testing.T) { testQLFlow(t, "42.", []token{ - {Position{1, 1}, tokenError, "float cannot end with a dot"}, + {toml.Position{1, 1}, tokenError, "float cannot end with a dot"}, }) } func TestLexNumberWithoutDigit(t *testing.T) { testQLFlow(t, "+", []token{ - {Position{1, 1}, tokenError, "no digit in that number"}, + {toml.Position{1, 1}, tokenError, "no digit in that number"}, }) } func TestLexUnknown(t *testing.T) { testQLFlow(t, "^", []token{ - {Position{1, 1}, tokenError, "unexpected char: '94'"}, + {toml.Position{1, 1}, tokenError, "unexpected char: '94'"}, }) } diff --git a/vendor/github.com/pelletier/go-toml/match.go b/vendor/github.com/pelletier/go-toml/query/match.go index 48b0f2a15..d7bb15a45 100644 --- a/vendor/github.com/pelletier/go-toml/match.go +++ b/vendor/github.com/pelletier/go-toml/query/match.go @@ -1,27 +1,10 @@ -package toml +package query import ( "fmt" + "github.com/pelletier/go-toml" ) -// support function to set positions for tomlValues -// NOTE: this is done to allow ctx.lastPosition to indicate the start of any -// values returned by the query engines -func tomlValueCheck(node interface{}, ctx *queryContext) interface{} { - switch castNode := node.(type) { - case *tomlValue: - ctx.lastPosition = castNode.position - return castNode.value - case []*TomlTree: - if len(castNode) > 0 { - ctx.lastPosition = castNode[0].position - } - return node - default: - return node - } -} - // base match type matchBase struct { next pathFn @@ -45,15 +28,7 @@ func (f *terminatingFn) setNext(next pathFn) { } func (f *terminatingFn) call(node interface{}, ctx *queryContext) { - switch castNode := node.(type) { - case *TomlTree: - ctx.result.appendResult(node, castNode.position) - case *tomlValue: - ctx.result.appendResult(node, castNode.position) - default: - // use last position for scalars - ctx.result.appendResult(node, ctx.lastPosition) - } + ctx.result.appendResult(node, ctx.lastPosition) } // match single key @@ -67,16 +42,18 @@ func newMatchKeyFn(name string) *matchKeyFn { } func (f *matchKeyFn) call(node interface{}, ctx *queryContext) { - if array, ok := node.([]*TomlTree); ok { + if array, ok := node.([]*toml.Tree); ok { for _, tree := range array { - item := tree.values[f.Name] + item := tree.Get(f.Name) if item != nil { + ctx.lastPosition = tree.GetPosition(f.Name) f.next.call(item, ctx) } } - } else if tree, ok := node.(*TomlTree); ok { - item := tree.values[f.Name] + } else if tree, ok := node.(*toml.Tree); ok { + item := tree.Get(f.Name) if item != nil { + ctx.lastPosition = tree.GetPosition(f.Name) f.next.call(item, ctx) } } @@ -93,8 +70,13 @@ func newMatchIndexFn(idx int) *matchIndexFn { } func (f *matchIndexFn) call(node interface{}, ctx *queryContext) { - if arr, ok := tomlValueCheck(node, ctx).([]interface{}); ok { + if arr, ok := node.([]interface{}); ok { if f.Idx < len(arr) && f.Idx >= 0 { + if treesArray, ok := node.([]*toml.Tree); ok { + if len(treesArray) > 0 { + ctx.lastPosition = treesArray[0].Position() + } + } f.next.call(arr[f.Idx], ctx) } } @@ -111,7 +93,7 @@ func newMatchSliceFn(start, end, step int) *matchSliceFn { } func (f *matchSliceFn) call(node interface{}, ctx *queryContext) { - if arr, ok := tomlValueCheck(node, ctx).([]interface{}); ok { + if arr, ok := node.([]interface{}); ok { // adjust indexes for negative values, reverse ordering realStart, realEnd := f.Start, f.End if realStart < 0 { @@ -125,6 +107,11 @@ func (f *matchSliceFn) call(node interface{}, ctx *queryContext) { } // loop and gather for idx := realStart; idx < realEnd; idx += f.Step { + if treesArray, ok := node.([]*toml.Tree); ok { + if len(treesArray) > 0 { + ctx.lastPosition = treesArray[0].Position() + } + } f.next.call(arr[idx], ctx) } } @@ -140,8 +127,10 @@ func newMatchAnyFn() *matchAnyFn { } func (f *matchAnyFn) call(node interface{}, ctx *queryContext) { - if tree, ok := node.(*TomlTree); ok { - for _, v := range tree.values { + if tree, ok := node.(*toml.Tree); ok { + for _, k := range tree.Keys() { + v := tree.Get(k) + ctx.lastPosition = tree.GetPosition(k) f.next.call(v, ctx) } } @@ -174,21 +163,25 @@ func newMatchRecursiveFn() *matchRecursiveFn { } func (f *matchRecursiveFn) call(node interface{}, ctx *queryContext) { - if tree, ok := node.(*TomlTree); ok { - var visit func(tree *TomlTree) - visit = func(tree *TomlTree) { - for _, v := range tree.values { + originalPosition := ctx.lastPosition + if tree, ok := node.(*toml.Tree); ok { + var visit func(tree *toml.Tree) + visit = func(tree *toml.Tree) { + for _, k := range tree.Keys() { + v := tree.Get(k) + ctx.lastPosition = tree.GetPosition(k) f.next.call(v, ctx) switch node := v.(type) { - case *TomlTree: + case *toml.Tree: visit(node) - case []*TomlTree: + case []*toml.Tree: for _, subtree := range node { visit(subtree) } } } } + ctx.lastPosition = originalPosition f.next.call(tree, ctx) visit(tree) } @@ -197,11 +190,11 @@ func (f *matchRecursiveFn) call(node interface{}, ctx *queryContext) { // match based on an externally provided functional filter type matchFilterFn struct { matchBase - Pos Position + Pos toml.Position Name string } -func newMatchFilterFn(name string, pos Position) *matchFilterFn { +func newMatchFilterFn(name string, pos toml.Position) *matchFilterFn { return &matchFilterFn{Name: name, Pos: pos} } @@ -211,17 +204,22 @@ func (f *matchFilterFn) call(node interface{}, ctx *queryContext) { panic(fmt.Sprintf("%s: query context does not have filter '%s'", f.Pos.String(), f.Name)) } - switch castNode := tomlValueCheck(node, ctx).(type) { - case *TomlTree: - for _, v := range castNode.values { - if tv, ok := v.(*tomlValue); ok { - if fn(tv.value) { - f.next.call(v, ctx) - } - } else { - if fn(v) { - f.next.call(v, ctx) + switch castNode := node.(type) { + case *toml.Tree: + for _, k := range castNode.Keys() { + v := castNode.Get(k) + if fn(v) { + ctx.lastPosition = castNode.GetPosition(k) + f.next.call(v, ctx) + } + } + case []*toml.Tree: + for _, v := range castNode { + if fn(v) { + if len(castNode) > 0 { + ctx.lastPosition = castNode[0].Position() } + f.next.call(v, ctx) } } case []interface{}: diff --git a/vendor/github.com/pelletier/go-toml/match_test.go b/vendor/github.com/pelletier/go-toml/query/match_test.go index b63654ad2..567b11cd7 100644 --- a/vendor/github.com/pelletier/go-toml/match_test.go +++ b/vendor/github.com/pelletier/go-toml/query/match_test.go @@ -1,8 +1,9 @@ -package toml +package query import ( "fmt" "testing" + "github.com/pelletier/go-toml" ) // dump path tree to a string @@ -194,8 +195,8 @@ func TestPathFilterExpr(t *testing.T) { "$[?('foo'),?(bar)]", buildPath( &matchUnionFn{[]pathFn{ - newMatchFilterFn("foo", Position{}), - newMatchFilterFn("bar", Position{}), + newMatchFilterFn("foo", toml.Position{}), + newMatchFilterFn("bar", toml.Position{}), }}, )) } diff --git a/vendor/github.com/pelletier/go-toml/queryparser.go b/vendor/github.com/pelletier/go-toml/query/parser.go index 1cbfc83b2..e4f91b97e 100644 --- a/vendor/github.com/pelletier/go-toml/queryparser.go +++ b/vendor/github.com/pelletier/go-toml/query/parser.go @@ -5,7 +5,7 @@ https://code.google.com/p/json-path/ */ -package toml +package query import ( "fmt" diff --git a/vendor/github.com/pelletier/go-toml/queryparser_test.go b/vendor/github.com/pelletier/go-toml/query/parser_test.go index b2b85cefd..b1d0a3ece 100644 --- a/vendor/github.com/pelletier/go-toml/queryparser_test.go +++ b/vendor/github.com/pelletier/go-toml/query/parser_test.go @@ -1,4 +1,4 @@ -package toml +package query import ( "fmt" @@ -7,19 +7,18 @@ import ( "strings" "testing" "time" + "github.com/pelletier/go-toml" ) type queryTestNode struct { value interface{} - position Position + position toml.Position } func valueString(root interface{}) string { result := "" //fmt.Sprintf("%T:", root) switch node := root.(type) { - case *tomlValue: - return valueString(node.value) - case *QueryResult: + case *Result: items := []string{} for i, v := range node.Values() { items = append(items, fmt.Sprintf("%s:%s", @@ -37,7 +36,7 @@ func valueString(root interface{}) string { } sort.Strings(items) result = "[" + strings.Join(items, ", ") + "]" - case *TomlTree: + case *toml.Tree: // workaround for unreliable map key ordering items := []string{} for _, k := range node.Keys() { @@ -78,13 +77,13 @@ func assertValue(t *testing.T, result, ref interface{}) { } } -func assertQueryPositions(t *testing.T, toml, query string, ref []interface{}) { - tree, err := Load(toml) +func assertQueryPositions(t *testing.T, tomlDoc string, query string, ref []interface{}) { + tree, err := toml.Load(tomlDoc) if err != nil { t.Errorf("Non-nil toml parse error: %v", err) return } - q, err := CompileQuery(query) + q, err := Compile(query) if err != nil { t.Error(err) return @@ -101,7 +100,7 @@ func TestQueryRoot(t *testing.T) { queryTestNode{ map[string]interface{}{ "a": int64(42), - }, Position{1, 1}, + }, toml.Position{1, 1}, }, }) } @@ -112,7 +111,7 @@ func TestQueryKey(t *testing.T) { "$.foo.a", []interface{}{ queryTestNode{ - int64(42), Position{2, 1}, + int64(42), toml.Position{2, 1}, }, }) } @@ -123,7 +122,7 @@ func TestQueryKeyString(t *testing.T) { "$.foo['a']", []interface{}{ queryTestNode{ - int64(42), Position{2, 1}, + int64(42), toml.Position{2, 1}, }, }) } @@ -134,7 +133,7 @@ func TestQueryIndex(t *testing.T) { "$.foo.a[5]", []interface{}{ queryTestNode{ - int64(6), Position{2, 1}, + int64(6), toml.Position{2, 1}, }, }) } @@ -145,19 +144,19 @@ func TestQuerySliceRange(t *testing.T) { "$.foo.a[0:5]", []interface{}{ queryTestNode{ - int64(1), Position{2, 1}, + int64(1), toml.Position{2, 1}, }, queryTestNode{ - int64(2), Position{2, 1}, + int64(2), toml.Position{2, 1}, }, queryTestNode{ - int64(3), Position{2, 1}, + int64(3), toml.Position{2, 1}, }, queryTestNode{ - int64(4), Position{2, 1}, + int64(4), toml.Position{2, 1}, }, queryTestNode{ - int64(5), Position{2, 1}, + int64(5), toml.Position{2, 1}, }, }) } @@ -168,13 +167,13 @@ func TestQuerySliceStep(t *testing.T) { "$.foo.a[0:5:2]", []interface{}{ queryTestNode{ - int64(1), Position{2, 1}, + int64(1), toml.Position{2, 1}, }, queryTestNode{ - int64(3), Position{2, 1}, + int64(3), toml.Position{2, 1}, }, queryTestNode{ - int64(5), Position{2, 1}, + int64(5), toml.Position{2, 1}, }, }) } @@ -188,13 +187,13 @@ func TestQueryAny(t *testing.T) { map[string]interface{}{ "a": int64(1), "b": int64(2), - }, Position{1, 1}, + }, toml.Position{1, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(3), "b": int64(4), - }, Position{4, 1}, + }, toml.Position{4, 1}, }, }) } @@ -207,19 +206,19 @@ func TestQueryUnionSimple(t *testing.T) { map[string]interface{}{ "a": int64(1), "b": int64(2), - }, Position{1, 1}, + }, toml.Position{1, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(3), "b": int64(4), - }, Position{4, 1}, + }, toml.Position{4, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(5), "b": int64(6), - }, Position{7, 1}, + }, toml.Position{7, 1}, }, }) } @@ -249,7 +248,7 @@ func TestQueryRecursionAll(t *testing.T) { "b": int64(6), }, }, - }, Position{1, 1}, + }, toml.Position{1, 1}, }, queryTestNode{ map[string]interface{}{ @@ -257,19 +256,19 @@ func TestQueryRecursionAll(t *testing.T) { "a": int64(1), "b": int64(2), }, - }, Position{1, 1}, + }, toml.Position{1, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(1), "b": int64(2), - }, Position{1, 1}, + }, toml.Position{1, 1}, }, queryTestNode{ - int64(1), Position{2, 1}, + int64(1), toml.Position{2, 1}, }, queryTestNode{ - int64(2), Position{3, 1}, + int64(2), toml.Position{3, 1}, }, queryTestNode{ map[string]interface{}{ @@ -277,19 +276,19 @@ func TestQueryRecursionAll(t *testing.T) { "a": int64(3), "b": int64(4), }, - }, Position{4, 1}, + }, toml.Position{4, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(3), "b": int64(4), - }, Position{4, 1}, + }, toml.Position{4, 1}, }, queryTestNode{ - int64(3), Position{5, 1}, + int64(3), toml.Position{5, 1}, }, queryTestNode{ - int64(4), Position{6, 1}, + int64(4), toml.Position{6, 1}, }, queryTestNode{ map[string]interface{}{ @@ -297,19 +296,19 @@ func TestQueryRecursionAll(t *testing.T) { "a": int64(5), "b": int64(6), }, - }, Position{7, 1}, + }, toml.Position{7, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(5), "b": int64(6), - }, Position{7, 1}, + }, toml.Position{7, 1}, }, queryTestNode{ - int64(5), Position{8, 1}, + int64(5), toml.Position{8, 1}, }, queryTestNode{ - int64(6), Position{9, 1}, + int64(6), toml.Position{9, 1}, }, }) } @@ -325,31 +324,31 @@ func TestQueryRecursionUnionSimple(t *testing.T) { "a": int64(1), "b": int64(2), }, - }, Position{1, 1}, + }, toml.Position{1, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(3), "b": int64(4), - }, Position{4, 1}, + }, toml.Position{4, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(1), "b": int64(2), - }, Position{1, 1}, + }, toml.Position{1, 1}, }, queryTestNode{ map[string]interface{}{ "a": int64(5), "b": int64(6), - }, Position{7, 1}, + }, toml.Position{7, 1}, }, }) } func TestQueryFilterFn(t *testing.T) { - buff, err := ioutil.ReadFile("example.toml") + buff, err := ioutil.ReadFile("../example.toml") if err != nil { t.Error(err) return @@ -359,16 +358,16 @@ func TestQueryFilterFn(t *testing.T) { "$..[?(int)]", []interface{}{ queryTestNode{ - int64(8001), Position{13, 1}, + int64(8001), toml.Position{13, 1}, }, queryTestNode{ - int64(8001), Position{13, 1}, + int64(8001), toml.Position{13, 1}, }, queryTestNode{ - int64(8002), Position{13, 1}, + int64(8002), toml.Position{13, 1}, }, queryTestNode{ - int64(5000), Position{14, 1}, + int64(5000), toml.Position{14, 1}, }, }) @@ -376,32 +375,32 @@ func TestQueryFilterFn(t *testing.T) { "$..[?(string)]", []interface{}{ queryTestNode{ - "TOML Example", Position{3, 1}, + "TOML Example", toml.Position{3, 1}, }, queryTestNode{ - "Tom Preston-Werner", Position{6, 1}, + "Tom Preston-Werner", toml.Position{6, 1}, }, queryTestNode{ - "GitHub", Position{7, 1}, + "GitHub", toml.Position{7, 1}, }, queryTestNode{ "GitHub Cofounder & CEO\nLikes tater tots and beer.", - Position{8, 1}, + toml.Position{8, 1}, }, queryTestNode{ - "192.168.1.1", Position{12, 1}, + "192.168.1.1", toml.Position{12, 1}, }, queryTestNode{ - "10.0.0.1", Position{21, 3}, + "10.0.0.1", toml.Position{21, 3}, }, queryTestNode{ - "eqdc10", Position{22, 3}, + "eqdc10", toml.Position{22, 3}, }, queryTestNode{ - "10.0.0.2", Position{25, 3}, + "10.0.0.2", toml.Position{25, 3}, }, queryTestNode{ - "eqdc10", Position{26, 3}, + "eqdc10", toml.Position{26, 3}, }, }) @@ -421,7 +420,7 @@ func TestQueryFilterFn(t *testing.T) { "organization": "GitHub", "bio": "GitHub Cofounder & CEO\nLikes tater tots and beer.", "dob": tv, - }, Position{5, 1}, + }, toml.Position{5, 1}, }, queryTestNode{ map[string]interface{}{ @@ -429,7 +428,7 @@ func TestQueryFilterFn(t *testing.T) { "ports": []interface{}{int64(8001), int64(8001), int64(8002)}, "connection_max": int64(5000), "enabled": true, - }, Position{11, 1}, + }, toml.Position{11, 1}, }, queryTestNode{ map[string]interface{}{ @@ -441,19 +440,19 @@ func TestQueryFilterFn(t *testing.T) { "ip": "10.0.0.2", "dc": "eqdc10", }, - }, Position{17, 1}, + }, toml.Position{17, 1}, }, queryTestNode{ map[string]interface{}{ "ip": "10.0.0.1", "dc": "eqdc10", - }, Position{20, 3}, + }, toml.Position{20, 3}, }, queryTestNode{ map[string]interface{}{ "ip": "10.0.0.2", "dc": "eqdc10", - }, Position{24, 3}, + }, toml.Position{24, 3}, }, queryTestNode{ map[string]interface{}{ @@ -461,7 +460,7 @@ func TestQueryFilterFn(t *testing.T) { []interface{}{"gamma", "delta"}, []interface{}{int64(1), int64(2)}, }, - }, Position{28, 1}, + }, toml.Position{28, 1}, }, }) @@ -469,7 +468,7 @@ func TestQueryFilterFn(t *testing.T) { "$..[?(time)]", []interface{}{ queryTestNode{ - tv, Position{9, 1}, + tv, toml.Position{9, 1}, }, }) @@ -477,7 +476,7 @@ func TestQueryFilterFn(t *testing.T) { "$..[?(bool)]", []interface{}{ queryTestNode{ - true, Position{15, 1}, + true, toml.Position{15, 1}, }, }) } diff --git a/vendor/github.com/pelletier/go-toml/query.go b/vendor/github.com/pelletier/go-toml/query/query.go index 307a1ecab..1c6cd8014 100644 --- a/vendor/github.com/pelletier/go-toml/query.go +++ b/vendor/github.com/pelletier/go-toml/query/query.go @@ -1,7 +1,9 @@ -package toml +package query import ( "time" + + "github.com/pelletier/go-toml" ) // NodeFilterFn represents a user-defined filter function, for use with @@ -15,50 +17,43 @@ import ( // to use from multiple goroutines. type NodeFilterFn func(node interface{}) bool -// QueryResult is the result of Executing a Query. -type QueryResult struct { +// Result is the result of Executing a Query. +type Result struct { items []interface{} - positions []Position + positions []toml.Position } // appends a value/position pair to the result set. -func (r *QueryResult) appendResult(node interface{}, pos Position) { +func (r *Result) appendResult(node interface{}, pos toml.Position) { r.items = append(r.items, node) r.positions = append(r.positions, pos) } -// Values is a set of values within a QueryResult. The order of values is not +// Values is a set of values within a Result. The order of values is not // guaranteed to be in document order, and may be different each time a query is // executed. -func (r QueryResult) Values() []interface{} { - values := make([]interface{}, len(r.items)) - for i, v := range r.items { - o, ok := v.(*tomlValue) - if ok { - values[i] = o.value - } else { - values[i] = v - } - } - return values +func (r Result) Values() []interface{} { + return r.items } -// Positions is a set of positions for values within a QueryResult. Each index +// Positions is a set of positions for values within a Result. Each index // in Positions() corresponds to the entry in Value() of the same index. -func (r QueryResult) Positions() []Position { +func (r Result) Positions() []toml.Position { return r.positions } // runtime context for executing query paths type queryContext struct { - result *QueryResult + result *Result filters *map[string]NodeFilterFn - lastPosition Position + lastPosition toml.Position } // generic path functor interface type pathFn interface { setNext(next pathFn) + // it is the caller's responsibility to set the ctx.lastPosition before invoking call() + // node can be one of: *toml.Tree, []*toml.Tree, or a scalar call(node interface{}, ctx *queryContext) } @@ -88,17 +83,17 @@ func (q *Query) appendPath(next pathFn) { next.setNext(newTerminatingFn()) // init the next functor } -// CompileQuery compiles a TOML path expression. The returned Query can be used -// to match elements within a TomlTree and its descendants. -func CompileQuery(path string) (*Query, error) { +// Compile compiles a TOML path expression. The returned Query can be used +// to match elements within a Tree and its descendants. See Execute. +func Compile(path string) (*Query, error) { return parseQuery(lexQuery(path)) } -// Execute executes a query against a TomlTree, and returns the result of the query. -func (q *Query) Execute(tree *TomlTree) *QueryResult { - result := &QueryResult{ +// Execute executes a query against a Tree, and returns the result of the query. +func (q *Query) Execute(tree *toml.Tree) *Result { + result := &Result{ items: []interface{}{}, - positions: []Position{}, + positions: []toml.Position{}, } if q.root == nil { result.appendResult(tree, tree.GetPosition("")) @@ -107,11 +102,21 @@ func (q *Query) Execute(tree *TomlTree) *QueryResult { result: result, filters: q.filters, } + ctx.lastPosition = tree.Position() q.root.call(tree, ctx) } return result } +// CompileAndExecute is a shorthand for Compile(path) followed by Execute(tree). +func CompileAndExecute(path string, tree *toml.Tree) (*Result, error) { + query, err := Compile(path) + if err != nil { + return nil, err + } + return query.Execute(tree), nil +} + // SetFilter sets a user-defined filter function. These may be used inside // "?(..)" query expressions to filter TOML document elements within a query. func (q *Query) SetFilter(name string, fn NodeFilterFn) { @@ -127,7 +132,7 @@ func (q *Query) SetFilter(name string, fn NodeFilterFn) { var defaultFilterFunctions = map[string]NodeFilterFn{ "tree": func(node interface{}) bool { - _, ok := node.(*TomlTree) + _, ok := node.(*toml.Tree) return ok }, "int": func(node interface{}) bool { diff --git a/vendor/github.com/pelletier/go-toml/query/query_test.go b/vendor/github.com/pelletier/go-toml/query/query_test.go new file mode 100644 index 000000000..903a8dc73 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/query/query_test.go @@ -0,0 +1,157 @@ +package query + +import ( + "fmt" + "testing" + + "github.com/pelletier/go-toml" +) + +func assertArrayContainsInAnyOrder(t *testing.T, array []interface{}, objects ...interface{}) { + if len(array) != len(objects) { + t.Fatalf("array contains %d objects but %d are expected", len(array), len(objects)) + } + + for _, o := range objects { + found := false + for _, a := range array { + if a == o { + found = true + break + } + } + if !found { + t.Fatal(o, "not found in array", array) + } + } +} + +func TestQueryExample(t *testing.T) { + config, _ := toml.Load(` + [[book]] + title = "The Stand" + author = "Stephen King" + [[book]] + title = "For Whom the Bell Tolls" + author = "Ernest Hemmingway" + [[book]] + title = "Neuromancer" + author = "William Gibson" + `) + authors, err := CompileAndExecute("$.book.author", config) + if err != nil { + t.Fatal("unexpected error:", err) + } + names := authors.Values() + if len(names) != 3 { + t.Fatalf("query should return 3 names but returned %d", len(names)) + } + assertArrayContainsInAnyOrder(t, names, "Stephen King", "Ernest Hemmingway", "William Gibson") +} + +func TestQueryReadmeExample(t *testing.T) { + config, _ := toml.Load(` +[postgres] +user = "pelletier" +password = "mypassword" +`) + + query, err := Compile("$..[user,password]") + if err != nil { + t.Fatal("unexpected error:", err) + } + results := query.Execute(config) + values := results.Values() + if len(values) != 2 { + t.Fatalf("query should return 2 values but returned %d", len(values)) + } + assertArrayContainsInAnyOrder(t, values, "pelletier", "mypassword") +} + +func TestQueryPathNotPresent(t *testing.T) { + config, _ := toml.Load(`a = "hello"`) + query, err := Compile("$.foo.bar") + if err != nil { + t.Fatal("unexpected error:", err) + } + results := query.Execute(config) + if err != nil { + t.Fatalf("err should be nil. got %s instead", err) + } + if len(results.items) != 0 { + t.Fatalf("no items should be matched. %d matched instead", len(results.items)) + } +} + +func ExampleNodeFilterFn_filterExample() { + tree, _ := toml.Load(` + [struct_one] + foo = "foo" + bar = "bar" + + [struct_two] + baz = "baz" + gorf = "gorf" + `) + + // create a query that references a user-defined-filter + query, _ := Compile("$[?(bazOnly)]") + + // define the filter, and assign it to the query + query.SetFilter("bazOnly", func(node interface{}) bool { + if tree, ok := node.(*toml.Tree); ok { + return tree.Has("baz") + } + return false // reject all other node types + }) + + // results contain only the 'struct_two' Tree + query.Execute(tree) +} + +func ExampleQuery_queryExample() { + config, _ := toml.Load(` + [[book]] + title = "The Stand" + author = "Stephen King" + [[book]] + title = "For Whom the Bell Tolls" + author = "Ernest Hemmingway" + [[book]] + title = "Neuromancer" + author = "William Gibson" + `) + + // find and print all the authors in the document + query, _ := Compile("$.book.author") + authors := query.Execute(config) + for _, name := range authors.Values() { + fmt.Println(name) + } +} + +func TestTomlQuery(t *testing.T) { + tree, err := toml.Load("[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6") + if err != nil { + t.Error(err) + return + } + query, err := Compile("$.foo.bar") + if err != nil { + t.Error(err) + return + } + result := query.Execute(tree) + values := result.Values() + if len(values) != 1 { + t.Errorf("Expected resultset of 1, got %d instead: %v", len(values), values) + } + + if tt, ok := values[0].(*toml.Tree); !ok { + t.Errorf("Expected type of Tree: %T", values[0]) + } else if tt.Get("a") != int64(1) { + t.Errorf("Expected 'a' with a value 1: %v", tt.Get("a")) + } else if tt.Get("b") != int64(2) { + t.Errorf("Expected 'b' with a value 2: %v", tt.Get("b")) + } +} diff --git a/vendor/github.com/pelletier/go-toml/query/tokens.go b/vendor/github.com/pelletier/go-toml/query/tokens.go new file mode 100644 index 000000000..429e289ab --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/query/tokens.go @@ -0,0 +1,107 @@ +package query + +import ( +"fmt" +"strconv" +"unicode" + "github.com/pelletier/go-toml" +) + +// Define tokens +type tokenType int + +const ( + eof = -(iota + 1) +) + +const ( + tokenError tokenType = iota + tokenEOF + tokenKey + tokenString + tokenInteger + tokenFloat + tokenLeftBracket + tokenRightBracket + tokenLeftParen + tokenRightParen + tokenComma + tokenColon + tokenDollar + tokenStar + tokenQuestion + tokenDot + tokenDotDot +) + +var tokenTypeNames = []string{ + "Error", + "EOF", + "Key", + "String", + "Integer", + "Float", + "[", + "]", + "(", + ")", + ",", + ":", + "$", + "*", + "?", + ".", + "..", +} + +type token struct { + toml.Position + typ tokenType + val string +} + +func (tt tokenType) String() string { + idx := int(tt) + if idx < len(tokenTypeNames) { + return tokenTypeNames[idx] + } + return "Unknown" +} + +func (t token) Int() int { + if result, err := strconv.Atoi(t.val); err != nil { + panic(err) + } else { + return result + } +} + +func (t token) String() string { + switch t.typ { + case tokenEOF: + return "EOF" + case tokenError: + return t.val + } + + return fmt.Sprintf("%q", t.val) +} + +func isSpace(r rune) bool { + return r == ' ' || r == '\t' +} + +func isAlphanumeric(r rune) bool { + return unicode.IsLetter(r) || r == '_' +} + +func isDigit(r rune) bool { + return unicode.IsNumber(r) +} + +func isHexDigit(r rune) bool { + return isDigit(r) || + (r >= 'a' && r <= 'f') || + (r >= 'A' && r <= 'F') +} + diff --git a/vendor/github.com/pelletier/go-toml/query_test.go b/vendor/github.com/pelletier/go-toml/query_test.go deleted file mode 100644 index 0d9f3832b..000000000 --- a/vendor/github.com/pelletier/go-toml/query_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package toml - -import ( - "testing" -) - -func assertArrayContainsInAnyOrder(t *testing.T, array []interface{}, objects ...interface{}) { - if len(array) != len(objects) { - t.Fatalf("array contains %d objects but %d are expected", len(array), len(objects)) - } - - for _, o := range objects { - found := false - for _, a := range array { - if a == o { - found = true - break - } - } - if !found { - t.Fatal(o, "not found in array", array) - } - } -} - -func TestQueryExample(t *testing.T) { - config, _ := Load(` - [[book]] - title = "The Stand" - author = "Stephen King" - [[book]] - title = "For Whom the Bell Tolls" - author = "Ernest Hemmingway" - [[book]] - title = "Neuromancer" - author = "William Gibson" - `) - - authors, _ := config.Query("$.book.author") - names := authors.Values() - if len(names) != 3 { - t.Fatalf("query should return 3 names but returned %d", len(names)) - } - assertArrayContainsInAnyOrder(t, names, "Stephen King", "Ernest Hemmingway", "William Gibson") -} - -func TestQueryReadmeExample(t *testing.T) { - config, _ := Load(` -[postgres] -user = "pelletier" -password = "mypassword" -`) - results, _ := config.Query("$..[user,password]") - values := results.Values() - if len(values) != 2 { - t.Fatalf("query should return 2 values but returned %d", len(values)) - } - assertArrayContainsInAnyOrder(t, values, "pelletier", "mypassword") -} - -func TestQueryPathNotPresent(t *testing.T) { - config, _ := Load(`a = "hello"`) - results, err := config.Query("$.foo.bar") - if err != nil { - t.Fatalf("err should be nil. got %s instead", err) - } - if len(results.items) != 0 { - t.Fatalf("no items should be matched. %d matched instead", len(results.items)) - } -} diff --git a/vendor/github.com/pelletier/go-toml/test.sh b/vendor/github.com/pelletier/go-toml/test.sh index 436d2fb6c..d2d2aed16 100755 --- a/vendor/github.com/pelletier/go-toml/test.sh +++ b/vendor/github.com/pelletier/go-toml/test.sh @@ -19,6 +19,9 @@ function git_clone() { popd } +# Remove potential previous runs +rm -rf src test_program_bin toml-test + # Run go vet go vet ./... @@ -36,13 +39,16 @@ go build -o toml-test github.com/BurntSushi/toml-test # vendorize the current lib for testing # NOTE: this basically mocks an install without having to go back out to github for code mkdir -p src/github.com/pelletier/go-toml/cmd +mkdir -p src/github.com/pelletier/go-toml/query cp *.go *.toml src/github.com/pelletier/go-toml cp -R cmd/* src/github.com/pelletier/go-toml/cmd +cp -R query/* src/github.com/pelletier/go-toml/query go build -o test_program_bin src/github.com/pelletier/go-toml/cmd/test_program.go # Run basic unit tests -go test github.com/pelletier/go-toml -v -covermode=count -coverprofile=coverage.out +go test github.com/pelletier/go-toml -covermode=count -coverprofile=coverage.out go test github.com/pelletier/go-toml/cmd/tomljson +go test github.com/pelletier/go-toml/query # run the entire BurntSushi test suite if [[ $# -eq 0 ]] ; then diff --git a/vendor/github.com/pelletier/go-toml/toml.go b/vendor/github.com/pelletier/go-toml/toml.go index 1ba56a1c1..99663217e 100644 --- a/vendor/github.com/pelletier/go-toml/toml.go +++ b/vendor/github.com/pelletier/go-toml/toml.go @@ -14,30 +14,35 @@ type tomlValue struct { position Position } -// TomlTree is the result of the parsing of a TOML file. -type TomlTree struct { - values map[string]interface{} // string -> *tomlValue, *TomlTree, []*TomlTree +// Tree is the result of the parsing of a TOML file. +type Tree struct { + values map[string]interface{} // string -> *tomlValue, *Tree, []*Tree position Position } -func newTomlTree() *TomlTree { - return &TomlTree{ +func newTree() *Tree { + return &Tree{ values: make(map[string]interface{}), position: Position{}, } } -// TreeFromMap initializes a new TomlTree object using the given map. -func TreeFromMap(m map[string]interface{}) (*TomlTree, error) { +// TreeFromMap initializes a new Tree object using the given map. +func TreeFromMap(m map[string]interface{}) (*Tree, error) { result, err := toTree(m) if err != nil { return nil, err } - return result.(*TomlTree), nil + return result.(*Tree), nil +} + +// Position returns the position of the tree. +func (t *Tree) Position() Position { + return t.position } // Has returns a boolean indicating if the given key exists. -func (t *TomlTree) Has(key string) bool { +func (t *Tree) Has(key string) bool { if key == "" { return false } @@ -45,25 +50,27 @@ func (t *TomlTree) Has(key string) bool { } // HasPath returns true if the given path of keys exists, false otherwise. -func (t *TomlTree) HasPath(keys []string) bool { +func (t *Tree) HasPath(keys []string) bool { return t.GetPath(keys) != nil } // Keys returns the keys of the toplevel tree. // Warning: this is a costly operation. -func (t *TomlTree) Keys() []string { - var keys []string +func (t *Tree) Keys() []string { + keys := make([]string, len(t.values)) + i := 0 for k := range t.values { - keys = append(keys, k) + keys[i] = k + i++ } return keys } -// Get the value at key in the TomlTree. +// Get the value at key in the Tree. // Key is a dot-separated path (e.g. a.b.c). // Returns nil if the path does not exist in the tree. // If keys is of length zero, the current tree is returned. -func (t *TomlTree) Get(key string) interface{} { +func (t *Tree) Get(key string) interface{} { if key == "" { return t } @@ -76,7 +83,7 @@ func (t *TomlTree) 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 *TomlTree) GetPath(keys []string) interface{} { +func (t *Tree) GetPath(keys []string) interface{} { if len(keys) == 0 { return t } @@ -87,9 +94,9 @@ func (t *TomlTree) GetPath(keys []string) interface{} { return nil } switch node := value.(type) { - case *TomlTree: + case *Tree: subtree = node - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { return nil @@ -109,7 +116,7 @@ func (t *TomlTree) GetPath(keys []string) interface{} { } // GetPosition returns the position of the given key. -func (t *TomlTree) GetPosition(key string) Position { +func (t *Tree) GetPosition(key string) Position { if key == "" { return t.position } @@ -118,7 +125,7 @@ func (t *TomlTree) GetPosition(key string) Position { // GetPositionPath returns the element in the tree indicated by 'keys'. // If keys is of length zero, the current tree is returned. -func (t *TomlTree) GetPositionPath(keys []string) Position { +func (t *Tree) GetPositionPath(keys []string) Position { if len(keys) == 0 { return t.position } @@ -129,9 +136,9 @@ func (t *TomlTree) GetPositionPath(keys []string) Position { return Position{0, 0} } switch node := value.(type) { - case *TomlTree: + case *Tree: subtree = node - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { return Position{0, 0} @@ -145,9 +152,9 @@ func (t *TomlTree) GetPositionPath(keys []string) Position { switch node := subtree.values[keys[len(keys)-1]].(type) { case *tomlValue: return node.position - case *TomlTree: + case *Tree: return node.position - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { return Position{0, 0} @@ -159,7 +166,7 @@ func (t *TomlTree) GetPositionPath(keys []string) Position { } // GetDefault works like Get but with a default value -func (t *TomlTree) GetDefault(key string, def interface{}) interface{} { +func (t *Tree) GetDefault(key string, def interface{}) interface{} { val := t.Get(key) if val == nil { return def @@ -169,30 +176,30 @@ func (t *TomlTree) GetDefault(key string, def interface{}) interface{} { // Set an element in the tree. // Key is a dot-separated path (e.g. a.b.c). -// Creates all necessary intermediates trees, if needed. -func (t *TomlTree) Set(key string, value interface{}) { +// Creates all necessary intermediate trees, if needed. +func (t *Tree) Set(key string, value interface{}) { t.SetPath(strings.Split(key, "."), value) } // SetPath sets an element in the tree. // Keys is an array of path elements (e.g. {"a","b","c"}). -// Creates all necessary intermediates trees, if needed. -func (t *TomlTree) SetPath(keys []string, value interface{}) { +// Creates all necessary intermediate trees, if needed. +func (t *Tree) SetPath(keys []string, value interface{}) { subtree := t for _, intermediateKey := range keys[:len(keys)-1] { nextTree, exists := subtree.values[intermediateKey] if !exists { - nextTree = newTomlTree() + nextTree = newTree() subtree.values[intermediateKey] = nextTree // add new element here } switch node := nextTree.(type) { - case *TomlTree: + case *Tree: subtree = node - case []*TomlTree: + case []*Tree: // go to most recent element if len(node) == 0 { // create element if it does not exist - subtree.values[intermediateKey] = append(node, newTomlTree()) + subtree.values[intermediateKey] = append(node, newTree()) } subtree = node[len(node)-1] } @@ -201,9 +208,9 @@ func (t *TomlTree) SetPath(keys []string, value interface{}) { var toInsert interface{} switch value.(type) { - case *TomlTree: + case *Tree: toInsert = value - case []*TomlTree: + case []*Tree: toInsert = value case *tomlValue: toInsert = value @@ -221,21 +228,21 @@ func (t *TomlTree) SetPath(keys []string, value interface{}) { // and tree[a][b][c] // // Returns nil on success, error object on failure -func (t *TomlTree) createSubTree(keys []string, pos Position) error { +func (t *Tree) createSubTree(keys []string, pos Position) error { subtree := t for _, intermediateKey := range keys { nextTree, exists := subtree.values[intermediateKey] if !exists { - tree := newTomlTree() + tree := newTree() tree.position = pos subtree.values[intermediateKey] = tree nextTree = tree } switch node := nextTree.(type) { - case []*TomlTree: + case []*Tree: subtree = node[len(node)-1] - case *TomlTree: + case *Tree: subtree = node default: return fmt.Errorf("unknown type for path %s (%s): %T (%#v)", @@ -245,17 +252,8 @@ func (t *TomlTree) createSubTree(keys []string, pos Position) error { return nil } -// Query compiles and executes a query on a tree and returns the query result. -func (t *TomlTree) Query(query string) (*QueryResult, error) { - q, err := CompileQuery(query) - if err != nil { - return nil, err - } - return q.Execute(t), nil -} - -// LoadReader creates a TomlTree from any io.Reader. -func LoadReader(reader io.Reader) (tree *TomlTree, err error) { +// LoadReader creates a Tree from any io.Reader. +func LoadReader(reader io.Reader) (tree *Tree, err error) { defer func() { if r := recover(); r != nil { if _, ok := r.(runtime.Error); ok { @@ -268,13 +266,13 @@ func LoadReader(reader io.Reader) (tree *TomlTree, err error) { return } -// Load creates a TomlTree from a string. -func Load(content string) (tree *TomlTree, err error) { +// Load creates a Tree from a string. +func Load(content string) (tree *Tree, err error) { return LoadReader(strings.NewReader(content)) } -// LoadFile creates a TomlTree from a file. -func LoadFile(path string) (tree *TomlTree, err error) { +// LoadFile creates a Tree from a file. +func LoadFile(path string) (tree *Tree, err error) { file, err := os.Open(path) if err != nil { return nil, err diff --git a/vendor/github.com/pelletier/go-toml/toml_test.go b/vendor/github.com/pelletier/go-toml/toml_test.go index 7c7f9eff9..ab9c24253 100644 --- a/vendor/github.com/pelletier/go-toml/toml_test.go +++ b/vendor/github.com/pelletier/go-toml/toml_test.go @@ -70,12 +70,12 @@ func TestTomlHasPath(t *testing.T) { } func TestTomlGetPath(t *testing.T) { - node := newTomlTree() + node := newTree() //TODO: set other node data for idx, item := range []struct { Path []string - Expected *TomlTree + Expected *Tree }{ { // empty path test []string{}, @@ -94,31 +94,6 @@ func TestTomlGetPath(t *testing.T) { } } -func TestTomlQuery(t *testing.T) { - tree, err := Load("[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6") - if err != nil { - t.Error(err) - return - } - result, err := tree.Query("$.foo.bar") - if err != nil { - t.Error(err) - return - } - values := result.Values() - if len(values) != 1 { - t.Errorf("Expected resultset of 1, got %d instead: %v", len(values), values) - } - - if tt, ok := values[0].(*TomlTree); !ok { - t.Errorf("Expected type of TomlTree: %T", values[0]) - } else if tt.Get("a") != int64(1) { - t.Errorf("Expected 'a' with a value 1: %v", tt.Get("a")) - } else if tt.Get("b") != int64(2) { - t.Errorf("Expected 'b' with a value 2: %v", tt.Get("b")) - } -} - func TestTomlFromMap(t *testing.T) { simpleMap := map[string]interface{}{"hello": 42} tree, err := TreeFromMap(simpleMap) diff --git a/vendor/github.com/pelletier/go-toml/tomltree_create.go b/vendor/github.com/pelletier/go-toml/tomltree_create.go index c6054f358..ee7114ed8 100644 --- a/vendor/github.com/pelletier/go-toml/tomltree_create.go +++ b/vendor/github.com/pelletier/go-toml/tomltree_create.go @@ -51,7 +51,7 @@ func simpleValueCoercion(object interface{}) (interface{}, error) { case fmt.Stringer: return original.String(), nil default: - return nil, fmt.Errorf("cannot convert type %T to TomlTree", object) + return nil, fmt.Errorf("cannot convert type %T to Tree", object) } } @@ -59,7 +59,7 @@ func sliceToTree(object interface{}) (interface{}, error) { // arrays are a bit tricky, since they can represent either a // collection of simple values, which is represented by one // *tomlValue, or an array of tables, which is represented by an - // array of *TomlTree. + // array of *Tree. // holding the assumption that this function is called from toTree only when value.Kind() is Array or Slice value := reflect.ValueOf(object) @@ -70,14 +70,14 @@ func sliceToTree(object interface{}) (interface{}, error) { } if insideType.Kind() == reflect.Map { // this is considered as an array of tables - tablesArray := make([]*TomlTree, 0, length) + tablesArray := make([]*Tree, 0, length) for i := 0; i < length; i++ { table := value.Index(i) tree, err := toTree(table.Interface()) if err != nil { return nil, err } - tablesArray = append(tablesArray, tree.(*TomlTree)) + tablesArray = append(tablesArray, tree.(*Tree)) } return tablesArray, nil } @@ -120,7 +120,7 @@ func toTree(object interface{}) (interface{}, error) { } values[key.String()] = newValue } - return &TomlTree{values, Position{}}, nil + return &Tree{values, Position{}}, nil } if value.Kind() == reflect.Array || value.Kind() == reflect.Slice { diff --git a/vendor/github.com/pelletier/go-toml/tomltree_create_test.go b/vendor/github.com/pelletier/go-toml/tomltree_create_test.go index 6c1496835..1ca108a52 100644 --- a/vendor/github.com/pelletier/go-toml/tomltree_create_test.go +++ b/vendor/github.com/pelletier/go-toml/tomltree_create_test.go @@ -1,9 +1,9 @@ package toml import ( + "strconv" "testing" "time" - "strconv" ) type customString string @@ -16,11 +16,11 @@ func (s stringer) String() string { func validate(t *testing.T, path string, object interface{}) { switch o := object.(type) { - case *TomlTree: + case *Tree: for key, tree := range o.values { validate(t, path+"."+key, tree) } - case []*TomlTree: + case []*Tree: for index, tree := range o { validate(t, path+"."+strconv.Itoa(index), tree) } @@ -37,11 +37,11 @@ func validate(t *testing.T, path string, object interface{}) { t.Logf("validation ok %s as %T", path, object) } -func validateTree(t *testing.T, tree *TomlTree) { +func validateTree(t *testing.T, tree *Tree) { validate(t, "", tree) } -func TestTomlTreeCreateToTree(t *testing.T) { +func TestTreeCreateToTree(t *testing.T) { data := map[string]interface{}{ "a_string": "bar", "an_int": 42, @@ -72,15 +72,15 @@ func TestTomlTreeCreateToTree(t *testing.T) { validateTree(t, tree) } -func TestTomlTreeCreateToTreeInvalidLeafType(t *testing.T) { +func TestTreeCreateToTreeInvalidLeafType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": t}) - expected := "cannot convert type *testing.T to TomlTree" + expected := "cannot convert type *testing.T to Tree" if err.Error() != expected { t.Fatalf("expected error %s, got %s", expected, err.Error()) } } -func TestTomlTreeCreateToTreeInvalidMapKeyType(t *testing.T) { +func TestTreeCreateToTreeInvalidMapKeyType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": map[int]interface{}{2: 1}}) expected := "map key needs to be a string, not int (int)" if err.Error() != expected { @@ -88,17 +88,17 @@ func TestTomlTreeCreateToTreeInvalidMapKeyType(t *testing.T) { } } -func TestTomlTreeCreateToTreeInvalidArrayMemberType(t *testing.T) { +func TestTreeCreateToTreeInvalidArrayMemberType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": []*testing.T{t}}) - expected := "cannot convert type *testing.T to TomlTree" + expected := "cannot convert type *testing.T to Tree" if err.Error() != expected { t.Fatalf("expected error %s, got %s", expected, err.Error()) } } -func TestTomlTreeCreateToTreeInvalidTableGroupType(t *testing.T) { +func TestTreeCreateToTreeInvalidTableGroupType(t *testing.T) { _, err := TreeFromMap(map[string]interface{}{"foo": []map[string]interface{}{map[string]interface{}{"hello": t}}}) - expected := "cannot convert type *testing.T to TomlTree" + expected := "cannot convert type *testing.T to Tree" if err.Error() != expected { t.Fatalf("expected error %s, got %s", expected, err.Error()) } diff --git a/vendor/github.com/pelletier/go-toml/tomltree_write.go b/vendor/github.com/pelletier/go-toml/tomltree_write.go index 6a7fa1745..d27afc118 100644 --- a/vendor/github.com/pelletier/go-toml/tomltree_write.go +++ b/vendor/github.com/pelletier/go-toml/tomltree_write.go @@ -4,11 +4,11 @@ import ( "bytes" "fmt" "io" + "reflect" "sort" "strconv" "strings" "time" - "reflect" ) // encodes a string to a TOML-compliant string value @@ -83,14 +83,14 @@ func tomlValueStringRepresentation(v interface{}) (string, error) { return "", fmt.Errorf("unsupported value type %T: %v", v, v) } -func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (int64, error) { +func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (int64, error) { simpleValuesKeys := make([]string, 0) complexValuesKeys := make([]string, 0) for k := range t.values { v := t.values[k] switch v.(type) { - case *TomlTree, []*TomlTree: + case *Tree, []*Tree: complexValuesKeys = append(complexValuesKeys, k) default: simpleValuesKeys = append(simpleValuesKeys, k) @@ -129,7 +129,7 @@ func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int6 switch node := v.(type) { // node has to be of those two types given how keys are sorted above - case *TomlTree: + case *Tree: tableName := fmt.Sprintf("\n%s[%s]\n", indent, combinedKey) writtenBytesCount, err := w.Write([]byte(tableName)) bytesCount += int64(writtenBytesCount) @@ -140,7 +140,7 @@ func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int6 if err != nil { return bytesCount, err } - case []*TomlTree: + case []*Tree: for _, subTree := range node { if len(subTree.values) > 0 { tableArrayName := fmt.Sprintf("\n%s[[%s]]\n", indent, combinedKey) @@ -162,16 +162,16 @@ func (t *TomlTree) writeTo(w io.Writer, indent, keyspace string, bytesCount int6 return bytesCount, nil } -// WriteTo encode the TomlTree as Toml and writes it to the writer w. +// WriteTo encode the Tree as Toml and writes it to the writer w. // Returns the number of bytes written in case of success, or an error if anything happened. -func (t *TomlTree) WriteTo(w io.Writer) (int64, error) { +func (t *Tree) WriteTo(w io.Writer) (int64, error) { return t.writeTo(w, "", "", 0) } // ToTomlString generates a human-readable representation of the current tree. // Output spans multiple lines, and is suitable for ingest by a TOML parser. // If the conversion cannot be performed, ToString returns a non-nil error. -func (t *TomlTree) ToTomlString() (string, error) { +func (t *Tree) ToTomlString() (string, error) { var buf bytes.Buffer _, err := t.WriteTo(&buf) if err != nil { @@ -182,32 +182,34 @@ func (t *TomlTree) ToTomlString() (string, error) { // String generates a human-readable representation of the current tree. // Alias of ToString. Present to implement the fmt.Stringer interface. -func (t *TomlTree) String() string { +func (t *Tree) String() string { result, _ := t.ToTomlString() return result } // ToMap recursively generates a representation of the tree using Go built-in structures. // The following types are used: -// * uint64 -// * int64 -// * bool -// * string -// * time.Time -// * map[string]interface{} (where interface{} is any of this list) -// * []interface{} (where interface{} is any of this list) -func (t *TomlTree) ToMap() map[string]interface{} { +// +// * bool +// * float64 +// * int64 +// * string +// * uint64 +// * time.Time +// * map[string]interface{} (where interface{} is any of this list) +// * []interface{} (where interface{} is any of this list) +func (t *Tree) ToMap() map[string]interface{} { result := map[string]interface{}{} for k, v := range t.values { switch node := v.(type) { - case []*TomlTree: + case []*Tree: var array []interface{} for _, item := range node { array = append(array, item.ToMap()) } result[k] = array - case *TomlTree: + case *Tree: result[k] = node.ToMap() case *tomlValue: result[k] = node.value diff --git a/vendor/github.com/pelletier/go-toml/tomltree_write_test.go b/vendor/github.com/pelletier/go-toml/tomltree_write_test.go index b5ad8db7c..1a006da3c 100644 --- a/vendor/github.com/pelletier/go-toml/tomltree_write_test.go +++ b/vendor/github.com/pelletier/go-toml/tomltree_write_test.go @@ -40,7 +40,7 @@ func assertErrorString(t *testing.T, expected string, err error) { } } -func TestTomlTreeWriteToTomlString(t *testing.T) { +func TestTreeWriteToTomlString(t *testing.T) { toml, err := Load(`name = { first = "Tom", last = "Preston-Werner" } points = { x = 1, y = 2 }`) @@ -63,7 +63,7 @@ points = { x = 1, y = 2 }`) }) } -func TestTomlTreeWriteToTomlStringSimple(t *testing.T) { +func TestTreeWriteToTomlStringSimple(t *testing.T) { tree, err := Load("[foo]\n\n[[foo.bar]]\na = 42\n\n[[foo.bar]]\na = 69\n") if err != nil { t.Errorf("Test failed to parse: %v", err) @@ -79,7 +79,7 @@ func TestTomlTreeWriteToTomlStringSimple(t *testing.T) { } } -func TestTomlTreeWriteToTomlStringKeysOrders(t *testing.T) { +func TestTreeWriteToTomlStringKeysOrders(t *testing.T) { for i := 0; i < 100; i++ { tree, _ := Load(` foobar = true @@ -119,7 +119,7 @@ func testMaps(t *testing.T, actual, expected map[string]interface{}) { } } -func TestTomlTreeWriteToMapSimple(t *testing.T) { +func TestTreeWriteToMapSimple(t *testing.T) { tree, _ := Load("a = 42\nb = 17") expected := map[string]interface{}{ @@ -130,32 +130,32 @@ func TestTomlTreeWriteToMapSimple(t *testing.T) { testMaps(t, tree.ToMap(), expected) } -func TestTomlTreeWriteToInvalidTreeSimpleValue(t *testing.T) { - tree := TomlTree{values: map[string]interface{}{"foo": int8(1)}} +func TestTreeWriteToInvalidTreeSimpleValue(t *testing.T) { + tree := Tree{values: map[string]interface{}{"foo": int8(1)}} _, err := tree.ToTomlString() assertErrorString(t, "invalid value type at foo: int8", err) } -func TestTomlTreeWriteToInvalidTreeTomlValue(t *testing.T) { - tree := TomlTree{values: map[string]interface{}{"foo": &tomlValue{int8(1), Position{}}}} +func TestTreeWriteToInvalidTreeTomlValue(t *testing.T) { + tree := Tree{values: map[string]interface{}{"foo": &tomlValue{int8(1), Position{}}}} _, err := tree.ToTomlString() assertErrorString(t, "unsupported value type int8: 1", err) } -func TestTomlTreeWriteToInvalidTreeTomlValueArray(t *testing.T) { - tree := TomlTree{values: map[string]interface{}{"foo": &tomlValue{[]interface{}{int8(1)}, Position{}}}} +func TestTreeWriteToInvalidTreeTomlValueArray(t *testing.T) { + tree := Tree{values: map[string]interface{}{"foo": &tomlValue{[]interface{}{int8(1)}, Position{}}}} _, err := tree.ToTomlString() assertErrorString(t, "unsupported value type int8: 1", err) } -func TestTomlTreeWriteToFailingWriterInSimpleValue(t *testing.T) { +func TestTreeWriteToFailingWriterInSimpleValue(t *testing.T) { toml, _ := Load(`a = 2`) writer := failingWriter{failAt: 0, written: 0} _, err := toml.WriteTo(writer) assertErrorString(t, "failingWriter failed after writting 0 bytes", err) } -func TestTomlTreeWriteToFailingWriterInTable(t *testing.T) { +func TestTreeWriteToFailingWriterInTable(t *testing.T) { toml, _ := Load(` [b] a = 2`) @@ -168,7 +168,7 @@ a = 2`) assertErrorString(t, "failingWriter failed after writting 13 bytes", err) } -func TestTomlTreeWriteToFailingWriterInArray(t *testing.T) { +func TestTreeWriteToFailingWriterInArray(t *testing.T) { toml, _ := Load(` [[b]] a = 2`) @@ -181,7 +181,7 @@ a = 2`) assertErrorString(t, "failingWriter failed after writting 15 bytes", err) } -func TestTomlTreeWriteToMapExampleFile(t *testing.T) { +func TestTreeWriteToMapExampleFile(t *testing.T) { tree, _ := LoadFile("example.toml") expected := map[string]interface{}{ "title": "TOML Example", @@ -217,7 +217,7 @@ func TestTomlTreeWriteToMapExampleFile(t *testing.T) { testMaps(t, tree.ToMap(), expected) } -func TestTomlTreeWriteToMapWithTablesInMultipleChunks(t *testing.T) { +func TestTreeWriteToMapWithTablesInMultipleChunks(t *testing.T) { tree, _ := Load(` [[menu.main]] a = "menu 1" @@ -238,7 +238,7 @@ func TestTomlTreeWriteToMapWithTablesInMultipleChunks(t *testing.T) { testMaps(t, treeMap, expected) } -func TestTomlTreeWriteToMapWithArrayOfInlineTables(t *testing.T) { +func TestTreeWriteToMapWithArrayOfInlineTables(t *testing.T) { tree, _ := Load(` [params] language_tabs = [ |