be_closed_matcher.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package matchers
  2. import (
  3. "fmt"
  4. "reflect"
  5. "github.com/onsi/gomega/format"
  6. )
  7. type BeClosedMatcher struct {
  8. }
  9. func (matcher *BeClosedMatcher) Match(actual interface{}) (success bool, err error) {
  10. if !isChan(actual) {
  11. return false, fmt.Errorf("BeClosed matcher expects a channel. Got:\n%s", format.Object(actual, 1))
  12. }
  13. channelType := reflect.TypeOf(actual)
  14. channelValue := reflect.ValueOf(actual)
  15. if channelType.ChanDir() == reflect.SendDir {
  16. return false, fmt.Errorf("BeClosed matcher cannot determine if a send-only channel is closed or open. Got:\n%s", format.Object(actual, 1))
  17. }
  18. winnerIndex, _, open := reflect.Select([]reflect.SelectCase{
  19. {Dir: reflect.SelectRecv, Chan: channelValue},
  20. {Dir: reflect.SelectDefault},
  21. })
  22. var closed bool
  23. if winnerIndex == 0 {
  24. closed = !open
  25. } else if winnerIndex == 1 {
  26. closed = false
  27. }
  28. return closed, nil
  29. }
  30. func (matcher *BeClosedMatcher) FailureMessage(actual interface{}) (message string) {
  31. return format.Message(actual, "to be closed")
  32. }
  33. func (matcher *BeClosedMatcher) NegatedFailureMessage(actual interface{}) (message string) {
  34. return format.Message(actual, "to be open")
  35. }