Skip to content

Commit dec3f96

Browse files
committed
Add extended filter/parser tests & adjust expected error messages
1 parent 7c59e64 commit dec3f96

File tree

1 file changed

+190
-31
lines changed

1 file changed

+190
-31
lines changed

internal/filter/parser_test.go

Lines changed: 190 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,74 @@ func TestParser(t *testing.T) {
1010
t.Parallel()
1111

1212
t.Run("MissingLogicalOperatorsAfterConditionsAreDetected", func(t *testing.T) {
13-
_, err := ParseFilter("(a=b|c=d)e=f")
13+
rule, err := ParseFilter("(a=b|c=d)e=f")
1414

15-
expected := "invalid filter '(a=b|c=d)e=f', unexpected e at pos 10: Expected logical operator"
15+
assert.Equal(t, rule, nil)
16+
expected := "invalid filter '(a=b|c=d)e=f', missing logical operator at pos 10"
1617
assert.EqualError(t, err, expected, "Errors should be the same")
1718
})
1819

1920
t.Run("MissingLogicalOperatorsAfterOperatorsAreDetected", func(t *testing.T) {
2021
_, err := ParseFilter("(a=b|c=d|)e=f")
2122

22-
expected := "invalid filter '(a=b|c=d|)e=f', unexpected e at pos 11: Expected logical operator"
23+
expected := "invalid filter '(a=b|c=d|)e=f', unexpected logical operator \"|\" at pos 9"
2324
assert.EqualError(t, err, expected, "Errors should be the same")
2425
})
2526

26-
t.Run("ParserIdentifiesInvalidExpression", func(t *testing.T) {
27+
t.Run("ParserIdentifiesInvalidFilters", func(t *testing.T) {
2728
_, err := ParseFilter("col=(")
28-
assert.EqualError(t, err, "invalid filter 'col=(', unexpected ( at pos 5", "Errors should be the same")
29+
assert.EqualError(t, err, "invalid filter 'col=(', unexpected \"(\" at pos 4", "Errors should be the same")
2930

3031
_, 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")
32+
assert.EqualError(t, err, "invalid filter '(((x=a)&y=b', mismatching opening and closing parentheses", "Errors should be the same")
3233

3334
_, 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")
35+
assert.EqualError(t, err, "invalid filter '(x=a)&y=b)', unexpected \")\" at pos 10", "Errors should be the same")
3536

3637
_, 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")
38+
assert.EqualError(t, err, "invalid filter '!(&', unexpected logical operator \"&\" at pos 3", "Errors should be the same")
4439

4540
_, 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")
41+
assert.EqualError(t, err, "invalid filter 'foo&bar=(te(st)', unexpected \"(\" at pos 8", "Errors should be the same")
4742

4843
_, 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")
44+
assert.EqualError(t, err, "invalid filter 'foo&bar=te(st)', missing logical operator at pos 12", "Errors should be the same")
5045

5146
_, err = ParseFilter("foo&bar=test)")
52-
assert.EqualError(t, err, "invalid filter 'foo&bar=test)', unexpected ) at pos 13", "Errors should be the same")
47+
assert.EqualError(t, err, "invalid filter 'foo&bar=test)', unexpected \")\" at pos 13", "Errors should be the same")
5348

5449
_, err = ParseFilter("!()|&()&)")
55-
assert.EqualError(t, err, "invalid filter '!()|&()&)', unexpected closing ')' at pos 9", "Errors should be the same")
50+
assert.EqualError(t, err, "invalid filter '!()|&()&)', empty filter groups are not allowed at pos 2", "Errors should be the same")
51+
52+
_, err = ParseFilter("=foo")
53+
assert.EqualError(t, err, "invalid filter '=foo', unexpected operator \"=\" at pos 0")
54+
55+
_, err = ParseFilter("foo>")
56+
assert.EqualError(t, err, "invalid filter 'foo>', unexpected operator \">\" at pos 4")
57+
58+
_, err = ParseFilter("foo==")
59+
assert.EqualError(t, err, "invalid filter 'foo==', unexpected operator \"=\" at pos 4")
60+
61+
_, err = ParseFilter("=>foo")
62+
assert.EqualError(t, err, "invalid filter '=>foo', unexpected operator \"=\" at pos 1")
63+
64+
_, err = ParseFilter("&foo")
65+
assert.EqualError(t, err, "invalid filter '&foo', unexpected logical operator \"&\" at pos 1")
66+
67+
_, err = ParseFilter("&&foo")
68+
assert.EqualError(t, err, "invalid filter '&&foo', unexpected logical operators \"&&\" at pos 1")
69+
70+
_, err = ParseFilter("(&foo=bar)")
71+
assert.EqualError(t, err, "invalid filter '(&foo=bar)', unexpected logical operator \"&\" at pos 2")
72+
73+
_, err = ParseFilter("(foo=bar|)")
74+
assert.EqualError(t, err, "invalid filter '(foo=bar|)', unexpected logical operator \"|\" at pos 9")
75+
76+
_, err = ParseFilter("((((((")
77+
assert.EqualError(t, err, "invalid filter '((((((', too many opening parentheses")
78+
79+
_, err = ParseFilter("foo&bar&col=val!=val")
80+
assert.EqualError(t, err, "invalid filter 'foo&bar&col=val!=val', missing logical operator at pos 16")
5681
})
5782
}
5883

@@ -104,38 +129,172 @@ func TestFilter(t *testing.T) {
104129
assert.Nil(t, err, "There should be no errors but got: %s", err)
105130
assert.IsType(t, &None{}, rule)
106131

132+
rule, err = ParseFilter("foo")
133+
assert.Nil(t, err, "There should be no errors but got: %s", err)
134+
assert.Equal(t, &Exists{column: "foo"}, rule)
135+
107136
rule, err = ParseFilter("!foo")
108137
assert.Nil(t, err, "There should be no errors but got: %s", err)
138+
assert.Equal(t, &None{rules: []Filter{&Exists{column: "foo"}}}, rule)
109139

110-
exists, _ := NewExists("foo")
111-
assert.Equal(t, &None{rules: []Filter{exists}}, rule)
140+
rule, err = ParseFilter("!foo=bar")
141+
assert.Nil(t, err, "There should be no errors but got: %s", err)
142+
assert.Equal(t, &None{rules: []Filter{&Equal{column: "foo", value: "bar"}}}, rule)
112143

113-
rule, err = ParseFilter("foo")
144+
rule, err = ParseFilter("!foo&!bar")
145+
assert.Nil(t, err, "There should be no errors but got: %s", err)
146+
var expected Filter
147+
expected = &All{rules: []Filter{
148+
&None{rules: []Filter{&Exists{column: "foo"}}},
149+
&None{rules: []Filter{&Exists{column: "bar"}}},
150+
}}
151+
assert.Equal(t, expected, rule)
152+
153+
rule, err = ParseFilter("!(!foo|bar)")
154+
assert.Nil(t, err, "There should be no errors but got: %s", err)
155+
156+
expected = &None{rules: []Filter{
157+
&Any{rules: []Filter{
158+
&None{rules: []Filter{&Exists{column: "foo"}}},
159+
&Exists{column: "bar"},
160+
}},
161+
}}
162+
assert.Equal(t, expected, rule)
163+
164+
rule, err = ParseFilter("!(!(foo|bar))")
165+
assert.Nil(t, err, "There should be no errors but got: %s", err)
166+
167+
expected = &None{rules: []Filter{
168+
&None{rules: []Filter{
169+
&Any{rules: []Filter{
170+
&Exists{column: "foo"},
171+
&Exists{column: "bar"},
172+
}},
173+
}},
174+
}}
175+
assert.Equal(t, expected, rule)
176+
})
177+
178+
t.Run("ParseFilterChain", func(t *testing.T) {
179+
rule, err := ParseFilter("(foo=bar)")
114180
assert.Nil(t, err, "There should be no errors but got: %s", err)
115-
assert.Equal(t, exists, rule)
181+
assert.Equal(t, &Equal{column: "foo", value: "bar"}, rule)
116182

117-
rule, err = ParseFilter("!(foo=bar|bar=foo)&(foo=bar|bar=foo)")
183+
rule, err = ParseFilter("(!foo=bar)")
184+
assert.Nil(t, err, "There should be no errors but got: %s", err)
185+
none := &None{rules: []Filter{
186+
&Equal{column: "foo", value: "bar"},
187+
}}
188+
assert.Equal(t, none, rule)
189+
190+
rule, err = ParseFilter("!(foo=bar)")
191+
assert.Nil(t, err, "There should be no errors but got: %s", err)
192+
none = &None{rules: []Filter{
193+
&Equal{column: "foo", value: "bar"},
194+
}}
195+
assert.Equal(t, none, rule)
196+
197+
rule, err = ParseFilter("!(!foo=bar)")
198+
assert.Nil(t, err, "There should be no errors but got: %s", err)
199+
none = &None{rules: []Filter{
200+
&None{rules: []Filter{&Equal{column: "foo", value: "bar"}}},
201+
}}
202+
assert.Equal(t, none, rule)
203+
204+
rule, err = ParseFilter("((!foo=bar)&bar!=foo)")
205+
assert.Nil(t, err, "There should be no errors but got: %s", err)
206+
all := &All{rules: []Filter{
207+
&None{rules: []Filter{&Equal{column: "foo", value: "bar"}}},
208+
&UnEqual{column: "bar", value: "foo"},
209+
}}
210+
assert.Equal(t, all, rule)
211+
212+
rule, err = ParseFilter("foo=bar&bar!=foo")
213+
assert.Nil(t, err, "There should be no errors but got: %s", err)
214+
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

120224
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")
135277
assert.Nil(t, err, "There should be no errors but got: %s", err)
136278

137-
expected := &Equal{column: "foo", value: "bar"}
138-
assert.Equal(t, expected, rule, "Parser doesn't parse single condition correctly")
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)
139298
})
140299

141300
t.Run("UrlEncodedFilterExpression", func(t *testing.T) {

0 commit comments

Comments
 (0)