Skip to content

Commit 172182c

Browse files
committed
Add extended filter/parser tests & adjust expected error messages
1 parent 3ab203b commit 172182c

File tree

1 file changed

+157
-29
lines changed

1 file changed

+157
-29
lines changed

internal/filter/parser_test.go

Lines changed: 157 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,71 @@ 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 binary \"=\" operator at pos 0")
54+
55+
_, err = ParseFilter("foo>")
56+
assert.EqualError(t, err, "invalid filter 'foo>', unexpected binary \">\" operator at pos 4")
57+
58+
_, err = ParseFilter("foo==")
59+
assert.EqualError(t, err, "invalid filter 'foo==', unsupported operator \"==\" at pos 4")
60+
61+
_, err = ParseFilter("=>foo")
62+
assert.EqualError(t, err, "invalid filter '=>foo', unsupported 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', unsupported logical operator \"&&\" 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")
5678
})
5779
}
5880

@@ -107,35 +129,141 @@ func TestFilter(t *testing.T) {
107129
rule, err = ParseFilter("!foo")
108130
assert.Nil(t, err, "There should be no errors but got: %s", err)
109131

132+
rule, err = ParseFilter("foo")
110133
exists, _ := NewExists("foo")
134+
assert.Nil(t, err, "There should be no errors but got: %s", err)
135+
assert.Equal(t, exists, rule)
136+
137+
rule, err = ParseFilter("!foo")
138+
exists, _ = NewExists("foo")
139+
assert.Nil(t, err, "There should be no errors but got: %s", err)
111140
assert.Equal(t, &None{rules: []Filter{exists}}, rule)
112141

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

117-
rule, err = ParseFilter("!(foo=bar|bar=foo)&(foo=bar|bar=foo)")
181+
rule, err = ParseFilter("foo=bar&bar!=foo")
182+
assert.Nil(t, err, "There should be no errors but got: %s", err)
183+
184+
expect := &All{rules: []Filter{
185+
&Equal{column: "foo", value: "bar"},
186+
&UnEqual{column: "bar", value: "foo"},
187+
}}
188+
assert.Equal(t, expect, rule)
189+
190+
rule, err = ParseFilter("!(foo=bar|bar=foo)&(foo!=bar|bar!=foo)")
118191
assert.Nil(t, err, "There should be no errors but got: %s", err)
119192

120193
expected := &All{rules: []Filter{
121194
&None{rules: []Filter{
195+
&Any{rules: []Filter{
196+
&Equal{column: "foo", value: "bar"},
197+
&Equal{column: "bar", value: "foo"},
198+
}},
199+
}},
200+
&Any{rules: []Filter{
201+
&UnEqual{column: "foo", value: "bar"},
202+
&UnEqual{column: "bar", value: "foo"},
203+
}},
204+
}}
205+
assert.Equal(t, expected, rule)
206+
207+
rule, err = ParseFilter("foo=bar&bar!=foo&john>doe|doe<john&column!=value|column=value")
208+
assert.Nil(t, err, "There should be no errors but got: %s", err)
209+
210+
expectAny := &Any{rules: []Filter{
211+
&All{rules: []Filter{
122212
&Equal{column: "foo", value: "bar"},
123-
&Equal{column: "bar", value: "foo"},
213+
&UnEqual{column: "bar", value: "foo"},
214+
&GreaterThan{column: "john", value: "doe"},
124215
}},
125216
&Any{rules: []Filter{
217+
&All{rules: []Filter{
218+
&LessThan{column: "doe", value: "john"},
219+
&UnEqual{column: "column", value: "value"},
220+
}},
221+
&Equal{column: "column", value: "value"},
222+
}},
223+
}}
224+
assert.Equal(t, expectAny, rule)
225+
226+
rule, err = ParseFilter("foo=bar&bar!=foo&(john>doe|doe<john&column!=value)|column=value")
227+
assert.Nil(t, err, "There should be no errors but got: %s", err)
228+
229+
expectAny = &Any{rules: []Filter{
230+
&All{rules: []Filter{
126231
&Equal{column: "foo", value: "bar"},
127-
&Equal{column: "bar", value: "foo"},
232+
&UnEqual{column: "bar", value: "foo"},
233+
&Any{rules: []Filter{
234+
&GreaterThan{column: "john", value: "doe"},
235+
&All{rules: []Filter{
236+
&LessThan{column: "doe", value: "john"},
237+
&UnEqual{column: "column", value: "value"},
238+
}},
239+
}},
128240
}},
241+
&Equal{column: "column", value: "value"},
129242
}}
130-
assert.Equal(t, expected, rule)
131-
})
243+
assert.Equal(t, expectAny, rule)
132244

133-
t.Run("ParserIdentifiesSingleCondition", func(t *testing.T) {
134-
rule, err := ParseFilter("foo=bar")
245+
rule, err = ParseFilter("foo=bar&bar!=foo|(john>doe|doe<john&column!=value)&column=value")
135246
assert.Nil(t, err, "There should be no errors but got: %s", err)
136247

137-
expected := &Equal{column: "foo", value: "bar"}
138-
assert.Equal(t, expected, rule, "Parser doesn't parse single condition correctly")
248+
expectAny = &Any{rules: []Filter{
249+
// The first two filter conditions
250+
&All{rules: []Filter{
251+
&Equal{column: "foo", value: "bar"},
252+
&UnEqual{column: "bar", value: "foo"},
253+
}},
254+
&All{rules: []Filter{
255+
&Any{rules: []Filter{ // Represents the filter conditions within the parentheses
256+
&GreaterThan{column: "john", value: "doe"},
257+
&All{rules: []Filter{
258+
&LessThan{column: "doe", value: "john"},
259+
&UnEqual{column: "column", value: "value"},
260+
}},
261+
}},
262+
// The last filter condition
263+
&Equal{column: "column", value: "value"},
264+
}},
265+
}}
266+
assert.Equal(t, expectAny, rule)
139267
})
140268

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

0 commit comments

Comments
 (0)