From f7b8e36f03d36a82c712accf942d8f0edb1b27ce Mon Sep 17 00:00:00 2001 From: Vladimir Hodakov Date: Sat, 19 Oct 2019 00:39:21 +0400 Subject: [PATCH] Add basic linter config, decrease moduled Go version --- .golangci.yaml | 24 ++++++++++++++ eval_test.go | 46 +++++++++++++------------- go.mod | 2 +- json_states.go | 78 ++++++++++++++++++++++----------------------- json_states_test.go | 2 +- path.go | 14 ++++++-- path_test.go | 16 +++++----- 7 files changed, 108 insertions(+), 74 deletions(-) create mode 100644 .golangci.yaml diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..fc96817 --- /dev/null +++ b/.golangci.yaml @@ -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 \ No newline at end of file diff --git a/eval_test.go b/eval_test.go index bc391af..f5f8983 100644 --- a/eval_test.go +++ b/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) { diff --git a/go.mod b/go.mod index f8e1262..01ecac0 100644 --- a/go.mod +++ b/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 diff --git a/json_states.go b/json_states.go index 2c28d7c..9e33c56 100644 --- a/json_states.go +++ b/json_states.go @@ -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) diff --git a/json_states_test.go b/json_states_test.go index 4ba22c1..c7d94b7 100644 --- a/json_states_test.go +++ b/json_states_test.go @@ -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) diff --git a/path.go b/path.go index 9d142b5..081b341 100644 --- a/path.go +++ b/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: diff --git a/path_test.go b/path_test.go index ab7f2a2..360c901 100644 --- a/path_test.go +++ b/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) {