@@ -9,57 +9,80 @@ import (
99func TestParser (t * testing.T ) {
1010 t .Parallel ()
1111
12- t .Run ("MissingLogicalOperatorsAfterConditionsAreDetected " , func (t * testing.T ) {
13- _ , err := ParseFilter ( "(a=b|c=d)e=f" )
12+ t .Run ("ParseInvalidFilters " , func (t * testing.T ) {
13+ t . Parallel ( )
1414
15- expected := "invalid filter '(a=b|c=d)e=f', unexpected e at pos 10: Expected logical operator"
16- assert .EqualError (t , err , expected , "Errors should be the same" )
17- })
18-
19- t .Run ("MissingLogicalOperatorsAfterOperatorsAreDetected" , func (t * testing.T ) {
20- _ , err := ParseFilter ("(a=b|c=d|)e=f" )
15+ rule , err := ParseFilter ("(a=b|c=d)e=f" )
16+ assert .Equal (t , rule , nil )
17+ assert .EqualError (t , err , "1:10 (9): no match found, expected: \" &\" , \" |\" or EOF" )
2118
22- expected := "invalid filter '(a=b|c=d|)e=f', unexpected e at pos 11: Expected logical operator"
23- assert .EqualError (t , err , expected , "Errors should be the same" )
24- })
19+ _ , err = ParseFilter ("(a=b|c=d|)e=f" )
20+ assert .EqualError (t , err , "1:10 (9): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
2521
26- t .Run ("ParserIdentifiesInvalidExpression" , func (t * testing.T ) {
27- _ , err := ParseFilter ("col=(" )
28- assert .EqualError (t , err , "invalid filter 'col=(', unexpected ( at pos 5" , "Errors should be the same" )
22+ _ , err = ParseFilter ("col=(" )
23+ assert .EqualError (t , err , "1:5 (4): no match found, expected: [^!&|~<>=()]" )
2924
3025 _ , err = ParseFilter ("(((x=a)&y=b" )
31- assert .EqualError (t , err , "invalid filter '(((x=a)&y=b', missing 2 closing ')' at pos 11" , "Errors should be the same " )
26+ assert .EqualError (t , err , "1:12 (11): no match found, expected: \" & \" , \" ) \" , \" | \" or [^!&|~<>=()] " )
3227
3328 _ , err = ParseFilter ("(x=a)&y=b)" )
34- assert .EqualError (t , err , "invalid filter '(x=a)&y=b)', unexpected ) at pos 10" , "Errors should be the same " )
29+ assert .EqualError (t , err , "1:10 (9): no match found, expected: \" & \" , \" | \" , [^!&|~<>=()] or EOF " )
3530
3631 _ , err = ParseFilter ("!(&" )
37- assert .EqualError (t , err , "invalid filter '!(&', unexpected & at pos 3" , "Errors should be the same" )
38-
39- _ , err = ParseFilter ("!(!&" )
40- assert .EqualError (t , err , "invalid filter '!(!&', unexpected & at pos 4: operator level 1" , "Errors should be the same" )
41-
42- _ , err = ParseFilter ("!(|test" )
43- assert .EqualError (t , err , "invalid filter '!(|test', unexpected | at pos 3" , "Errors should be the same" )
32+ assert .EqualError (t , err , "1:3 (2): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
4433
4534 _ , err = ParseFilter ("foo&bar=(te(st)" )
46- assert .EqualError (t , err , "invalid filter 'foo&bar=(te(st)', unexpected ( at pos 9" , "Errors should be the same " )
35+ assert .EqualError (t , err , "1:9 (8): no match found, expected: [^!&|~<>=()] " )
4736
4837 _ , err = ParseFilter ("foo&bar=te(st)" )
49- assert .EqualError (t , err , "invalid filter 'foo&bar=te(st)', unexpected ( at pos 11" , "Errors should be the same " )
38+ assert .EqualError (t , err , "1:11 (10): no match found, expected: \" & \" , \" | \" , [^!&|~<>=()] or EOF " )
5039
5140 _ , err = ParseFilter ("foo&bar=test)" )
52- assert .EqualError (t , err , "invalid filter 'foo&bar=test)', unexpected ) at pos 13" , "Errors should be the same " )
41+ assert .EqualError (t , err , "1:13 (12): no match found, expected: \" & \" , \" | \" , [^!&|~<>=()] or EOF " )
5342
5443 _ , err = ParseFilter ("!()|&()&)" )
55- assert .EqualError (t , err , "invalid filter '!()|&()&)', unexpected closing ')' at pos 9" , "Errors should be the same" )
44+ assert .EqualError (t , err , "1:3 (2): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
45+
46+ _ , err = ParseFilter ("=foo" )
47+ assert .EqualError (t , err , "1:1 (0): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
48+
49+ _ , err = ParseFilter ("foo>" )
50+ assert .EqualError (t , err , "1:5 (4): no match found, expected: [^!&|~<>=()]" )
51+
52+ _ , err = ParseFilter ("foo==" )
53+ assert .EqualError (t , err , "1:5 (4): no match found, expected: [^!&|~<>=()]" )
54+
55+ _ , err = ParseFilter ("=>foo" )
56+ assert .EqualError (t , err , "1:1 (0): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
57+
58+ _ , err = ParseFilter ("&foo" )
59+ assert .EqualError (t , err , "1:1 (0): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
60+
61+ _ , err = ParseFilter ("&&foo" )
62+ assert .EqualError (t , err , "1:1 (0): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
63+
64+ _ , err = ParseFilter ("(&foo=bar)" )
65+ assert .EqualError (t , err , "1:2 (1): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
66+
67+ _ , err = ParseFilter ("(foo=bar|)" )
68+ assert .EqualError (t , err , "1:10 (9): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
69+
70+ _ , err = ParseFilter ("((((((" )
71+ assert .EqualError (t , err , "1:7 (6): no match found, expected: \" !\" , \" (\" or [^!&|~<>=()]" )
72+
73+ _ , err = ParseFilter ("foo&bar&col=val!=val" )
74+ assert .EqualError (t , err , "1:16 (15): no match found, expected: \" &\" , \" |\" , [^!&|~<>=()] or EOF" )
75+
76+ _ , err = ParseFilter ("col%7umn" )
77+ assert .EqualError (t , err , "1:1 (0): rule ExistsExpr: invalid URL escape \" %7u\" " )
78+
79+ _ , err = ParseFilter ("((0&((((((((((((((0=0)" )
80+ assert .EqualError (t , err , "1:23 (22): no match found, expected: \" &\" , \" )\" or \" |\" " )
5681 })
57- }
5882
59- func TestFilter (t * testing.T ) {
60- t .Parallel ()
83+ t . Run ( "ParseAllKindOfSimpleFilters" , func (t * testing.T ) {
84+ t .Parallel ()
6185
62- t .Run ("ParserIdentifiesAllKindOfFilters" , func (t * testing.T ) {
6386 rule , err := ParseFilter ("foo=bar" )
6487 assert .Nil (t , err , "There should be no errors but got: %s" , err )
6588 assert .IsType (t , & Equal {}, rule )
@@ -68,11 +91,11 @@ func TestFilter(t *testing.T) {
6891 assert .Nil (t , err , "There should be no errors but got: %s" , err )
6992 assert .IsType (t , & UnEqual {}, rule )
7093
71- rule , err = ParseFilter ("foo= bar*" )
94+ rule , err = ParseFilter ("foo~ bar*" )
7295 assert .Nil (t , err , "There should be no errors but got: %s" , err )
7396 assert .IsType (t , & Like {}, rule )
7497
75- rule , err = ParseFilter ("foo!= bar*" )
98+ rule , err = ParseFilter ("foo!~ bar*" )
7699 assert .Nil (t , err , "There should be no errors but got: %s" , err )
77100 assert .IsType (t , & Unlike {}, rule )
78101
@@ -104,49 +127,229 @@ func TestFilter(t *testing.T) {
104127 assert .Nil (t , err , "There should be no errors but got: %s" , err )
105128 assert .IsType (t , & None {}, rule )
106129
130+ rule , err = ParseFilter ("foo" )
131+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
132+ assert .Equal (t , & Exists {column : "foo" }, rule )
133+
107134 rule , err = ParseFilter ("!foo" )
108135 assert .Nil (t , err , "There should be no errors but got: %s" , err )
136+ assert .Equal (t , & None {rules : []Filter {& Exists {column : "foo" }}}, rule )
137+
138+ rule , err = ParseFilter ("!foo=bar" )
139+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
140+ assert .Equal (t , & None {rules : []Filter {& Equal {column : "foo" , value : "bar" }}}, rule )
141+ })
109142
110- exists , _ := NewExists ( "foo" )
111- assert . Equal ( t , & None { rules : [] Filter { exists }}, rule )
143+ t . Run ( "ParseFilterChain" , func ( t * testing. T ) {
144+ t . Parallel ( )
112145
113- rule , err = ParseFilter ("foo" )
146+ rule , err := ParseFilter ("(foo=bar)" )
147+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
148+ assert .Equal (t , & Equal {column : "foo" , value : "bar" }, rule )
149+
150+ rule , err = ParseFilter ("(!foo=bar)" )
151+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
152+ none := & None {rules : []Filter {
153+ & Equal {column : "foo" , value : "bar" },
154+ }}
155+ assert .Equal (t , none , rule )
156+
157+ rule , err = ParseFilter ("!(foo=bar)" )
158+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
159+ none = & None {rules : []Filter {
160+ & Equal {column : "foo" , value : "bar" },
161+ }}
162+ assert .Equal (t , none , rule )
163+
164+ rule , err = ParseFilter ("!(!foo=bar)" )
165+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
166+ none = & None {rules : []Filter {
167+ & None {rules : []Filter {& Equal {column : "foo" , value : "bar" }}},
168+ }}
169+ assert .Equal (t , none , rule )
170+
171+ rule , err = ParseFilter ("((!foo=bar)&bar!=foo)" )
172+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
173+ all := & All {rules : []Filter {
174+ & None {rules : []Filter {& Equal {column : "foo" , value : "bar" }}},
175+ & UnEqual {column : "bar" , value : "foo" },
176+ }}
177+ assert .Equal (t , all , rule )
178+
179+ rule , err = ParseFilter ("!foo&!bar" )
180+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
181+ var expected Filter
182+ expected = & All {rules : []Filter {
183+ & None {rules : []Filter {& Exists {column : "foo" }}},
184+ & None {rules : []Filter {& Exists {column : "bar" }}},
185+ }}
186+ assert .Equal (t , expected , rule )
187+
188+ rule , err = ParseFilter ("!(!foo|bar)" )
189+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
190+
191+ expected = & None {rules : []Filter {
192+ & Any {rules : []Filter {
193+ & None {rules : []Filter {& Exists {column : "foo" }}},
194+ & Exists {column : "bar" },
195+ }},
196+ }}
197+ assert .Equal (t , expected , rule )
198+
199+ rule , err = ParseFilter ("!(!(foo|bar))" )
200+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
201+
202+ expected = & None {rules : []Filter {
203+ & None {rules : []Filter {
204+ & Any {rules : []Filter {
205+ & Exists {column : "foo" },
206+ & Exists {column : "bar" },
207+ }},
208+ }},
209+ }}
210+ assert .Equal (t , expected , rule )
211+
212+ rule , err = ParseFilter ("foo=bar&bar!=foo" )
114213 assert .Nil (t , err , "There should be no errors but got: %s" , err )
115- assert .Equal (t , exists , rule )
116214
117- rule , err = ParseFilter ("!(foo=bar|bar=foo)&(foo=bar|bar=foo)" )
215+ expect := & All {rules : []Filter {
216+ & Equal {column : "foo" , value : "bar" },
217+ & UnEqual {column : "bar" , value : "foo" },
218+ }}
219+ assert .Equal (t , expect , rule )
220+
221+ rule , err = ParseFilter ("!(foo=bar|bar=foo)&(foo!=bar|bar!=foo)" )
118222 assert .Nil (t , err , "There should be no errors but got: %s" , err )
119223
120- expected : = & All {rules : []Filter {
224+ expected = & All {rules : []Filter {
121225 & None {rules : []Filter {
226+ & Any {rules : []Filter {
227+ & Equal {column : "foo" , value : "bar" },
228+ & Equal {column : "bar" , value : "foo" },
229+ }},
230+ }},
231+ & Any {rules : []Filter {
232+ & UnEqual {column : "foo" , value : "bar" },
233+ & UnEqual {column : "bar" , value : "foo" },
234+ }},
235+ }}
236+ assert .Equal (t , expected , rule )
237+
238+ rule , err = ParseFilter ("foo=bar&bar!=foo&john>doe|doe<john&column!=value|column=value" )
239+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
240+
241+ expectAny := & Any {rules : []Filter {
242+ & All {rules : []Filter {
122243 & Equal {column : "foo" , value : "bar" },
123- & Equal {column : "bar" , value : "foo" },
244+ & UnEqual {column : "bar" , value : "foo" },
245+ & GreaterThan {column : "john" , value : "doe" },
124246 }},
125247 & Any {rules : []Filter {
248+ & All {rules : []Filter {
249+ & LessThan {column : "doe" , value : "john" },
250+ & UnEqual {column : "column" , value : "value" },
251+ }},
252+ & Equal {column : "column" , value : "value" },
253+ }},
254+ }}
255+ assert .Equal (t , expectAny , rule )
256+
257+ rule , err = ParseFilter ("foo=bar&bar!=foo&(john>doe|doe<john&column!=value)|column=value" )
258+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
259+
260+ expectAny = & Any {rules : []Filter {
261+ & All {rules : []Filter {
126262 & Equal {column : "foo" , value : "bar" },
127- & Equal {column : "bar" , value : "foo" },
263+ & UnEqual {column : "bar" , value : "foo" },
264+ & Any {rules : []Filter {
265+ & GreaterThan {column : "john" , value : "doe" },
266+ & All {rules : []Filter {
267+ & LessThan {column : "doe" , value : "john" },
268+ & UnEqual {column : "column" , value : "value" },
269+ }},
270+ }},
128271 }},
272+ & Equal {column : "column" , value : "value" },
129273 }}
130- assert .Equal (t , expected , rule )
131- })
274+ assert .Equal (t , expectAny , rule )
132275
133- t .Run ("ParserIdentifiesSingleCondition" , func (t * testing.T ) {
134- rule , err := ParseFilter ("foo=bar" )
276+ rule , err = ParseFilter ("foo=bar&bar!=foo|(john>doe|doe<john&column!=value)&column=value" )
277+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
278+
279+ expectAny = & Any {rules : []Filter {
280+ // The first two filter conditions
281+ & All {rules : []Filter {
282+ & Equal {column : "foo" , value : "bar" },
283+ & UnEqual {column : "bar" , value : "foo" },
284+ }},
285+ & All {rules : []Filter {
286+ & Any {rules : []Filter { // Represents the filter conditions within the parentheses
287+ & GreaterThan {column : "john" , value : "doe" },
288+ & All {rules : []Filter {
289+ & LessThan {column : "doe" , value : "john" },
290+ & UnEqual {column : "column" , value : "value" },
291+ }},
292+ }},
293+ // The last filter condition
294+ & Equal {column : "column" , value : "value" },
295+ }},
296+ }}
297+ assert .Equal (t , expectAny , rule )
298+
299+ rule , err = ParseFilter ("foo=bar&bar!=foo|(john>doe|doe<john&(column!=value|value!~column))&column=value" )
135300 assert .Nil (t , err , "There should be no errors but got: %s" , err )
136301
137- expected := & Equal {column : "foo" , value : "bar" }
138- assert .Equal (t , expected , rule , "Parser doesn't parse single condition correctly" )
302+ expectAny = & Any {rules : []Filter {
303+ // The first two filter conditions
304+ & All {rules : []Filter {
305+ & Equal {column : "foo" , value : "bar" },
306+ & UnEqual {column : "bar" , value : "foo" },
307+ }},
308+ & All {rules : []Filter {
309+ & Any {rules : []Filter { // Represents the filter conditions within the parentheses
310+ & GreaterThan {column : "john" , value : "doe" },
311+ & All {rules : []Filter {
312+ & LessThan {column : "doe" , value : "john" },
313+ & Any {rules : []Filter { // Represents the filter conditions within the nested parentheses
314+ & UnEqual {column : "column" , value : "value" },
315+ & Unlike {column : "value" , value : "column" },
316+ }},
317+ }},
318+ }},
319+ // The last filter condition
320+ & Equal {column : "column" , value : "value" },
321+ }},
322+ }}
323+ assert .Equal (t , expectAny , rule )
139324 })
140325
141- t .Run ("UrlEncodedFilterExpression" , func (t * testing.T ) {
326+ t .Run ("UrlEncodedFilter" , func (t * testing.T ) {
327+ t .Parallel ()
328+
142329 rule , err := ParseFilter ("col%3Cumn<val%3Cue" )
143330 assert .Nil (t , err , "There should be no errors but got: %s" , err )
144331 assert .Equal (t , & LessThan {column : "col<umn" , value : "val<ue" }, rule )
145332
333+ rule , err = ParseFilter ("col%7Cumn" )
334+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
335+ assert .Equal (t , & Exists {column : "col|umn" }, rule )
336+
146337 rule , err = ParseFilter ("col%7Cumn=val%7Cue" )
147338 assert .Nil (t , err , "There should be no errors but got: %s" , err )
148339 assert .Equal (t , & Equal {column : "col|umn" , value : "val|ue" }, rule )
149340
341+ rule , err = ParseFilter ("col%7Cumn!=val%7Cue" )
342+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
343+ assert .Equal (t , & UnEqual {column : "col|umn" , value : "val|ue" }, rule )
344+
345+ rule , err = ParseFilter ("col%7Cumn~val%7Cue" )
346+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
347+ assert .Equal (t , & Like {column : "col|umn" , value : "val|ue" }, rule )
348+
349+ rule , err = ParseFilter ("col%7Cumn!~val%7Cue" )
350+ assert .Nil (t , err , "There should be no errors but got: %s" , err )
351+ assert .Equal (t , & Unlike {column : "col|umn" , value : "val|ue" }, rule )
352+
150353 rule , err = ParseFilter ("col%26umn<=val%26ue" )
151354 assert .Nil (t , err , "There should be no errors but got: %s" , err )
152355 assert .Equal (t , & LessThanOrEqual {column : "col&umn" , value : "val&ue" }, rule )
@@ -174,8 +377,8 @@ func FuzzParser(f *testing.F) {
174377 f .Add ("foo&bar=test)" )
175378 f .Add ("foo=bar" )
176379 f .Add ("foo!=bar" )
177- f .Add ("foo= bar*" )
178- f .Add ("foo!= bar*" )
380+ f .Add ("foo~ bar*" )
381+ f .Add ("foo!~ bar*" )
179382 f .Add ("foo<bar" )
180383 f .Add ("foo<=bar" )
181384 f .Add ("foo>bar" )
@@ -187,6 +390,7 @@ func FuzzParser(f *testing.F) {
187390 f .Add ("foo" )
188391 f .Add ("!(foo=bar|bar=foo)&(foo=bar|bar=foo)" )
189392 f .Add ("foo=bar" )
393+ f .Add ("col%7umn" )
190394 f .Add ("col%3Cumn<val%3Cue" )
191395 f .Add ("col%7Cumn=val%7Cue" )
192396 f .Add ("col%26umn<=val%26ue" )
0 commit comments