forked from mirror/glob
wip
This commit is contained in:
parent
2b9d056d0d
commit
abc7140723
|
@ -5,190 +5,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gobwas/glob/match"
|
"github.com/gobwas/glob/match"
|
||||||
"github.com/gobwas/glob/match/debug"
|
|
||||||
"github.com/gobwas/glob/syntax/ast"
|
"github.com/gobwas/glob/syntax/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
var separators = []rune{'.'}
|
var separators = []rune{'.'}
|
||||||
|
|
||||||
func TestGlueMatchers(t *testing.T) {
|
|
||||||
for id, test := range []struct {
|
|
||||||
in []match.Matcher
|
|
||||||
exp match.Matcher
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewSuper(),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
},
|
|
||||||
match.NewMin(1),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewAny(separators),
|
|
||||||
match.NewSingle(separators),
|
|
||||||
},
|
|
||||||
match.EveryOf{match.Matchers{
|
|
||||||
match.NewMin(1),
|
|
||||||
match.NewContains(string(separators), true),
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewSingle(nil),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
},
|
|
||||||
match.EveryOf{match.Matchers{
|
|
||||||
match.NewMin(3),
|
|
||||||
match.NewMax(3),
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewList([]rune{'a'}, true),
|
|
||||||
match.NewAny([]rune{'a'}),
|
|
||||||
},
|
|
||||||
match.EveryOf{match.Matchers{
|
|
||||||
match.NewMin(1),
|
|
||||||
match.NewContains("a", true),
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
act, err := compileMatchers(test.in)
|
|
||||||
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: %#v;\nexp: %#v", id, act, test.exp)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompileMatchers(t *testing.T) {
|
|
||||||
for id, test := range []struct {
|
|
||||||
in []match.Matcher
|
|
||||||
exp match.Matcher
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewSuper(),
|
|
||||||
match.NewSingle(separators),
|
|
||||||
match.NewText("c"),
|
|
||||||
},
|
|
||||||
match.NewBTree(
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewBTree(
|
|
||||||
match.NewSingle(separators),
|
|
||||||
match.NewSuper(),
|
|
||||||
nil,
|
|
||||||
),
|
|
||||||
nil,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewAny(nil),
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewAny(nil),
|
|
||||||
},
|
|
||||||
match.NewBTree(
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewAny(nil),
|
|
||||||
match.NewAny(nil),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewRange('a', 'c', true),
|
|
||||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
},
|
|
||||||
match.NewRow(
|
|
||||||
4,
|
|
||||||
match.Matchers{
|
|
||||||
match.NewRange('a', 'c', true),
|
|
||||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
}...,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
act, err := compileMatchers(test.in)
|
|
||||||
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: %#v\nexp: %#v", id, act, test.exp)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConvertMatchers(t *testing.T) {
|
|
||||||
for id, test := range []struct {
|
|
||||||
in, exp []match.Matcher
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewRange('a', 'c', true),
|
|
||||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
match.NewAny(nil),
|
|
||||||
},
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewRow(
|
|
||||||
4,
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewRange('a', 'c', true),
|
|
||||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
}...,
|
|
||||||
),
|
|
||||||
match.NewAny(nil),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewRange('a', 'c', true),
|
|
||||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
|
||||||
match.NewText("c"),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
match.NewAny(nil),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
match.NewSingle(nil),
|
|
||||||
match.NewAny(nil),
|
|
||||||
},
|
|
||||||
[]match.Matcher{
|
|
||||||
match.NewRow(
|
|
||||||
3,
|
|
||||||
match.Matchers{
|
|
||||||
match.NewRange('a', 'c', true),
|
|
||||||
match.NewList([]rune{'z', 't', 'e'}, false),
|
|
||||||
match.NewText("c"),
|
|
||||||
}...,
|
|
||||||
),
|
|
||||||
match.NewMin(3),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
act := minimizeMatchers(test.in)
|
|
||||||
if !reflect.DeepEqual(act, test.exp) {
|
|
||||||
t.Errorf("#%d unexpected convert matchers 2 result:\nact: %#v\nexp: %#v", id, act, test.exp)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompiler(t *testing.T) {
|
func TestCompiler(t *testing.T) {
|
||||||
for id, test := range []struct {
|
for id, test := range []struct {
|
||||||
ast *ast.Node
|
ast *ast.Node
|
||||||
|
@ -254,10 +75,10 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
),
|
),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.EveryOf{Matchers: match.Matchers{
|
result: match.NewEveryOf([]match.Matcher{
|
||||||
match.NewMin(3),
|
match.NewMin(3),
|
||||||
match.NewContains(string(separators), true),
|
match.NewAny(separators),
|
||||||
}},
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
|
@ -275,14 +96,11 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
),
|
),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.NewBTree(
|
result: match.NewTree(
|
||||||
match.NewRow(
|
match.NewRow([]match.MatchIndexSizer{
|
||||||
4,
|
|
||||||
match.Matchers{
|
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.NewSingle(separators),
|
match.NewSingle(separators),
|
||||||
}...,
|
}),
|
||||||
),
|
|
||||||
match.NewAny(separators),
|
match.NewAny(separators),
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
@ -297,11 +115,14 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
),
|
),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.NewBTree(
|
result: match.NewTree(
|
||||||
match.NewText("/"),
|
match.NewText("/"),
|
||||||
nil,
|
nil,
|
||||||
match.NewBTree(
|
match.NewTree(
|
||||||
match.NewAnyOf(match.NewText("z"), match.NewText("ab")),
|
match.MustIndexedAnyOf(
|
||||||
|
match.NewText("z"),
|
||||||
|
match.NewText("ab"),
|
||||||
|
),
|
||||||
nil,
|
nil,
|
||||||
match.NewSuper(),
|
match.NewSuper(),
|
||||||
),
|
),
|
||||||
|
@ -315,15 +136,12 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
),
|
),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.NewBTree(
|
result: match.NewTree(
|
||||||
match.NewRow(
|
match.NewRow([]match.MatchIndexSizer{
|
||||||
5,
|
|
||||||
match.Matchers{
|
|
||||||
match.NewSingle(separators),
|
match.NewSingle(separators),
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.NewSingle(separators),
|
match.NewSingle(separators),
|
||||||
}...,
|
}),
|
||||||
),
|
|
||||||
match.NewSuper(),
|
match.NewSuper(),
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
@ -359,7 +177,7 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
),
|
),
|
||||||
result: match.NewContains("abc", false),
|
result: match.NewContains("abc"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
|
@ -371,13 +189,14 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
),
|
),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.NewBTree(
|
result: match.NewTree(
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.NewAny(separators),
|
match.NewAny(separators),
|
||||||
match.NewAny(separators),
|
match.NewAny(separators),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
// TODO: THIS!
|
||||||
ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
|
@ -385,7 +204,7 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
),
|
),
|
||||||
result: match.NewBTree(
|
result: match.NewTree(
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.NewMin(1),
|
match.NewMin(1),
|
||||||
match.NewMin(1),
|
match.NewMin(1),
|
||||||
|
@ -430,14 +249,14 @@ func TestCompiler(t *testing.T) {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
result: match.NewBTree(
|
result: match.NewTree(
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
nil,
|
nil,
|
||||||
match.AnyOf{Matchers: match.Matchers{
|
match.NewAnyOf(
|
||||||
match.NewSingle(nil),
|
match.NewSingle(nil),
|
||||||
match.NewList([]rune{'d', 'e', 'f'}, false),
|
match.NewList([]rune{'d', 'e', 'f'}, false),
|
||||||
match.NewNothing(),
|
match.NewNothing(),
|
||||||
}},
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -446,14 +265,11 @@ func TestCompiler(t *testing.T) {
|
||||||
ast.NewNode(ast.KindRange, ast.Range{Lo: 'a', Hi: 'x', Not: true}),
|
ast.NewNode(ast.KindRange, ast.Range{Lo: 'a', Hi: 'x', Not: true}),
|
||||||
ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
),
|
),
|
||||||
result: match.NewBTree(
|
result: match.NewTree(
|
||||||
match.NewRow(
|
match.NewRow([]match.MatchIndexSizer{
|
||||||
2,
|
|
||||||
match.Matchers{
|
|
||||||
match.NewRange('a', 'z', false),
|
match.NewRange('a', 'z', false),
|
||||||
match.NewRange('a', 'x', true),
|
match.NewRange('a', 'x', true),
|
||||||
}...,
|
}),
|
||||||
),
|
|
||||||
nil,
|
nil,
|
||||||
match.NewSuper(),
|
match.NewSuper(),
|
||||||
),
|
),
|
||||||
|
@ -473,17 +289,14 @@ func TestCompiler(t *testing.T) {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
result: match.NewRow(
|
result: match.NewRow([]match.MatchIndexSizer{
|
||||||
7,
|
|
||||||
match.Matchers{
|
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.AnyOf{Matchers: match.Matchers{
|
match.MustIndexedSizedAnyOf(
|
||||||
match.NewList([]rune{'a', 'b', 'c'}, false),
|
match.NewList([]rune{'a', 'b', 'c'}, false),
|
||||||
match.NewList([]rune{'d', 'e', 'f'}, false),
|
match.NewList([]rune{'d', 'e', 'f'}, false),
|
||||||
}},
|
|
||||||
match.NewText("ghi"),
|
|
||||||
}...,
|
|
||||||
),
|
),
|
||||||
|
match.NewText("ghi"),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
m, err := Compile(test.ast, test.sep)
|
m, err := Compile(test.ast, test.sep)
|
||||||
|
@ -493,7 +306,7 @@ func TestCompiler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(m, test.result) {
|
if !reflect.DeepEqual(m, test.result) {
|
||||||
t.Errorf("[%d] Compile():\nexp: %#v\nact: %#v\n\ngraphviz:\nexp:\n%s\nact:\n%s\n", id, test.result, m, debug.Graphviz("", test.result.(match.Matcher)), debug.Graphviz("", m.(match.Matcher)))
|
t.Errorf("[%d] Compile():\nexp: %#v\nact: %#v\n\ngraphviz:\nexp:\n%s\nact:\n%s\n", id, test.result, m, match.Graphviz("", test.result.(match.Matcher)), match.Graphviz("", m.(match.Matcher)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,35 @@ type AnyOf struct {
|
||||||
func NewAnyOf(ms ...Matcher) Matcher {
|
func NewAnyOf(ms ...Matcher) Matcher {
|
||||||
a := AnyOf{ms, minLen(ms)}
|
a := AnyOf{ms, minLen(ms)}
|
||||||
if mis, ok := MatchIndexers(ms); ok {
|
if mis, ok := MatchIndexers(ms); ok {
|
||||||
return IndexedAnyOf{a, mis}
|
x := IndexedAnyOf{a, mis}
|
||||||
|
if msz, ok := MatchIndexSizers(ms); ok {
|
||||||
|
sz := -1
|
||||||
|
for _, m := range msz {
|
||||||
|
n := m.RunesCount()
|
||||||
|
if sz == -1 {
|
||||||
|
sz = n
|
||||||
|
} else if sz != n {
|
||||||
|
sz = -1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sz != -1 {
|
||||||
|
return IndexedSizedAnyOf{x, sz}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MustIndexedAnyOf(ms ...Matcher) MatchIndexer {
|
||||||
|
return NewAnyOf(ms...).(MatchIndexer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MustIndexedSizedAnyOf(ms ...Matcher) MatchIndexSizer {
|
||||||
|
return NewAnyOf(ms...).(MatchIndexSizer)
|
||||||
|
}
|
||||||
|
|
||||||
func (a AnyOf) Match(s string) bool {
|
func (a AnyOf) Match(s string) bool {
|
||||||
for _, m := range a.ms {
|
for _, m := range a.ms {
|
||||||
if m.Match(s) {
|
if m.Match(s) {
|
||||||
|
@ -72,3 +96,12 @@ func (a IndexedAnyOf) Index(s string) (int, []int) {
|
||||||
func (a IndexedAnyOf) String() string {
|
func (a IndexedAnyOf) String() string {
|
||||||
return fmt.Sprintf("<indexed_any_of:[%s]>", a.ms)
|
return fmt.Sprintf("<indexed_any_of:[%s]>", a.ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IndexedSizedAnyOf struct {
|
||||||
|
IndexedAnyOf
|
||||||
|
runes int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a IndexedSizedAnyOf) RunesCount() int {
|
||||||
|
return a.runes
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,10 @@ func NewContains(needle string) Contains {
|
||||||
return Contains{needle, false}
|
return Contains{needle, false}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewNotContains(needle string) Contains {
|
||||||
|
return Contains{needle, true}
|
||||||
|
}
|
||||||
|
|
||||||
func (c Contains) Match(s string) bool {
|
func (c Contains) Match(s string) bool {
|
||||||
return strings.Contains(s, c.s) != c.not
|
return strings.Contains(s, c.s) != c.not
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@ func (l List) MinLen() int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l List) RunesCount() int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
func (l List) Index(s string) (int, []int) {
|
func (l List) Index(s string) (int, []int) {
|
||||||
for i, r := range s {
|
for i, r := range s {
|
||||||
if l.not == (runes.IndexRune(l.rs, r) == -1) {
|
if l.not == (runes.IndexRune(l.rs, r) == -1) {
|
||||||
|
|
|
@ -42,15 +42,28 @@ type Container interface {
|
||||||
|
|
||||||
func MatchIndexers(ms []Matcher) ([]MatchIndexer, bool) {
|
func MatchIndexers(ms []Matcher) ([]MatchIndexer, bool) {
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
if _, ok := m.(Indexer); !ok {
|
if _, ok := m.(MatchIndexer); !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mis := make([]MatchIndexer, len(ms))
|
r := make([]MatchIndexer, len(ms))
|
||||||
for i := range mis {
|
for i := range r {
|
||||||
mis[i] = ms[i].(MatchIndexer)
|
r[i] = ms[i].(MatchIndexer)
|
||||||
}
|
}
|
||||||
return mis, true
|
return r, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func MatchIndexSizers(ms []Matcher) ([]MatchIndexSizer, bool) {
|
||||||
|
for _, m := range ms {
|
||||||
|
if _, ok := m.(MatchIndexSizer); !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r := make([]MatchIndexSizer, len(ms))
|
||||||
|
for i := range r {
|
||||||
|
r[i] = ms[i].(MatchIndexSizer)
|
||||||
|
}
|
||||||
|
return r, true
|
||||||
}
|
}
|
||||||
|
|
||||||
type Matchers []Matcher
|
type Matchers []Matcher
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
package match
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gobwas/glob/match"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCompile(t *testing.T) {
|
||||||
|
for id, test := range []struct {
|
||||||
|
in []Matcher
|
||||||
|
exp Matcher
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
[]Matcher{
|
||||||
|
NewSuper(),
|
||||||
|
NewSingle(nil),
|
||||||
|
},
|
||||||
|
NewMin(1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]Matcher{
|
||||||
|
NewAny(separators),
|
||||||
|
NewSingle(separators),
|
||||||
|
},
|
||||||
|
NewEveryOf([]Matcher{
|
||||||
|
NewMin(1),
|
||||||
|
NewContains(string(separators)),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]Matcher{
|
||||||
|
NewSingle(nil),
|
||||||
|
NewSingle(nil),
|
||||||
|
NewSingle(nil),
|
||||||
|
},
|
||||||
|
NewEveryOf([]Matcher{
|
||||||
|
NewMin(3),
|
||||||
|
NewMax(3),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]Matcher{
|
||||||
|
NewList([]rune{'a'}, true),
|
||||||
|
NewAny([]rune{'a'}),
|
||||||
|
},
|
||||||
|
NewEveryOf([]Matcher{
|
||||||
|
NewMin(1),
|
||||||
|
NewContains("a"),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]Matcher{
|
||||||
|
NewSuper(),
|
||||||
|
NewSingle(separators),
|
||||||
|
NewText("c"),
|
||||||
|
},
|
||||||
|
NewTree(
|
||||||
|
NewText("c"),
|
||||||
|
NewBTree(
|
||||||
|
NewSingle(separators),
|
||||||
|
NewSuper(),
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]Matcher{
|
||||||
|
NewAny(nil),
|
||||||
|
NewText("c"),
|
||||||
|
NewAny(nil),
|
||||||
|
},
|
||||||
|
NewTree(
|
||||||
|
NewText("c"),
|
||||||
|
NewAny(nil),
|
||||||
|
NewAny(nil),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]Matcher{
|
||||||
|
NewRange('a', 'c', true),
|
||||||
|
NewList([]rune{'z', 't', 'e'}, false),
|
||||||
|
NewText("c"),
|
||||||
|
NewSingle(nil),
|
||||||
|
},
|
||||||
|
NewRow([]MatchIndexSizer{
|
||||||
|
NewRange('a', 'c', true),
|
||||||
|
NewList([]rune{'z', 't', 'e'}, false),
|
||||||
|
NewText("c"),
|
||||||
|
NewSingle(nil),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
act, err := Compile(test.in)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("#%d compile matchers error: %s", id, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(act, test.exp) {
|
||||||
|
t.Errorf("#%d unexpected compile matchers result:\nact: %#v;\nexp: %#v", id, act, test.exp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMinimize(t *testing.T) {
|
||||||
|
for id, test := range []struct {
|
||||||
|
in, exp []match.Matcher
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
[]match.Matcher{
|
||||||
|
match.NewRange('a', 'c', true),
|
||||||
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
|
match.NewText("c"),
|
||||||
|
match.NewSingle(nil),
|
||||||
|
match.NewAny(nil),
|
||||||
|
},
|
||||||
|
[]match.Matcher{
|
||||||
|
match.NewRow(
|
||||||
|
4,
|
||||||
|
[]match.Matcher{
|
||||||
|
match.NewRange('a', 'c', true),
|
||||||
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
|
match.NewText("c"),
|
||||||
|
match.NewSingle(nil),
|
||||||
|
}...,
|
||||||
|
),
|
||||||
|
match.NewAny(nil),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]match.Matcher{
|
||||||
|
match.NewRange('a', 'c', true),
|
||||||
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
|
match.NewText("c"),
|
||||||
|
match.NewSingle(nil),
|
||||||
|
match.NewAny(nil),
|
||||||
|
match.NewSingle(nil),
|
||||||
|
match.NewSingle(nil),
|
||||||
|
match.NewAny(nil),
|
||||||
|
},
|
||||||
|
[]match.Matcher{
|
||||||
|
match.NewRow(
|
||||||
|
3,
|
||||||
|
match.Matchers{
|
||||||
|
match.NewRange('a', 'c', true),
|
||||||
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
|
match.NewText("c"),
|
||||||
|
}...,
|
||||||
|
),
|
||||||
|
match.NewMin(3),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
act := minimizeMatchers(test.in)
|
||||||
|
if !reflect.DeepEqual(act, test.exp) {
|
||||||
|
t.Errorf("#%d unexpected convert matchers 2 result:\nact: %#v\nexp: %#v", id, act, test.exp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,10 @@ func (self Range) MinLen() int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self Range) RunesCount() int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
func (self Range) Match(s string) bool {
|
func (self Range) Match(s string) bool {
|
||||||
r, w := utf8.DecodeRuneInString(s)
|
r, w := utf8.DecodeRuneInString(s)
|
||||||
if len(s) > w {
|
if len(s) > w {
|
||||||
|
|
Loading…
Reference in New Issue