mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 02:44:59 +00:00
234 lines
4.2 KiB
Go
234 lines
4.2 KiB
Go
// Copyright 2022 Molecula Corp. (DBA FeatureBase).
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
package pilosa
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestPlanLike(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
like string
|
|
plan []filterStep
|
|
match, nonmatch []string
|
|
}{
|
|
{
|
|
name: "Empty",
|
|
like: "",
|
|
plan: []filterStep{},
|
|
match: []string{""},
|
|
nonmatch: []string{"a", " "},
|
|
},
|
|
{
|
|
name: "Exact",
|
|
like: "x",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("x"),
|
|
},
|
|
},
|
|
match: []string{"x"},
|
|
nonmatch: []string{"", "y", "z", "xy", "yx"},
|
|
},
|
|
{
|
|
name: "Anything",
|
|
like: "%",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepMinLength,
|
|
n: 0,
|
|
},
|
|
},
|
|
match: []string{"", "a", "b", "ab"},
|
|
},
|
|
{
|
|
name: "Prefix",
|
|
like: "x%",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("x"),
|
|
},
|
|
{
|
|
kind: filterStepMinLength,
|
|
n: 0,
|
|
},
|
|
},
|
|
match: []string{"xy", "xyz", "xyzzy"},
|
|
nonmatch: []string{"plugh", "yx", ""},
|
|
},
|
|
{
|
|
name: "Suffix",
|
|
like: "%x",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepSuffix,
|
|
str: []byte("x"),
|
|
},
|
|
},
|
|
match: []string{"x", "xx", "ax"},
|
|
nonmatch: []string{"", "a", "x^"},
|
|
},
|
|
{
|
|
name: "Sandwich",
|
|
like: "x%y",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("x"),
|
|
},
|
|
{
|
|
kind: filterStepSuffix,
|
|
str: []byte("y"),
|
|
},
|
|
},
|
|
match: []string{"xy", "xzy", "xyzzy"},
|
|
nonmatch: []string{"plugh", ".xy.", ".x.y", "x.y."},
|
|
},
|
|
{
|
|
name: "DoubleDeckerSandwich",
|
|
like: "x%y%z",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("x"),
|
|
},
|
|
{
|
|
kind: filterStepSkipThrough,
|
|
str: []byte("y"),
|
|
},
|
|
{
|
|
kind: filterStepSuffix,
|
|
str: []byte("z"),
|
|
},
|
|
},
|
|
match: []string{"xyz", "xzyzz", "x.y.z", "x.y.y..z"},
|
|
nonmatch: []string{"plugh", ".xyz.", ".x.y.z", "x.y.z."},
|
|
},
|
|
{
|
|
name: "Skips",
|
|
like: "a_b_%_c_%_%_d",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("a"),
|
|
},
|
|
{
|
|
kind: filterStepSkipN,
|
|
n: 1,
|
|
},
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("b"),
|
|
},
|
|
{
|
|
kind: filterStepSkipThrough,
|
|
str: []byte("c"),
|
|
n: 2,
|
|
},
|
|
{
|
|
kind: filterStepSuffix,
|
|
str: []byte("d"),
|
|
n: 3,
|
|
},
|
|
},
|
|
match: []string{"a1b234c5678d"},
|
|
nonmatch: []string{"abcd", "a1b2345678d", "a1b2c5678d"},
|
|
},
|
|
{
|
|
name: "SingleRune",
|
|
like: "_",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepSkipN,
|
|
n: 1,
|
|
},
|
|
},
|
|
match: []string{"a", "á", "☺"},
|
|
nonmatch: []string{"ab", "á", "h̷", ""},
|
|
},
|
|
{
|
|
name: "DoubleRune",
|
|
like: "__",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepSkipN,
|
|
n: 2,
|
|
},
|
|
},
|
|
match: []string{"ab", "á", "h̷"},
|
|
nonmatch: []string{"a", "á", "☺", "abc"},
|
|
},
|
|
{
|
|
name: "MiddleBlank",
|
|
like: "x_y",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("x"),
|
|
},
|
|
{
|
|
kind: filterStepSkipN,
|
|
n: 1,
|
|
},
|
|
{
|
|
kind: filterStepPrefix,
|
|
str: []byte("y"),
|
|
},
|
|
},
|
|
match: []string{"x.y", "xay", "x y", "x⊕y"},
|
|
nonmatch: []string{"x++y", "", "a"},
|
|
},
|
|
{
|
|
name: "MinLength",
|
|
like: "_%_",
|
|
plan: []filterStep{
|
|
{
|
|
kind: filterStepMinLength,
|
|
n: 2,
|
|
},
|
|
},
|
|
match: []string{"ab", "á", "abc", "pilosa"},
|
|
nonmatch: []string{"h", "á", ".", "☺"},
|
|
},
|
|
}
|
|
t.Run("Plan", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, c := range cases {
|
|
c := c
|
|
t.Run(c.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
plan := planLike(c.like)
|
|
if !reflect.DeepEqual(plan, c.plan) {
|
|
t.Errorf("incorrect plan: %v", plan)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
t.Run("Match", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, c := range cases {
|
|
c := c
|
|
t.Run(c.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, m := range c.match {
|
|
if !matchLike([]byte(m), c.plan...) {
|
|
t.Errorf("key %q was not matched", m)
|
|
}
|
|
}
|
|
for _, nm := range c.nonmatch {
|
|
if matchLike([]byte(nm), c.plan...) {
|
|
t.Errorf("key %q was matched", nm)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|