github.com/cloudfoundry-attic/ltc@v0.0.0-20151123212628-098adc7919fc/test_helpers/matchers/contain_exactly_matcher.go (about) 1 package matchers 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 8 "github.com/onsi/gomega/types" 9 ) 10 11 type containExactlyMatcher struct { 12 expected interface{} 13 } 14 15 func ContainExactly(expected interface{}) types.GomegaMatcher { 16 return &containExactlyMatcher{expected: expected} 17 } 18 19 func (matcher *containExactlyMatcher) Match(actual interface{}) (success bool, err error) { 20 21 if !isArraySliceMap(matcher.expected) || !isArraySliceMap(actual) { 22 return false, errors.New("Matcher can only take an array, slice or map") 23 } 24 25 expectedValueOccurrences := calculateOccurrencesMap(matcher.expected) 26 actualValueOccurrences := calculateOccurrencesMap(actual) 27 28 return reflect.DeepEqual(expectedValueOccurrences, actualValueOccurrences), nil 29 } 30 31 func calculateOccurrencesMap(actualOrExpected interface{}) map[interface{}]int { 32 value := reflect.ValueOf(actualOrExpected) 33 occurrences := make(map[interface{}]int) 34 var keys []reflect.Value 35 if isMap(actualOrExpected) { 36 keys = value.MapKeys() 37 } 38 39 for i := 0; i < value.Len(); i++ { 40 var valueToHash interface{} 41 if isMap(actualOrExpected) { 42 valueToHash = value.MapIndex(keys[i]).Interface() 43 } else { 44 valueToHash = value.Index(i).Interface() 45 } 46 occurrences[fmt.Sprintf("%#v", valueToHash)]++ 47 } 48 49 return occurrences 50 } 51 52 func (matcher *containExactlyMatcher) FailureMessage(actual interface{}) (message string) { 53 return fmt.Sprintf("Expected %#v\n to contain exactly: %#v\n but it did not.", actual, matcher.expected) 54 } 55 56 func (matcher *containExactlyMatcher) NegatedFailureMessage(actual interface{}) (message string) { 57 return fmt.Sprintf("Expected %#v\n not to contain exactly: %#v\n but it did!", actual, matcher.expected) 58 } 59 60 func isArraySliceMap(a interface{}) bool { 61 if a == nil { 62 return false 63 } 64 switch reflect.TypeOf(a).Kind() { 65 case reflect.Array, reflect.Slice, reflect.Map: 66 return true 67 default: 68 return false 69 } 70 } 71 72 func isMap(a interface{}) bool { 73 // if a == nil { 74 // return false 75 // } 76 return reflect.TypeOf(a).Kind() == reflect.Map 77 }