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
		}
	}
}
Exemple #2
0
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
}