Skip to content

Commit 17aafb0

Browse files
authored
Merge pull request #148 from gongfarmer/master
bug #147: stop at character '!' when scanning key name, to avoid consuming first char of operator '!='
2 parents 0cc23fa + 6f3f441 commit 17aafb0

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

lib/jsonpath/parser.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def parse_exp(exp)
6868
scanner = StringScanner.new(exp)
6969
elements = []
7070
until scanner.eos?
71-
if (t = scanner.scan(/\['[a-zA-Z@&*\/$%^?_]+'\]|\.[a-zA-Z0-9_]+[?!]?/))
71+
if (t = scanner.scan(/\['[a-zA-Z@&*\/$%^?_]+'\]|\.[a-zA-Z0-9_]+[?]?/))
7272
elements << t.gsub(/[\[\]'.]|\s+/, '')
7373
elsif (t = scanner.scan(/(\s+)?[<>=!\-+][=~]?(\s+)?/))
7474
operator = t

test/test_jsonpath.rb

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,20 @@ def test_recognize_filters
7070
assert_equal [@object['store']['book'][0], @object['store']['book'][2]], JsonPath.new("$..book[?(@['price'] < 10)]").on(@object)
7171
assert_equal [@object['store']['book'][0], @object['store']['book'][2]], JsonPath.new("$..book[?(@['price'] == 9)]").on(@object)
7272
assert_equal [@object['store']['book'][3]], JsonPath.new("$..book[?(@['price'] > 20)]").on(@object)
73-
assert_equal [
74-
@object['store']['book'][0],
75-
@object['store']['book'][4],
76-
@object['store']['book'][5],
77-
@object['store']['book'][6]
78-
], JsonPath.new("$..book[?(@['category'] != 'fiction')]").on(@object)
73+
end
74+
75+
def test_not_equals_operator
76+
expected =
77+
[
78+
@object['store']['book'][0],
79+
@object['store']['book'][4],
80+
@object['store']['book'][5],
81+
@object['store']['book'][6]
82+
]
83+
assert_equal(expected, JsonPath.new("$..book[?(@['category'] != 'fiction')]").on(@object))
84+
assert_equal(expected, JsonPath.new("$..book[?(@['category']!=fiction)]").on(@object))
85+
assert_equal(expected, JsonPath.new("$..book[?(@.category!=fiction)]").on(@object))
86+
assert_equal(expected, JsonPath.new("$..book[?(@.category != 'fiction')]").on(@object))
7987
end
8088

8189
def test_or_operator
@@ -86,15 +94,36 @@ def test_or_operator
8694
assert_equal result, JsonPath.new("$..book[?(@.price==23 || @.price==13 || @.price==9)].title").on(@object)
8795
end
8896

97+
def test_or_operator_with_not_equals
98+
# Should be the same regardless of key style ( @.key vs @['key'] )
99+
result = ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien', 'Lukyanenko']
100+
assert_equal result, JsonPath.new("$..book[?(@['title']=='Osennie Vizity' || @['author']!='Lukyanenko')].author").on(@object)
101+
assert_equal result, JsonPath.new("$..book[?(@.title=='Osennie Vizity' || @.author != Lukyanenko )].author").on(@object)
102+
assert_equal result, JsonPath.new("$..book[?(@.title=='Osennie Vizity' || @.author!=Lukyanenko )].author").on(@object)
103+
end
104+
89105
def test_and_operator
90106
assert_equal [], JsonPath.new("$..book[?(@['price'] == 13 && @['price'] == 23)]").on(@object)
91-
assert_equal [], JsonPath.new("$..book[?(@.price==13 && @.category==fiction && @.title==no_match)]").on(@object)
107+
assert_equal [], JsonPath.new("$..book[?(@.price>=13 && @.category==fiction && @.title==no_match)]").on(@object)
92108
assert_equal [], JsonPath.new("$..book[?(@.title==no_match && @.category==fiction && @.price==13)]").on(@object)
93109
assert_equal [], JsonPath.new("$..book[?(@.price==13 && @.title==no_match && @.category==fiction)]").on(@object)
110+
assert_equal [], JsonPath.new("$..book[?(@.price==13 && @.bad_key_name==true && @.category==fiction)]").on(@object)
111+
112+
expected = [@object['store']['book'][1]]
113+
assert_equal expected, JsonPath.new("$..book[?(@['price'] < 23 && @['price'] > 9)]").on(@object)
114+
assert_equal expected, JsonPath.new("$..book[?(@.price < 23 && @.price > 9)]").on(@object)
115+
116+
expected = ['Sword of Honour', 'The Lord of the Rings']
117+
assert_equal expected, JsonPath.new("$..book[?(@.price>=13 && @.category==fiction)].title").on(@object)
118+
assert_equal ['The Lord of the Rings'], JsonPath.new("$..book[?(@.category==fiction && @.isbn && @.price>9)].title").on(@object)
119+
assert_equal ['Sayings of the Century'], JsonPath.new("$..book[?(@['price'] == 9 && @.author=='Nigel Rees')].title").on(@object)
120+
assert_equal ['Sayings of the Century'], JsonPath.new("$..book[?(@['price'] == 9 && @.tags..asdf)].title").on(@object)
94121
end
95122

96-
def test_and_operator_with_more_results
97-
assert_equal [@object['store']['book'][1]], JsonPath.new("$..book[?(@['price'] < 23 && @['price'] > 9)]").on(@object)
123+
def test_and_operator_with_not_equals
124+
expected = ['Nigel Rees']
125+
assert_equal expected, JsonPath.new("$..book[?(@['price']==9 && @['category']!=fiction)].author").on(@object)
126+
assert_equal expected, JsonPath.new("$..book[?(@.price==9 && @.category!=fiction)].author").on(@object)
98127
end
99128

100129
def test_nested_grouping
@@ -577,7 +606,18 @@ def test_boolean_parameter_value
577606
'name' => 'testname2'
578607
}]
579608
}
580-
assert_equal [{ 'isTrue' => true, 'name' => 'testname1' }], JsonPath.new('$.data[?(@.isTrue)]').on(data)
609+
610+
# These queries should be equivalent
611+
expected = [{ 'isTrue' => true, 'name' => 'testname1' }]
612+
assert_equal expected, JsonPath.new('$.data[?(@.isTrue)]').on(data)
613+
assert_equal expected, JsonPath.new('$.data[?(@.isTrue==true)]').on(data)
614+
assert_equal expected, JsonPath.new('$.data[?(@.isTrue == true)]').on(data)
615+
616+
# These queries should be equivalent
617+
expected = [{ 'isTrue' => false, 'name' => 'testname2' }]
618+
assert_equal expected, JsonPath.new('$.data[?(@.isTrue != true)]').on(data)
619+
assert_equal expected, JsonPath.new('$.data[?(@.isTrue!=true)]').on(data)
620+
assert_equal expected, JsonPath.new('$.data[?(@.isTrue==false)]').on(data)
581621
end
582622

583623
def test_and_operator_with_boolean_parameter_value
@@ -601,6 +641,7 @@ def test_and_operator_with_boolean_parameter_value
601641

602642
def test_regex_simple
603643
assert_equal %w[asdf asdf2], JsonPath.new('$.store.book..tags[?(@ =~ /asdf/)]').on(@object)
644+
assert_equal %w[asdf asdf2], JsonPath.new('$.store.book..tags[?(@=~/asdf/)]').on(@object)
604645
end
605646

606647
def test_regex_simple_miss

0 commit comments

Comments
 (0)