github.com/onsi/gomega@v1.32.0/matchers/and.go (about) 1 package matchers 2 3 import ( 4 "fmt" 5 6 "github.com/onsi/gomega/format" 7 "github.com/onsi/gomega/types" 8 ) 9 10 type AndMatcher struct { 11 Matchers []types.GomegaMatcher 12 13 // state 14 firstFailedMatcher types.GomegaMatcher 15 } 16 17 func (m *AndMatcher) Match(actual interface{}) (success bool, err error) { 18 m.firstFailedMatcher = nil 19 for _, matcher := range m.Matchers { 20 success, err := matcher.Match(actual) 21 if !success || err != nil { 22 m.firstFailedMatcher = matcher 23 return false, err 24 } 25 } 26 return true, nil 27 } 28 29 func (m *AndMatcher) FailureMessage(actual interface{}) (message string) { 30 return m.firstFailedMatcher.FailureMessage(actual) 31 } 32 33 func (m *AndMatcher) NegatedFailureMessage(actual interface{}) (message string) { 34 // not the most beautiful list of matchers, but not bad either... 35 return format.Message(actual, fmt.Sprintf("To not satisfy all of these matchers: %s", m.Matchers)) 36 } 37 38 func (m *AndMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { 39 /* 40 Example with 3 matchers: A, B, C 41 42 Match evaluates them: T, F, <?> => F 43 So match is currently F, what should MatchMayChangeInTheFuture() return? 44 Seems like it only depends on B, since currently B MUST change to allow the result to become T 45 46 Match eval: T, T, T => T 47 So match is currently T, what should MatchMayChangeInTheFuture() return? 48 Seems to depend on ANY of them being able to change to F. 49 */ 50 51 if m.firstFailedMatcher == nil { 52 // so all matchers succeeded.. Any one of them changing would change the result. 53 for _, matcher := range m.Matchers { 54 if types.MatchMayChangeInTheFuture(matcher, actual) { 55 return true 56 } 57 } 58 return false // none of were going to change 59 } 60 // one of the matchers failed.. it must be able to change in order to affect the result 61 return types.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual) 62 }