gofmt pass
This commit is contained in:
@@ -8,18 +8,18 @@ import (
|
|||||||
// NOTE: this is done to allow ctx.lastPosition to indicate the start of any
|
// NOTE: this is done to allow ctx.lastPosition to indicate the start of any
|
||||||
// values returned by the query engines
|
// values returned by the query engines
|
||||||
func tomlValueCheck(node interface{}, ctx *queryContext) interface{} {
|
func tomlValueCheck(node interface{}, ctx *queryContext) interface{} {
|
||||||
switch castNode := node.(type) {
|
switch castNode := node.(type) {
|
||||||
case *tomlValue:
|
case *tomlValue:
|
||||||
ctx.lastPosition = castNode.position
|
ctx.lastPosition = castNode.position
|
||||||
return castNode.value
|
return castNode.value
|
||||||
case []*TomlTree:
|
case []*TomlTree:
|
||||||
if len(castNode) > 0 {
|
if len(castNode) > 0 {
|
||||||
ctx.lastPosition = castNode[0].position
|
ctx.lastPosition = castNode[0].position
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
default:
|
default:
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// base match
|
// base match
|
||||||
@@ -45,15 +45,15 @@ func (f *terminatingFn) SetNext(next PathFn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *terminatingFn) Call(node interface{}, ctx *queryContext) {
|
func (f *terminatingFn) Call(node interface{}, ctx *queryContext) {
|
||||||
switch castNode := node.(type) {
|
switch castNode := node.(type) {
|
||||||
case *TomlTree:
|
case *TomlTree:
|
||||||
ctx.result.appendResult(node, castNode.position)
|
ctx.result.appendResult(node, castNode.position)
|
||||||
case *tomlValue:
|
case *tomlValue:
|
||||||
ctx.result.appendResult(node, castNode.position)
|
ctx.result.appendResult(node, castNode.position)
|
||||||
default:
|
default:
|
||||||
// use last position for scalars
|
// use last position for scalars
|
||||||
ctx.result.appendResult(node, ctx.lastPosition)
|
ctx.result.appendResult(node, ctx.lastPosition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// match single key
|
// match single key
|
||||||
@@ -86,11 +86,11 @@ func newMatchIndexFn(idx int) *matchIndexFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *matchIndexFn) Call(node interface{}, ctx *queryContext) {
|
func (f *matchIndexFn) Call(node interface{}, ctx *queryContext) {
|
||||||
if arr, ok := tomlValueCheck(node, ctx).([]interface{}); ok {
|
if arr, ok := tomlValueCheck(node, ctx).([]interface{}); ok {
|
||||||
if f.Idx < len(arr) && f.Idx >= 0 {
|
if f.Idx < len(arr) && f.Idx >= 0 {
|
||||||
f.next.Call(arr[f.Idx], ctx)
|
f.next.Call(arr[f.Idx], ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter by slicing
|
// filter by slicing
|
||||||
@@ -134,7 +134,7 @@ func newMatchAnyFn() *matchAnyFn {
|
|||||||
|
|
||||||
func (f *matchAnyFn) Call(node interface{}, ctx *queryContext) {
|
func (f *matchAnyFn) Call(node interface{}, ctx *queryContext) {
|
||||||
if tree, ok := node.(*TomlTree); ok {
|
if tree, ok := node.(*TomlTree); ok {
|
||||||
for _,v := range tree.values {
|
for _, v := range tree.values {
|
||||||
f.next.Call(v, ctx)
|
f.next.Call(v, ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ func assertPathMatch(t *testing.T, path, ref *Query) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assertPath(t *testing.T, query string, ref *Query) {
|
func assertPath(t *testing.T, query string, ref *Query) {
|
||||||
path, _:= parseQuery(lexQuery(query))
|
path, _ := parseQuery(lexQuery(query))
|
||||||
assertPathMatch(t, path, ref)
|
assertPathMatch(t, path, ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ func (p *tomlParser) parseGroup() tomlParserStateFn {
|
|||||||
|
|
||||||
p.seenGroupKeys = append(p.seenGroupKeys, key.val)
|
p.seenGroupKeys = append(p.seenGroupKeys, key.val)
|
||||||
keys := strings.Split(key.val, ".")
|
keys := strings.Split(key.val, ".")
|
||||||
if err := p.tree.createSubTree(keys,startToken.Position); err != nil {
|
if err := p.tree.createSubTree(keys, startToken.Position); err != nil {
|
||||||
p.raiseError(key, "%s", err)
|
p.raiseError(key, "%s", err)
|
||||||
}
|
}
|
||||||
p.assume(tokenRightBracket)
|
p.assume(tokenRightBracket)
|
||||||
@@ -274,7 +274,7 @@ func (p *tomlParser) parseArray() []interface{} {
|
|||||||
|
|
||||||
func parseToml(flow chan token) *TomlTree {
|
func parseToml(flow chan token) *TomlTree {
|
||||||
result := newTomlTree()
|
result := newTomlTree()
|
||||||
result.position = Position{1,1}
|
result.position = Position{1, 1}
|
||||||
parser := &tomlParser{
|
parser := &tomlParser{
|
||||||
flow: flow,
|
flow: flow,
|
||||||
tree: result,
|
tree: result,
|
||||||
|
|||||||
+6
-6
@@ -396,7 +396,7 @@ func TestDocumentPositions(t *testing.T) {
|
|||||||
assertPosition(t,
|
assertPosition(t,
|
||||||
"[foo]\nbar=42\nbaz=69",
|
"[foo]\nbar=42\nbaz=69",
|
||||||
map[string]Position{
|
map[string]Position{
|
||||||
"": Position{1, 1},
|
"": Position{1, 1},
|
||||||
"foo": Position{1, 1},
|
"foo": Position{1, 1},
|
||||||
"foo.bar": Position{2, 1},
|
"foo.bar": Position{2, 1},
|
||||||
"foo.baz": Position{3, 1},
|
"foo.baz": Position{3, 1},
|
||||||
@@ -407,7 +407,7 @@ func TestDocumentPositionsWithSpaces(t *testing.T) {
|
|||||||
assertPosition(t,
|
assertPosition(t,
|
||||||
" [foo]\n bar=42\n baz=69",
|
" [foo]\n bar=42\n baz=69",
|
||||||
map[string]Position{
|
map[string]Position{
|
||||||
"": Position{1, 1},
|
"": Position{1, 1},
|
||||||
"foo": Position{1, 3},
|
"foo": Position{1, 3},
|
||||||
"foo.bar": Position{2, 3},
|
"foo.bar": Position{2, 3},
|
||||||
"foo.baz": Position{3, 3},
|
"foo.baz": Position{3, 3},
|
||||||
@@ -418,7 +418,7 @@ func TestDocumentPositionsWithGroupArray(t *testing.T) {
|
|||||||
assertPosition(t,
|
assertPosition(t,
|
||||||
"[[foo]]\nbar=42\nbaz=69",
|
"[[foo]]\nbar=42\nbaz=69",
|
||||||
map[string]Position{
|
map[string]Position{
|
||||||
"": Position{1, 1},
|
"": Position{1, 1},
|
||||||
"foo": Position{1, 1},
|
"foo": Position{1, 1},
|
||||||
"foo.bar": Position{2, 1},
|
"foo.bar": Position{2, 1},
|
||||||
"foo.baz": Position{3, 1},
|
"foo.baz": Position{3, 1},
|
||||||
@@ -429,9 +429,9 @@ func TestNestedTreePosition(t *testing.T) {
|
|||||||
assertPosition(t,
|
assertPosition(t,
|
||||||
"[foo.bar]\na=42\nb=69",
|
"[foo.bar]\na=42\nb=69",
|
||||||
map[string]Position{
|
map[string]Position{
|
||||||
"": Position{1, 1},
|
"": Position{1, 1},
|
||||||
"foo": Position{1, 1},
|
"foo": Position{1, 1},
|
||||||
"foo.bar": Position{1, 1},
|
"foo.bar": Position{1, 1},
|
||||||
"foo.bar.a": Position{2, 1},
|
"foo.bar.a": Position{2, 1},
|
||||||
"foo.bar.b": Position{3, 1},
|
"foo.bar.b": Position{3, 1},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,29 +4,29 @@ type nodeFilterFn func(node interface{}) bool
|
|||||||
type nodeFn func(node interface{}) interface{}
|
type nodeFn func(node interface{}) interface{}
|
||||||
|
|
||||||
type QueryResult struct {
|
type QueryResult struct {
|
||||||
items []interface{}
|
items []interface{}
|
||||||
positions []Position
|
positions []Position
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *QueryResult) appendResult(node interface{}, pos Position) {
|
func (r *QueryResult) appendResult(node interface{}, pos Position) {
|
||||||
r.items = append(r.items, node)
|
r.items = append(r.items, node)
|
||||||
r.positions = append(r.positions, pos)
|
r.positions = append(r.positions, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *QueryResult) Values() []interface{} {
|
func (r *QueryResult) Values() []interface{} {
|
||||||
return r.items
|
return r.items
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *QueryResult) Positions() []Position {
|
func (r *QueryResult) Positions() []Position {
|
||||||
return r.positions
|
return r.positions
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtime context for executing query paths
|
// runtime context for executing query paths
|
||||||
type queryContext struct {
|
type queryContext struct {
|
||||||
result *QueryResult
|
result *QueryResult
|
||||||
filters *map[string]nodeFilterFn
|
filters *map[string]nodeFilterFn
|
||||||
scripts *map[string]nodeFn
|
scripts *map[string]nodeFn
|
||||||
lastPosition Position
|
lastPosition Position
|
||||||
}
|
}
|
||||||
|
|
||||||
// generic path functor interface
|
// generic path functor interface
|
||||||
@@ -68,20 +68,20 @@ func Compile(path string) (*Query, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *Query) Execute(tree *TomlTree) *QueryResult {
|
func (q *Query) Execute(tree *TomlTree) *QueryResult {
|
||||||
result := &QueryResult {
|
result := &QueryResult{
|
||||||
items: []interface{}{},
|
items: []interface{}{},
|
||||||
positions: []Position{},
|
positions: []Position{},
|
||||||
}
|
}
|
||||||
if q.root == nil {
|
if q.root == nil {
|
||||||
result.appendResult(tree, tree.GetPosition(""))
|
result.appendResult(tree, tree.GetPosition(""))
|
||||||
} else {
|
} else {
|
||||||
ctx := &queryContext{
|
ctx := &queryContext{
|
||||||
result: result,
|
result: result,
|
||||||
filters: q.filters,
|
filters: q.filters,
|
||||||
scripts: q.scripts,
|
scripts: q.scripts,
|
||||||
}
|
}
|
||||||
q.root.Call(tree, ctx)
|
q.root.Call(tree, ctx)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ func (l *queryLexer) follow(next string) bool {
|
|||||||
return strings.HasPrefix(l.input[l.pos:], next)
|
return strings.HasPrefix(l.input[l.pos:], next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (l *queryLexer) lexVoid() queryLexStateFn {
|
func (l *queryLexer) lexVoid() queryLexStateFn {
|
||||||
for {
|
for {
|
||||||
next := l.peek()
|
next := l.peek()
|
||||||
|
|||||||
+4
-4
@@ -15,17 +15,17 @@ import (
|
|||||||
type queryParser struct {
|
type queryParser struct {
|
||||||
flow chan token
|
flow chan token
|
||||||
tokensBuffer []token
|
tokensBuffer []token
|
||||||
query *Query
|
query *Query
|
||||||
union []PathFn
|
union []PathFn
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
type queryParserStateFn func() queryParserStateFn
|
type queryParserStateFn func() queryParserStateFn
|
||||||
|
|
||||||
// Formats and panics an error message based on a token
|
// Formats and panics an error message based on a token
|
||||||
func (p *queryParser) parseError(tok *token, msg string, args ...interface{}) queryParserStateFn {
|
func (p *queryParser) parseError(tok *token, msg string, args ...interface{}) queryParserStateFn {
|
||||||
p.err = fmt.Errorf(tok.Position.String() + ": " + msg, args...)
|
p.err = fmt.Errorf(tok.Position.String()+": "+msg, args...)
|
||||||
return nil // trigger parse to end
|
return nil // trigger parse to end
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *queryParser) run() {
|
func (p *queryParser) run() {
|
||||||
|
|||||||
+210
-210
@@ -2,72 +2,72 @@ package toml
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type queryTestNode struct {
|
type queryTestNode struct {
|
||||||
value interface{}
|
value interface{}
|
||||||
position Position
|
position Position
|
||||||
}
|
}
|
||||||
|
|
||||||
func valueString(root interface{}) string {
|
func valueString(root interface{}) string {
|
||||||
result := "" //fmt.Sprintf("%T:", root)
|
result := "" //fmt.Sprintf("%T:", root)
|
||||||
switch node := root.(type) {
|
switch node := root.(type) {
|
||||||
case *tomlValue:
|
case *tomlValue:
|
||||||
return valueString(node.value)
|
return valueString(node.value)
|
||||||
case *QueryResult:
|
case *QueryResult:
|
||||||
items := []string{}
|
items := []string{}
|
||||||
for i, v := range node.Values() {
|
for i, v := range node.Values() {
|
||||||
items = append(items, fmt.Sprintf("%s:%s",
|
items = append(items, fmt.Sprintf("%s:%s",
|
||||||
node.Positions()[i].String(), valueString(v)))
|
node.Positions()[i].String(), valueString(v)))
|
||||||
}
|
}
|
||||||
sort.Strings(items)
|
sort.Strings(items)
|
||||||
result = "[" + strings.Join(items, ", ") + "]"
|
result = "[" + strings.Join(items, ", ") + "]"
|
||||||
case queryTestNode:
|
case queryTestNode:
|
||||||
result = fmt.Sprintf("%s:%s",
|
result = fmt.Sprintf("%s:%s",
|
||||||
node.position.String(), valueString(node.value))
|
node.position.String(), valueString(node.value))
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
items := []string{}
|
items := []string{}
|
||||||
for _, v := range node {
|
for _, v := range node {
|
||||||
items = append(items, valueString(v))
|
items = append(items, valueString(v))
|
||||||
}
|
}
|
||||||
sort.Strings(items)
|
sort.Strings(items)
|
||||||
result = "[" + strings.Join(items, ", ") + "]"
|
result = "[" + strings.Join(items, ", ") + "]"
|
||||||
case *TomlTree:
|
case *TomlTree:
|
||||||
// workaround for unreliable map key ordering
|
// workaround for unreliable map key ordering
|
||||||
items := []string{}
|
items := []string{}
|
||||||
for _, k := range node.Keys() {
|
for _, k := range node.Keys() {
|
||||||
v := node.GetPath([]string{k})
|
v := node.GetPath([]string{k})
|
||||||
items = append(items, k + ":" + valueString(v))
|
items = append(items, k+":"+valueString(v))
|
||||||
}
|
}
|
||||||
sort.Strings(items)
|
sort.Strings(items)
|
||||||
result = "{" + strings.Join(items, ", ") + "}"
|
result = "{" + strings.Join(items, ", ") + "}"
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
// workaround for unreliable map key ordering
|
// workaround for unreliable map key ordering
|
||||||
items := []string{}
|
items := []string{}
|
||||||
for k, v := range node {
|
for k, v := range node {
|
||||||
items = append(items, k + ":" + valueString(v))
|
items = append(items, k+":"+valueString(v))
|
||||||
}
|
}
|
||||||
sort.Strings(items)
|
sort.Strings(items)
|
||||||
result = "{" + strings.Join(items, ", ") + "}"
|
result = "{" + strings.Join(items, ", ") + "}"
|
||||||
case int64:
|
case int64:
|
||||||
result += fmt.Sprintf("%d", node)
|
result += fmt.Sprintf("%d", node)
|
||||||
case string:
|
case string:
|
||||||
result += "'" + node + "'"
|
result += "'" + node + "'"
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertValue(t *testing.T, result, ref interface{}) {
|
func assertValue(t *testing.T, result, ref interface{}) {
|
||||||
pathStr := valueString(result)
|
pathStr := valueString(result)
|
||||||
refStr := valueString(ref)
|
refStr := valueString(ref)
|
||||||
if pathStr != refStr {
|
if pathStr != refStr {
|
||||||
t.Errorf("values do not match")
|
t.Errorf("values do not match")
|
||||||
t.Log("test:", pathStr)
|
t.Log("test:", pathStr)
|
||||||
t.Log("ref: ", refStr)
|
t.Log("ref: ", refStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertQueryPositions(t *testing.T, toml, query string, ref []interface{}) {
|
func assertQueryPositions(t *testing.T, toml, query string, ref []interface{}) {
|
||||||
@@ -76,12 +76,12 @@ func assertQueryPositions(t *testing.T, toml, query string, ref []interface{}) {
|
|||||||
t.Errorf("Non-nil toml parse error: %v", err)
|
t.Errorf("Non-nil toml parse error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
q, err := Compile(query)
|
q, err := Compile(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
results := q.Execute(tree)
|
results := q.Execute(tree)
|
||||||
assertValue(t, results, ref)
|
assertValue(t, results, ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,10 +91,10 @@ func TestQueryRoot(t *testing.T) {
|
|||||||
"$",
|
"$",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(42),
|
"a": int64(42),
|
||||||
}, Position{1, 1},
|
}, Position{1, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,8 +104,8 @@ func TestQueryKey(t *testing.T) {
|
|||||||
"$.foo.a",
|
"$.foo.a",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(42), Position{2,1},
|
int64(42), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,8 +115,8 @@ func TestQueryKeyString(t *testing.T) {
|
|||||||
"$.foo['a']",
|
"$.foo['a']",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(42), Position{2,1},
|
int64(42), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,8 +126,8 @@ func TestQueryIndex(t *testing.T) {
|
|||||||
"$.foo.a[5]",
|
"$.foo.a[5]",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(6), Position{2,1},
|
int64(6), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,21 +137,21 @@ func TestQuerySliceRange(t *testing.T) {
|
|||||||
"$.foo.a[0:5]",
|
"$.foo.a[0:5]",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(1), Position{2,1},
|
int64(1), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(2), Position{2,1},
|
int64(2), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(3), Position{2,1},
|
int64(3), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(4), Position{2,1},
|
int64(4), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(5), Position{2,1},
|
int64(5), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQuerySliceStep(t *testing.T) {
|
func TestQuerySliceStep(t *testing.T) {
|
||||||
@@ -159,15 +159,15 @@ func TestQuerySliceStep(t *testing.T) {
|
|||||||
"[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
|
"[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
|
||||||
"$.foo.a[0:5:2]",
|
"$.foo.a[0:5:2]",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(1), Position{2,1},
|
int64(1), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(3), Position{2,1},
|
int64(3), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(5), Position{2,1},
|
int64(5), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,17 +177,17 @@ func TestQueryAny(t *testing.T) {
|
|||||||
"$.foo.*",
|
"$.foo.*",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(1),
|
"a": int64(1),
|
||||||
"b": int64(2),
|
"b": int64(2),
|
||||||
}, Position{1,1},
|
}, Position{1, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(3),
|
"a": int64(3),
|
||||||
"b": int64(4),
|
"b": int64(4),
|
||||||
}, Position{4,1},
|
}, Position{4, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func TestQueryUnionSimple(t *testing.T) {
|
func TestQueryUnionSimple(t *testing.T) {
|
||||||
@@ -196,24 +196,24 @@ func TestQueryUnionSimple(t *testing.T) {
|
|||||||
"$.*[bar,foo]",
|
"$.*[bar,foo]",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(1),
|
"a": int64(1),
|
||||||
"b": int64(2),
|
"b": int64(2),
|
||||||
}, Position{1,1},
|
}, Position{1, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(3),
|
"a": int64(3),
|
||||||
"b": int64(4),
|
"b": int64(4),
|
||||||
}, Position{4,1},
|
}, Position{4, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(5),
|
"a": int64(5),
|
||||||
"b": int64(6),
|
"b": int64(6),
|
||||||
}, Position{7,1},
|
}, Position{7, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryRecursionAll(t *testing.T) {
|
func TestQueryRecursionAll(t *testing.T) {
|
||||||
@@ -222,65 +222,65 @@ func TestQueryRecursionAll(t *testing.T) {
|
|||||||
"$..*",
|
"$..*",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"bar": map[string]interface{}{
|
"bar": map[string]interface{}{
|
||||||
"a": int64(1),
|
"a": int64(1),
|
||||||
"b": int64(2),
|
"b": int64(2),
|
||||||
},
|
},
|
||||||
}, Position{1,1},
|
}, Position{1, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(1),
|
"a": int64(1),
|
||||||
"b": int64(2),
|
"b": int64(2),
|
||||||
}, Position{1,1},
|
}, Position{1, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(1), Position{2,1},
|
int64(1), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(2), Position{3,1},
|
int64(2), Position{3, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"foo": map[string]interface{}{
|
"foo": map[string]interface{}{
|
||||||
"a": int64(3),
|
"a": int64(3),
|
||||||
"b": int64(4),
|
"b": int64(4),
|
||||||
},
|
},
|
||||||
}, Position{4,1},
|
}, Position{4, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(3),
|
"a": int64(3),
|
||||||
"b": int64(4),
|
"b": int64(4),
|
||||||
}, Position{4,1},
|
}, Position{4, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(3), Position{5,1},
|
int64(3), Position{5, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(4), Position{6,1},
|
int64(4), Position{6, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"foo": map[string]interface{}{
|
"foo": map[string]interface{}{
|
||||||
"a": int64(5),
|
"a": int64(5),
|
||||||
"b": int64(6),
|
"b": int64(6),
|
||||||
},
|
},
|
||||||
}, Position{7,1},
|
}, Position{7, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(5),
|
"a": int64(5),
|
||||||
"b": int64(6),
|
"b": int64(6),
|
||||||
}, Position{7,1},
|
}, Position{7, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(5), Position{8,1},
|
int64(5), Position{8, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(6), Position{9,1},
|
int64(6), Position{9, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,23 +290,23 @@ func TestQueryRecursionUnionSimple(t *testing.T) {
|
|||||||
"$..['foo','bar']",
|
"$..['foo','bar']",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(1),
|
"a": int64(1),
|
||||||
"b": int64(2),
|
"b": int64(2),
|
||||||
}, Position{1,1},
|
}, Position{1, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(3),
|
"a": int64(3),
|
||||||
"b": int64(4),
|
"b": int64(4),
|
||||||
}, Position{4,1},
|
}, Position{4, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"a": int64(5),
|
"a": int64(5),
|
||||||
"b": int64(6),
|
"b": int64(6),
|
||||||
}, Position{7,1},
|
}, Position{7, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,9 +315,9 @@ func TestQueryScriptFnLast(t *testing.T) {
|
|||||||
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
||||||
"$.foo.a[(last)]",
|
"$.foo.a[(last)]",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(9), Position{2,1},
|
int64(9), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,21 +326,21 @@ func TestQueryFilterFnOdd(t *testing.T) {
|
|||||||
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
||||||
"$.foo.a[?(odd)]",
|
"$.foo.a[?(odd)]",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(1), Position{2,1},
|
int64(1), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(3), Position{2,1},
|
int64(3), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(5), Position{2,1},
|
int64(5), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(7), Position{2,1},
|
int64(7), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(9), Position{2,1},
|
int64(9), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,20 +349,20 @@ func TestQueryFilterFnEven(t *testing.T) {
|
|||||||
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
||||||
"$.foo.a[?(even)]",
|
"$.foo.a[?(even)]",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(0), Position{2,1},
|
int64(0), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(2), Position{2,1},
|
int64(2), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(4), Position{2,1},
|
int64(4), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(6), Position{2,1},
|
int64(6), Position{2, 1},
|
||||||
},
|
},
|
||||||
queryTestNode{
|
queryTestNode{
|
||||||
int64(8), Position{2,1},
|
int64(8), Position{2, 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package toml
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"unicode"
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,18 +26,18 @@ const (
|
|||||||
tokenEqual
|
tokenEqual
|
||||||
tokenLeftBracket
|
tokenLeftBracket
|
||||||
tokenRightBracket
|
tokenRightBracket
|
||||||
tokenLeftParen
|
tokenLeftParen
|
||||||
tokenRightParen
|
tokenRightParen
|
||||||
tokenDoubleLeftBracket
|
tokenDoubleLeftBracket
|
||||||
tokenDoubleRightBracket
|
tokenDoubleRightBracket
|
||||||
tokenDate
|
tokenDate
|
||||||
tokenKeyGroup
|
tokenKeyGroup
|
||||||
tokenKeyGroupArray
|
tokenKeyGroupArray
|
||||||
tokenComma
|
tokenComma
|
||||||
tokenColon
|
tokenColon
|
||||||
tokenDollar
|
tokenDollar
|
||||||
tokenStar
|
tokenStar
|
||||||
tokenQuestion
|
tokenQuestion
|
||||||
tokenDot
|
tokenDot
|
||||||
tokenDotDot
|
tokenDotDot
|
||||||
tokenEOL
|
tokenEOL
|
||||||
@@ -55,20 +55,20 @@ var tokenTypeNames = []string{
|
|||||||
"=",
|
"=",
|
||||||
"[",
|
"[",
|
||||||
"[",
|
"[",
|
||||||
"(",
|
"(",
|
||||||
")",
|
")",
|
||||||
"]]",
|
"]]",
|
||||||
"[[",
|
"[[",
|
||||||
"Date",
|
"Date",
|
||||||
"KeyGroup",
|
"KeyGroup",
|
||||||
"KeyGroupArray",
|
"KeyGroupArray",
|
||||||
",",
|
",",
|
||||||
":",
|
":",
|
||||||
"$",
|
"$",
|
||||||
"*",
|
"*",
|
||||||
"?",
|
"?",
|
||||||
".",
|
".",
|
||||||
"..",
|
"..",
|
||||||
"EOL",
|
"EOL",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -207,8 +207,8 @@ func (t *TomlTree) createSubTree(keys []string, pos Position) error {
|
|||||||
}
|
}
|
||||||
nextTree, exists := subtree.values[intermediateKey]
|
nextTree, exists := subtree.values[intermediateKey]
|
||||||
if !exists {
|
if !exists {
|
||||||
tree := newTomlTree()
|
tree := newTomlTree()
|
||||||
tree.position = pos
|
tree.position = pos
|
||||||
subtree.values[intermediateKey] = tree
|
subtree.values[intermediateKey] = tree
|
||||||
nextTree = tree
|
nextTree = tree
|
||||||
}
|
}
|
||||||
@@ -320,11 +320,11 @@ func (t *TomlTree) toToml(indent, keyspace string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TomlTree) Query(query string) (*QueryResult, error) {
|
func (t *TomlTree) Query(query string) (*QueryResult, error) {
|
||||||
if q, err := Compile(query); err != nil {
|
if q, err := Compile(query); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
return q.Execute(t), nil
|
return q.Execute(t), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToString generates a human-readable representation of the current tree.
|
// ToString generates a human-readable representation of the current tree.
|
||||||
@@ -335,26 +335,26 @@ func (t *TomlTree) ToString() string {
|
|||||||
|
|
||||||
// Load creates a TomlTree from a string.
|
// Load creates a TomlTree from a string.
|
||||||
func Load(content string) (tree *TomlTree, err error) {
|
func Load(content string) (tree *TomlTree, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
if _, ok := r.(runtime.Error); ok {
|
if _, ok := r.(runtime.Error); ok {
|
||||||
panic(r)
|
panic(r)
|
||||||
}
|
}
|
||||||
err = errors.New(r.(string))
|
err = errors.New(r.(string))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
tree = parseToml(lexToml(content))
|
tree = parseToml(lexToml(content))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadFile creates a TomlTree from a file.
|
// LoadFile creates a TomlTree from a file.
|
||||||
func LoadFile(path string) (tree *TomlTree, err error) {
|
func LoadFile(path string) (tree *TomlTree, err error) {
|
||||||
buff, ferr := ioutil.ReadFile(path)
|
buff, ferr := ioutil.ReadFile(path)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
err = ferr
|
err = ferr
|
||||||
} else {
|
} else {
|
||||||
s := string(buff)
|
s := string(buff)
|
||||||
tree, err = Load(s)
|
tree, err = Load(s)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-21
@@ -49,26 +49,26 @@ func TestTomlGetPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTomlQuery(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")
|
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 {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
result, err := tree.Query("$.foo.bar")
|
result, err := tree.Query("$.foo.bar")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
values := result.Values()
|
values := result.Values()
|
||||||
if len(values) != 1 {
|
if len(values) != 1 {
|
||||||
t.Errorf("Expected resultset of 1, got %d instead: %v", len(values), values)
|
t.Errorf("Expected resultset of 1, got %d instead: %v", len(values), values)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tt, ok := values[0].(*TomlTree); !ok {
|
if tt, ok := values[0].(*TomlTree); !ok {
|
||||||
t.Errorf("Expected type of TomlTree: %T Tv", values[0], values[0])
|
t.Errorf("Expected type of TomlTree: %T Tv", values[0], values[0])
|
||||||
} else if tt.Get("a") != int64(1) {
|
} else if tt.Get("a") != int64(1) {
|
||||||
t.Errorf("Expected 'a' with a value 1: %v", tt.Get("a"))
|
t.Errorf("Expected 'a' with a value 1: %v", tt.Get("a"))
|
||||||
} else if tt.Get("b") != int64(2) {
|
} else if tt.Get("b") != int64(2) {
|
||||||
t.Errorf("Expected 'b' with a value 2: %v", tt.Get("b"))
|
t.Errorf("Expected 'b' with a value 2: %v", tt.Get("b"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user