6 . "github.com/onsi/ginkgo"
7 . "github.com/onsi/gomega"
8 . "github.com/onsi/gomega/matchers"
11 type kungFuActor interface {
19 func (j *jackie) DrunkenMaster() bool {
23 var _ = Describe("ReceiveMatcher", func() {
24 Context("with no argument", func() {
25 Context("for a buffered channel", func() {
26 It("should succeed", func() {
27 channel := make(chan bool, 1)
29 Ω(channel).ShouldNot(Receive())
33 Ω(channel).Should(Receive())
37 Context("for an unbuffered channel", func() {
38 It("should succeed (eventually)", func() {
39 channel := make(chan bool)
41 Ω(channel).ShouldNot(Receive())
44 time.Sleep(10 * time.Millisecond)
48 Eventually(channel).Should(Receive())
53 Context("with a pointer argument", func() {
54 Context("of the correct type", func() {
55 It("should write the value received on the channel to the pointer", func() {
56 channel := make(chan int, 1)
60 Ω(channel).ShouldNot(Receive(&value))
61 Ω(value).Should(BeZero())
65 Ω(channel).Should(Receive(&value))
66 Ω(value).Should(Equal(17))
70 Context("to various types of objects", func() {
71 It("should work", func() {
73 stringChan := make(chan string, 1)
77 Ω(stringChan).Should(Receive(&s))
78 Ω(s).Should(Equal("foo"))
81 sliceChan := make(chan []bool, 1)
82 sliceChan <- []bool{true, true, false}
85 Ω(sliceChan).Should(Receive(&sl))
86 Ω(sl).Should(Equal([]bool{true, true, false}))
88 //channels of channels
89 chanChan := make(chan chan bool, 1)
93 var receivedC chan bool
94 Ω(chanChan).Should(Receive(&receivedC))
95 Ω(receivedC).Should(Equal(c))
97 //channels of interfaces
98 jackieChan := make(chan kungFuActor, 1)
99 aJackie := &jackie{name: "Jackie Chan"}
100 jackieChan <- aJackie
102 var theJackie kungFuActor
103 Ω(jackieChan).Should(Receive(&theJackie))
104 Ω(theJackie).Should(Equal(aJackie))
108 Context("of the wrong type", func() {
109 It("should error", func() {
110 channel := make(chan int)
111 var incorrectType bool
113 success, err := (&ReceiveMatcher{Arg: &incorrectType}).Match(channel)
114 Ω(success).Should(BeFalse())
115 Ω(err).Should(HaveOccurred())
118 success, err = (&ReceiveMatcher{Arg: notAPointer}).Match(channel)
119 Ω(success).Should(BeFalse())
120 Ω(err).Should(HaveOccurred())
125 Context("with a matcher", func() {
126 It("should defer to the underlying matcher", func() {
127 intChannel := make(chan int, 1)
129 Ω(intChannel).Should(Receive(Equal(3)))
132 Ω(intChannel).ShouldNot(Receive(Equal(3)))
134 stringChannel := make(chan []string, 1)
135 stringChannel <- []string{"foo", "bar", "baz"}
136 Ω(stringChannel).Should(Receive(ContainElement(ContainSubstring("fo"))))
138 stringChannel <- []string{"foo", "bar", "baz"}
139 Ω(stringChannel).ShouldNot(Receive(ContainElement(ContainSubstring("archipelago"))))
142 It("should defer to the underlying matcher for the message", func() {
143 matcher := Receive(Equal(3))
144 channel := make(chan int, 1)
146 matcher.Match(channel)
147 Ω(matcher.FailureMessage(channel)).Should(MatchRegexp(`Expected\s+<int>: 2\s+to equal\s+<int>: 3`))
150 matcher.Match(channel)
151 Ω(matcher.NegatedFailureMessage(channel)).Should(MatchRegexp(`Expected\s+<int>: 3\s+not to equal\s+<int>: 3`))
154 It("should work just fine with Eventually", func() {
155 stringChannel := make(chan string)
158 time.Sleep(5 * time.Millisecond)
160 time.Sleep(5 * time.Millisecond)
164 Eventually(stringChannel).Should(Receive(Equal("B")))
167 Context("if the matcher errors", func() {
168 It("should error", func() {
169 channel := make(chan int, 1)
171 success, err := (&ReceiveMatcher{Arg: ContainSubstring("three")}).Match(channel)
172 Ω(success).Should(BeFalse())
173 Ω(err).Should(HaveOccurred())
177 Context("if nothing is received", func() {
178 It("should fail", func() {
179 channel := make(chan int, 1)
180 success, err := (&ReceiveMatcher{Arg: Equal(1)}).Match(channel)
181 Ω(success).Should(BeFalse())
182 Ω(err).ShouldNot(HaveOccurred())
187 Context("When actual is a *closed* channel", func() {
188 Context("for a buffered channel", func() {
189 It("should work until it hits the end of the buffer", func() {
190 channel := make(chan bool, 1)
195 Ω(channel).Should(Receive())
196 Ω(channel).ShouldNot(Receive())
200 Context("for an unbuffered channel", func() {
201 It("should always fail", func() {
202 channel := make(chan bool)
205 Ω(channel).ShouldNot(Receive())
210 Context("When actual is a send-only channel", func() {
211 It("should error", func() {
212 channel := make(chan bool)
214 var writerChannel chan<- bool
215 writerChannel = channel
217 success, err := (&ReceiveMatcher{}).Match(writerChannel)
218 Ω(success).Should(BeFalse())
219 Ω(err).Should(HaveOccurred())
223 Context("when acutal is a non-channel", func() {
224 It("should error", func() {
225 var nilChannel chan bool
227 success, err := (&ReceiveMatcher{}).Match(nilChannel)
228 Ω(success).Should(BeFalse())
229 Ω(err).Should(HaveOccurred())
231 success, err = (&ReceiveMatcher{}).Match(nil)
232 Ω(success).Should(BeFalse())
233 Ω(err).Should(HaveOccurred())
235 success, err = (&ReceiveMatcher{}).Match(3)
236 Ω(success).Should(BeFalse())
237 Ω(err).Should(HaveOccurred())
241 Describe("when used with eventually and a custom matcher", func() {
242 It("should return the matcher's error when a failing value is received on the channel, instead of the must receive something failure", func() {
243 failures := InterceptGomegaFailures(func() {
244 c := make(chan string, 0)
245 Eventually(c, 0.01).Should(Receive(Equal("hello")))
247 Ω(failures[0]).Should(ContainSubstring("When passed a matcher, ReceiveMatcher's channel *must* receive something."))
249 failures = InterceptGomegaFailures(func() {
250 c := make(chan string, 1)
252 Eventually(c, 0.01).Should(Receive(Equal("hello")))
254 Ω(failures[0]).Should(ContainSubstring("<string>: hello"))
258 Describe("Bailing early", func() {
259 It("should bail early when passed a closed channel", func() {
264 failures := InterceptGomegaFailures(func() {
265 Eventually(c).Should(Receive())
267 Ω(time.Since(t)).Should(BeNumerically("<", 500*time.Millisecond))
268 Ω(failures).Should(HaveLen(1))
271 It("should bail early when passed a non-channel", func() {
273 failures := InterceptGomegaFailures(func() {
274 Eventually(3).Should(Receive())
276 Ω(time.Since(t)).Should(BeNumerically("<", 500*time.Millisecond))
277 Ω(failures).Should(HaveLen(1))