package matchers import ( "fmt" "github.com/onsi/gomega/format" ) type mismatchFailure struct { failure string index int } type HaveExactElementsMatcher struct { Elements []interface{} mismatchFailures []mismatchFailure missingIndex int extraIndex int } func (matcher *HaveExactElementsMatcher) Match(actual interface{}) (success bool, err error) { matcher.resetState() if isMap(actual) { return false, fmt.Errorf("error") } matchers := matchers(matcher.Elements) values := valuesOf(actual) lenMatchers := len(matchers) lenValues := len(values) success = true for i := 0; i < lenMatchers || i < lenValues; i++ { if i >= lenMatchers { matcher.extraIndex = i success = false continue } if i >= lenValues { matcher.missingIndex = i success = false return } elemMatcher := matchers[i].(omegaMatcher) match, err := elemMatcher.Match(values[i]) if err != nil { matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ index: i, failure: err.Error(), }) success = false } else if !match { matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ index: i, failure: elemMatcher.FailureMessage(values[i]), }) success = false } } return success, nil } func (matcher *HaveExactElementsMatcher) FailureMessage(actual interface{}) (message string) { message = format.Message(actual, "to have exact elements with", presentable(matcher.Elements)) if matcher.missingIndex > 0 { message = fmt.Sprintf("%s\nthe missing elements start from index %d", message, matcher.missingIndex) } if matcher.extraIndex > 0 { message = fmt.Sprintf("%s\nthe extra elements start from index %d", message, matcher.extraIndex) } if len(matcher.mismatchFailures) != 0 { message = fmt.Sprintf("%s\nthe mismatch indexes were:", message) } for _, mismatch := range matcher.mismatchFailures { message = fmt.Sprintf("%s\n%d: %s", message, mismatch.index, mismatch.failure) } return } func (matcher *HaveExactElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) { return format.Message(actual, "not to contain elements", presentable(matcher.Elements)) } func (matcher *HaveExactElementsMatcher) resetState() { matcher.mismatchFailures = nil matcher.missingIndex = 0 matcher.extraIndex = 0 }