Skip to content

A matcher that matches at least one of the given matchers #58

@favonia

Description

@favonia

Requested feature

A new matcher combinator like All but returns true when one of the matchers returns true.

Why the feature is needed

We currently have All that matches all the matchers, just like the universal quantifier in the logic. It would be great to have AnyOf that matches at least one of them, similar to the existential quantifier in the logic. This is helpful when an argument can be one of several values. For example, with the new AnyOf matcher, we may write the following:

gomock.InOrder(
	m.EXPECT().SetDirection(AnyOf("north", "south", "west", "east"), true),
	m.EXPECT().Run(),
)

This means we expect a method call SetDirection("north", true), SetDirection("south", true), SetDirection("west", true) or SetDirection("east", true), which is then followed by a method call Run().

(Optional) Proposed solution

Here is a sample implementation. It's trivial for me to make a PR if the maintainers feel positive about this feature.

type anyOfMatcher struct {
	matchers []Matcher
}

func (am anyOfMatcher) Matches(x any) bool {
	for _, m := range am.matchers {
		if m.Matches(x) {
			return true
		}
	}
	return false
}

func (am anyOfMatcher) String() string {
	ss := make([]string, 0, len(am.matchers))
	for _, matcher := range am.matchers {
		ss = append(ss, matcher.String())
	}
	return strings.Join(ss, " | ")
}

func AnyOf(xs ...any) Matcher {
	ms := make([]Matcher, 0, len(xs))
	for _, x := range xs {
		if m, ok := x.(Matcher); ok {
			ms = append(ms, m)
		} else {
			ms = append(ms, Eq(x))
		}
	}
	return anyOfMatcher{ms}
}

Related issues and PRs (from the original gomock)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions