Skip to content

Commit d1ba18e

Browse files
committed
chore: simple test cases
1 parent 236113f commit d1ba18e

File tree

3 files changed

+87
-35
lines changed

3 files changed

+87
-35
lines changed

pkg/jsonpath/parser.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,13 @@ func (p *Parser) parseChildSegment() (Segment, error) {
124124
// .STRING_LITERAL
125125
// []
126126
firstToken := p.tokens[p.current]
127-
if firstToken.Token == DOT && p.tokens[p.current+1].Token == WILDCARD {
127+
if firstToken.Token == CHILD && p.tokens[p.current+1].Token == WILDCARD {
128128
p.current += 2
129129
return &ChildSegment{SubKind: ChildSegmentDotWildcard, Tokens: []TokenInfo{firstToken, p.tokens[p.current+1]}}, nil
130-
} else if firstToken.Token == DOT && p.tokens[p.current+1].Token == STRING_LITERAL {
130+
} else if firstToken.Token == CHILD && p.tokens[p.current+1].Token == STRING_LITERAL {
131131
p.current += 2
132132
return &ChildSegment{SubKind: ChildSegmentDotMemberName, Tokens: []TokenInfo{firstToken, p.tokens[p.current+1]}}, nil
133-
} else if firstToken.Token == DOT && p.tokens[p.current+1].Token == BRACKET_LEFT {
133+
} else if firstToken.Token == CHILD && p.tokens[p.current+1].Token == BRACKET_LEFT {
134134
prior := p.current
135135
p.current += 2
136136
innerSegment, err := p.parseSelector()

pkg/jsonpath/token.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ const (
181181
BRACKET_RIGHT
182182
COLON
183183
COMMA
184-
DOT
185184
TILDE
186185
AND
187186
OR
@@ -195,6 +194,16 @@ const (
195194
MATCHES
196195
)
197196

197+
var SimpleTokens = [...]Token{
198+
STRING_LITERAL,
199+
NUMBER,
200+
STRING,
201+
CHILD,
202+
BRACKET_LEFT,
203+
BRACKET_RIGHT,
204+
ROOT,
205+
}
206+
198207
var tokens = [...]string{
199208
ILLEGAL: "ILLEGAL",
200209
STRING_LITERAL: "STRING_LITERAL",
@@ -223,7 +232,6 @@ var tokens = [...]string{
223232
BRACKET_RIGHT: "]",
224233
COLON: ":",
225234
COMMA: ",",
226-
DOT: ".",
227235
TILDE: "~",
228236
AND: "&&",
229237
OR: "||",
@@ -245,6 +253,27 @@ func (tok Token) String() string {
245253
return "token(" + strconv.Itoa(int(tok)) + ")"
246254
}
247255

256+
func (tok Tokens) IsSimple() bool {
257+
if len(tok) == 0 {
258+
return false
259+
}
260+
if tok[0].Token != ROOT {
261+
return false
262+
}
263+
for _, token := range tok {
264+
isSimple := false
265+
for _, simpleToken := range SimpleTokens {
266+
if token.Token == simpleToken {
267+
isSimple = true
268+
}
269+
}
270+
if !isSimple {
271+
return false
272+
}
273+
}
274+
return true
275+
}
276+
248277
// When there's an error in the tokenizer, this helps represent it.
249278
func (t Tokenizer) ErrorString(target TokenInfo, msg string) string {
250279
var errorBuilder strings.Builder
@@ -352,7 +381,7 @@ func NewTokenizer(input string) *Tokenizer {
352381
}
353382

354383
// Tokenize tokenizes the input string and returns a slice of TokenInfo.
355-
func (t *Tokenizer) Tokenize() []TokenInfo {
384+
func (t *Tokenizer) Tokenize() Tokens {
356385
for t.pos < len(t.input) {
357386
t.skipWhitespace()
358387
if t.pos >= len(t.input) {

pkg/jsonpath/token_test.go

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -291,47 +291,48 @@ func TestTokenizer(t *testing.T) {
291291
}
292292
}
293293

294-
func TestTokenizer_NoPanic(t *testing.T) {
294+
func TestTokenizer_categorize(t *testing.T) {
295295
testCases := []struct {
296296
name string
297297
path string
298298
illegal bool
299+
simple bool
299300
}{
300-
{name: "identity", path: ""},
301-
{name: "root", path: "$"},
301+
{name: "identity", path: "", simple: true},
302+
{name: "root", path: "$", simple: true},
302303
{name: "unmatched closing parenthesis", path: ")", illegal: true},
303304
{name: "unmatched closing square bracket", path: "]", illegal: true},
304-
{name: "dot child", path: "$.child"},
305+
{name: "dot child", path: "$.child", simple: true},
305306
{name: "dot child with implicit root", path: ".child"},
306307
{name: "undotted child with implicit root", path: "child"},
307-
{name: "dot child with no name", path: "$."},
308-
{name: "dot child with missing dot", path: "$a"},
309-
{name: "dot child with trailing dot", path: "$.child."},
310-
{name: "dot child of dot child", path: "$.child1.child2"},
308+
{name: "dot child with no name", path: "$.", simple: true},
309+
{name: "dot child with missing dot", path: "$a", simple: true},
310+
{name: "dot child with trailing dot", path: "$.child.", simple: true},
311+
{name: "dot child of dot child", path: "$.child1.child2", simple: true},
311312
{name: "dot child with array subscript", path: "$.child[*]"},
312313
{name: "dot child with malformed array subscript", path: "$.child[1:2:3:4]"},
313314
{name: "dot child with array subscript with zero step", path: "$.child[1:2:0]"},
314315
{name: "dot child with non-integer array subscript", path: "$.child[1:2:a]"},
315316
{name: "dot child with unclosed array subscript", path: "$.child[*"},
316-
{name: "dot child with missing array subscript", path: "$.child[]"},
317-
{name: "dot child with embedded space", path: "$.child more"},
318-
{name: "bracket child", path: "$['child']"},
319-
{name: "bracket child with double quotes", path: `$["child"]`},
317+
{name: "dot child with missing array subscript", path: "$.child[]", simple: true},
318+
{name: "dot child with embedded space", path: "$.child more", simple: true},
319+
{name: "bracket child", path: "$['child']", simple: true},
320+
{name: "bracket child with double quotes", path: `$["child"]`, simple: true},
320321
{name: "bracket child with unmatched quotes", path: `$["child']`, illegal: true},
321-
{name: "bracket child with empty name", path: "$['']"},
322-
{name: "bracket child of bracket child", path: "$['child1']['child2']"},
323-
{name: "double quoted bracket child of bracket child", path: `$['child1']["child2"]`},
322+
{name: "bracket child with empty name", path: "$['']", simple: true},
323+
{name: "bracket child of bracket child", path: "$['child1']['child2']", simple: true},
324+
{name: "double quoted bracket child of bracket child", path: `$['child1']["child2"]`, simple: true},
324325
{name: "bracket child union", path: "$['child','child2']"},
325326
{name: "bracket child union with whitespace", path: "$[ 'child' , 'child2' ]"},
326327
{name: "bracket child union with mixed quotes", path: `$[ 'child' , "child2" ]`},
327-
{name: "bracket child quoted union literal", path: "$[',']"},
328+
{name: "bracket child quoted union literal", path: "$[',']", simple: true},
328329
{name: "bracket child with array subscript", path: "$['child'][*]"},
329330
{name: "bracket child with malformed array subscript", path: "$['child'][1:2:3:4]"},
330331
{name: "bracket child with non-integer array subscript", path: "$['child'][1:2:a]"},
331332
{name: "bracket child with unclosed array subscript", path: "$['child'][*"},
332-
{name: "bracket child with missing array subscript", path: "$['child'][]"},
333-
{name: "bracket child followed by space", path: "$['child'] "},
334-
{name: "bracket dotted child", path: "$['child1.child2']"},
333+
{name: "bracket child with missing array subscript", path: "$['child'][]", simple: true},
334+
{name: "bracket child followed by space", path: "$['child'] ", simple: true},
335+
{name: "bracket dotted child", path: "$['child1.child2']", simple: true},
335336
{name: "bracket child with array subscript", path: "$['child'][*]"},
336337
{name: "property name dot child", path: "$.child~", illegal: true},
337338
{name: "property name dot child with implicit root", path: ".child~", illegal: true},
@@ -374,9 +375,9 @@ func TestTokenizer_NoPanic(t *testing.T) {
374375
{name: "bracket child with malformed array subscript", path: "$['child'][1:2:3:4]"},
375376
{name: "bracket child with malformed array subscript in union", path: "$['child'][0,1:2:3:4]"},
376377
{name: "bracket child with non-integer array subscript", path: "$['child'][1:2:a]"},
377-
{name: "bracket child of dot child", path: "$.child1['child2']"},
378+
{name: "bracket child of dot child", path: "$.child1['child2']", simple: true},
378379
{name: "array slice of root", path: "$[1:3]"},
379-
{name: "dot child of bracket child", path: "$['child1'].child2"},
380+
{name: "dot child of bracket child", path: "$['child1'].child2", simple: true},
380381
{name: "recursive descent", path: "$..child"},
381382
{name: "recursive descent of dot child", path: "$.child1..child2"},
382383
{name: "recursive descent of bracket child", path: "$['child1']..child2"},
@@ -484,10 +485,10 @@ func TestTokenizer_NoPanic(t *testing.T) {
484485
{name: "filter regular expression to match float literal", path: `$[?(.1=~/.*/)]`, illegal: true},
485486
{name: "filter invalid regular expression", path: `$[?(@.child=~/(.*/)]`, illegal: true},
486487
{name: "unescaped single quote in bracket child name", path: `$['single'quote']`, illegal: true},
487-
{name: "escaped single quote in bracket child name", path: `$['single\']quote']`},
488-
{name: "escaped backslash in bracket child name", path: `$['\\']`},
488+
{name: "escaped single quote in bracket child name", path: `$['single\']quote']`, simple: true},
489+
{name: "escaped backslash in bracket child name", path: `$['\\']`, simple: true},
489490
{name: "unescaped single quote after escaped backslash in bracket child name", path: `$['single\\'quote']`, illegal: true},
490-
{name: "unsupported escape sequence in bracket child name", path: `$['\n']`},
491+
{name: "unsupported escape sequence in bracket child name", path: `$['\n']`, simple: true},
491492
{name: "unclosed and empty bracket child name with space", path: `$[ '`, illegal: true},
492493
{name: "unclosed and empty bracket child name with formfeed", path: "[\f'", illegal: true},
493494
{name: "filter involving value of current node on left hand side", path: "$[?(@==1)]"},
@@ -496,11 +497,11 @@ func TestTokenizer_NoPanic(t *testing.T) {
496497

497498
for _, tc := range testCases {
498499
t.Run(tc.name, func(t *testing.T) {
499-
defer func() {
500-
if r := recover(); r != nil {
501-
t.Errorf("Tokenizer panicked for path: %s\nPanic: %v", tc.path, r)
502-
}
503-
}()
500+
//defer func() {
501+
// if r := recover(); r != nil {
502+
// t.Errorf("Tokenizer panicked for path: %s\nPanic: %v", tc.path, r)
503+
// }
504+
//}()
504505

505506
tokenizer := NewTokenizer(tc.path)
506507
tokenizedJsonPath := tokenizer.Tokenize()
@@ -516,6 +517,28 @@ func TestTokenizer_NoPanic(t *testing.T) {
516517
if tc.illegal && !foundIllegal {
517518
t.Errorf(tokenizer.ErrorTokenString(tokenizedJsonPath[0], "Expected an illegal token"))
518519
}
520+
521+
if tc.simple && foundIllegal {
522+
t.Errorf("Expected a simple path, but found an illegal token")
523+
}
524+
525+
if tc.simple && !tokenizedJsonPath.IsSimple() {
526+
for _, token := range tokenizedJsonPath {
527+
528+
simple := false
529+
for _, subToken := range SimpleTokens {
530+
if token.Token == subToken {
531+
simple = true
532+
}
533+
}
534+
if !simple {
535+
t.Errorf(tokenizer.ErrorString(token, "Expected a simple path, but found a non-simple token"))
536+
}
537+
}
538+
}
539+
if !tc.simple && tokenizedJsonPath.IsSimple() {
540+
t.Errorf(tokenizer.ErrorTokenString(tokenizedJsonPath[0], "Expected a non-simple path, but found it was simple"))
541+
}
519542
})
520543
}
521544
}

0 commit comments

Comments
 (0)