contain_element_matcher.go 1.4 KB

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