blob: 46b3c279a47732d557d14407bd1110f35f7791b2 [file] [log] [blame]
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package filter
import (
"reflect"
"testing"
)
func TestFilterToString(t *testing.T) {
t.Parallel()
for _, tc := range []struct {
f *F
want string
}{
{Regexp("field1", "abc"), `field1 eq abc`},
{NotRegexp("field1", "abc"), `field1 ne abc`},
{EqualInt("field1", 13), "field1 eq 13"},
{NotEqualInt("field1", 13), "field1 ne 13"},
{EqualBool("field1", true), "field1 eq true"},
{NotEqualBool("field1", true), "field1 ne true"},
{Regexp("field1", "abc").AndRegexp("field2", "def"), `(field1 eq abc) (field2 eq def)`},
{Regexp("field1", "abc").AndNotEqualInt("field2", 17), `(field1 eq abc) (field2 ne 17)`},
{Regexp("field1", "abc").And(EqualInt("field2", 17)), `(field1 eq abc) (field2 eq 17)`},
} {
if tc.f.String() != tc.want {
t.Errorf("filter %#v String() = %q, want %q", tc.f, tc.f.String(), tc.want)
}
}
}
func TestFilterMatch(t *testing.T) {
t.Parallel()
type inner struct {
X string
}
type S struct {
S string
I int
B bool
Unhandled struct{}
NestedField *inner
}
for _, tc := range []struct {
f *F
o interface{}
want bool
}{
{f: None, o: &S{}, want: true},
{f: Regexp("s", "abc"), o: &S{}},
{f: EqualInt("i", 10), o: &S{}},
{f: EqualBool("b", true), o: &S{}},
{f: NotRegexp("s", "abc"), o: &S{}, want: true},
{f: NotEqualInt("i", 10), o: &S{}, want: true},
{f: NotEqualBool("b", true), o: &S{}, want: true},
{f: Regexp("s", "abc").AndEqualBool("b", true), o: &S{}},
{f: Regexp("s", "abc"), o: &S{S: "abc"}, want: true},
{f: Regexp("s", "a.*"), o: &S{S: "abc"}, want: true},
{f: Regexp("s", "a((("), o: &S{S: "abc"}},
{f: NotRegexp("s", "abc"), o: &S{S: "abc"}},
{f: EqualInt("i", 10), o: &S{I: 11}},
{f: EqualInt("i", 10), o: &S{I: 10}, want: true},
{f: Regexp("s", "abc").AndEqualBool("b", true), o: &S{S: "abc"}},
{f: Regexp("s", "abcd").AndEqualBool("b", true), o: &S{S: "abc"}},
{f: Regexp("s", "abc").AndEqualBool("b", true), o: &S{S: "abc", B: true}, want: true},
{f: Regexp("s", "abc").And(EqualBool("b", true)), o: &S{S: "abc", B: true}, want: true},
{f: Regexp("unhandled", "xyz"), o: &S{}},
{f: Regexp("nested_field.x", "xyz"), o: &S{}},
{f: Regexp("nested_field.x", "xyz"), o: &S{NestedField: &inner{"xyz"}}, want: true},
{f: NotRegexp("nested_field.x", "xyz"), o: &S{NestedField: &inner{"xyz"}}},
{f: Regexp("nested_field.y", "xyz"), o: &S{NestedField: &inner{"xyz"}}},
{f: Regexp("nested_field", "xyz"), o: &S{NestedField: &inner{"xyz"}}},
} {
got := tc.f.Match(tc.o)
if got != tc.want {
t.Errorf("%v: Match(%+v) = %v, want %v", tc.f, tc.o, got, tc.want)
}
}
}
func TestFilterSnakeToCamelCase(t *testing.T) {
t.Parallel()
for _, tc := range []struct {
s string
want string
}{
{"", ""},
{"abc", "Abc"},
{"_foo", "Foo"},
{"a_b_c", "ABC"},
{"a_BC_def", "ABCDef"},
{"a_Bc_def", "ABcDef"},
} {
got := snakeToCamelCase(tc.s)
if got != tc.want {
t.Errorf("snakeToCamelCase(%q) = %q, want %q", tc.s, got, tc.want)
}
}
}
func TestFilterExtractValue(t *testing.T) {
t.Parallel()
type nest2 struct {
Y string
}
type nest struct {
X string
Nest2 nest2
}
st := &struct {
S string
I int
F bool
Nest nest
NestPtr *nest
Unhandled float64
}{
"abc",
13,
true,
nest{"xyz", nest2{"zzz"}},
&nest{"yyy", nest2{}},
0.0,
}
for _, tc := range []struct {
path string
o interface{}
want interface{}
wantErr bool
}{
{path: "s", o: st, want: "abc"},
{path: "i", o: st, want: 13},
{path: "f", o: st, want: true},
{path: "nest.x", o: st, want: "xyz"},
{path: "nest_ptr.x", o: st, want: "yyy"},
// Error cases.
{path: "", o: st, wantErr: true},
{path: "no_such_field", o: st, wantErr: true},
{path: "s.invalid_type", o: st, wantErr: true},
{path: "unhandled", o: st, wantErr: true},
{path: "nest.x", o: &struct{ Nest *nest }{}, wantErr: true},
} {
o, err := extractValue(tc.path, tc.o)
gotErr := err != nil
if gotErr != tc.wantErr {
t.Errorf("extractValue(%v, %+v) = %v, %v; gotErr = %v, tc.wantErr = %v", tc.path, tc.o, o, err, gotErr, tc.wantErr)
}
if err != nil {
continue
}
if !reflect.DeepEqual(o, tc.want) {
t.Errorf("extractValue(%v, %+v) = %v, nil; want %v, nil", tc.path, tc.o, o, tc.want)
}
}
}