// Copyright (C) 2017 Marius Schellenberger package filter import "testing" type Example struct { String string Int int Bool bool Struct Struct1 } type Struct1 struct { String string Struct Struct2 } type Struct2 struct { Int int } type filter []Example func makefilter(v filter) (f filter) { f = make(filter, len(v)) copy(f, v) return } func (v filter) Len() int { return len(v) } func (v filter) Index(i int) interface{} { return v[i] } func (v *filter) Remove(i, j int) { *v = append((*v)[:i], (*v)[j:]...) } var ( data = filter{ {"str1", 42, true, Struct1{"s1", Struct2{1}}}, {"2str", 42, true, Struct1{"s2", Struct2{2}}}, {"str3", 42, false, Struct1{"s3", Struct2{3}}}, } benchData = filter{ {"str1", 41, true, Struct1{"s1", Struct2{1}}}, {"2str", 42, true, Struct1{"s2", Struct2{1}}}, {"str3", 43, false, Struct1{"s3", Struct2{1}}}, {"str4", 44, false, Struct1{"s4", Struct2{1}}}, {"str5", 45, false, Struct1{"s5", Struct2{1}}}, {"str6", 46, false, Struct1{"s6", Struct2{1}}}, {"str7", 47, true, Struct1{"s7", Struct2{1}}}, {"str8", 48, true, Struct1{"s8", Struct2{1}}}, {"str9", 49, true, Struct1{"s9", Struct2{1}}}, {"str10", 50, true, Struct1{"s10", Struct2{1}}}, {"str11", 51, false, Struct1{"s11", Struct2{1}}}, {"str12", 52, false, Struct1{"s12", Struct2{1}}}, } ) func TestNewQuery(t *testing.T) { _, err := NewQuery("String:1 String:2", AND) if err == nil { t.Error("multiple AND fields") } _, err = NewQuery("String:1 sdcs Int:1", AND) if err == nil { t.Error("invalid match") } } const ( filter1 = "String:*st* Bool:true" filter2 = "Struct.Struct.Int:2 Struct.Struct.Int:3" ) func TestFilter(t *testing.T) { f1 := makefilter(data) q1, err := NewQuery(filter1, AND) if err != nil { t.Error(err) } q1.Filter(&f1) if len(f1) != 2 { t.Error("f1 len is:", len(f1)) } if f1[0] != data[0] { t.Error("f1[0] != data[0]") } if f1[1] != data[1] { t.Error("f1[1] != data[1]") } f2 := makefilter(data) q2, err := NewQuery(filter2, OR) if err != nil { t.Error(err) } q2.Filter(&f2) if len(f2) != 2 { t.Error("f2 len is:", len(f2)) } if f2[0] != data[1] { t.Error("f2[0] != data[1]") } if f2[1] != data[2] { t.Error("f2[1] != data[2]") } f3 := makefilter(data) q3, err := NewQuery(filter2, NOT) if err != nil { t.Error(err) } q3.Filter(&f3) if len(f3) != 1 { t.Error("f3 len is:", len(f3)) } if f3[0] != data[0] { t.Error("f3[0] != data[0]") } } func TestGenericFilter(t *testing.T) { q1, err := NewQuery(filter1, AND) if err != nil { t.Error(err) } a1 := q1.GenericFilter(data) if a1 == nil { t.Error("a1 is nil") } f1 := a1.(filter) if len(f1) != 2 { t.Error("f1 len is:", len(f1)) } if f1[0] != data[0] { t.Error("f1[0] != data[0]") } if f1[1] != data[1] { t.Error("f1[1] != data[1]") } q2, err := NewQuery(filter2, OR) if err != nil { t.Error(err) } a2 := q2.GenericFilter(data) if a2 == nil { t.Error("a2 is nil") } f2 := a2.(filter) if len(f2) != 2 { t.Error("f2 len is:", len(f2)) } if f2[0] != data[1] { t.Error("f2[0] != data[1]") } if f2[1] != data[2] { t.Error("f2[1] != data[2]") } q3, err := NewQuery(filter2, NOT) if err != nil { t.Error(err) } a3 := q3.GenericFilter(data) if a3 == nil { t.Error("a3 is nil") } f3 := a3.(filter) if len(f3) != 1 { t.Error("f3 len is:", len(f3)) } if f3[0] != data[0] { t.Error("f3[0] != data[0]") } } const ( simple = "Bool:true" comp = "String:*st* Bool:false Struct.Struct.Int:1" compOr = "Int:47 Bool:false Struct.String:s1*" ) func BenchmarkNewQuerySimple(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { NewQuery(simple, OR) } } func BenchmarkNewQueryComplex(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { NewQuery(comp, AND) } } func BenchmarkNewQueryComplexOr(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { NewQuery(compOr, OR) } } func BenchmarkFilterSimple(b *testing.B) { b.ReportAllocs() q, err := NewQuery(simple, OR) if err != nil { b.Error(err) } fd := makefilter(benchData) for i := 0; i < b.N; i++ { q.Filter(&fd) } } func BenchmarkFilterComplex(b *testing.B) { b.ReportAllocs() q, err := NewQuery(comp, AND) if err != nil { b.Error(err) } fd := makefilter(benchData) for i := 0; i < b.N; i++ { q.Filter(&fd) } } func BenchmarkFilterComplexOr(b *testing.B) { b.ReportAllocs() q, err := NewQuery(compOr, OR) if err != nil { b.Error(err) } fd := makefilter(benchData) for i := 0; i < b.N; i++ { q.Filter(&fd) } } func BenchmarkGenericFilterSimple(b *testing.B) { b.ReportAllocs() q, err := NewQuery(simple, OR) if err != nil { b.Error(err) } for i := 0; i < b.N; i++ { q.GenericFilter(benchData) } } func BenchmarkGenericFilterComplex(b *testing.B) { b.ReportAllocs() q, err := NewQuery(comp, AND) if err != nil { b.Error(err) } for i := 0; i < b.N; i++ { q.GenericFilter(benchData) } } func BenchmarkGenericFilterComplexOr(b *testing.B) { b.ReportAllocs() q, err := NewQuery(compOr, OR) if err != nil { b.Error(err) } for i := 0; i < b.N; i++ { q.GenericFilter(benchData) } }