contain_element_matcher.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package matchers
  2. import (
  3. "fmt"
  4. "reflect"
  5. "github.com/onsi/gomega/format"
  6. )
  7. type ContainElementMatcher struct {
  8. Element interface{}
  9. }
  10. func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, err error) {
  11. if !isArrayOrSlice(actual) && !isMap(actual) {
  12. return false, fmt.Errorf("ContainElement matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1))
  13. }
  14. elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher)
  15. if !elementIsMatcher {
  16. elemMatcher = &EqualMatcher{Expected: matcher.Element}
  17. }
  18. value := reflect.ValueOf(actual)
  19. var keys []reflect.Value
  20. if isMap(actual) {
  21. keys = value.MapKeys()
  22. }
  23. var lastError error
  24. for i := 0; i < value.Len(); i++ {
  25. var success bool
  26. var err error
  27. if isMap(actual) {
  28. success, err = elemMatcher.Match(value.MapIndex(keys[i]).Interface())
  29. } else {
  30. success, err = elemMatcher.Match(value.Index(i).Interface())
  31. }
  32. if err != nil {
  33. lastError = err
  34. continue
  35. }
  36. if success {
  37. return true, nil
  38. }
  39. }
  40. return false, lastError
  41. }
  42. func (matcher *ContainElementMatcher) FailureMessage(actual interface{}) (message string) {
  43. return format.Message(actual, "to contain element matching", matcher.Element)
  44. }
  45. func (matcher *ContainElementMatcher) NegatedFailureMessage(actual interface{}) (message string) {
  46. return format.Message(actual, "not to contain element matching", matcher.Element)
  47. }