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  }