blob: 874bda39cd189be990e3adffce08122ee1343058 [file] [log] [blame]
Scott Baker2b0ad652019-08-21 14:57:07 -07001/*
2 * Copyright 2019-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Zack Williamse940c7a2019-08-21 14:25:39 -070017package filter
18
19import (
Scott Baker9a2d9a42020-06-09 18:11:26 -070020 "github.com/stretchr/testify/assert"
Zack Williamse940c7a2019-08-21 14:25:39 -070021 "testing"
22)
23
Scott Baker9a2d9a42020-06-09 18:11:26 -070024type TestFilterIncludedStruct struct {
25 Six string
26}
27
Zack Williamse940c7a2019-08-21 14:25:39 -070028type TestFilterStruct struct {
29 One string
30 Two string
31 Three string
Scott Baker9a2d9a42020-06-09 18:11:26 -070032 Five TestFilterIncludedStruct
Zack Williamse940c7a2019-08-21 14:25:39 -070033}
34
35func TestFilterList(t *testing.T) {
Scott Baker9a2d9a42020-06-09 18:11:26 -070036 f, err := Parse("One=a,Two=b,Five.Six=d")
Zack Williamse940c7a2019-08-21 14:25:39 -070037 if err != nil {
38 t.Errorf("Unable to parse filter: %s", err.Error())
39 }
40
41 data := []interface{}{
42 TestFilterStruct{
43 One: "a",
44 Two: "b",
45 Three: "c",
Scott Baker9a2d9a42020-06-09 18:11:26 -070046 Five: TestFilterIncludedStruct{Six: "d"},
Zack Williamse940c7a2019-08-21 14:25:39 -070047 },
48 TestFilterStruct{
49 One: "1",
50 Two: "2",
51 Three: "3",
Scott Baker9a2d9a42020-06-09 18:11:26 -070052 Five: TestFilterIncludedStruct{Six: "4"},
Zack Williamse940c7a2019-08-21 14:25:39 -070053 },
54 TestFilterStruct{
55 One: "a",
56 Two: "b",
57 Three: "z",
Scott Baker9a2d9a42020-06-09 18:11:26 -070058 Five: TestFilterIncludedStruct{Six: "d"},
Zack Williamse940c7a2019-08-21 14:25:39 -070059 },
60 }
61
62 r, _ := f.Process(data)
63
64 if _, ok := r.([]interface{}); !ok {
65 t.Errorf("Expected list, but didn't get one")
66 }
67
68 if len(r.([]interface{})) != 2 {
69 t.Errorf("Expected %d got %d", 2, len(r.([]interface{})))
70 }
71
72 if r.([]interface{})[0] != data[0] {
73 t.Errorf("Filtered list did not match, item %d", 0)
74 }
75 if r.([]interface{})[1] != data[2] {
76 t.Errorf("Filtered list did not match, item %d", 1)
77 }
78}
79
80func TestFilterItem(t *testing.T) {
81 f, err := Parse("One=a,Two=b")
82 if err != nil {
83 t.Errorf("Unable to parse filter: %s", err.Error())
84 }
85
86 data := TestFilterStruct{
87 One: "a",
88 Two: "b",
89 Three: "c",
90 }
91
92 r, _ := f.Process(data)
93
94 if r == nil {
95 t.Errorf("Expected item, got nil")
96 }
97
98 if _, ok := r.([]interface{}); ok {
99 t.Errorf("Expected item, but got list")
100 }
101}
102
103func TestGoodFilters(t *testing.T) {
104 var f Filter
105 var err error
106 f, err = Parse("One=a,Two=b")
107 if err != nil {
108 t.Errorf("1. Unable to parse filter: %s", err.Error())
109 }
110 if len(f) != 2 ||
111 f["One"].Value != "a" ||
112 f["One"].Op != EQ ||
113 f["Two"].Value != "b" ||
114 f["Two"].Op != EQ {
115 t.Errorf("1. Filter did not parse correctly")
116 }
117
118 f, err = Parse("One=a")
119 if err != nil {
120 t.Errorf("2. Unable to parse filter: %s", err.Error())
121 }
122 if len(f) != 1 ||
123 f["One"].Value != "a" ||
124 f["One"].Op != EQ {
125 t.Errorf("2. Filter did not parse correctly")
126 }
127
128 f, err = Parse("One<a")
129 if err != nil {
130 t.Errorf("3. Unable to parse filter: %s", err.Error())
131 }
132 if len(f) != 1 ||
133 f["One"].Value != "a" ||
134 f["One"].Op != LT {
135 t.Errorf("3. Filter did not parse correctly")
136 }
137
138 f, err = Parse("One!=a")
139 if err != nil {
140 t.Errorf("4. Unable to parse filter: %s", err.Error())
141 }
142 if len(f) != 1 ||
143 f["One"].Value != "a" ||
144 f["One"].Op != NE {
145 t.Errorf("4. Filter did not parse correctly")
146 }
147}
148
149func TestBadFilters(t *testing.T) {
150 _, err := Parse("One%a")
151 if err == nil {
152 t.Errorf("Parsed filter when it shouldn't have")
153 }
154}
155
156func TestSingleRecord(t *testing.T) {
157 f, err := Parse("One=d")
158 if err != nil {
159 t.Errorf("Unable to parse filter: %s", err.Error())
160 }
161
162 data := TestFilterStruct{
163 One: "a",
164 Two: "b",
165 Three: "c",
166 }
167
168 r, err := f.Process(data)
169 if err != nil {
170 t.Errorf("Error processing data")
171 }
172
173 if r != nil {
174 t.Errorf("expected no results, got some")
175 }
176}
177
Scott Baker9a2d9a42020-06-09 18:11:26 -0700178// Invalid fields will throw an exception.
Zack Williamse940c7a2019-08-21 14:25:39 -0700179func TestInvalidField(t *testing.T) {
180 f, err := Parse("Four=a")
181 if err != nil {
182 t.Errorf("Unable to parse filter: %s", err.Error())
183 }
184
185 data := TestFilterStruct{
186 One: "a",
187 Two: "b",
188 Three: "c",
189 }
190
191 r, err := f.Process(data)
Scott Baker9a2d9a42020-06-09 18:11:26 -0700192 assert.EqualError(t, err, "Failed to find field Four while filtering")
193
194 if r != nil {
195 t.Errorf("expected no results, got some")
Zack Williamse940c7a2019-08-21 14:25:39 -0700196 }
Scott Baker9a2d9a42020-06-09 18:11:26 -0700197}
198
199func TestInvalidDotted(t *testing.T) {
200 f, err := Parse("Five.NonExistent=a")
201 if err != nil {
202 t.Errorf("Unable to parse filter: %s", err.Error())
203 }
204
205 data := TestFilterStruct{
206 One: "a",
207 Two: "b",
208 Three: "c",
209 Five: TestFilterIncludedStruct{Six: "w"},
210 }
211
212 r, err := f.Process(data)
213 assert.EqualError(t, err, "Failed to find field NonExistent while filtering")
214
215 if r != nil {
216 t.Errorf("expected no results, got some")
217 }
218}
219
220func TestTrailingDot(t *testing.T) {
221 f, err := Parse("Five.Six.=a")
222 if err != nil {
223 t.Errorf("Unable to parse filter: %s", err.Error())
224 }
225
226 data := TestFilterStruct{
227 One: "a",
228 Two: "b",
229 Three: "c",
230 Five: TestFilterIncludedStruct{Six: "w"},
231 }
232
233 r, err := f.Process(data)
234 assert.EqualError(t, err, "Dotted field name specified in filter did not resolve to a valid field")
235
236 if r != nil {
237 t.Errorf("expected no results, got some")
238 }
239}
240
241func TestDottedOnString(t *testing.T) {
242 f, err := Parse("One.IsNotAStruct=a")
243 if err != nil {
244 t.Errorf("Unable to parse filter: %s", err.Error())
245 }
246
247 data := TestFilterStruct{
248 One: "a",
249 Two: "b",
250 Three: "c",
251 Five: TestFilterIncludedStruct{Six: "w"},
252 }
253
254 r, err := f.Process(data)
255 assert.EqualError(t, err, "Dotted field name specified in filter did not resolve to a valid field")
Zack Williamse940c7a2019-08-21 14:25:39 -0700256
257 if r != nil {
258 t.Errorf("expected no results, got some")
259 }
260}
261
262func TestREFilter(t *testing.T) {
263 var f Filter
264 var err error
265 f, err = Parse("One~a")
266 if err != nil {
267 t.Errorf("Unable to parse RE expression")
268 }
269 if len(f) != 1 {
270 t.Errorf("filter parsed incorrectly")
271 }
272
273 data := []interface{}{
274 TestFilterStruct{
275 One: "a",
276 Two: "b",
277 Three: "c",
278 },
279 TestFilterStruct{
280 One: "1",
281 Two: "2",
282 Three: "3",
283 },
284 TestFilterStruct{
285 One: "a",
286 Two: "b",
287 Three: "z",
288 },
289 }
290
David Bainbridge12f036f2019-10-15 22:09:04 +0000291 if _, err = f.Process(data); err != nil {
292 t.Errorf("Error processing data")
293 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700294}
295
296func TestBadRE(t *testing.T) {
297 _, err := Parse("One~(qs*")
298 if err == nil {
299 t.Errorf("Expected RE parse error, got none")
300 }
301}