...

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

Documentation: github.com/onsi/gomega/matchers

     1  package matchers_test
     2  
     3  import (
     4  	"time"
     5  
     6  	. "github.com/onsi/ginkgo/v2"
     7  	. "github.com/onsi/gomega"
     8  	. "github.com/onsi/gomega/matchers"
     9  )
    10  
    11  type kungFuActor interface {
    12  	DrunkenMaster() bool
    13  }
    14  
    15  type jackie struct {
    16  	name string
    17  }
    18  
    19  func (j *jackie) DrunkenMaster() bool {
    20  	return true
    21  }
    22  
    23  type someError struct{ s string }
    24  
    25  func (e *someError) Error() string { return e.s }
    26  
    27  var _ = Describe("ReceiveMatcher", func() {
    28  	Context("with no argument", func() {
    29  		Context("for a buffered channel", func() {
    30  			It("should succeed", func() {
    31  				channel := make(chan bool, 1)
    32  
    33  				Expect(channel).ShouldNot(Receive())
    34  
    35  				channel <- true
    36  
    37  				Expect(channel).Should(Receive())
    38  			})
    39  		})
    40  
    41  		Context("for an unbuffered channel", func() {
    42  			It("should succeed (eventually)", func() {
    43  				channel := make(chan bool)
    44  
    45  				Expect(channel).ShouldNot(Receive())
    46  
    47  				go func() {
    48  					time.Sleep(10 * time.Millisecond)
    49  					channel <- true
    50  				}()
    51  
    52  				Eventually(channel).Should(Receive())
    53  			})
    54  		})
    55  	})
    56  
    57  	Context("with too many arguments", func() {
    58  		It("should error", func() {
    59  			channel := make(chan bool, 1)
    60  			var actual bool
    61  
    62  			channel <- true
    63  
    64  			success, err := (&ReceiveMatcher{Args: []interface{}{
    65  				&actual,
    66  				Equal(true),
    67  				42,
    68  			}}).Match(channel)
    69  			Expect(success).To(BeFalse())
    70  			Expect(err).To(HaveOccurred())
    71  		})
    72  	})
    73  
    74  	Context("with swapped arguments", func() {
    75  		It("should error", func() {
    76  			channel := make(chan bool, 1)
    77  			var actual bool
    78  
    79  			channel <- true
    80  
    81  			success, err := (&ReceiveMatcher{Args: []interface{}{
    82  				Equal(true),
    83  				&actual,
    84  			}}).Match(channel)
    85  			Expect(success).To(BeFalse())
    86  			Expect(err).To(HaveOccurred())
    87  		})
    88  	})
    89  
    90  	Context("with a pointer argument", func() {
    91  		Context("of the correct type", func() {
    92  			When("the channel has an interface type", func() {
    93  				It("should write the value received on the channel to the pointer", func() {
    94  					channel := make(chan error, 1)
    95  
    96  					var value *someError
    97  
    98  					Ω(channel).ShouldNot(Receive(&value))
    99  					Ω(value).Should(BeZero())
   100  
   101  					channel <- &someError{"boooom!"}
   102  
   103  					Ω(channel).Should(Receive(&value))
   104  					Ω(value).Should(MatchError("boooom!"))
   105  				})
   106  			})
   107  		})
   108  
   109  		Context("of the correct type", func() {
   110  			It("should write the value received on the channel to the pointer", func() {
   111  				channel := make(chan int, 1)
   112  
   113  				var value int
   114  
   115  				Expect(channel).ShouldNot(Receive(&value))
   116  				Expect(value).Should(BeZero())
   117  
   118  				channel <- 17
   119  
   120  				Expect(channel).Should(Receive(&value))
   121  				Expect(value).Should(Equal(17))
   122  			})
   123  		})
   124  
   125  		Context("to various types of objects", func() {
   126  			It("should work", func() {
   127  				//channels of strings
   128  				stringChan := make(chan string, 1)
   129  				stringChan <- "foo"
   130  
   131  				var s string
   132  				Expect(stringChan).Should(Receive(&s))
   133  				Expect(s).Should(Equal("foo"))
   134  
   135  				//channels of slices
   136  				sliceChan := make(chan []bool, 1)
   137  				sliceChan <- []bool{true, true, false}
   138  
   139  				var sl []bool
   140  				Expect(sliceChan).Should(Receive(&sl))
   141  				Expect(sl).Should(Equal([]bool{true, true, false}))
   142  
   143  				//channels of channels
   144  				chanChan := make(chan chan bool, 1)
   145  				c := make(chan bool)
   146  				chanChan <- c
   147  
   148  				var receivedC chan bool
   149  				Expect(chanChan).Should(Receive(&receivedC))
   150  				Expect(receivedC).Should(Equal(c))
   151  
   152  				//channels of interfaces
   153  				jackieChan := make(chan kungFuActor, 1)
   154  				aJackie := &jackie{name: "Jackie Chan"}
   155  				jackieChan <- aJackie
   156  
   157  				var theJackie kungFuActor
   158  				Expect(jackieChan).Should(Receive(&theJackie))
   159  				Expect(theJackie).Should(Equal(aJackie))
   160  			})
   161  		})
   162  
   163  		Context("of the wrong type", func() {
   164  			It("should error", func() {
   165  				channel := make(chan int, 1)
   166  				channel <- 10
   167  
   168  				var incorrectType bool
   169  
   170  				success, err := (&ReceiveMatcher{Args: []interface{}{&incorrectType}}).Match(channel)
   171  				Expect(success).Should(BeFalse())
   172  				Expect(err).Should(HaveOccurred())
   173  
   174  				var notAPointer int
   175  				success, err = (&ReceiveMatcher{Args: []interface{}{notAPointer}}).Match(channel)
   176  				Expect(success).Should(BeFalse())
   177  				Expect(err).Should(HaveOccurred())
   178  			})
   179  		})
   180  	})
   181  
   182  	Context("with a matcher", func() {
   183  		It("should defer to the underlying matcher", func() {
   184  			intChannel := make(chan int, 1)
   185  			intChannel <- 3
   186  			Expect(intChannel).Should(Receive(Equal(3)))
   187  
   188  			intChannel <- 2
   189  			Expect(intChannel).ShouldNot(Receive(Equal(3)))
   190  
   191  			stringChannel := make(chan []string, 1)
   192  			stringChannel <- []string{"foo", "bar", "baz"}
   193  			Expect(stringChannel).Should(Receive(ContainElement(ContainSubstring("fo"))))
   194  
   195  			stringChannel <- []string{"foo", "bar", "baz"}
   196  			Expect(stringChannel).ShouldNot(Receive(ContainElement(ContainSubstring("archipelago"))))
   197  		})
   198  
   199  		It("should defer to the underlying matcher for the message", func() {
   200  			matcher := Receive(Equal(3))
   201  			channel := make(chan int, 1)
   202  			channel <- 2
   203  			matcher.Match(channel)
   204  			Expect(matcher.FailureMessage(channel)).Should(MatchRegexp(`Expected\s+<int>: 2\s+to equal\s+<int>: 3`))
   205  
   206  			channel <- 3
   207  			matcher.Match(channel)
   208  			Expect(matcher.NegatedFailureMessage(channel)).Should(MatchRegexp(`Expected\s+<int>: 3\s+not to equal\s+<int>: 3`))
   209  		})
   210  
   211  		It("should work just fine with Eventually", func() {
   212  			stringChannel := make(chan string)
   213  
   214  			go func() {
   215  				time.Sleep(5 * time.Millisecond)
   216  				stringChannel <- "A"
   217  				time.Sleep(5 * time.Millisecond)
   218  				stringChannel <- "B"
   219  			}()
   220  
   221  			Eventually(stringChannel).Should(Receive(Equal("B")))
   222  		})
   223  
   224  		Context("if the matcher errors", func() {
   225  			It("should error", func() {
   226  				channel := make(chan int, 1)
   227  				channel <- 3
   228  				success, err := (&ReceiveMatcher{Args: []interface{}{ContainSubstring("three")}}).Match(channel)
   229  				Expect(success).Should(BeFalse())
   230  				Expect(err).Should(HaveOccurred())
   231  			})
   232  		})
   233  
   234  		Context("if nothing is received", func() {
   235  			It("should fail", func() {
   236  				channel := make(chan int, 1)
   237  				success, err := (&ReceiveMatcher{Args: []interface{}{Equal(1)}}).Match(channel)
   238  				Expect(success).Should(BeFalse())
   239  				Expect(err).ShouldNot(HaveOccurred())
   240  			})
   241  		})
   242  	})
   243  
   244  	Context("with a pointer and a matcher argument", func() {
   245  		It("should succeed", func() {
   246  			channel := make(chan bool, 1)
   247  			channel <- true
   248  
   249  			var received bool
   250  
   251  			Expect(channel).Should(Receive(&received, Equal(true)))
   252  			Expect(received).Should(BeTrue())
   253  		})
   254  	})
   255  
   256  	Context("When actual is a *closed* channel", func() {
   257  		Context("for a buffered channel", func() {
   258  			It("should work until it hits the end of the buffer", func() {
   259  				channel := make(chan bool, 1)
   260  				channel <- true
   261  
   262  				close(channel)
   263  
   264  				Expect(channel).Should(Receive())
   265  				Expect(channel).ShouldNot(Receive())
   266  			})
   267  		})
   268  
   269  		Context("for an unbuffered channel", func() {
   270  			It("should always fail", func() {
   271  				channel := make(chan bool)
   272  				close(channel)
   273  
   274  				Expect(channel).ShouldNot(Receive())
   275  			})
   276  		})
   277  	})
   278  
   279  	Context("When actual is a send-only channel", func() {
   280  		It("should error", func() {
   281  			channel := make(chan bool)
   282  
   283  			var writerChannel chan<- bool
   284  			writerChannel = channel
   285  
   286  			success, err := (&ReceiveMatcher{}).Match(writerChannel)
   287  			Expect(success).Should(BeFalse())
   288  			Expect(err).Should(HaveOccurred())
   289  		})
   290  	})
   291  
   292  	When("acutal is a non-channel", func() {
   293  		It("should error", func() {
   294  			var nilChannel chan bool
   295  
   296  			success, err := (&ReceiveMatcher{}).Match(nilChannel)
   297  			Expect(success).Should(BeFalse())
   298  			Expect(err).Should(HaveOccurred())
   299  
   300  			success, err = (&ReceiveMatcher{}).Match(nil)
   301  			Expect(success).Should(BeFalse())
   302  			Expect(err).Should(HaveOccurred())
   303  
   304  			success, err = (&ReceiveMatcher{}).Match(3)
   305  			Expect(success).Should(BeFalse())
   306  			Expect(err).Should(HaveOccurred())
   307  		})
   308  	})
   309  
   310  	Describe("when used with eventually and a custom matcher", func() {
   311  		It("should return the matcher's error when a failing value is received on the channel, instead of the must receive something failure", func() {
   312  			failures := InterceptGomegaFailures(func() {
   313  				c := make(chan string)
   314  				Eventually(c, 0.01).Should(Receive(Equal("hello")))
   315  			})
   316  			Expect(failures[0]).Should(ContainSubstring("When passed a matcher, ReceiveMatcher's channel *must* receive something."))
   317  
   318  			failures = InterceptGomegaFailures(func() {
   319  				c := make(chan string, 1)
   320  				c <- "hi"
   321  				Eventually(c, 0.01).Should(Receive(Equal("hello")))
   322  			})
   323  			Expect(failures[0]).Should(ContainSubstring("<string>: hello"))
   324  		})
   325  	})
   326  
   327  	Describe("Bailing early", func() {
   328  		It("should bail early when passed a closed channel", func() {
   329  			c := make(chan bool)
   330  			close(c)
   331  
   332  			t := time.Now()
   333  			failures := InterceptGomegaFailures(func() {
   334  				Eventually(c).Should(Receive())
   335  			})
   336  			Expect(time.Since(t)).Should(BeNumerically("<", 500*time.Millisecond))
   337  			Expect(failures).Should(HaveLen(1))
   338  		})
   339  
   340  		It("should bail early when passed a non-channel", func() {
   341  			t := time.Now()
   342  			failures := InterceptGomegaFailures(func() {
   343  				Eventually(3).Should(Receive())
   344  			})
   345  			Expect(time.Since(t)).Should(BeNumerically("<", 500*time.Millisecond))
   346  			Expect(failures).Should(HaveLen(1))
   347  		})
   348  	})
   349  })
   350  

View as plain text