| package matchers | 
 |  | 
 | import ( | 
 | 	"fmt" | 
 | 	"reflect" | 
 |  | 
 | 	"github.com/onsi/gomega/format" | 
 | 	"github.com/onsi/gomega/matchers/support/goraph/bipartitegraph" | 
 | ) | 
 |  | 
 | type ConsistOfMatcher struct { | 
 | 	Elements []interface{} | 
 | } | 
 |  | 
 | func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) { | 
 | 	if !isArrayOrSlice(actual) && !isMap(actual) { | 
 | 		return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map.  Got:\n%s", format.Object(actual, 1)) | 
 | 	} | 
 |  | 
 | 	elements := matcher.Elements | 
 | 	if len(matcher.Elements) == 1 && isArrayOrSlice(matcher.Elements[0]) { | 
 | 		elements = []interface{}{} | 
 | 		value := reflect.ValueOf(matcher.Elements[0]) | 
 | 		for i := 0; i < value.Len(); i++ { | 
 | 			elements = append(elements, value.Index(i).Interface()) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	matchers := []interface{}{} | 
 | 	for _, element := range elements { | 
 | 		matcher, isMatcher := element.(omegaMatcher) | 
 | 		if !isMatcher { | 
 | 			matcher = &EqualMatcher{Expected: element} | 
 | 		} | 
 | 		matchers = append(matchers, matcher) | 
 | 	} | 
 |  | 
 | 	values := matcher.valuesOf(actual) | 
 |  | 
 | 	if len(values) != len(matchers) { | 
 | 		return false, nil | 
 | 	} | 
 |  | 
 | 	neighbours := func(v, m interface{}) (bool, error) { | 
 | 		match, err := m.(omegaMatcher).Match(v) | 
 | 		return match && err == nil, nil | 
 | 	} | 
 |  | 
 | 	bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours) | 
 | 	if err != nil { | 
 | 		return false, err | 
 | 	} | 
 |  | 
 | 	return len(bipartiteGraph.LargestMatching()) == len(values), nil | 
 | } | 
 |  | 
 | func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} { | 
 | 	value := reflect.ValueOf(actual) | 
 | 	values := []interface{}{} | 
 | 	if isMap(actual) { | 
 | 		keys := value.MapKeys() | 
 | 		for i := 0; i < value.Len(); i++ { | 
 | 			values = append(values, value.MapIndex(keys[i]).Interface()) | 
 | 		} | 
 | 	} else { | 
 | 		for i := 0; i < value.Len(); i++ { | 
 | 			values = append(values, value.Index(i).Interface()) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return values | 
 | } | 
 |  | 
 | func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) { | 
 | 	return format.Message(actual, "to consist of", matcher.Elements) | 
 | } | 
 |  | 
 | func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) { | 
 | 	return format.Message(actual, "not to consist of", matcher.Elements) | 
 | } |