filter/filter_test.go
2018-01-17 23:08:10 +01:00

437 lines
8.1 KiB
Go

// Copyright (C) 2018 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")
if err == nil {
t.Error("multiple AND fields")
}
_, err = NewQuery("String:1 sdcs Int:1")
if err == nil {
t.Error("invalid match")
}
_, err = NewQuery("String:1 sort:Bool:ASC")
if err == nil {
t.Error("invalid sort")
}
_, err = NewQuery(" ")
if err == nil {
t.Error("empty query")
}
_, err = NewQuery("OR")
if err == nil {
t.Error("empty query")
}
}
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("AND " + filter1)
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("OR " + filter2)
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("NOT " + filter2)
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]")
}
}
const (
sort1 = "sort:Int:desc"
sort2 = "sort:Int:desc Bool:true"
)
func TestSortFilter(t *testing.T) {
f1 := makefilter(benchData)
q1, err := NewQuery(sort1)
if err != nil {
t.Error(err)
}
q1.Filter(&f1)
if len(f1) != 12 {
t.Error("f1 len is:", len(f1))
}
if f1[0] != benchData[11] {
t.Error("f1[0] != benchData[11]")
}
if f1[11] != benchData[0] {
t.Error("f1[11] != benchData[0]")
}
f2 := makefilter(benchData)
q2, err := NewQuery("OR " + sort2)
if err != nil {
t.Error(err)
}
q2.Filter(&f2)
if len(f2) != 6 {
t.Error("f2 len is:", len(f2))
}
if f2[0] != benchData[9] {
t.Error("f2[0] != benchData[9]")
}
if f2[5] != benchData[0] {
t.Error("f2[5] != benchData[0]")
}
f3 := makefilter(benchData)
q3, err := NewQuery("NOT " + sort2)
if err != nil {
t.Error(err)
}
q3.Filter(&f3)
if len(f3) != 6 {
t.Error("f3 len is:", len(f3))
}
if f3[0] != benchData[11] {
t.Error("f3[0] != benchData[11]")
}
if f3[5] != benchData[2] {
t.Error("f3[5] != benchData[2]")
}
}
func TestGenericFilter(t *testing.T) {
q1, err := NewQuery(filter1)
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("OR " + filter2)
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("NOT " + filter2)
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 = "OR Bool:true"
comp = "String:*st* Bool:false Struct.Struct.Int:1"
compOr = "OR Int:47 Bool:false Struct.String:s1*"
sortOnly = "OR sort:Int:desc"
simpleSort = "OR sort:Int:desc Bool:true"
compSort = "sort:Int:desc String:*st* Bool:false Struct.Struct.Int:1"
compOrSort = "OR sort:Int:desc Int:47 Bool:false Struct.String:s1*"
)
func BenchmarkNewQuerySimple(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewQuery(simple)
}
}
func BenchmarkNewQueryComplex(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewQuery(comp)
}
}
func BenchmarkNewQueryComplexOr(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewQuery(compOr)
}
}
func BenchmarkNewQueryCacheComplexOr(b *testing.B) {
c := NewQueryCache(1)
b.ReportAllocs()
for i := 0; i < b.N; i++ {
c.NewQuery(compOr)
}
}
func BenchmarkNewQuerySort(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewQuery(sortOnly)
}
}
func BenchmarkNewQuerySortSimple(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewQuery(simpleSort)
}
}
func BenchmarkNewQuerySortComplex(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewQuery(compSort)
}
}
func BenchmarkNewQuerySortComplexOr(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
NewQuery(compOrSort)
}
}
func BenchmarkNewQueryCacheSortComplexOr(b *testing.B) {
c := NewQueryCache(1)
b.ReportAllocs()
for i := 0; i < b.N; i++ {
c.NewQuery(compOrSort)
}
}
func BenchmarkFilterSimple(b *testing.B) {
b.ReportAllocs()
q, err := NewQuery(simple)
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)
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)
if err != nil {
b.Error(err)
}
fd := makefilter(benchData)
for i := 0; i < b.N; i++ {
q.Filter(&fd)
}
}
func BenchmarkSort(b *testing.B) {
b.ReportAllocs()
q, err := NewQuery(sortOnly)
if err != nil {
b.Error(err)
}
fd := makefilter(benchData)
for i := 0; i < b.N; i++ {
q.Filter(&fd)
}
}
func BenchmarkSortFilterSimple(b *testing.B) {
b.ReportAllocs()
q, err := NewQuery(simpleSort)
if err != nil {
b.Error(err)
}
fd := makefilter(benchData)
for i := 0; i < b.N; i++ {
q.Filter(&fd)
}
}
func BenchmarkSortFilterComplex(b *testing.B) {
b.ReportAllocs()
q, err := NewQuery(compSort)
if err != nil {
b.Error(err)
}
fd := makefilter(benchData)
for i := 0; i < b.N; i++ {
q.Filter(&fd)
}
}
func BenchmarkSortFilterComplexOr(b *testing.B) {
b.ReportAllocs()
q, err := NewQuery(compOrSort)
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)
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)
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)
if err != nil {
b.Error(err)
}
for i := 0; i < b.N; i++ {
q.GenericFilter(benchData)
}
}