Add basic linter config, decrease moduled Go version
This commit is contained in:
parent
6adf5bc3b9
commit
f7b8e36f03
24
.golangci.yaml
Normal file
24
.golangci.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
run:
|
||||
deadline: 2m
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- gochecknoglobals
|
||||
- gocritic
|
||||
- funlen
|
||||
linters-settings:
|
||||
lll:
|
||||
line-length: 180
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- dupl
|
||||
- errcheck
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gosec
|
||||
- lll
|
||||
- goconst
|
||||
- unparam
|
||||
- unused
|
46
eval_test.go
46
eval_test.go
@ -15,32 +15,32 @@ type test struct {
|
||||
}
|
||||
|
||||
var tests = []test{
|
||||
test{`key selection`, `{"aKey":32}`, `$.aKey+`, []Result{newResult(`32`, JsonNumber, `aKey`)}},
|
||||
test{`nested key selection`, `{"aKey":{"bKey":32}}`, `$.aKey+`, []Result{newResult(`{"bKey":32}`, JsonObject, `aKey`)}},
|
||||
test{`empty array`, `{"aKey":[]}`, `$.aKey+`, []Result{newResult(`[]`, JsonArray, `aKey`)}},
|
||||
test{`multiple same-level keys, weird spacing`, `{ "aKey" : true , "bKey": [ 1 , 2 ], "cKey" : true } `, `$.bKey+`, []Result{newResult(`[1,2]`, JsonArray, `bKey`)}},
|
||||
{`key selection`, `{"aKey":32}`, `$.aKey+`, []Result{newResult(`32`, JsonNumber, `aKey`)}},
|
||||
{`nested key selection`, `{"aKey":{"bKey":32}}`, `$.aKey+`, []Result{newResult(`{"bKey":32}`, JsonObject, `aKey`)}},
|
||||
{`empty array`, `{"aKey":[]}`, `$.aKey+`, []Result{newResult(`[]`, JsonArray, `aKey`)}},
|
||||
{`multiple same-level keys, weird spacing`, `{ "aKey" : true , "bKey": [ 1 , 2 ], "cKey" : true } `, `$.bKey+`, []Result{newResult(`[1,2]`, JsonArray, `bKey`)}},
|
||||
|
||||
test{`array index selection`, `{"aKey":[123,456]}`, `$.aKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, 1)}},
|
||||
test{`array wild index selection`, `{"aKey":[123,456]}`, `$.aKey[*]+`, []Result{newResult(`123`, JsonNumber, `aKey`, 0), newResult(`456`, JsonNumber, `aKey`, 1)}},
|
||||
test{`array range index selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:3]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}},
|
||||
test{`array range (no index) selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:1]+`, []Result{}},
|
||||
test{`array range (no upper bound) selection`, `{"aKey":[11,22,33]}`, `$.aKey[1:]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}},
|
||||
{`array index selection`, `{"aKey":[123,456]}`, `$.aKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, 1)}},
|
||||
{`array wild index selection`, `{"aKey":[123,456]}`, `$.aKey[*]+`, []Result{newResult(`123`, JsonNumber, `aKey`, 0), newResult(`456`, JsonNumber, `aKey`, 1)}},
|
||||
{`array range index selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:3]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}},
|
||||
{`array range (no index) selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:1]+`, []Result{}},
|
||||
{`array range (no upper bound) selection`, `{"aKey":[11,22,33]}`, `$.aKey[1:]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}},
|
||||
|
||||
test{`empty array - try selection`, `{"aKey":[]}`, `$.aKey[1]+`, []Result{}},
|
||||
test{`null selection`, `{"aKey":[null]}`, `$.aKey[0]+`, []Result{newResult(`null`, JsonNull, `aKey`, 0)}},
|
||||
test{`empty object`, `{"aKey":{}}`, `$.aKey+`, []Result{newResult(`{}`, JsonObject, `aKey`)}},
|
||||
test{`object w/ height=2`, `{"aKey":{"bKey":32}}`, `$.aKey.bKey+`, []Result{newResult(`32`, JsonNumber, `aKey`, `bKey`)}},
|
||||
test{`array of multiple types`, `{"aKey":[1,{"s":true},"asdf"]}`, `$.aKey[1]+`, []Result{newResult(`{"s":true}`, JsonObject, `aKey`, 1)}},
|
||||
test{`nested array selection`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey+`, []Result{newResult(`[123,456]`, JsonArray, `aKey`, `bKey`)}},
|
||||
test{`nested array`, `[[[[[]], [true, false, []]]]]`, `$[0][0][1][2]+`, []Result{newResult(`[]`, JsonArray, 0, 0, 1, 2)}},
|
||||
test{`index of array selection`, `{"aKey":{"bKey":[123, 456, 789]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}},
|
||||
test{`index of array selection (more than one)`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}},
|
||||
test{`multi-level object/array`, `{"1Key":{"aKey": null, "bKey":{"trash":[1,2]}, "cKey":[123,456] }, "2Key":false}`, `$.1Key.bKey.trash[0]+`, []Result{newResult(`1`, JsonNumber, `1Key`, `bKey`, `trash`, 0)}},
|
||||
test{`multi-level array`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*].michael[1]+`, []Result{newResult(`6`, JsonNumber, `aKey`, 3, `michael`, 1)}},
|
||||
test{`multi-level array 2`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*][1]+`, []Result{newResult(`"3"`, JsonString, `aKey`, 4, 1)}},
|
||||
{`empty array - try selection`, `{"aKey":[]}`, `$.aKey[1]+`, []Result{}},
|
||||
{`null selection`, `{"aKey":[null]}`, `$.aKey[0]+`, []Result{newResult(`null`, JsonNull, `aKey`, 0)}},
|
||||
{`empty object`, `{"aKey":{}}`, `$.aKey+`, []Result{newResult(`{}`, JsonObject, `aKey`)}},
|
||||
{`object w/ height=2`, `{"aKey":{"bKey":32}}`, `$.aKey.bKey+`, []Result{newResult(`32`, JsonNumber, `aKey`, `bKey`)}},
|
||||
{`array of multiple types`, `{"aKey":[1,{"s":true},"asdf"]}`, `$.aKey[1]+`, []Result{newResult(`{"s":true}`, JsonObject, `aKey`, 1)}},
|
||||
{`nested array selection`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey+`, []Result{newResult(`[123,456]`, JsonArray, `aKey`, `bKey`)}},
|
||||
{`nested array`, `[[[[[]], [true, false, []]]]]`, `$[0][0][1][2]+`, []Result{newResult(`[]`, JsonArray, 0, 0, 1, 2)}},
|
||||
{`index of array selection`, `{"aKey":{"bKey":[123, 456, 789]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}},
|
||||
{`index of array selection (more than one)`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}},
|
||||
{`multi-level object/array`, `{"1Key":{"aKey": null, "bKey":{"trash":[1,2]}, "cKey":[123,456] }, "2Key":false}`, `$.1Key.bKey.trash[0]+`, []Result{newResult(`1`, JsonNumber, `1Key`, `bKey`, `trash`, 0)}},
|
||||
{`multi-level array`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*].michael[1]+`, []Result{newResult(`6`, JsonNumber, `aKey`, 3, `michael`, 1)}},
|
||||
{`multi-level array 2`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*][1]+`, []Result{newResult(`"3"`, JsonString, `aKey`, 4, 1)}},
|
||||
|
||||
test{`evaluation literal equality`, `{"items":[ {"name":"alpha", "value":11}]}`, `$.items[*]?("bravo" == "bravo").value+`, []Result{newResult(`11`, JsonNumber, `items`, 0, `value`)}},
|
||||
test{`evaluation based on string equal to path value`, `{"items":[ {"name":"alpha", "value":11}, {"name":"bravo", "value":22}, {"name":"charlie", "value":33} ]}`, `$.items[*]?(@.name == "bravo").value+`, []Result{newResult(`22`, JsonNumber, `items`, 1, `value`)}},
|
||||
{`evaluation literal equality`, `{"items":[ {"name":"alpha", "value":11}]}`, `$.items[*]?("bravo" == "bravo").value+`, []Result{newResult(`11`, JsonNumber, `items`, 0, `value`)}},
|
||||
{`evaluation based on string equal to path value`, `{"items":[ {"name":"alpha", "value":11}, {"name":"bravo", "value":22}, {"name":"charlie", "value":33} ]}`, `$.items[*]?(@.name == "bravo").value+`, []Result{newResult(`22`, JsonNumber, `items`, 1, `value`)}},
|
||||
}
|
||||
|
||||
func TestPathQuery(t *testing.T) {
|
||||
|
2
go.mod
2
go.mod
@ -1,5 +1,5 @@
|
||||
module source.wtfteam.pro/libraries/jsonpath
|
||||
|
||||
go 1.13
|
||||
go 1.12
|
||||
|
||||
require github.com/stretchr/testify v1.4.0
|
||||
|
@ -46,16 +46,16 @@ func lexJsonRoot(l lexer, state *intStack) stateFn {
|
||||
var next stateFn
|
||||
switch cur {
|
||||
case '{':
|
||||
next = stateJsonObjectOpen
|
||||
next = stateJSONObjectOpen
|
||||
case '[':
|
||||
next = stateJsonArrayOpen
|
||||
next = stateJSONArrayOpen
|
||||
default:
|
||||
next = l.errorf("Expected '{' or '[' at root of JSON instead of %#U", cur)
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
func stateJsonObjectOpen(l lexer, state *intStack) stateFn {
|
||||
func stateJSONObjectOpen(l lexer, state *intStack) stateFn {
|
||||
cur := l.take()
|
||||
if cur != '{' {
|
||||
return l.errorf("Expected '{' as start of object instead of %#U", cur)
|
||||
@ -63,10 +63,10 @@ func stateJsonObjectOpen(l lexer, state *intStack) stateFn {
|
||||
l.emit(jsonBraceLeft)
|
||||
state.push(jsonBraceLeft)
|
||||
|
||||
return stateJsonObject
|
||||
return stateJSONObject
|
||||
}
|
||||
|
||||
func stateJsonArrayOpen(l lexer, state *intStack) stateFn {
|
||||
func stateJSONArrayOpen(l lexer, state *intStack) stateFn {
|
||||
cur := l.take()
|
||||
if cur != '[' {
|
||||
return l.errorf("Expected '[' as start of array instead of %#U", cur)
|
||||
@ -74,10 +74,10 @@ func stateJsonArrayOpen(l lexer, state *intStack) stateFn {
|
||||
l.emit(jsonBracketLeft)
|
||||
state.push(jsonBracketLeft)
|
||||
|
||||
return stateJsonArray
|
||||
return stateJSONArray
|
||||
}
|
||||
|
||||
func stateJsonObject(l lexer, state *intStack) stateFn {
|
||||
func stateJSONObject(l lexer, state *intStack) stateFn {
|
||||
var next stateFn
|
||||
cur := l.peek()
|
||||
switch cur {
|
||||
@ -89,16 +89,16 @@ func stateJsonObject(l lexer, state *intStack) stateFn {
|
||||
l.take()
|
||||
l.emit(jsonBraceRight)
|
||||
state.pop()
|
||||
next = stateJsonAfterValue
|
||||
next = stateJSONAfterValue
|
||||
case '"':
|
||||
next = stateJsonKey
|
||||
next = stateJSONKey
|
||||
default:
|
||||
next = l.errorf("Expected '}' or \" within an object instead of %#U", cur)
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
func stateJsonArray(l lexer, state *intStack) stateFn {
|
||||
func stateJSONArray(l lexer, state *intStack) stateFn {
|
||||
var next stateFn
|
||||
cur := l.peek()
|
||||
switch cur {
|
||||
@ -110,14 +110,14 @@ func stateJsonArray(l lexer, state *intStack) stateFn {
|
||||
l.take()
|
||||
l.emit(jsonBracketRight)
|
||||
state.pop()
|
||||
next = stateJsonAfterValue
|
||||
next = stateJSONAfterValue
|
||||
default:
|
||||
next = stateJsonValue
|
||||
next = stateJSONValue
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
func stateJsonAfterValue(l lexer, state *intStack) stateFn {
|
||||
func stateJSONAfterValue(l lexer, state *intStack) stateFn {
|
||||
cur := l.take()
|
||||
top, ok := state.peek()
|
||||
topVal := noValue
|
||||
@ -130,9 +130,9 @@ func stateJsonAfterValue(l lexer, state *intStack) stateFn {
|
||||
l.emit(jsonComma)
|
||||
switch topVal {
|
||||
case jsonBraceLeft:
|
||||
return stateJsonKey
|
||||
return stateJSONKey
|
||||
case jsonBracketLeft:
|
||||
return stateJsonValue
|
||||
return stateJSONValue
|
||||
case noValue:
|
||||
return l.errorf("Found %#U outside of array or object", cur)
|
||||
default:
|
||||
@ -143,11 +143,11 @@ func stateJsonAfterValue(l lexer, state *intStack) stateFn {
|
||||
state.pop()
|
||||
switch topVal {
|
||||
case jsonBraceLeft:
|
||||
return stateJsonAfterValue
|
||||
return stateJSONAfterValue
|
||||
case jsonBracketLeft:
|
||||
return l.errorf("Unexpected %#U in array", cur)
|
||||
case noValue:
|
||||
return stateJsonAfterRoot
|
||||
return stateJSONAfterRoot
|
||||
}
|
||||
case ']':
|
||||
l.emit(jsonBracketRight)
|
||||
@ -156,9 +156,9 @@ func stateJsonAfterValue(l lexer, state *intStack) stateFn {
|
||||
case jsonBraceLeft:
|
||||
return l.errorf("Unexpected %#U in object", cur)
|
||||
case jsonBracketLeft:
|
||||
return stateJsonAfterValue
|
||||
return stateJSONAfterValue
|
||||
case noValue:
|
||||
return stateJsonAfterRoot
|
||||
return stateJSONAfterRoot
|
||||
}
|
||||
case eof:
|
||||
if state.len() == 0 {
|
||||
@ -173,65 +173,65 @@ func stateJsonAfterValue(l lexer, state *intStack) stateFn {
|
||||
return nil
|
||||
}
|
||||
|
||||
func stateJsonKey(l lexer, state *intStack) stateFn {
|
||||
func stateJSONKey(l lexer, state *intStack) stateFn {
|
||||
if err := l.takeString(); err != nil {
|
||||
return l.errorf(err.Error())
|
||||
}
|
||||
l.emit(jsonKey)
|
||||
|
||||
return stateJsonColon
|
||||
return stateJSONColon
|
||||
}
|
||||
|
||||
func stateJsonColon(l lexer, state *intStack) stateFn {
|
||||
func stateJSONColon(l lexer, state *intStack) stateFn {
|
||||
cur := l.take()
|
||||
if cur != ':' {
|
||||
return l.errorf("Expected ':' after key string instead of %#U", cur)
|
||||
}
|
||||
l.emit(jsonColon)
|
||||
|
||||
return stateJsonValue
|
||||
return stateJSONValue
|
||||
}
|
||||
|
||||
func stateJsonValue(l lexer, state *intStack) stateFn {
|
||||
func stateJSONValue(l lexer, state *intStack) stateFn {
|
||||
cur := l.peek()
|
||||
|
||||
switch cur {
|
||||
case eof:
|
||||
return l.errorf("Unexpected EOF instead of value")
|
||||
case '"':
|
||||
return stateJsonString
|
||||
return stateJSONString
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
return stateJsonNumber
|
||||
return stateJSONNumber
|
||||
case 't', 'f':
|
||||
return stateJsonBool
|
||||
return stateJSONBool
|
||||
case 'n':
|
||||
return stateJsonNull
|
||||
return stateJSONNull
|
||||
case '{':
|
||||
return stateJsonObjectOpen
|
||||
return stateJSONObjectOpen
|
||||
case '[':
|
||||
return stateJsonArrayOpen
|
||||
return stateJSONArrayOpen
|
||||
default:
|
||||
return l.errorf("Unexpected character as start of value: %#U", cur)
|
||||
}
|
||||
}
|
||||
|
||||
func stateJsonString(l lexer, state *intStack) stateFn {
|
||||
func stateJSONString(l lexer, state *intStack) stateFn {
|
||||
if err := l.takeString(); err != nil {
|
||||
return l.errorf(err.Error())
|
||||
}
|
||||
l.emit(jsonString)
|
||||
return stateJsonAfterValue
|
||||
return stateJSONAfterValue
|
||||
}
|
||||
|
||||
func stateJsonNumber(l lexer, state *intStack) stateFn {
|
||||
func stateJSONNumber(l lexer, state *intStack) stateFn {
|
||||
if err := takeJSONNumeric(l); err != nil {
|
||||
return l.errorf(err.Error())
|
||||
}
|
||||
l.emit(jsonNumber)
|
||||
return stateJsonAfterValue
|
||||
return stateJSONAfterValue
|
||||
}
|
||||
|
||||
func stateJsonBool(l lexer, state *intStack) stateFn {
|
||||
func stateJSONBool(l lexer, state *intStack) stateFn {
|
||||
cur := l.peek()
|
||||
var match []byte
|
||||
switch cur {
|
||||
@ -245,18 +245,18 @@ func stateJsonBool(l lexer, state *intStack) stateFn {
|
||||
return l.errorf("Could not parse value as 'true' or 'false'")
|
||||
}
|
||||
l.emit(jsonBool)
|
||||
return stateJsonAfterValue
|
||||
return stateJSONAfterValue
|
||||
}
|
||||
|
||||
func stateJsonNull(l lexer, state *intStack) stateFn {
|
||||
func stateJSONNull(l lexer, state *intStack) stateFn {
|
||||
if !takeExactSequence(l, nullBytes) {
|
||||
return l.errorf("Could not parse value as 'null'")
|
||||
}
|
||||
l.emit(jsonNull)
|
||||
return stateJsonAfterValue
|
||||
return stateJSONAfterValue
|
||||
}
|
||||
|
||||
func stateJsonAfterRoot(l lexer, state *intStack) stateFn {
|
||||
func stateJSONAfterRoot(l lexer, state *intStack) stateFn {
|
||||
cur := l.take()
|
||||
if cur != eof {
|
||||
return l.errorf("Expected EOF instead of %#U", cur)
|
||||
|
@ -159,7 +159,7 @@ var examples = []string{
|
||||
}`,
|
||||
}
|
||||
|
||||
func TestMixedCaseJson(t *testing.T) {
|
||||
func TestMixedCaseJSON(t *testing.T) {
|
||||
as := assert.New(t)
|
||||
for _, json := range examples {
|
||||
lexer := NewSliceLexer([]byte(json), JSON)
|
||||
|
14
path.go
14
path.go
@ -93,7 +93,9 @@ func genIndexKey(tr tokenReader) (*operator, error) {
|
||||
return nil, fmt.Errorf("Unexpected value within brackets after index: %q", t.val)
|
||||
}
|
||||
case pathKey:
|
||||
k.keyStrings = map[string]struct{}{string(t.val[1 : len(t.val)-1]): struct{}{}}
|
||||
k.keyStrings = map[string]struct{}{
|
||||
string(t.val[1 : len(t.val)-1]): {},
|
||||
}
|
||||
k.typ = opTypeName
|
||||
|
||||
if t, ok = tr.next(); !ok || t.typ != pathBracketRight {
|
||||
@ -185,7 +187,15 @@ func tokensToOperators(tr tokenReader) (*Path, error) {
|
||||
if p.val[0] == '"' && p.val[len(p.val)-1] == '"' {
|
||||
keyName = p.val[1 : len(p.val)-1]
|
||||
}
|
||||
q.operators = append(q.operators, &operator{typ: opTypeName, keyStrings: map[string]struct{}{string(keyName): struct{}{}}})
|
||||
q.operators = append(
|
||||
q.operators,
|
||||
&operator{
|
||||
typ: opTypeName,
|
||||
keyStrings: map[string]struct{}{
|
||||
string(keyName): {},
|
||||
},
|
||||
},
|
||||
)
|
||||
case pathWildcard:
|
||||
q.operators = append(q.operators, &operator{typ: opTypeNameWild})
|
||||
case pathValue:
|
||||
|
16
path_test.go
16
path_test.go
@ -13,15 +13,15 @@ type optest struct {
|
||||
}
|
||||
|
||||
var optests = []optest{
|
||||
optest{"single key (period) ", `$.aKey`, []int{opTypeName}},
|
||||
optest{"single key (bracket)", `$["aKey"]`, []int{opTypeName}},
|
||||
optest{"single key (period) ", `$.*`, []int{opTypeNameWild}},
|
||||
optest{"single index", `$[12]`, []int{opTypeIndex}},
|
||||
optest{"single key", `$[23:45]`, []int{opTypeIndexRange}},
|
||||
optest{"single key", `$[*]`, []int{opTypeIndexWild}},
|
||||
{"single key (period) ", `$.aKey`, []int{opTypeName}},
|
||||
{"single key (bracket)", `$["aKey"]`, []int{opTypeName}},
|
||||
{"single key (period) ", `$.*`, []int{opTypeNameWild}},
|
||||
{"single index", `$[12]`, []int{opTypeIndex}},
|
||||
{"single key", `$[23:45]`, []int{opTypeIndexRange}},
|
||||
{"single key", `$[*]`, []int{opTypeIndexWild}},
|
||||
|
||||
optest{"double key", `$["aKey"]["bKey"]`, []int{opTypeName, opTypeName}},
|
||||
optest{"double key", `$["aKey"].bKey`, []int{opTypeName, opTypeName}},
|
||||
{"double key", `$["aKey"]["bKey"]`, []int{opTypeName, opTypeName}},
|
||||
{"double key", `$["aKey"].bKey`, []int{opTypeName, opTypeName}},
|
||||
}
|
||||
|
||||
func TestQueryOperators(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user