...

Source file src/github.com/onsi/gomega/matchers/be_sent_matcher.go

Documentation: github.com/onsi/gomega/matchers

     1  // untested sections: 3
     2  
     3  package matchers
     4  
     5  import (
     6  	"fmt"
     7  	"reflect"
     8  
     9  	"github.com/onsi/gomega/format"
    10  )
    11  
    12  type BeSentMatcher struct {
    13  	Arg           interface{}
    14  	channelClosed bool
    15  }
    16  
    17  func (matcher *BeSentMatcher) Match(actual interface{}) (success bool, err error) {
    18  	if !isChan(actual) {
    19  		return false, fmt.Errorf("BeSent expects a channel.  Got:\n%s", format.Object(actual, 1))
    20  	}
    21  
    22  	channelType := reflect.TypeOf(actual)
    23  	channelValue := reflect.ValueOf(actual)
    24  
    25  	if channelType.ChanDir() == reflect.RecvDir {
    26  		return false, fmt.Errorf("BeSent matcher cannot be passed a receive-only channel.  Got:\n%s", format.Object(actual, 1))
    27  	}
    28  
    29  	argType := reflect.TypeOf(matcher.Arg)
    30  	assignable := argType.AssignableTo(channelType.Elem())
    31  
    32  	if !assignable {
    33  		return false, fmt.Errorf("Cannot pass:\n%s to the channel:\n%s\nThe types don't match.", format.Object(matcher.Arg, 1), format.Object(actual, 1))
    34  	}
    35  
    36  	argValue := reflect.ValueOf(matcher.Arg)
    37  
    38  	defer func() {
    39  		if e := recover(); e != nil {
    40  			success = false
    41  			err = fmt.Errorf("Cannot send to a closed channel")
    42  			matcher.channelClosed = true
    43  		}
    44  	}()
    45  
    46  	winnerIndex, _, _ := reflect.Select([]reflect.SelectCase{
    47  		{Dir: reflect.SelectSend, Chan: channelValue, Send: argValue},
    48  		{Dir: reflect.SelectDefault},
    49  	})
    50  
    51  	var didSend bool
    52  	if winnerIndex == 0 {
    53  		didSend = true
    54  	}
    55  
    56  	return didSend, nil
    57  }
    58  
    59  func (matcher *BeSentMatcher) FailureMessage(actual interface{}) (message string) {
    60  	return format.Message(actual, "to send:", matcher.Arg)
    61  }
    62  
    63  func (matcher *BeSentMatcher) NegatedFailureMessage(actual interface{}) (message string) {
    64  	return format.Message(actual, "not to send:", matcher.Arg)
    65  }
    66  
    67  func (matcher *BeSentMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
    68  	if !isChan(actual) {
    69  		return false
    70  	}
    71  
    72  	return !matcher.channelClosed
    73  }
    74  

View as plain text