7 "github.com/onsi/gomega/format"
10 type ReceiveMatcher struct {
12 receivedValue reflect.Value
16 func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err error) {
18 return false, fmt.Errorf("ReceiveMatcher expects a channel. Got:\n%s", format.Object(actual, 1))
21 channelType := reflect.TypeOf(actual)
22 channelValue := reflect.ValueOf(actual)
24 if channelType.ChanDir() == reflect.SendDir {
25 return false, fmt.Errorf("ReceiveMatcher matcher cannot be passed a send-only channel. Got:\n%s", format.Object(actual, 1))
28 var subMatcher omegaMatcher
29 var hasSubMatcher bool
31 if matcher.Arg != nil {
32 subMatcher, hasSubMatcher = (matcher.Arg).(omegaMatcher)
34 argType := reflect.TypeOf(matcher.Arg)
35 if argType.Kind() != reflect.Ptr {
36 return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1))
39 assignable := channelType.Elem().AssignableTo(argType.Elem())
41 return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(matcher.Arg, 1))
46 winnerIndex, value, open := reflect.Select([]reflect.SelectCase{
47 reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue},
48 reflect.SelectCase{Dir: reflect.SelectDefault},
57 matcher.channelClosed = closed
65 matcher.receivedValue = value
66 return subMatcher.Match(matcher.receivedValue.Interface())
73 if matcher.Arg != nil {
74 outValue := reflect.ValueOf(matcher.Arg)
75 reflect.Indirect(outValue).Set(value)
84 func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) {
85 subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
88 if matcher.channelClosed {
89 closedAddendum = " The channel is closed."
93 if matcher.receivedValue.IsValid() {
94 return subMatcher.FailureMessage(matcher.receivedValue.Interface())
96 return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
98 return format.Message(actual, "to receive something."+closedAddendum)
102 func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) {
103 subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
106 if matcher.channelClosed {
107 closedAddendum = " The channel is closed."
111 if matcher.receivedValue.IsValid() {
112 return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface())
114 return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
116 return format.Message(actual, "not to receive anything."+closedAddendum)
120 func (matcher *ReceiveMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
125 return !matcher.channelClosed