Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Matching a sequence of actuals, in no particular order #683

Open
thediveo opened this issue Jul 22, 2023 · 0 comments
Open

RFC: Matching a sequence of actuals, in no particular order #683

thediveo opened this issue Jul 22, 2023 · 0 comments

Comments

@thediveo
Copy link
Collaborator

Another one from the "odd stuff" department: from time to time I need to receive several things from a channel, but the order of them might be undefined. Such as events overtaking each other.

And to be honest, I ever wanted to give MakeMatcher a try! 👍🏼

My first attempt is an All(...) matcher to be used with Receive():

// All succeeds only after it has been shown a sequence of actual values that
// “ticked off” the specified matchers in no particular order. All will return
// an error in case it encounters an actual value not matching any of the
// specified matchers. If the same match should occur multiple times it needs to
// be specified as many times as required.
func All(matchers ...types.GomegaMatcher) types.GomegaMatcher {
	// Now that's fun to keep state not in a struct "object" but instead capture
	// state in a closure.
	remaining := slices.Clone(matchers)
	return MakeMatcher(func(actual any) (bool, error) {
		for idx, matcher := range remaining {
			succeeded, err := matcher.Match(actual)
			if err != nil {
				return false, err
			}
			if !succeeded {
				continue // ...maybe another one will match...?
			}
			remaining = slices.Delete(remaining, idx, idx+1)
			if len(remaining) > 0 {
				return false, nil
			}
			return true, nil
		}
		return false, errors.New("not in expected set")
	}).WithTemplate("Expected:\n{{.FormattedActual}}\n{{.To}} complete set")
}

However, the All matcher is a little bit off the beaten matcher path, as it does not keep silent when it doesn't match, but instead throws an error. It's like the temporal version of Contains(...) (on arrays, slices and maps), but this time on channel receives.

Any suggestion as to how to improve the error reporting in this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant