Path: blob/main/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go
2880 views
package matchers12import (3"fmt"4"reflect"56"github.com/onsi/gomega/format"7"github.com/onsi/gomega/matchers/internal/miter"8)910type HaveEachMatcher struct {11Element any12}1314func (matcher *HaveEachMatcher) Match(actual any) (success bool, err error) {15if !isArrayOrSlice(actual) && !isMap(actual) && !miter.IsIter(actual) {16return false, fmt.Errorf("HaveEach matcher expects an array/slice/map/iter.Seq/iter.Seq2. Got:\n%s",17format.Object(actual, 1))18}1920elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher)21if !elementIsMatcher {22elemMatcher = &EqualMatcher{Expected: matcher.Element}23}2425if miter.IsIter(actual) {26// rejecting the non-elements case works different for iterators as we27// don't want to fetch all elements into a slice first.28count := 029var success bool30var err error31if miter.IsSeq2(actual) {32miter.IterateKV(actual, func(k, v reflect.Value) bool {33count++34success, err = elemMatcher.Match(v.Interface())35if err != nil {36return false37}38return success39})40} else {41miter.IterateV(actual, func(v reflect.Value) bool {42count++43success, err = elemMatcher.Match(v.Interface())44if err != nil {45return false46}47return success48})49}50if count == 0 {51return false, fmt.Errorf("HaveEach matcher expects a non-empty iter.Seq/iter.Seq2. Got:\n%s",52format.Object(actual, 1))53}54return success, err55}5657value := reflect.ValueOf(actual)58if value.Len() == 0 {59return false, fmt.Errorf("HaveEach matcher expects a non-empty array/slice/map. Got:\n%s",60format.Object(actual, 1))61}6263var valueAt func(int) any64if isMap(actual) {65keys := value.MapKeys()66valueAt = func(i int) any {67return value.MapIndex(keys[i]).Interface()68}69} else {70valueAt = func(i int) any {71return value.Index(i).Interface()72}73}7475// if we never failed then we succeed; the empty/nil cases have already been76// rejected above.77for i := 0; i < value.Len(); i++ {78success, err := elemMatcher.Match(valueAt(i))79if err != nil {80return false, err81}82if !success {83return false, nil84}85}8687return true, nil88}8990// FailureMessage returns a suitable failure message.91func (matcher *HaveEachMatcher) FailureMessage(actual any) (message string) {92return format.Message(actual, "to contain element matching", matcher.Element)93}9495// NegatedFailureMessage returns a suitable negated failure message.96func (matcher *HaveEachMatcher) NegatedFailureMessage(actual any) (message string) {97return format.Message(actual, "not to contain element matching", matcher.Element)98}99100101