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