| package matchers |
| |
| import ( |
| "fmt" |
| "reflect" |
| |
| "github.com/onsi/gomega/format" |
| ) |
| |
| type BeClosedMatcher struct { |
| } |
| |
| func (matcher *BeClosedMatcher) Match(actual interface{}) (success bool, err error) { |
| if !isChan(actual) { |
| return false, fmt.Errorf("BeClosed matcher expects a channel. Got:\n%s", format.Object(actual, 1)) |
| } |
| |
| channelType := reflect.TypeOf(actual) |
| channelValue := reflect.ValueOf(actual) |
| |
| if channelType.ChanDir() == reflect.SendDir { |
| return false, fmt.Errorf("BeClosed matcher cannot determine if a send-only channel is closed or open. Got:\n%s", format.Object(actual, 1)) |
| } |
| |
| winnerIndex, _, open := reflect.Select([]reflect.SelectCase{ |
| reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue}, |
| reflect.SelectCase{Dir: reflect.SelectDefault}, |
| }) |
| |
| var closed bool |
| if winnerIndex == 0 { |
| closed = !open |
| } else if winnerIndex == 1 { |
| closed = false |
| } |
| |
| return closed, nil |
| } |
| |
| func (matcher *BeClosedMatcher) FailureMessage(actual interface{}) (message string) { |
| return format.Message(actual, "to be closed") |
| } |
| |
| func (matcher *BeClosedMatcher) NegatedFailureMessage(actual interface{}) (message string) { |
| return format.Message(actual, "to be open") |
| } |