...
1
2
3 package matchers
4
5 import (
6 "fmt"
7 "reflect"
8
9 "github.com/onsi/gomega/format"
10 )
11
12 type HaveKeyWithValueMatcher struct {
13 Key interface{}
14 Value interface{}
15 }
16
17 func (matcher *HaveKeyWithValueMatcher) Match(actual interface{}) (success bool, err error) {
18 if !isMap(actual) {
19 return false, fmt.Errorf("HaveKeyWithValue matcher expects a map. Got:%s", format.Object(actual, 1))
20 }
21
22 keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher)
23 if !keyIsMatcher {
24 keyMatcher = &EqualMatcher{Expected: matcher.Key}
25 }
26
27 valueMatcher, valueIsMatcher := matcher.Value.(omegaMatcher)
28 if !valueIsMatcher {
29 valueMatcher = &EqualMatcher{Expected: matcher.Value}
30 }
31
32 keys := reflect.ValueOf(actual).MapKeys()
33 for i := 0; i < len(keys); i++ {
34 success, err := keyMatcher.Match(keys[i].Interface())
35 if err != nil {
36 return false, fmt.Errorf("HaveKeyWithValue's key matcher failed with:\n%s%s", format.Indent, err.Error())
37 }
38 if success {
39 actualValue := reflect.ValueOf(actual).MapIndex(keys[i])
40 success, err := valueMatcher.Match(actualValue.Interface())
41 if err != nil {
42 return false, fmt.Errorf("HaveKeyWithValue's value matcher failed with:\n%s%s", format.Indent, err.Error())
43 }
44 return success, nil
45 }
46 }
47
48 return false, nil
49 }
50
51 func (matcher *HaveKeyWithValueMatcher) FailureMessage(actual interface{}) (message string) {
52 str := "to have {key: value}"
53 if _, ok := matcher.Key.(omegaMatcher); ok {
54 str += " matching"
55 } else if _, ok := matcher.Value.(omegaMatcher); ok {
56 str += " matching"
57 }
58
59 expect := make(map[interface{}]interface{}, 1)
60 expect[matcher.Key] = matcher.Value
61 return format.Message(actual, str, expect)
62 }
63
64 func (matcher *HaveKeyWithValueMatcher) NegatedFailureMessage(actual interface{}) (message string) {
65 kStr := "not to have key"
66 if _, ok := matcher.Key.(omegaMatcher); ok {
67 kStr = "not to have key matching"
68 }
69
70 vStr := "or that key's value not be"
71 if _, ok := matcher.Value.(omegaMatcher); ok {
72 vStr = "or to have that key's value not matching"
73 }
74
75 return format.Message(actual, kStr, matcher.Key, vStr, matcher.Value)
76 }
77
View as plain text