be_closed_matcher.go 1.2 KB

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