glob/compiler_test.go

547 lines
12 KiB
Go
Raw Normal View History

2016-01-08 20:14:31 +03:00
package glob
import (
"github.com/gobwas/glob/match"
"reflect"
"testing"
)
2016-02-02 22:03:37 +03:00
var separators = []rune{'.'}
2016-01-08 20:14:31 +03:00
func TestGlueMatchers(t *testing.T) {
for id, test := range []struct {
in []match.Matcher
exp match.Matcher
}{
{
[]match.Matcher{
match.Super{},
match.Single{},
},
match.Min{1},
},
{
[]match.Matcher{
match.Any{separators},
match.Single{separators},
},
2016-01-12 14:06:59 +03:00
match.EveryOf{match.Matchers{
2016-01-08 20:14:31 +03:00
match.Min{1},
2016-02-02 22:03:37 +03:00
match.Contains{string(separators), true},
2016-01-08 20:14:31 +03:00
}},
},
{
[]match.Matcher{
match.Single{},
match.Single{},
match.Single{},
},
2016-01-12 14:06:59 +03:00
match.EveryOf{match.Matchers{
2016-01-08 20:14:31 +03:00
match.Min{3},
match.Max{3},
}},
},
{
[]match.Matcher{
2016-02-02 22:03:37 +03:00
match.List{[]rune{'a'}, true},
match.Any{[]rune{'a'}},
2016-01-08 20:14:31 +03:00
},
2016-01-12 14:06:59 +03:00
match.EveryOf{match.Matchers{
2016-01-08 20:14:31 +03:00
match.Min{1},
match.Contains{"a", true},
}},
},
} {
2016-01-09 02:34:41 +03:00
act, err := compileMatchers(test.in)
2016-01-08 20:14:31 +03:00
if err != nil {
t.Errorf("#%d convert matchers error: %s", id, err)
continue
}
if !reflect.DeepEqual(act, test.exp) {
t.Errorf("#%d unexpected convert matchers result:\nact: %s;\nexp: %s", id, act, test.exp)
continue
}
}
}
2016-01-09 02:34:41 +03:00
func TestCompileMatchers(t *testing.T) {
2016-01-08 20:14:31 +03:00
for id, test := range []struct {
in []match.Matcher
exp match.Matcher
}{
{
[]match.Matcher{
match.Super{},
match.Single{separators},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-08 20:14:31 +03:00
},
2016-01-14 18:29:13 +03:00
match.NewBTree(
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-14 18:29:13 +03:00
match.NewBTree(
match.Single{separators},
match.Super{},
nil,
),
nil,
),
2016-01-08 20:14:31 +03:00
},
{
[]match.Matcher{
match.Any{},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-08 20:14:31 +03:00
match.Any{},
},
2016-01-14 18:29:13 +03:00
match.NewBTree(
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-14 18:29:13 +03:00
match.Any{},
match.Any{},
),
2016-01-08 20:14:31 +03:00
},
2016-01-09 02:34:41 +03:00
{
[]match.Matcher{
match.Range{'a', 'c', true},
2016-02-02 22:03:37 +03:00
match.List{[]rune{'z', 't', 'e'}, false},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-09 02:34:41 +03:00
match.Single{},
},
2016-01-14 18:29:13 +03:00
match.Row{
Matchers: match.Matchers{
match.Range{'a', 'c', true},
2016-02-02 22:03:37 +03:00
match.List{[]rune{'z', 't', 'e'}, false},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-14 18:29:13 +03:00
match.Single{},
},
2016-01-14 21:32:02 +03:00
RunesLength: 4,
2016-01-14 18:29:13 +03:00
},
2016-01-09 02:34:41 +03:00
},
2016-01-08 20:14:31 +03:00
} {
2016-01-09 02:34:41 +03:00
act, err := compileMatchers(test.in)
2016-01-08 20:14:31 +03:00
if err != nil {
t.Errorf("#%d convert matchers error: %s", id, err)
continue
}
if !reflect.DeepEqual(act, test.exp) {
t.Errorf("#%d unexpected convert matchers result:\nact: %s;\nexp: %s", id, act, test.exp)
continue
}
}
}
2016-01-11 10:17:19 +03:00
func TestConvertMatchers(t *testing.T) {
2016-01-09 02:34:41 +03:00
for id, test := range []struct {
in, exp []match.Matcher
}{
{
[]match.Matcher{
match.Range{'a', 'c', true},
2016-02-02 22:03:37 +03:00
match.List{[]rune{'z', 't', 'e'}, false},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-09 02:34:41 +03:00
match.Single{},
match.Any{},
},
[]match.Matcher{
2016-01-14 18:29:13 +03:00
match.Row{
Matchers: match.Matchers{
match.Range{'a', 'c', true},
2016-02-02 22:03:37 +03:00
match.List{[]rune{'z', 't', 'e'}, false},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-14 18:29:13 +03:00
match.Single{},
},
2016-01-14 21:32:02 +03:00
RunesLength: 4,
2016-01-14 18:29:13 +03:00
},
2016-01-09 02:34:41 +03:00
match.Any{},
},
},
{
[]match.Matcher{
match.Range{'a', 'c', true},
2016-02-02 22:03:37 +03:00
match.List{[]rune{'z', 't', 'e'}, false},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-09 02:34:41 +03:00
match.Single{},
match.Any{},
match.Single{},
match.Single{},
match.Any{},
},
[]match.Matcher{
2016-01-14 18:29:13 +03:00
match.Row{
Matchers: match.Matchers{
match.Range{'a', 'c', true},
2016-02-02 22:03:37 +03:00
match.List{[]rune{'z', 't', 'e'}, false},
2016-01-14 21:32:02 +03:00
match.NewText("c"),
2016-01-14 18:29:13 +03:00
},
2016-01-14 21:32:02 +03:00
RunesLength: 3,
2016-01-14 18:29:13 +03:00
},
2016-01-13 20:13:11 +03:00
match.Min{3},
2016-01-09 02:34:41 +03:00
},
},
} {
2016-01-14 18:29:13 +03:00
act := minimizeMatchers(test.in)
2016-01-09 02:34:41 +03:00
if !reflect.DeepEqual(act, test.exp) {
t.Errorf("#%d unexpected convert matchers 2 result:\nact: %s;\nexp: %s", id, act, test.exp)
continue
}
}
}
2016-01-08 20:14:31 +03:00
func pattern(nodes ...node) *nodePattern {
return &nodePattern{
nodeImpl: nodeImpl{
desc: nodes,
},
}
}
func anyOf(nodes ...node) *nodeAnyOf {
return &nodeAnyOf{
nodeImpl: nodeImpl{
desc: nodes,
},
}
}
func TestCompiler(t *testing.T) {
for id, test := range []struct {
ast *nodePattern
result Glob
2016-02-02 22:03:37 +03:00
sep []rune
2016-01-08 20:14:31 +03:00
}{
{
ast: pattern(&nodeText{text: "abc"}),
2016-01-14 21:32:02 +03:00
result: match.NewText("abc"),
2016-01-08 20:14:31 +03:00
},
{
ast: pattern(&nodeAny{}),
sep: separators,
result: match.Any{separators},
},
{
ast: pattern(&nodeAny{}),
result: match.Super{},
},
{
ast: pattern(&nodeSuper{}),
result: match.Super{},
},
{
ast: pattern(&nodeSingle{}),
sep: separators,
result: match.Single{separators},
},
{
ast: pattern(&nodeRange{
lo: 'a',
hi: 'z',
not: true,
}),
result: match.Range{'a', 'z', true},
},
{
ast: pattern(&nodeList{
chars: "abc",
not: true,
}),
2016-02-02 22:03:37 +03:00
result: match.List{[]rune{'a', 'b', 'c'}, true},
2016-01-08 20:14:31 +03:00
},
{
ast: pattern(&nodeAny{}, &nodeSingle{}, &nodeSingle{}, &nodeSingle{}),
sep: separators,
2016-01-12 14:06:59 +03:00
result: match.EveryOf{Matchers: match.Matchers{
2016-01-08 20:14:31 +03:00
match.Min{3},
2016-02-02 22:03:37 +03:00
match.Contains{string(separators), true},
2016-01-08 20:14:31 +03:00
}},
},
{
ast: pattern(&nodeAny{}, &nodeSingle{}, &nodeSingle{}, &nodeSingle{}),
result: match.Min{3},
},
{
ast: pattern(&nodeAny{}, &nodeText{text: "abc"}, &nodeSingle{}),
sep: separators,
2016-01-14 18:29:13 +03:00
result: match.NewBTree(
match.Row{
Matchers: match.Matchers{
2016-01-14 21:32:02 +03:00
match.NewText("abc"),
2016-01-14 18:29:13 +03:00
match.Single{separators},
},
2016-01-14 21:32:02 +03:00
RunesLength: 4,
2016-01-14 18:29:13 +03:00
},
match.Any{separators},
nil,
),
2016-01-08 20:14:31 +03:00
},
{
ast: pattern(&nodeSuper{}, &nodeSingle{}, &nodeText{text: "abc"}, &nodeSingle{}),
sep: separators,
2016-01-14 18:29:13 +03:00
result: match.NewBTree(
match.Row{
Matchers: match.Matchers{
match.Single{separators},
2016-01-14 21:32:02 +03:00
match.NewText("abc"),
2016-01-14 18:29:13 +03:00
match.Single{separators},
},
2016-01-14 21:32:02 +03:00
RunesLength: 5,
2016-01-14 18:29:13 +03:00
},
match.Super{},
nil,
),
2016-01-08 20:14:31 +03:00
},
{
ast: pattern(&nodeAny{}, &nodeText{text: "abc"}),
result: match.Suffix{"abc"},
},
{
ast: pattern(&nodeText{text: "abc"}, &nodeAny{}),
result: match.Prefix{"abc"},
},
{
2016-01-12 14:13:56 +03:00
ast: pattern(&nodeText{text: "abc"}, &nodeAny{}, &nodeText{text: "def"}),
2016-01-12 14:06:59 +03:00
result: match.PrefixSuffix{"abc", "def"},
2016-01-08 20:14:31 +03:00
},
{
ast: pattern(&nodeAny{}, &nodeAny{}, &nodeAny{}, &nodeText{text: "abc"}, &nodeAny{}, &nodeAny{}),
result: match.Contains{"abc", false},
},
{
2016-01-14 18:29:13 +03:00
ast: pattern(&nodeAny{}, &nodeAny{}, &nodeAny{}, &nodeText{text: "abc"}, &nodeAny{}, &nodeAny{}),
sep: separators,
result: match.NewBTree(
2016-01-14 21:32:02 +03:00
match.NewText("abc"),
2016-01-14 18:29:13 +03:00
match.Any{separators},
match.Any{separators},
),
2016-01-08 20:14:31 +03:00
},
{
ast: pattern(&nodeSuper{}, &nodeSingle{}, &nodeText{text: "abc"}, &nodeSuper{}, &nodeSingle{}),
2016-01-14 18:29:13 +03:00
result: match.NewBTree(
2016-01-14 21:32:02 +03:00
match.NewText("abc"),
2016-01-14 18:29:13 +03:00
match.Min{1},
match.Min{1},
),
2016-01-08 20:14:31 +03:00
},
{
2016-01-15 19:50:12 +03:00
ast: pattern(anyOf(&nodeText{text: "abc"})),
result: match.NewText("abc"),
2016-01-08 20:14:31 +03:00
},
{
2016-01-15 19:50:12 +03:00
ast: pattern(anyOf(pattern(anyOf(pattern(&nodeText{text: "abc"}))))),
result: match.NewText("abc"),
},
{
ast: pattern(anyOf(
pattern(
&nodeText{text: "abc"},
&nodeSingle{},
),
pattern(
&nodeText{text: "abc"},
&nodeList{chars: "def"},
),
pattern(
&nodeText{text: "abc"},
),
pattern(
&nodeText{text: "abc"},
),
)),
result: match.NewBTree(
match.NewText("abc"),
nil,
match.AnyOf{Matchers: match.Matchers{
match.Single{},
2016-02-02 22:03:37 +03:00
match.List{List: []rune{'d', 'e', 'f'}},
2016-01-15 19:50:12 +03:00
match.Nothing{},
2016-01-08 20:14:31 +03:00
}},
2016-01-15 19:50:12 +03:00
),
2016-01-08 20:14:31 +03:00
},
2016-01-09 02:34:41 +03:00
{
ast: pattern(
&nodeRange{lo: 'a', hi: 'z'},
&nodeRange{lo: 'a', hi: 'x', not: true},
&nodeAny{},
),
2016-01-14 18:29:13 +03:00
result: match.NewBTree(
match.Row{
Matchers: match.Matchers{
match.Range{Lo: 'a', Hi: 'z'},
match.Range{Lo: 'a', Hi: 'x', Not: true},
},
2016-01-14 21:32:02 +03:00
RunesLength: 2,
2016-01-14 18:29:13 +03:00
},
nil,
match.Super{},
),
2016-01-09 02:34:41 +03:00
},
2016-01-15 19:50:12 +03:00
{
ast: pattern(anyOf(
pattern(
&nodeText{text: "abc"},
&nodeList{chars: "abc"},
&nodeText{text: "ghi"},
),
pattern(
&nodeText{text: "abc"},
&nodeList{chars: "def"},
&nodeText{text: "ghi"},
),
)),
result: match.Row{
RunesLength: 7,
Matchers: match.Matchers{
match.NewText("abc"),
match.AnyOf{Matchers: match.Matchers{
2016-02-02 22:03:37 +03:00
match.List{List: []rune{'a', 'b', 'c'}},
match.List{List: []rune{'d', 'e', 'f'}},
2016-01-15 19:50:12 +03:00
}},
match.NewText("ghi"),
},
},
},
// {
2016-01-11 10:17:19 +03:00
// ast: pattern(
// anyOf(&nodeText{text: "a"}, &nodeText{text: "b"}),
// anyOf(&nodeText{text: "c"}, &nodeText{text: "d"}),
// ),
// result: match.AnyOf{Matchers: match.Matchers{
2016-01-14 18:29:13 +03:00
// match.Row{Matchers: match.Matchers{match.Raw{"a"}, match.Raw{"c", 1}}},
2016-01-11 10:17:19 +03:00
// match.Row{Matchers: match.Matchers{match.Raw{"a"}, match.Raw{"d"}}},
2016-01-14 18:29:13 +03:00
// match.Row{Matchers: match.Matchers{match.Raw{"b"}, match.Raw{"c", 1}}},
2016-01-11 10:17:19 +03:00
// match.Row{Matchers: match.Matchers{match.Raw{"b"}, match.Raw{"d"}}},
// }},
// },
2016-01-08 20:14:31 +03:00
} {
prog, err := compile(test.ast, test.sep)
if err != nil {
t.Errorf("compilation error: %s", err)
continue
}
if !reflect.DeepEqual(prog, test.result) {
t.Errorf("#%d results are not equal:\nexp: %s,\nact: %s", id, test.result, prog)
continue
}
}
}
2016-01-15 19:50:12 +03:00
const complexityString = "abcd"
//func BenchmarkComplexityAny(b *testing.B) {
// m := match.Any{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityContains(b *testing.B) {
// m := match.Contains{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityList(b *testing.B) {
// m := match.List{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityMax(b *testing.B) {
// m := match.Max{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityMin(b *testing.B) {
// m := match.Min{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityNothing(b *testing.B) {
// m := match.Nothing{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityPrefix(b *testing.B) {
// m := match.Prefix{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityPrefixSuffix(b *testing.B) {
// m := match.PrefixSuffix{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityRange(b *testing.B) {
// m := match.Range{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityRow(b *testing.B) {
// m := match.Row{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexitySingle(b *testing.B) {
// m := match.Single{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexitySuffix(b *testing.B) {
// m := match.Suffix{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexitySuper(b *testing.B) {
// m := match.Super{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityText(b *testing.B) {
// m := match.Text{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityAnyOf(b *testing.B) {
// m := match.AnyOf{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityBTree(b *testing.B) {
// m := match.NewBTree(match.NewText("abc"), match.NewText("d"), match.NewText("e"))
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}
//func BenchmarkComplexityEveryOf(b *testing.B) {
// m := match.EveryOf{}
// for i := 0; i < b.N; i++ {
// _ = m.Match(complexityString)
// _, _ = m.Index(complexityString)
// }
//}