github.com/onsi/gomega@v1.32.0/matchers/have_exact_elements.go (about) 1 package matchers 2 3 import ( 4 "fmt" 5 6 "github.com/onsi/gomega/format" 7 ) 8 9 type mismatchFailure struct { 10 failure string 11 index int 12 } 13 14 type HaveExactElementsMatcher struct { 15 Elements []interface{} 16 mismatchFailures []mismatchFailure 17 missingIndex int 18 extraIndex int 19 } 20 21 func (matcher *HaveExactElementsMatcher) Match(actual interface{}) (success bool, err error) { 22 matcher.resetState() 23 24 if isMap(actual) { 25 return false, fmt.Errorf("error") 26 } 27 28 matchers := matchers(matcher.Elements) 29 values := valuesOf(actual) 30 31 lenMatchers := len(matchers) 32 lenValues := len(values) 33 34 for i := 0; i < lenMatchers || i < lenValues; i++ { 35 if i >= lenMatchers { 36 matcher.extraIndex = i 37 continue 38 } 39 40 if i >= lenValues { 41 matcher.missingIndex = i 42 return 43 } 44 45 elemMatcher := matchers[i].(omegaMatcher) 46 match, err := elemMatcher.Match(values[i]) 47 if err != nil { 48 matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ 49 index: i, 50 failure: err.Error(), 51 }) 52 } else if !match { 53 matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ 54 index: i, 55 failure: elemMatcher.FailureMessage(values[i]), 56 }) 57 } 58 } 59 60 return matcher.missingIndex+matcher.extraIndex+len(matcher.mismatchFailures) == 0, nil 61 } 62 63 func (matcher *HaveExactElementsMatcher) FailureMessage(actual interface{}) (message string) { 64 message = format.Message(actual, "to have exact elements with", presentable(matcher.Elements)) 65 if matcher.missingIndex > 0 { 66 message = fmt.Sprintf("%s\nthe missing elements start from index %d", message, matcher.missingIndex) 67 } 68 if matcher.extraIndex > 0 { 69 message = fmt.Sprintf("%s\nthe extra elements start from index %d", message, matcher.extraIndex) 70 } 71 if len(matcher.mismatchFailures) != 0 { 72 message = fmt.Sprintf("%s\nthe mismatch indexes were:", message) 73 } 74 for _, mismatch := range matcher.mismatchFailures { 75 message = fmt.Sprintf("%s\n%d: %s", message, mismatch.index, mismatch.failure) 76 } 77 return 78 } 79 80 func (matcher *HaveExactElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) { 81 return format.Message(actual, "not to contain elements", presentable(matcher.Elements)) 82 } 83 84 func (matcher *HaveExactElementsMatcher) resetState() { 85 matcher.mismatchFailures = nil 86 matcher.missingIndex = 0 87 matcher.extraIndex = 0 88 }