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 glueAsEvery(matchers []match.Matcher) match.Matcher { if len(matchers) <= 1 { return nil } var ( hasAny bool hasSuper bool hasSingle bool min int separator []rune ) for i, matcher := range matchers { var sep []rune switch m := matcher.(type) { case match.Super: sep = []rune{} hasSuper = true case match.Any: sep = m.Separators hasAny = true case match.Single: sep = m.Separators hasSingle = true min++ case match.List: if !m.Not { return nil } sep = m.List hasSingle = true min++ default: return nil } // initialize if i == 0 { separator = sep } if runes.Equal(sep, separator) { continue } return nil } if hasSuper && !hasAny && !hasSingle { return match.NewSuper() } if hasAny && !hasSuper && !hasSingle { return match.NewAny(separator) } if (hasAny || hasSuper) && min > 0 && len(separator) == 0 { return match.NewMin(min) } every := match.NewEveryOf() if min > 0 { every.Add(match.NewMin(min)) if !hasAny && !hasSuper { every.Add(match.NewMax(min)) } } if len(separator) > 0 { every.Add(match.NewContains(string(separator), true)) } return every }