github.com/onsi/gomega@v1.32.0/matchers/have_key_with_value_matcher.go (about) 1 // untested sections:10 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 }