github.com/onsi/gomega@v1.32.0/docs/index.md (about)

     1  ---
     2  layout: default
     3  title: Gomega
     4  ---
     5  {% raw  %}
     6  ![Gomega](./images/gomega.png)
     7  
     8  [Gomega](http://github.com/onsi/gomega) is a matcher/assertion library.  It is best paired with the [Ginkgo](http://github.com/onsi/ginkgo) BDD test framework, but can be adapted for use in other contexts too.
     9  
    10  ## Support Policy
    11  
    12  Gomega provides support for versions of Go that are noted by the [Go release policy](https://golang.org/doc/devel/release.html#policy) i.e. N and N-1 major versions.
    13  
    14  ## Getting Gomega
    15  
    16  Just `go get` it:
    17  
    18  ```bash
    19  $ go get github.com/onsi/gomega/...
    20  ```
    21  
    22  ## Getting Gomega as needed
    23  
    24  Instead of getting all of Gomega and it's dependency tree, you can use the go command to get the dependencies as needed.
    25  
    26  For example, import gomega in your test code:
    27  
    28  ```go
    29  import "github.com/onsi/gomega"
    30  ```
    31  
    32  Use `go get -t` to retrieve the packages referenced in your test code:
    33  
    34  ```bash
    35  $ cd /path/to/my/app
    36  $ go get -t ./...
    37  ```
    38  
    39  ## Using Gomega with Ginkgo
    40  
    41  When a Gomega assertion fails, Gomega calls a `GomegaFailHandler`.  This is a function that you must provide using `gomega.RegisterFailHandler()`.
    42  
    43  If you're using Ginkgo, all you need to do is:
    44  
    45  ```go
    46  gomega.RegisterFailHandler(ginkgo.Fail)
    47  ```
    48  
    49  before you start your test suite.
    50  
    51  If you use the `ginkgo` CLI to `ginkgo bootstrap` a test suite, this hookup will be automatically generated for you.
    52  
    53  > `GomegaFailHandler` is defined in the `types` subpackage.
    54  
    55  ## Using Gomega with Golang's XUnit-style Tests
    56  
    57  Though Gomega is tailored to work best with Ginkgo it is easy to use Gomega with Golang's XUnit style tests.  Here's how:
    58  
    59  To use Gomega with Golang's XUnit style tests:
    60  
    61  ```go
    62  func TestFarmHasCow(t *testing.T) {
    63      g := NewWithT(t)
    64  
    65      f := farm.New([]string{"Cow", "Horse"})
    66      g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow")
    67  }
    68  ```
    69  
    70  `NewWithT(t)` wraps a `*testing.T` and returns a struct that supports `Expect`, `Eventually`, and `Consistently`.
    71  
    72  ## Making Assertions
    73  
    74  Gomega provides two notations for making assertions.  These notations are functionally equivalent and their differences are purely aesthetic.
    75  
    76  - When you use the `Ω` notation, your assertions look like this:
    77  
    78  ```go
    79  Ω(ACTUAL).Should(Equal(EXPECTED))
    80  Ω(ACTUAL).ShouldNot(Equal(EXPECTED))
    81  ```
    82  
    83  - When you use the `Expect` notation, your assertions look like this:
    84  
    85  ```go
    86  Expect(ACTUAL).To(Equal(EXPECTED))
    87  Expect(ACTUAL).NotTo(Equal(EXPECTED))
    88  Expect(ACTUAL).ToNot(Equal(EXPECTED))
    89  ```
    90  
    91  On OS X the `Ω` character should be easy to type, it is usually just option-z: `⌥z`.
    92  
    93  On the left hand side, you can pass anything you want in to `Ω` and `Expect` for `ACTUAL`.  On the right hand side you must pass an object that satisfies the `GomegaMatcher` interface.  Gomega's matchers (e.g. `Equal(EXPECTED)`) are simply functions that create and initialize an appropriate `GomegaMatcher` object.
    94  
    95  > Note that `Should` and `To` are just syntactic sugar and are functionally identical. Same is the case for `ToNot` and `NotTo`.
    96  
    97  > The `GomegaMatcher` interface is pretty simple and is discussed in the [custom matchers](#adding-your-own-matchers) section.  It is defined in the `types` subpackage.
    98  
    99  ### Handling Errors
   100  
   101  It is a common pattern, in Golang, for functions and methods to return two things - a value and an error.  For example:
   102  
   103  ```go
   104  func DoSomethingHard() (string, error) {
   105      ...
   106  }
   107  ```
   108  
   109  To assert on the return value of such a method you might write a test that looks like this:
   110  
   111  ```go
   112  result, err := DoSomethingHard()
   113  Ω(err).ShouldNot(HaveOccurred())
   114  Ω(result).Should(Equal("foo"))
   115  ```
   116  
   117  Gomega streamlines this very common use case.  Both `Ω` and `Expect` accept *multiple* arguments.  The first argument is passed to the matcher, and the match only succeeds if *all* subsequent arguments are `nil` or zero-valued.  With this, we can rewrite the above example as:
   118  
   119  ```go
   120  Ω(DoSomethingHard()).Should(Equal("foo"))
   121  ```
   122  
   123  This will only pass if the return value of `DoSomethingHard()` is `("foo", nil)`.
   124  
   125  Additionally, if you call a function with a single `error` return value you can use the `Succeed` matcher to assert the function has returned without error.  So for a function of the form:
   126  
   127  ```go
   128  func DoSomethingSimple() error {
   129      ...
   130  }
   131  ```
   132  
   133  You can either write:
   134  
   135  ```go
   136  err := DoSomethingSimple()
   137  Ω(err).ShouldNot(HaveOccurred())
   138  ```
   139  
   140  Or you can write:
   141  
   142  ```go
   143  Ω(DoSomethingSimple()).Should(Succeed())
   144  ```
   145  
   146  > You should not use a function with multiple return values (like `DoSomethingHard`) with `Succeed`.  Matchers are only passed the *first* value provided to `Ω`/`Expect`, the subsequent arguments are handled by `Ω` and `Expect` as outlined above.  As a result of this behavior `Ω(DoSomethingHard()).ShouldNot(Succeed())` would never pass.
   147  
   148  Assertions about errors on functions with multiple return values can be made as follows (and in a lazy way when not asserting that all other return values are zero values):
   149  
   150  ```go
   151  _, _, _, err := MultipleReturnValuesFunc()
   152  Ω(err).Should(HaveOccurred())
   153  ```
   154  
   155  Alternatively, such error assertions on multi return value functions can be simplified by chaining `Error` to `Ω` and `Expect`. Doing so will additionally automatically assert that all return values, except for the trailing error return value, are in fact zero values:
   156  
   157  ```go
   158  Ω(MultipleReturnValuesFunc()).Error().Should(HaveOccurred())
   159  ```
   160  
   161  Similar, asserting that no error occurred is supported, too (where the other return values are allowed to take on any value):
   162  
   163  ```go
   164  Ω(MultipleReturnValuesFunc()).Error().ShouldNot(HaveOccurred())
   165  ```
   166  
   167  ### Annotating Assertions
   168  
   169  You can annotate any assertion by passing either a format string (and optional inputs to format) or a function of type `func() string` after the `GomegaMatcher`:
   170  
   171  ```go
   172  Ω(ACTUAL).Should(Equal(EXPECTED), "My annotation %d", foo)
   173  Ω(ACTUAL).ShouldNot(Equal(EXPECTED), "My annotation %d", foo)
   174  Expect(ACTUAL).To(Equal(EXPECTED), "My annotation %d", foo)
   175  Expect(ACTUAL).NotTo(Equal(EXPECTED), "My annotation %d", foo)
   176  Expect(ACTUAL).ToNot(Equal(EXPECTED), "My annotation %d", foo)
   177  Expect(ACTUAL).To(Equal(EXPECTED), func() string { return "My annotation" })
   178  ```
   179  
   180  If you pass a format string, the format string and inputs will be passed to `fmt.Sprintf(...)`.
   181  If you instead pass a function, the function will be lazily evaluated if the assertion fails.
   182  In both cases, if the assertion fails, Gomega will print your annotation alongside its standard failure message.
   183  
   184  This is useful in cases where the standard failure message lacks context.  For example, if the following assertion fails:
   185  
   186  ```go
   187  Ω(SprocketsAreLeaky()).Should(BeFalse())
   188  ```
   189  
   190  Gomega will output:
   191  
   192  ```
   193  Expected
   194   <bool>: true
   195  to be false
   196  ```
   197  
   198  But this assertion:
   199  
   200  ```go
   201  Ω(SprocketsAreLeaky()).Should(BeFalse(), "Sprockets shouldn't leak")
   202  ```
   203  
   204  Will offer the more helpful output:
   205  
   206  ```
   207  Sprockets shouldn't leak
   208  Expected
   209    <bool>: true
   210  to be false
   211  ```
   212  
   213  
   214  ### Adjusting Output
   215  
   216  When a failure occurs, Gomega prints out a recursive description of the objects involved in the failed assertion.  This output can be very verbose, but Gomega's philosophy is to give as much output as possible to aid in identifying the root cause of a test failure.
   217  
   218  These recursive object renditions are performed by the `format` subpackage. Import the format subpackage in your test code:
   219  
   220  ```go
   221  import "github.com/onsi/gomega/format"
   222  ```
   223  
   224  `format` provides some globally adjustable settings to tune Gomega's output:
   225  
   226  - `format.MaxLength = 4000`: Gomega will recursively traverse nested data structures as it produces output. If the length of this string representation is more than MaxLength, it will be truncated to MaxLength. To disable this behavior, set the MaxLength to `0`.
   227  - `format.MaxDepth = 10`: Gomega will recursively traverse nested data structures as it produces output. By default the maximum depth of this recursion is set to `10` you can adjust this to see deeper or shallower representations of objects.
   228  - Implementing `format.GomegaStringer`: If `GomegaStringer` interface is implemented on an object, Gomega will call `GomegaString` for an object's string representation. This is regardless of the `format.UseStringerRepresentation` value. Best practice to implement this interface is to implement it in a helper test file (e.g. `helper_test.go`) to avoid leaking it to your package's exported API.
   229  - `format.UseStringerRepresentation = false`: Gomega does *not* call `String` or `GoString` on objects that satisfy the `Stringer` and `GoStringer` interfaces.  Oftentimes such representations, while more human readable, do not contain all the relevant information associated with an object thereby making it harder to understand why a test might be failing.  If you'd rather see the output of `String` or `GoString` set this property to `true`.
   230  
   231  > For a tricky example of why `format.UseStringerRepresentation = false` is your friend, check out issue [#37](https://github.com/onsi/gomega/issues/37).
   232  
   233  - `format.PrintContextObjects = false`: Gomega by default will not print the content of objects satisfying the context.Context interface, due to too much output. If you want to enable displaying that content, set this property to `true`.
   234  
   235  If you want to use Gomega's recursive object description in your own code you can call into the `format` package directly:
   236  
   237  ```go
   238  fmt.Println(format.Object(theThingYouWantToPrint, 1))
   239  ```
   240  
   241  - `format.TruncatedDiff = true`: Gomega will truncate long strings and only show where they differ. You can set this to `false` if
   242  you want to see the full strings.
   243  
   244  You can also register your own custom formatter using `format.RegisterCustomFormatter(f)`.  Custom formatters must be of type `type CustomFormatter func(value interface{}) (string, bool)`.  Gomega will pass in any objects to be formatted to each registered custom formatter.  A custom formatter signals that it will handle the passed-in object by returning a formatted string and `true`.  If it does not handle the object it should return `"", false`.  Strings returned by custom formatters will _not_ be truncated (though they may be truncated if the object being formatted is within another struct).  Custom formatters take precedence of `GomegaStringer` and `format.UseStringerRepresentation`.
   245  
   246  `format.RegisterCustomFormatter` returns a key that can be used to unregister the custom formatter:
   247  
   248  ```go
   249  key := format.RegisterCustomFormatter(myFormatter)
   250  ...
   251  format.UnregisterCustomFormatter(key)
   252  ```
   253  
   254  ## Making Asynchronous Assertions
   255  
   256  Gomega has support for making *asynchronous* assertions.  There are two functions that provide this support: `Eventually` and `Consistently`.
   257  
   258  ### Eventually
   259  
   260  `Eventually` checks that an assertion *eventually* passes.  `Eventually` blocks when called and attempts an assertion periodically until it passes or a timeout occurs.  Both the timeout and polling interval are configurable as optional arguments:
   261  
   262  ```go
   263  Eventually(ACTUAL, (TIMEOUT), (POLLING_INTERVAL), (context.Context)).Should(MATCHER)
   264  ```
   265  
   266  The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms).  Both intervals can be specified as time.Duration, parsable duration strings (e.g. "100ms") or `float64` (in which case they are interpreted as seconds).  You can also provide a `context.Context` which - when cancelled - will instruct `Eventually` to stop and exit with a failure message.  You are also allowed to pass in the `context.Context` _first_ as `Eventually(ctx, ACTUAL)`.
   267  
   268  > As with synchronous assertions, you can annotate asynchronous assertions by passing either a format string and optional inputs or a function of type `func() string` after the `GomegaMatcher`.
   269  
   270  Alternatively, the timeout and polling interval can also be specified by chaining `Within` and `ProbeEvery` or `WithTimeout` and `WithPolling` to `Eventually`:
   271  
   272  ```go
   273  Eventually(ACTUAL).WithTimeout(TIMEOUT).WithPolling(POLLING_INTERVAL).Should(MATCHER)
   274  Eventually(ACTUAL).Within(TIMEOUT).ProbeEvery(POLLING_INTERVAL).Should(MATCHER)
   275  ```
   276  
   277  You can also configure the context in this way:
   278  
   279  ```go
   280  Eventually(ACTUAL).WithTimeout(TIMEOUT).WithPolling(POLLING_INTERVAL).WithContext(ctx).Should(MATCHER)
   281  ```
   282  
   283  When no explicit timeout is provided, `Eventually` will use the default timeout.  However if no explicit timeout is provided _and_ a context is provided, `Eventually` will not apply a timeout but will instead keep trying until the context is cancelled.  If both a context and a timeout are provided, `Eventually` will keep trying until either the context is cancelled or time runs out, whichever comes first.
   284  
   285  You can also ensure a number of consecutive pass before continuing with `MustPassRepeatedly`:
   286  
   287  ```go
   288  Eventually(ACTUAL).MustPassRepeatedly(NUMBER).Should(MATCHER)
   289  ```
   290  
   291  Eventually works with any Gomega compatible matcher and supports making assertions against three categories of `ACTUAL` value:
   292  
   293  #### Category 1: Making `Eventually` assertions on values
   294  
   295  There are several examples of values that can change over time.  These can be passed in to `Eventually` and will be passed to the matcher repeatedly until a match occurs.  For example:
   296  
   297  ```go
   298  c := make(chan bool)
   299  go DoStuff(c)
   300  Eventually(c, "50ms").Should(BeClosed())
   301  ```
   302  
   303  will poll the channel repeatedly until it is closed.  In this example `Eventually` will block until either the specified timeout of 50ms has elapsed or the channel is closed, whichever comes first.
   304  
   305  Several Gomega libraries allow you to use Eventually in this way.  For example, the `gomega/gexec` package allows you to block until a `*gexec.Session` exits successfully via:
   306  
   307  ```go
   308  Eventually(session).Should(gexec.Exit(0))
   309  ```
   310  
   311  And the `gomega/gbytes` package allows you to monitor a streaming `*gbytes.Buffer` until a given string is seen:
   312  
   313  ```go
   314  Eventually(buffer).Should(gbytes.Say("hello there"))
   315  ```
   316  
   317  In these examples, both `session` and `buffer` are designed to be thread-safe when polled by the `Exit` and `Say` matchers.  This is not true in general of most raw values, so while it is tempting to do something like:
   318  
   319  ```go
   320  /* === INVALID === */
   321  var s *string
   322  go mutateStringEventually(s)
   323  Eventually(s).Should(Equal("I've changed"))
   324  ```
   325  
   326  this will trigger Go's race detector as the goroutine polling via Eventually will race over the value of `s` with the goroutine mutating the string.
   327  
   328  Similarly, something like `Eventually(slice).Should(HaveLen(N))` probably won't do what you think it should -- `Eventually` will be passed a pointer to the slice, yes, but if the slice is being `append`ed to (as in: `slice = append(slice, ...)`) Go will generate a new pointer and the pointer passed to `Eventually` will not contain the new elements.
   329  
   330  In both cases you should always pass `Eventually` a function that, when polled, returns the latest value of the object in question in a thread-safe way.
   331  
   332  #### Category 2: Making `Eventually` assertions on functions
   333  
   334  `Eventually` can be passed functions that **return at least one value**.  When configured this way, `Eventually` will poll the function repeatedly and pass the first returned value to the matcher.
   335  
   336  For example:
   337  
   338  ```go
   339  Eventually(func() int {
   340     return client.FetchCount()
   341  }).Should(BeNumerically(">=", 17))
   342  ```
   343  
   344  will repeatedly poll `client.FetchCount` until the `BeNumerically` matcher is satisfied.
   345  
   346  > Note that this example could have been written as `Eventually(client.FetchCount).Should(BeNumerically(">=", 17))`
   347  
   348  If multiple values are returned by the function, `Eventually` will pass the first value to the matcher and require that all others are zero-valued.  This allows you to pass `Eventually` a function that returns a value and an error - a common pattern in Go.
   349  
   350  For example, consider a method that returns a value and an error:
   351  
   352  ```go
   353  func FetchFromDB() (string, error)
   354  ```
   355  
   356  Then
   357  
   358  ```go
   359  Eventually(FetchFromDB).Should(Equal("got it"))
   360  ```
   361  
   362  will pass only if and when the returned error is `nil` *and* the returned string satisfies the matcher.
   363  
   364  
   365  Eventually can also accept functions that take arguments, however you must provide those arguments using `Eventually().WithArguments()`.  For example, consider a function that takes a user-id and makes a network request to fetch a full name:
   366  
   367  ```go
   368  func FetchFullName(userId int) (string, error)
   369  ```
   370  
   371  You can poll this function like so:
   372  
   373  ```go
   374  Eventually(FetchFullName).WithArguments(1138).Should(Equal("Wookie"))
   375  ```
   376  
   377  `WithArguments()` supports multiple arguments as well as variadic arguments.
   378  
   379  It is important to note that the function passed into Eventually is invoked **synchronously** when polled.  `Eventually` does not (in fact, it cannot) kill the function if it takes longer to return than `Eventually`'s configured timeout.  This is where using a `context.Context` can be helpful.  Here is an example that leverages Gingko's support for interruptible nodes and spec timeouts:
   380  
   381  ```go
   382  It("fetches the correct count", func(ctx SpecContext) {
   383      Eventually(func() int {
   384          return client.FetchCount(ctx, "/users")
   385      }, ctx).Should(BeNumerically(">=", 17))
   386  }, SpecTimeout(time.Second))
   387  ```
   388  
   389  now when the spec times out both the `client.FetchCount` function and `Eventually` will be signaled and told to exit. you can also use `Eventually().WithContext(ctx)` to provide the context.
   390  
   391  
   392  Since functions that take a context.Context as a first-argument are common in Go, `Eventually` supports automatically injecting the provided context into the function.  This plays nicely with `WithArguments()` as well.  You can rewrite the above example as:
   393  
   394  ```go
   395  It("fetches the correct count", func(ctx SpecContext) {
   396      Eventually(client.FetchCount).WithContext(ctx).WithArguments("/users").Should(BeNumerically(">=", 17))
   397  }, SpecTimeout(time.Second))
   398  ```
   399  
   400  now the `ctx` `SpecContext` is used both by `Eventually` and `client.FetchCount` and the `"/users"` argument is passed in after the `ctx` argument.
   401  
   402  The use of a context also allows you to specify a single timeout across a collection of `Eventually` assertions:
   403  
   404  ```go
   405  It("adds a few books and checks the count", func(ctx SpecContext) {
   406      intialCount := client.FetchCount(ctx, "/items")
   407      client.AddItem(ctx, "foo")
   408      client.AddItem(ctx, "bar")
   409      //note that there are several supported ways to pass in the context.  All are equivalent:
   410      Eventually(ctx, client.FetchCount).WithArguments("/items").Should(BeNumerically("==", initialCount + 2))
   411      Eventually(client.FetchItems).WithContext(ctx).Should(ContainElement("foo"))
   412      Eventually(client.FetchItems, ctx).Should(ContainElement("foo"))
   413  }, SpecTimeout(time.Second * 5))
   414  ```
   415  
   416  In addition, Gingko's `SpecContext` allows Gomega to tell Ginkgo about the status of a currently running `Eventually` whenever a Progress Report is generated.  So, if a spec times out while running an `Eventually` Ginkgo will not only show you which `Eventually` was running when the timeout occurred, but will also include the failure the `Eventually` was hitting when the timeout occurred.
   417  
   418  #### Category 3: Making assertions _in_ the function passed into `Eventually`
   419  
   420  When testing complex systems it can be valuable to assert that a *set* of assertions passes `Eventually`.  `Eventually` supports this by accepting functions that take **a single `Gomega` argument** and **return zero or more values**.
   421  
   422  Here's an example that makes some assertions and returns a value and error:
   423  
   424  ```go
   425  Eventually(func(g Gomega) (Widget, error) {
   426      ids, err := client.FetchIDs()
   427      g.Expect(err).NotTo(HaveOccurred())
   428      g.Expect(ids).To(ContainElement(1138))
   429      return client.FetchWidget(1138)
   430  }).Should(Equal(expectedWidget))
   431  ```
   432  
   433  will pass only if all the assertions in the polled function pass and the return value satisfied the matcher.  Note that the assertions in the body of the polled function must be performed using the passed-in `g Gomega` object.  If you use the global DSL expectations, `Eventually` will not intercept any failures and the test will fail.
   434  
   435  `Eventually` also supports a special case polling function that takes a single `Gomega` argument and returns no values.  `Eventually` assumes such a function is making assertions and is designed to work with the `Succeed` matcher to validate that all assertions have passed.
   436  
   437  For example:
   438  
   439  ```go
   440  Eventually(func(g Gomega) {
   441     model, err := client.Find(1138)
   442     g.Expect(err).NotTo(HaveOccurred())
   443     g.Expect(model.Reticulate()).To(Succeed())
   444     g.Expect(model.IsReticulated()).To(BeTrue())
   445     g.Expect(model.Save()).To(Succeed())
   446  }).Should(Succeed())
   447  ```
   448  
   449  will rerun the function until all assertions pass.
   450  
   451  You can also pass additional arguments to functions that take a Gomega.  The only rule is that the Gomega argument must be first.  If you also want to pass the context attached to `Eventually` you must ensure that is the second argument.  For example:
   452  
   453  ```go
   454  Eventually(func(g Gomega, ctx context.Context, path string, expected ...string){
   455      tok, err := client.GetToken(ctx)
   456      g.Expect(err).NotTo(HaveOccurred())
   457  
   458      elements, err := client.Fetch(ctx, tok, path)
   459      g.Expect(err).NotTo(HaveOccurred())
   460      g.Expect(elements).To(ConsistOf(expected))
   461  }).WithContext(ctx).WithArguments("/names", "Joe", "Jane", "Sam").Should(Succeed())
   462  ```
   463  
   464  ### Consistently
   465  
   466  `Consistently` checks that an assertion passes for a period of time.  It does this by polling its argument repeatedly during the period. It fails if the matcher ever fails during that period.
   467  
   468  For example:
   469  
   470  ```go
   471  Consistently(func() []int {
   472      return thing.MemoryUsage()
   473  }).Should(BeNumerically("<", 10))
   474  ```
   475  
   476  `Consistently` will poll the passed in function repeatedly and check the return value against the `GomegaMatcher`.  `Consistently` blocks and only returns when the desired duration has elapsed or if the matcher fails or if an (optional) passed-in context is cancelled.  The default value for the wait-duration is 100 milliseconds.  The default polling interval is 10 milliseconds.  Like `Eventually`, you can change these values by passing them in just after your function:
   477  
   478  ```go
   479  Consistently(ACTUAL, (DURATION), (POLLING_INTERVAL), (context.Context)).Should(MATCHER)
   480  ```
   481  
   482  As with `Eventually`, the duration parameters can be `time.Duration`s, string representations of a `time.Duration` (e.g. `"200ms"`) or `float64`s that are interpreted as seconds.
   483  
   484  Also as with `Eventually`, `Consistently` supports chaining `WithTimeout`, `WithPolling`, `WithContext` and `WithArguments` in the form of:
   485  
   486  ```go
   487  Consistently(ACTUAL).WithTimeout(DURATION).WithPolling(POLLING_INTERVAL).WithContext(ctx).WithArguments(...).Should(MATCHER)
   488  ```
   489  
   490  `Consistently` tries to capture the notion that something "does not eventually" happen.  A common use-case is to assert that no goroutine writes to a channel for a period of time.  If you pass `Consistently` an argument that is not a function, it simply passes that argument to the matcher.  So we can assert that:
   491  
   492  ```go
   493  Consistently(channel).ShouldNot(Receive())
   494  ```
   495  
   496  To assert that nothing gets sent to a channel.
   497  
   498  As with `Eventually`, you can also pass `Consistently` a function.  In fact, `Consistently` works with the three categories of `ACTUAL` value outlined for `Eventually` in the section above.
   499  
   500  If `Consistently` is passed a `context.Context` it will exit if the context is cancelled - however it will always register the cancellation of the context as a failure.  That is, the context is not used to control the duration of `Consistently` - that is always done by the `DURATION` parameter; instead, the context is used to allow `Consistently` to bail out early if it's time for the spec to finish up (e.g. a timeout has elapsed, or the user has sent an interrupt signal).
   501  
   502  When no explicit duration is provided, `Consistently` will use the default duration.  Unlike `Eventually`, this behavior holds whether or not a context is provided.
   503  
   504  > Developers often try to use `runtime.Gosched()` to nudge background goroutines to run.  This can lead to flaky tests as it is not deterministic that a given goroutine will run during the `Gosched`.  `Consistently` is particularly handy in these cases: it polls for 100ms which is typically more than enough time for all your Goroutines to run.  Yes, this is basically like putting a time.Sleep() in your tests... Sometimes, when making negative assertions in a concurrent world, that's the best you can do!
   505  
   506  ### Bailing Out Early - Polling Functions
   507  
   508  There are cases where you need to signal to `Eventually` and `Consistently` that they should stop trying.  Gomega provides`StopTrying(message string)` to allow you to send that signal.  There are two ways to use `StopTrying`.
   509  
   510  First, you can return `StopTrying` as an error. Consider, for example, the case where `Eventually` is searching through a set of possible queries with a server:
   511  
   512  ```go
   513  playerIndex, numPlayers := 0, 11
   514  Eventually(func() (string, error) {
   515      if playerIndex == numPlayers {
   516          return "", StopTrying("no more players left")
   517      }
   518      name := client.FetchPlayer(playerIndex)
   519      playerIndex += 1
   520      return name, nil
   521  }).Should(Equal("Patrick Mahomes"))
   522  ```
   523  
   524  Here we return a `StopTrying` error to tell `Eventually` that we've looked through all possible players and that it should stop.
   525  
   526  You can also call `StopTrying(...).Now()` to immediately end execution of the function. Consider, for example, the case of a client communicating with a server that experiences an irrevocable error:
   527  
   528  ```go
   529  Eventually(func() []string {
   530      names, err := client.FetchAllPlayers()
   531      if err == client.IRRECOVERABLE_ERROR {
   532          StopTrying("An irrecoverable error occurred").Now()
   533      }
   534      return names
   535  }).Should(ContainElement("Patrick Mahomes"))
   536  ```
   537  
   538  calling `.Now()` will trigger a panic that will signal to `Eventually` that it should stop trying.
   539  
   540  You can also return `StopTrying()` errors and use `StopTrying().Now()` with `Consistently`.
   541  
   542  Both `Eventually` and `Consistently` always treat the `StopTrying()` signal as a failure.   The failure message will include the message passed in to `StopTrying()`.
   543  
   544  You can add additional information to this failure message in a few ways.  You can wrap an error via `StopTrying(message).Wrap(wrappedErr)` - now the output will read `<message>: <wrappedErr.Error()>`.
   545  
   546  You can also attach arbitrary objects to `StopTrying()` via `StopTrying(message).Attach(description string, object any)`.  Gomega will run the object through Gomega's standard formatting library to build a consistent representation for end users.  You can attach multiple objects in this way and the output will look like:
   547  
   548  ```
   549  Told to stop trying after <X>
   550  
   551  <message>: <wrappedErr.Error()>
   552      <description>:
   553          <formatted-object>
   554      <description>:
   555          <formatted-object>
   556  ```
   557  
   558  ### Bailing Out Early - Matchers
   559  
   560  Just like functions being polled, matchers can also indicate if `Eventually`/`Consistently` should stop polling.  Matchers implement a `Match` method with the following signature:
   561  
   562  ```go
   563  Match(actual interface{}) (success bool, err error)
   564  ```
   565  
   566  If a matcher returns `StopTrying` for `error`, or calls `StopTrying(...).Now()`, `Eventually` and `Consistently` will stop polling and fail: `StopTrying` **always** signifies a failure.
   567  
   568  > Note: An alternative mechanism for having matchers bail out early is documented in the [custom matchers section below](#aborting-eventuallyconsistently).  This mechanism, which entails implementing a `MatchMayChangeIntheFuture(<actual>) bool` method, allows matchers to signify that no future change is possible out-of-band of the call to the matcher.
   569  
   570  ### Changing the Polling Interval Dynamically
   571  
   572  You typically configure the polling interval for `Eventually` and `Consistently` using the `.WithPolling()` or `.ProbeEvery()` chaining methods.  Sometimes, however, a polled function or matcher might want to signal that a service is unavailable but should be tried again after a certain duration.
   573  
   574  You can signal this to both `Eventually` and `Consistently` using `TryAgainAfter(<duration>)`.  This error-signal operates like `StopTrying()`: you can return `TryAgainAfter(<duration>)` as an error or throw a panic via `TryAgainAfter(<duration>).Now()`.  In either case, both `Eventually` and `Consistently` will wait for the specified duration before trying again.
   575  
   576  If a timeout occurs after the `TryAgainAfter` signal is sent but _before_ the next poll occurs both `Eventually` _and_ `Consistently` will always fail and print out the content of `TryAgainAfter`.  The default message is `"told to try again after <duration>"` however, as with `StopTrying` you can use `.Wrap()` and `.Attach()` to wrap an error and attach additional objects to include in the message, respectively.
   577  
   578  ### Modifying Default Intervals
   579  
   580  By default, `Eventually` will poll every 10 milliseconds for up to 1 second and `Consistently` will monitor every 10 milliseconds for up to 100 milliseconds.  You can modify these defaults across your test suite with:
   581  
   582  ```go
   583  SetDefaultEventuallyTimeout(t time.Duration)
   584  SetDefaultEventuallyPollingInterval(t time.Duration)
   585  SetDefaultConsistentlyDuration(t time.Duration)
   586  SetDefaultConsistentlyPollingInterval(t time.Duration)
   587  ```
   588  
   589  You can also adjust these global timeouts by setting the `GOMEGA_DEFAULT_EVENTUALLY_TIMEOUT`, `GOMEGA_DEFAULT_EVENTUALLY_POLLING_INTERVAL`, `GOMEGA_DEFAULT_CONSISTENTLY_DURATION`, and `GOMEGA_DEFAULT_CONSISTENTLY_POLLING_INTERVAL` environment variables to a parseable duration string. The environment variables have a lower precedence than `SetDefault...()`.
   590  
   591  ## Making Assertions in Helper Functions
   592  
   593  While writing [custom matchers](#adding-your-own-matchers) is an expressive way to make assertions against your code, it is often more convenient to write one-off helper functions like so:
   594  
   595  ```go
   596  var _ = Describe("Turbo-encabulator", func() {
   597      ...
   598      func assertTurboEncabulatorContains(components ...string) {
   599          teComponents, err := turboEncabulator.GetComponents()
   600          Expect(err).NotTo(HaveOccurred())
   601  
   602          Expect(teComponents).To(HaveLen(components))
   603          for _, component := range components {
   604              Expect(teComponents).To(ContainElement(component))
   605          }
   606      }
   607  
   608      It("should have components", func() {
   609          assertTurboEncabulatorContains("semi-boloid slots", "grammeters")
   610      })
   611  })
   612  ```
   613  
   614  This makes your tests more expressive and reduces boilerplate.  However, when an assertion in the helper fails the line numbers provided by Gomega are unhelpful.  Instead of pointing you to the line in your test that failed, they point you the line in the helper.
   615  
   616  To fix this, Ginkgo and Gomega provide two options.  If you are on a recent version of Ginkgo you can register your helper with Ginkgo via `GinkgoHelper()`:
   617  
   618  ```go
   619  func assertTurboEncabulatorContains(components ...string) {
   620      GinkgoHelper()
   621      teComponents, err := turboEncabulator.GetComponents()
   622      Expect(err).NotTo(HaveOccurred())
   623  
   624      Expect(teComponents).To(HaveLen(components))
   625      for _, component := range components {
   626          Expect(teComponents).To(ContainElement(component))
   627      }
   628  }
   629  ```
   630  
   631  now, line numbers generated by Ginkgo will skip `assertTurboEncabulatorContains` and point to the calling site instead.  `GinkgoHelper()` is the recommended way to solve this problem as it allows for straightforward nesting and reuse of helper functions.
   632  
   633  If, for some reason, you can't use `GinkgoHelper()` Gomega does provide an alternative: versions of `Expect`, `Eventually` and `Consistently` named `ExpectWithOffset`, `EventuallyWithOffset` and `ConsistentlyWithOffset` that allow you to specify an *offset* in the call stack.  The offset is the first argument to these functions.
   634  
   635  With this, we can rewrite our helper as:
   636  
   637  ```go
   638  func assertTurboEncabulatorContains(components ...string) {
   639      teComponents, err := turboEncabulator.GetComponents()
   640      ExpectWithOffset(1, err).NotTo(HaveOccurred())
   641  
   642      ExpectWithOffset(1, teComponents).To(HaveLen(components))
   643      for _, component := range components {
   644        ExpectWithOffset(1, teComponents).To(ContainElement(component))
   645      }
   646  }
   647  ```
   648  
   649  Now, failed assertions will point to the correct call to the helper in the test.
   650  
   651  Alternatively, you can just use the baseline versions of `Expect`, `Eventually` and `Consistently` and combine them with `WithOffset`:
   652  
   653  ```go
   654  func assertTurboEncabulatorContains(components ...string) {
   655      teComponents, err := turboEncabulator.GetComponents()
   656      Expect(err).WithOffset(1).NotTo(HaveOccurred())
   657  
   658      Expect(teComponents).WithOffset(1).To(HaveLen(components))
   659      for _, component := range components {
   660        Expect(teComponents).WithOffset(1).To(ContainElement(component))
   661      }
   662  }
   663  ```
   664  
   665  Again, we recommend using `GinkgoHelper()` instead of `WithOffset(...)`.
   666  
   667  ## Provided Matchers
   668  
   669  Gomega comes with a bunch of `GomegaMatcher`s.  They're all documented here.  If there's one you'd like to see written either [send a pull request or open an issue](http://github.com/onsi/gomega).
   670  
   671  A number of community-supported matchers have appeared as well.  A list is maintained on the Gomega [wiki](https://github.com/onsi/gomega/wiki).
   672  
   673  These docs only go over the positive assertion case (`Should`), the negative case (`ShouldNot`) is simply the negation of the positive case.  They also use the `Ω` notation, but - as mentioned above - the `Expect` notation is equivalent.
   674  
   675  ### Asserting Equivalence
   676  
   677  #### Equal(expected interface{})
   678  
   679  ```go
   680  Ω(ACTUAL).Should(Equal(EXPECTED))
   681  ```
   682  
   683  uses [`reflect.DeepEqual`](http://golang.org/pkg/reflect#deepequal) to compare `ACTUAL` with `EXPECTED`.
   684  
   685  `reflect.DeepEqual` is awesome.  It will use `==` when appropriate (e.g. when comparing primitives) but will recursively dig into maps, slices, arrays, and even your own structs to ensure deep equality.  `reflect.DeepEqual`, however, is strict about comparing types.  Both `ACTUAL` and `EXPECTED` *must* have the same type.  If you want to compare across different types (e.g. if you've defined a type alias) you should use `BeEquivalentTo`.
   686  
   687  It is an error for both `ACTUAL` and `EXPECTED` to be nil, you should use `BeNil()` instead.
   688  
   689  When both `ACTUAL` and `EXPECTED` are a very long strings, it will attempt to pretty-print the diff and display exactly where they differ.
   690  
   691  > For asserting equality between numbers of different types, you'll want to use the [`BeNumerically()`](#benumericallycomparator-string-compareto-interface) matcher.
   692  
   693  #### BeComparableTo(expected interface{}, options ...cmp.Option)
   694  
   695  ```go
   696  Ω(ACTUAL).Should(BeComparableTo(EXPECTED, options ...cmp.Option))
   697  ```
   698  
   699  uses [`gocmp.Equal`](http://github.com/google/go-cmp) from `github.com/google/go-cmp` to compare `ACTUAL` with `EXPECTED`.  This performs a deep object comparison like `reflect.DeepEqual` but offers a few additional configuration options.  Learn more at the [go-cmp godocs](https://pkg.go.dev/github.com/google/go-cmp).
   700  
   701  #### BeEquivalentTo(expected interface{})
   702  
   703  ```go
   704  Ω(ACTUAL).Should(BeEquivalentTo(EXPECTED))
   705  ```
   706  
   707  Like `Equal`, `BeEquivalentTo` uses `reflect.DeepEqual` to compare `ACTUAL` with `EXPECTED`.  Unlike `Equal`, however, `BeEquivalentTo` will first convert `ACTUAL`'s type to that of `EXPECTED` before making the comparison with `reflect.DeepEqual`.
   708  
   709  This means that `BeEquivalentTo` will successfully match equivalent values of different types.  This is particularly useful, for example, with type aliases:
   710  
   711  ```go
   712  type FoodSrce string
   713  
   714  Ω(FoodSrce("Cheeseboard Pizza")
   715   ).Should(Equal("Cheeseboard Pizza")) //will fail
   716  Ω(FoodSrce("Cheeseboard Pizza")
   717   ).Should(BeEquivalentTo("Cheeseboard Pizza")) //will pass
   718  ```
   719  
   720  As with `Equal` it is an error for both `ACTUAL` and `EXPECTED` to be nil, you should use `BeNil()` instead.
   721  
   722  As a rule, you **should not** use `BeEquivalentTo` with numbers.  Both of the following assertions are true:
   723  
   724  ```go
   725  Ω(5.1).Should(BeEquivalentTo(5))
   726  Ω(5).ShouldNot(BeEquivalentTo(5.1))
   727  ```
   728  
   729  the first assertion passes because 5.1 will be cast to an integer and will get rounded down!  Such false positives are terrible and should be avoided.  Use [`BeNumerically()`](#benumericallycomparator-string-compareto-interface) to compare numbers instead.
   730  
   731  #### BeIdenticalTo(expected interface{})
   732  
   733  ```go
   734  Ω(ACTUAL).Should(BeIdenticalTo(EXPECTED))
   735  ```
   736  
   737  Like `Equal`, `BeIdenticalTo` compares `ACTUAL` to `EXPECTED` for equality. Unlike `Equal`, however, it uses `==` to compare values. In practice, this means that primitive values like strings, integers and floats are identical to, as well as pointers to values.
   738  
   739  `BeIdenticalTo` is most useful when you want to assert that two pointers point to the exact same location in memory.
   740  
   741  As with `Equal` it is an error for both `ACTUAL` and `EXPECTED` to be nil, you should use `BeNil()` instead.
   742  
   743  #### BeAssignableToTypeOf(expected interface)
   744  
   745  ```go
   746  Ω(ACTUAL).Should(BeAssignableToTypeOf(EXPECTED interface))
   747  ```
   748  
   749  succeeds if `ACTUAL` is a type that can be assigned to a variable with the same type as `EXPECTED`.  It is an error for either `ACTUAL` or `EXPECTED` to be `nil`.
   750  
   751  ### Asserting Presence
   752  
   753  #### BeNil()
   754  
   755  ```go
   756  Ω(ACTUAL).Should(BeNil())
   757  ```
   758  
   759  succeeds if `ACTUAL` is, in fact, `nil`.
   760  
   761  #### BeZero()
   762  
   763  ```go
   764  Ω(ACTUAL).Should(BeZero())
   765  ```
   766  
   767  succeeds if `ACTUAL` is the zero value for its type *or* if `ACTUAL` is `nil`.
   768  
   769  ### Asserting Truthiness
   770  
   771  #### BeTrue()
   772  
   773  ```go
   774  Ω(ACTUAL).Should(BeTrue())
   775  ```
   776  
   777  succeeds if `ACTUAL` is `bool` typed and has the value `true`.  It is an error for `ACTUAL` to not be a `bool`. 
   778  
   779  Since Gomega has no additional context about your assertion the failure messages are generally not particularly helpful.  So it's generally recommended that you use `BeTrueBecause` instead.
   780  
   781  > Some matcher libraries have a notion of "truthiness" to assert that an object is present.  Gomega is strict, and `BeTrue()` only works with `bool`s.  You can use `Ω(ACTUAL).ShouldNot(BeZero())` or `Ω(ACTUAL).ShouldNot(BeNil())` to verify object presence.
   782  
   783  ### BeTrueBecause(reason)
   784  
   785  ```go
   786  Ω(ACTUAL).Should(BeTrueBecause(REASON, ARGS...))
   787  ```
   788  
   789  is just like `BeTrue()` but allows you to pass in a reason.  This is a best practice as the default failure message is not particularly helpful. `fmt.Sprintf(REASON, ARGS...)` is used to render the reason.  For example:
   790  
   791  ```go
   792  Ω(cow.JumpedOver(moon)).Should(BeTrueBecause("the cow should have jumped over the moon"))
   793  ```
   794  
   795  #### BeFalse()
   796  
   797  ```go
   798  Ω(ACTUAL).Should(BeFalse())
   799  ```
   800  
   801  succeeds if `ACTUAL` is `bool` typed and has the value `false`.  It is an error for `ACTUAL` to not be a `bool`.  You should generaly use `BeFalseBecause` instead to pas in a reason for a more helpful error message.
   802  
   803  ### BeFalseBecause(reason)
   804  
   805  ```go
   806  Ω(ACTUAL).Should(BeFalseBecause(REASON, ARGS...))
   807  ```
   808  
   809  is just like `BeFalse()` but allows you to pass in a reason.  This is a best practice as the default failure message is not particularly helpful.  `fmt.Sprintf(REASON, ARGS...)` is used to render the reason.
   810  
   811  ```go
   812  Ω(cow.JumpedOver(mars)).Should(BeFalseBecause("the cow should not have jumped over mars"))
   813  ```
   814  
   815  ### Asserting on Errors
   816  
   817  #### HaveOccurred()
   818  
   819  ```go
   820  Ω(ACTUAL).Should(HaveOccurred())
   821  ```
   822  
   823  succeeds if `ACTUAL` is a non-nil `error`.  Thus, the typical Go error checking pattern looks like:
   824  
   825  ```go
   826  err := SomethingThatMightFail()
   827  Ω(err).ShouldNot(HaveOccurred())
   828  ```
   829  
   830  #### Succeed()
   831  
   832  ```go
   833  Ω(ACTUAL).Should(Succeed())
   834  ```
   835  
   836  succeeds if `ACTUAL` is `nil`.  The intended usage is
   837  
   838  ```go
   839  Ω(FUNCTION()).Should(Succeed())
   840  ```
   841  
   842  where `FUNCTION()` is a function call that returns an error-type as its *first or only* return value.  See [Handling Errors](#handling-errors) for a more detailed discussion.
   843  
   844  #### MatchError(expected interface{})
   845  
   846  ```go
   847  Ω(ACTUAL).Should(MatchError(EXPECTED, <FUNCTION_ERROR_DESCRIPTION>))
   848  ```
   849  
   850  succeeds if `ACTUAL` is a non-nil `error` that matches `EXPECTED`. `EXPECTED` must be one of the following:
   851  
   852  - A string, in which case the matcher asserts that `ACTUAL.Error() == EXPECTED`
   853  - An error (i.e. anything satisfying Go's `error` interface).  In which case the matcher:
   854      - First checks if `errors.Is(ACTUAL, EXPECTED)` returns `true`
   855      - If not, it checks if `ACTUAL` or any of the errors it wraps (directly or indirectly) equals `EXPECTED` via `reflect.DeepEqual()`.
   856  - A matcher, in which case `ACTUAL.Error()` is tested against the matcher, for example `Expect(err).Should(MatchError(ContainSubstring("sprocket not found")))`  will pass if `err.Error()` has the substring "sprocke tnot found"
   857  - A function with signature `func(error) bool`.  The matcher then passes if `f(ACTUAL)` returns `true`.  If using a function in this way you are required to pass a `FUNCTION_ERROR_DESCRIPTION` argument to `MatchError` that describes the function.  This description is used in the failure message.  For example: `Expect(err).To(MatchError(os.IsNotExist, "IsNotExist))`
   858  
   859  Any other type for `EXPECTED` is an error. It is also an error for `ACTUAL` to be nil.  Note that `FUNCTION_ERROR_DESCRIPTION` is a description of the error function, if used.  This is required when passing a function but is ignored in all other cases.
   860  
   861  ### Working with Channels
   862  
   863  #### BeClosed()
   864  
   865  ```go
   866  Ω(ACTUAL).Should(BeClosed())
   867  ```
   868  
   869  succeeds if `ACTUAL` is a closed channel. It is an error to pass a non-channel to `BeClosed`, it is also an error to pass `nil`.
   870  
   871  In order to check whether or not the channel is closed, Gomega must try to read from the channel (even in the `ShouldNot(BeClosed())` case).  You should keep this in mind if you wish to make subsequent assertions about values coming down the channel.
   872  
   873  Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before asserting that it is closed (it is not possible to detect that a buffered-channel has been closed until all its buffered values are read).
   874  
   875  Finally, as a corollary: it is an error to check whether or not a send-only channel is closed.
   876  
   877  #### Receive()
   878  
   879  ```go
   880  Ω(ACTUAL).Should(Receive(<optionalPointer>))
   881  ```
   882  
   883  succeeds if there is a message to be received on actual. Actual must be a channel (and cannot be a send-only channel) -- anything else is an error.
   884  
   885  `Receive` returns *immediately*.  It *never* blocks:
   886  
   887  - If there is nothing on the channel `c` then `Ω(c).Should(Receive())` will fail and `Ω(c).ShouldNot(Receive())` will pass.
   888  - If there is something on the channel `c` ready to be read, then `Ω(c).Should(Receive())` will pass and `Ω(c).ShouldNot(Receive())` will fail.
   889  - If the channel `c` is closed then `Ω(c).Should(Receive())` will fail and `Ω(c).ShouldNot(Receive())` will pass.
   890  
   891  If you have a go-routine running in the background that will write to channel `c`, for example:
   892  
   893  ```go
   894  go func() {
   895      time.Sleep(100 * time.Millisecond)
   896      c <- true
   897  }()
   898  ```
   899  
   900  you can assert that `c` receives something (anything!) eventually:
   901  
   902  ```go
   903  Eventually(c).Should(Receive())
   904  ```
   905  
   906  This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`).
   907  
   908  A similar use-case is to assert that no go-routine writes to a channel (for a period of time).  You can do this with `Consistently`:
   909  
   910  ```go
   911  Consistently(c).ShouldNot(Receive())
   912  ```
   913  
   914  `Receive` also allows you to make assertions on the received object.  You do this by passing `Receive` a matcher:
   915  
   916  ```go
   917  Eventually(c).Should(Receive(Equal("foo")))
   918  ```
   919  
   920  This assertion will only succeed if `c` receives an object *and* that object satisfies `Equal("foo")`.  Note that `Eventually` will continually poll `c` until this condition is met.  If there are objects coming down the channel that do not satisfy the passed in matcher, they will be pulled off and discarded until an object that *does* satisfy the matcher is received.
   921  
   922  In addition, there are occasions when you need to grab the object sent down the channel (e.g. to make several assertions against the object).  To do this, you can ask the `Receive` matcher for the value passed to the channel by passing it a pointer to a variable of the appropriate type:
   923  
   924  ```go
   925  var receivedBagel Bagel
   926  Eventually(bagelChan).Should(Receive(&receivedBagel))
   927  Ω(receivedBagel.Contents()).Should(ContainElement("cream cheese"))
   928  Ω(receivedBagel.Kind()).Should(Equal("sesame"))
   929  ```
   930  
   931  Of course, this could have been written as `receivedBagel := <-bagelChan` - however using `Receive` makes it easy to avoid hanging the test suite should nothing ever come down the channel. The pointer can point to any variable whose type is assignable from the channel element type, or if the channel type is an interface and the underlying type is assignable to the pointer.
   932  
   933  Finally, `Receive` *never* blocks.  `Eventually(c).Should(Receive())` repeatedly polls `c` in a non-blocking fashion.  That means that you cannot use this pattern to verify that a *non-blocking send* has occurred on the channel - [more details at this GitHub issue](https://github.com/onsi/gomega/issues/82).
   934  
   935  #### BeSent(value interface{})
   936  
   937  ```go
   938  Ω(ACTUAL).Should(BeSent(VALUE))
   939  ```
   940  
   941  attempts to send `VALUE` to the channel `ACTUAL` without blocking.  It succeeds if this is possible.
   942  
   943  `ACTUAL` must be a channel (and cannot be a receive-only channel) that can be sent the type of the `VALUE` passed into `BeSent` -- anything else is an error. In addition, `ACTUAL` must not be closed.
   944  
   945  `BeSent` never blocks:
   946  
   947  - If the channel `c` is not ready to receive then `Ω(c).Should(BeSent("foo"))` will fail immediately.
   948  - If the channel `c` is eventually ready to receive then `Eventually(c).Should(BeSent("foo"))` will succeed... presuming the channel becomes ready to receive before `Eventually`'s timeout.
   949  - If the channel `c` is closed then `Ω(c).Should(BeSent("foo"))` and `Ω(c).ShouldNot(BeSent("foo"))` will both fail immediately.
   950  
   951  Of course, `VALUE` is actually sent to the channel.  The point of `BeSent` is less to make an assertion about the availability of the channel (which is typically an implementation detail that your test should not be concerned with). Rather, the point of `BeSent` is to make it possible to easily and expressively write tests that can timeout on blocked channel sends.
   952  
   953  ### Working with files
   954  
   955  #### BeAnExistingFile
   956  
   957  ```go
   958  Ω(ACTUAL).Should(BeAnExistingFile())
   959  ```
   960  
   961  succeeds if a file located at `ACTUAL` exists.
   962  
   963  `ACTUAL` must be a string representing the filepath.
   964  
   965  #### BeARegularFile
   966  
   967  ```go
   968  Ω(ACTUAL).Should(BeARegularFile())
   969  ```
   970  
   971  succeeds IFF a file located at `ACTUAL` exists and is a regular file.
   972  
   973  `ACTUAL` must be a string representing the filepath.
   974  
   975  #### BeADirectory
   976  
   977  ```go
   978  Ω(ACTUAL).Should(BeADirectory())
   979  ```
   980  
   981  succeeds IFF a file is located at `ACTUAL` exists and is a directory.
   982  
   983  `ACTUAL` must be a string representing the filepath.
   984  
   985  ### Working with Strings, JSON and YAML
   986  
   987  #### ContainSubstring(substr string, args ...interface{})
   988  
   989  ```go
   990  Ω(ACTUAL).Should(ContainSubstring(STRING, ARGS...))
   991  ```
   992  
   993  succeeds if `ACTUAL` contains the substring generated by:
   994  
   995  ```go
   996  fmt.Sprintf(STRING, ARGS...)
   997  ```
   998  
   999  `ACTUAL` must either be a `string`, `[]byte` or a `Stringer` (a type implementing the `String()` method).  Any other input is an error.
  1000  
  1001  > Note, of course, that the `ARGS...` are not required.  They are simply a convenience to allow you to build up strings programmatically inline in the matcher.
  1002  
  1003  #### HavePrefix(prefix string, args ...interface{})
  1004  
  1005  ```go
  1006  Ω(ACTUAL).Should(HavePrefix(STRING, ARGS...))
  1007  ```
  1008  
  1009  succeeds if `ACTUAL` has the string prefix generated by:
  1010  
  1011  ```go
  1012  fmt.Sprintf(STRING, ARGS...)
  1013  ```
  1014  
  1015  `ACTUAL` must either be a `string`, `[]byte` or a `Stringer` (a type implementing the `String()` method).  Any other input is an error.
  1016  
  1017  > Note, of course, that the `ARGS...` are not required.  They are simply a convenience to allow you to build up strings programmatically inline in the matcher.
  1018  
  1019  #### HaveSuffix(suffix string, args ...interface{})
  1020  
  1021  ```go
  1022  Ω(ACTUAL).Should(HaveSuffix(STRING, ARGS...))
  1023  ```
  1024  
  1025  succeeds if `ACTUAL` has the string suffix generated by:
  1026  
  1027  ```go
  1028  fmt.Sprintf(STRING, ARGS...)
  1029  ```
  1030  
  1031  `ACTUAL` must either be a `string`, `[]byte` or a `Stringer` (a type implementing the `String()` method).  Any other input is an error.
  1032  
  1033  > Note, of course, that the `ARGS...` are not required.  They are simply a convenience to allow you to build up strings programmatically inline in the matcher.
  1034  
  1035  #### MatchRegexp(regexp string, args ...interface{})
  1036  
  1037  ```go
  1038  Ω(ACTUAL).Should(MatchRegexp(STRING, ARGS...))
  1039  ```
  1040  
  1041  succeeds if `ACTUAL` is matched by the regular expression string generated by:
  1042  
  1043  ```go
  1044  fmt.Sprintf(STRING, ARGS...)
  1045  ```
  1046  
  1047  `ACTUAL` must either be a `string`, `[]byte` or a `Stringer` (a type implementing the `String()` method).  Any other input is an error.  It is also an error for the regular expression to fail to compile.
  1048  
  1049  > Note, of course, that the `ARGS...` are not required.  They are simply a convenience to allow you to build up strings programmatically inline in the matcher.
  1050  
  1051  #### MatchJSON(json interface{})
  1052  
  1053  ```go
  1054  Ω(ACTUAL).Should(MatchJSON(EXPECTED))
  1055  ```
  1056  
  1057  Both `ACTUAL` and `EXPECTED` must be a `string`, `[]byte` or a `Stringer`.  `MatchJSON` succeeds if both `ACTUAL` and `EXPECTED` are JSON representations of the same object.  This is verified by parsing both `ACTUAL` and `EXPECTED` and then asserting equality on the resulting objects with `reflect.DeepEqual`.  By doing this `MatchJSON` avoids any issues related to white space, formatting, and key-ordering.
  1058  
  1059  It is an error for either `ACTUAL` or `EXPECTED` to be invalid JSON.
  1060  
  1061  In some cases it is useful to match two JSON strings while ignoring list order.  For this you can use the community maintained [MatchUnorderedJSON](https://github.com/Benjamintf1/Expanded-Unmarshalled-Matchers) matcher.
  1062  
  1063  #### MatchXML(xml interface{})
  1064  
  1065  ```go
  1066  Ω(ACTUAL).Should(MatchXML(EXPECTED))
  1067  ```
  1068  
  1069  Both `ACTUAL` and `EXPECTED` must be a `string`, `[]byte` or a `Stringer`.  `MatchXML` succeeds if both `ACTUAL` and `EXPECTED` are XML representations of the same object.  This is verified by parsing both `ACTUAL` and `EXPECTED` and then asserting equality on the resulting objects with `reflect.DeepEqual`.  By doing this `MatchXML` avoids any issues related to white space or formatting.
  1070  
  1071  It is an error for either `ACTUAL` or `EXPECTED` to be invalid XML.
  1072  
  1073  #### MatchYAML(yaml interface{})
  1074  
  1075  ```go
  1076  Ω(ACTUAL).Should(MatchYAML(EXPECTED))
  1077  ```
  1078  
  1079  Both `ACTUAL` and `EXPECTED` must be a `string`, `[]byte` or a `Stringer`.  `MatchYAML` succeeds if both `ACTUAL` and `EXPECTED` are YAML representations of the same object.  This is verified by parsing both `ACTUAL` and `EXPECTED` and then asserting equality on the resulting objects with `reflect.DeepEqual`.  By doing this `MatchYAML` avoids any issues related to white space, formatting, and key-ordering.
  1080  
  1081  It is an error for either `ACTUAL` or `EXPECTED` to be invalid YAML.
  1082  
  1083  ### Working with Collections
  1084  
  1085  #### BeEmpty()
  1086  
  1087  ```go
  1088  Ω(ACTUAL).Should(BeEmpty())
  1089  ```
  1090  
  1091  succeeds if `ACTUAL` is, in fact, empty. `ACTUAL` must be of type `string`, `array`, `map`, `chan`, or `slice`.  It is an error for it to have any other type.
  1092  
  1093  #### HaveLen(count int)
  1094  
  1095  ```go
  1096  Ω(ACTUAL).Should(HaveLen(INT))
  1097  ```
  1098  
  1099  succeeds if the length of `ACTUAL` is `INT`. `ACTUAL` must be of type `string`, `array`, `map`, `chan`, or `slice`.  It is an error for it to have any other type.
  1100  
  1101  #### HaveCap(count int)
  1102  
  1103  ```go
  1104  Ω(ACTUAL).Should(HaveCap(INT))
  1105  ```
  1106  
  1107  succeeds if the capacity of `ACTUAL` is `INT`. `ACTUAL` must be of type `array`, `chan`, or `slice`.  It is an error for it to have any other type.
  1108  
  1109  #### ContainElement(element interface{})
  1110  
  1111  ```go
  1112  Ω(ACTUAL).Should(ContainElement(ELEMENT))
  1113  ```
  1114  
  1115  or
  1116  
  1117  ```go
  1118  Ω(ACTUAL).Should(ContainElement(ELEMENT, <POINTER>))
  1119  ```
  1120  
  1121  
  1122  succeeds if `ACTUAL` contains an element that equals `ELEMENT`.  `ACTUAL` must be an `array`, `slice`, or `map` -- anything else is an error.  For `map`s `ContainElement` searches through the map's values (not keys!).
  1123  
  1124  By default `ContainElement()` uses the `Equal()` matcher under the hood to assert equality between `ACTUAL`'s elements and `ELEMENT`.  You can change this, however, by passing `ContainElement` a `GomegaMatcher`. For example, to check that a slice of strings has an element that matches a substring:
  1125  
  1126  ```go
  1127  Ω([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar")))
  1128  ```
  1129  
  1130  In addition, there are occasions when you need to grab (all) matching contained elements, for instance, to make several assertions against the matching contained elements. To do this, you can ask the `ContainElement()` matcher for the matching contained elements by passing it a pointer to a variable of the appropriate type. If multiple matching contained elements are expected, then a pointer to either a slice or a map should be passed (but not a pointer to an array), otherwise a pointer to a scalar (non-slice, non-map):
  1131  
  1132  ```go
  1133  var findings []string
  1134  Ω([]string{"foo", "foobar", "bar"}).Should(ContainElement(ContainSubstring("foo"), &findings))
  1135  
  1136  var finding string
  1137  Ω([]string{"foo", "foobar", "bar"}).Should(ContainElement("foobar", &finding))
  1138  ```
  1139  
  1140  The `ContainElement` matcher will fail with a descriptive error message in case of multiple matches when the pointer references a scalar type.
  1141  
  1142  In case of maps, the matching contained elements will be returned with their keys in the map referenced by the pointer.
  1143  
  1144  ```go
  1145  var findings map[int]string
  1146  Ω(map[int]string{
  1147      1: "bar",
  1148      2: "foobar",
  1149      3: "foo",
  1150  }).Should(ContainElement(ContainSubstring("foo"), &findings))
  1151  ```
  1152  
  1153  #### ContainElements(element ...interface{})
  1154  
  1155  ```go
  1156  Ω(ACTUAL).Should(ContainElements(ELEMENT1, ELEMENT2, ELEMENT3, ...))
  1157  ```
  1158  
  1159  or
  1160  
  1161  ```go
  1162  Ω(ACTUAL).Should(ContainElements([]SOME_TYPE{ELEMENT1, ELEMENT2, ELEMENT3, ...}))
  1163  ```
  1164  
  1165  succeeds if `ACTUAL` contains the elements passed into the matcher. The ordering of the elements does not matter.
  1166  
  1167  By default `ContainElements()` uses `Equal()` to match the elements, however custom matchers can be passed in instead.  Here are some examples:
  1168  
  1169  ```go
  1170  Ω([]string{"Foo", "FooBar"}).Should(ContainElements("FooBar"))
  1171  Ω([]string{"Foo", "FooBar"}).Should(ContainElements(ContainSubstring("Bar"), "Foo"))
  1172  ```
  1173  
  1174  Actual must be an `array`, `slice` or `map`.  For maps, `ContainElements` matches against the `map`'s values.
  1175  
  1176  You typically pass variadic arguments to `ContainElements` (as in the examples above).  However, if you need to pass in a slice you can provided that it
  1177  is the only element passed in to `ContainElements`:
  1178  
  1179  ```go
  1180  Ω([]string{"Foo", "FooBar"}).Should(ContainElements([]string{"FooBar", "Foo"}))
  1181  ```
  1182  
  1183  Note that Go's type system does not allow you to write this as `ContainElements([]string{"FooBar", "Foo"}...)` as `[]string` and `[]interface{}` are different types - hence the need for this special rule.
  1184  
  1185  The difference between the `ContainElements` and `ConsistOf` matchers is that the latter is more restrictive because the `ConsistOf` matcher checks additionally that the `ACTUAL` elements and the elements passed into the matcher have the same length.
  1186  
  1187  #### BeElementOf(elements ...interface{})
  1188  
  1189  ```go
  1190  Ω(ACTUAL).Should(BeElementOf(ELEMENT1, ELEMENT2, ELEMENT3, ...))
  1191  ```
  1192  
  1193  succeeds if `ACTUAL` equals one of the elements passed into the matcher. When a single element `ELEMENT` of type `array` or `slice` is passed into the matcher, `BeElementOf` succeeds if `ELEMENT` contains an element that equals `ACTUAL` (reverse of `ContainElement`). `BeElementOf` always uses the `Equal()` matcher under the hood to assert equality.
  1194  
  1195  #### BeKeyOf(m interface{})
  1196  
  1197  ```go
  1198  Ω(ACTUAL).Should(BeKeyOf(MAP))
  1199  ```
  1200  
  1201  succeeds if `ACTUAL` equals one of the keys of `MAP`. It is an error for `MAP` to be of any type other than a map. `BeKeyOf` always uses the `Equal()` matcher under the hood to assert equality of `ACTUAL` with a map key.
  1202  
  1203  `BeKeyOf` can be used in situations where it is not possible to rewrite an assertion to use the more idiomatic `HaveKey`: one use is in combination with `ContainElement` doubling as a filter. For instance, the following example asserts that all expected specific sprockets are present in a larger list of sprockets:
  1204  
  1205  ```go
  1206  var names = map[string]struct {
  1207  	detail string
  1208  }{
  1209  	"edgy_emil":              {detail: "sprocket_project_A"},
  1210  	"furious_freddy":         {detail: "sprocket_project_B"},
  1211  }
  1212  
  1213  var canaries []Sprocket
  1214  Expect(projects).To(ContainElement(HaveField("Name", BeKeyOf(names)), &canaries))
  1215  Expect(canaries).To(HaveLen(len(names)))
  1216  ```
  1217  
  1218  #### ConsistOf(element ...interface{})
  1219  
  1220  ```go
  1221  Ω(ACTUAL).Should(ConsistOf(ELEMENT1, ELEMENT2, ELEMENT3, ...))
  1222  ```
  1223  
  1224  or
  1225  
  1226  ```go
  1227  Ω(ACTUAL).Should(ConsistOf([]SOME_TYPE{ELEMENT1, ELEMENT2, ELEMENT3, ...}))
  1228  ```
  1229  
  1230  succeeds if `ACTUAL` contains precisely the elements passed into the matcher. The ordering of the elements does not matter.
  1231  
  1232  By default `ConsistOf()` uses `Equal()` to match the elements, however custom matchers can be passed in instead.  Here are some examples:
  1233  
  1234  ```go
  1235  Ω([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo"))
  1236  Ω([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Bar"), "Foo"))
  1237  Ω([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Foo"), ContainSubstring("Foo")))
  1238  ```
  1239  
  1240  Actual must be an `array`, `slice` or `map`.  For maps, `ConsistOf` matches against the `map`'s values.
  1241  
  1242  You typically pass variadic arguments to `ConsistOf` (as in the examples above).  However, if you need to pass in a slice you can provided that it
  1243  is the only element passed in to `ConsistOf`:
  1244  
  1245  ```go
  1246  Ω([]string{"Foo", "FooBar"}).Should(ConsistOf([]string{"FooBar", "Foo"}))
  1247  ```
  1248  
  1249  Note that Go's type system does not allow you to write this as `ConsistOf([]string{"FooBar", "Foo"}...)` as `[]string` and `[]interface{}` are different types - hence the need for this special rule.
  1250  
  1251  #### HaveExactElements(element ...interface{})
  1252  
  1253  ```go
  1254  Expect(ACTUAL).To(HaveExactElements(ELEMENT1, ELEMENT2, ELEMENT3, ...))
  1255  ```
  1256  
  1257  or
  1258  
  1259  ```go
  1260  Expect(ACTUAL).To(HaveExactElements([]SOME_TYPE{ELEMENT1, ELEMENT2, ELEMENT3, ...}))
  1261  ```
  1262  
  1263  succeeds if `ACTUAL` contains precisely the elements and ordering passed into the matchers.
  1264  
  1265  By default `HaveExactElements()` uses `Equal()` to match the elements, however custom matchers can be passed in instead.  Here are some examples:
  1266  
  1267  ```go
  1268  Expect([]string{"Foo", "FooBar"}).To(HaveExactElements("Foo", "FooBar"))
  1269  Expect([]string{"Foo", "FooBar"}).To(HaveExactElements("Foo", ContainSubstring("Bar")))
  1270  Expect([]string{"Foo", "FooBar"}).To(HaveExactElements(ContainSubstring("Foo"), ContainSubstring("Foo")))
  1271  ```
  1272  
  1273  Actual must be an `array` or `slice`.
  1274  
  1275  You typically pass variadic arguments to `HaveExactElements` (as in the examples above).  However, if you need to pass in a slice you can provided that it
  1276  is the only element passed in to `HaveExactElements`:
  1277  
  1278  ```go
  1279  Expect([]string{"Foo", "FooBar"}).To(HaveExactElements([]string{"FooBar", "Foo"}))
  1280  ```
  1281  
  1282  Note that Go's type system does not allow you to write this as `HaveExactElements([]string{"FooBar", "Foo"}...)` as `[]string` and `[]interface{}` are different types - hence the need for this special rule.
  1283  
  1284  #### HaveEach(element interface{})
  1285  
  1286  ```go
  1287  Ω(ACTUAL).Should(HaveEach(ELEMENT))
  1288  ```
  1289  
  1290  succeeds if `ACTUAL` solely consists of elements that equal `ELEMENT`.  `ACTUAL` must be an `array`, `slice`, or `map` -- anything else is an error.  For `map`s `HaveEach` searches through the map's values (not keys!).
  1291  
  1292  In order to avoid ambiguity it is an error for `ACTUAL` to be an empty `array`, `slice`, or `map` (or a correctly typed `nil`) -- in these cases it cannot be decided if `HaveEach` should match, or should not match. If in your test it is acceptable for `ACTUAL` to be empty, you can use `Or(BeEmpty(), HaveEach(ELEMENT))` instead.
  1293  
  1294  By default `HaveEach()` uses the `Equal()` matcher under the hood to assert equality between `ACTUAL`'s elements and `ELEMENT`.  You can change this, however, by passing `HaveEach` a `GomegaMatcher`. For example, to check that a slice of strings has an element that matches a substring:
  1295  
  1296  ```go
  1297  Ω([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo")))
  1298  ```
  1299  
  1300  #### HaveKey(key interface{})
  1301  
  1302  ```go
  1303  Ω(ACTUAL).Should(HaveKey(KEY))
  1304  ```
  1305  
  1306  succeeds if `ACTUAL` is a map with a key that equals `KEY`.  It is an error for `ACTUAL` to not be a `map`.
  1307  
  1308  By default `HaveKey()` uses the `Equal()` matcher under the hood to assert equality between `ACTUAL`'s keys and `KEY`.  You can change this, however, by passing `HaveKey` a `GomegaMatcher`. For example, to check that a map has a key that matches a regular expression:
  1309  
  1310  ```go
  1311  Ω(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`)))
  1312  ```
  1313  
  1314  #### HaveKeyWithValue(key interface{}, value interface{})
  1315  
  1316  ```go
  1317  Ω(ACTUAL).Should(HaveKeyWithValue(KEY, VALUE))
  1318  ```
  1319  
  1320  succeeds if `ACTUAL` is a map with a key that equals `KEY` mapping to a value that equals `VALUE`.  It is an error for `ACTUAL` to not be a `map`.
  1321  
  1322  By default `HaveKeyWithValue()` uses the `Equal()` matcher under the hood to assert equality between `ACTUAL`'s keys and `KEY` and between the associated value and `VALUE`.  You can change this, however, by passing `HaveKeyWithValue` a `GomegaMatcher` for either parameter. For example, to check that a map has a key that matches a regular expression and which is also associated with a value that passes some numerical threshold:
  1323  
  1324  ```go
  1325  Ω(map[string]int{"Foo": 3, "BazFoo": 4}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), BeNumerically(">", 3)))
  1326  ```
  1327  
  1328  #### HaveField(field interface{}, value interface{})
  1329  
  1330  ```go
  1331  Ω(ACTUAL).Should(HaveField(FIELD, VALUE))
  1332  ```
  1333  
  1334  succeeds if `ACTUAL` is a struct with a value that can be traversed via `FIELD` that equals `VALUE`.  It is an error for `ACTUAL` to not be a `struct`.
  1335  
  1336  By default `HaveField()` uses the `Equal()` matcher under the hood to assert equality between the extracted value and `VALUE`.  You can change this, however, by passing `HaveField` a `GomegaMatcher` for `VALUE`.
  1337  
  1338  `FIELD` allows you to access fields within the `ACTUAL` struct.  Nested structs can be accessed using the `.` delimiter.  `HaveField()` also allows you to invoke methods on the struct by adding a `()` suffix to the `FIELD` - these methods must take no arguments and return exactly one value.  For example consider the following types:
  1339  
  1340  ```go
  1341  type Book struct {
  1342      Title string
  1343      Author Person
  1344  }
  1345  
  1346  type Person struct {
  1347      Name string
  1348      DOB time.Time
  1349  }
  1350  ```
  1351  
  1352  and an instance book `var book = Book{...}` - you can use `HaveField` to make assertions like:
  1353  
  1354  ```go
  1355  Ω(book).Should(HaveField("Title", "Les Miserables"))
  1356  Ω(book).Should(HaveField("Title", ContainSubstring("Les Mis")))
  1357  Ω(book).Should(HaveField("Author.Name", "Victor Hugo"))
  1358  Ω(book).Should(HaveField("Author.DOB.Year()", BeNumerically("<", 1900)))
  1359  ```
  1360  
  1361  `HaveField` can pair powerfully with a collection matcher like `ContainElement`.  To assert that a list of books as at least one element with an author born in February you could write:
  1362  
  1363  ```go
  1364  Ω(books).Should(ContainElement(HaveField("Author.DOB.Month()", Equal(2))))
  1365  ```
  1366  
  1367  If you want to make lots of complex assertions against the fields of a struct take a look at the [`gstruct`package](#codegstructcode-testing-complex-data-types) documented below.
  1368  
  1369  #### HaveExistingField(field interface{})
  1370  
  1371  While `HaveField()` considers a missing field to be an error (instead of non-success), combining it with `HaveExistingField()` allows `HaveField()` to be reused in test contexts other than assertions: for instance, as filters to [`ContainElement(ELEMENT, <POINTER>)`](#containelementelement-interface) or in detecting resource leaks (like leaked file descriptors).
  1372  
  1373  ```go
  1374  Ω(ACTUAL).Should(HaveExistingField(FIELD))
  1375  ```
  1376  
  1377  succeeds if `ACTUAL` is a struct with a field `FIELD`, regardless of this field's value. It is an error for `ACTUAL` to not be a `struct`. Like `HaveField()`, `HaveExistingField()` supports accessing nested structs using the `.` delimiter. Methods on the struct are invoked by adding a `()` suffix to the `FIELD` - these methods must take no arguments and return exactly one value.
  1378  
  1379  To assert a particular field value, but only if such a field exists in an `ACTUAL` struct, use the composing [`And`](#andmatchers-gomegamatcher) matcher:
  1380  
  1381  ```go
  1382  Ω(ACTUAL).Should(And(HaveExistingField(FIELD), HaveField(FIELD, VALUE)))
  1383  ```
  1384  
  1385  ### Working with Numbers and Times
  1386  
  1387  #### BeNumerically(comparator string, compareTo ...interface{})
  1388  
  1389  ```go
  1390  Ω(ACTUAL).Should(BeNumerically(COMPARATOR_STRING, EXPECTED, <THRESHOLD>))
  1391  ```
  1392  
  1393  performs numerical assertions in a type-agnostic way.  `ACTUAL` and `EXPECTED` should be numbers, though the specific type of number is irrelevant (`float32`, `float64`, `uint8`, etc...).  It is an error for `ACTUAL` or `EXPECTED` to not be a number.
  1394  
  1395  There are six supported comparators:
  1396  
  1397  - `Ω(ACTUAL).Should(BeNumerically("==", EXPECTED))`:
  1398      asserts that `ACTUAL` and `EXPECTED` are numerically equal.
  1399  
  1400  - `Ω(ACTUAL).Should(BeNumerically("~", EXPECTED, <THRESHOLD>))`:
  1401      asserts that `ACTUAL` and `EXPECTED` are within `<THRESHOLD>` of one another.  By default `<THRESHOLD>` is `1e-8` but you can specify a custom value.
  1402  
  1403  - `Ω(ACTUAL).Should(BeNumerically(">", EXPECTED))`:
  1404      asserts that `ACTUAL` is greater than `EXPECTED`.
  1405  
  1406  - `Ω(ACTUAL).Should(BeNumerically(">=", EXPECTED))`:
  1407      asserts that `ACTUAL` is greater than or equal to  `EXPECTED`.
  1408  
  1409  - `Ω(ACTUAL).Should(BeNumerically("<", EXPECTED))`:
  1410      asserts that `ACTUAL` is less than `EXPECTED`.
  1411  
  1412  - `Ω(ACTUAL).Should(BeNumerically("<=", EXPECTED))`:
  1413      asserts that `ACTUAL` is less than or equal to `EXPECTED`.
  1414  
  1415  Any other comparator is an error.
  1416  
  1417  #### BeTemporally(comparator string, compareTo time.Time, threshold ...time.Duration)
  1418  
  1419  ```go
  1420  Ω(ACTUAL).Should(BeTemporally(COMPARATOR_STRING, EXPECTED_TIME, <THRESHOLD_DURATION>))
  1421  ```
  1422  
  1423  performs time-related assertions.  `ACTUAL` must be a `time.Time`.
  1424  
  1425  There are six supported comparators:
  1426  
  1427  - `Ω(ACTUAL).Should(BeTemporally("==", EXPECTED_TIME))`:
  1428      asserts that `ACTUAL` and `EXPECTED_TIME` are identical `time.Time`s.
  1429  
  1430  - `Ω(ACTUAL).Should(BeTemporally("~", EXPECTED_TIME, <THRESHOLD_DURATION>))`:
  1431      asserts that `ACTUAL` and `EXPECTED_TIME` are within `<THRESHOLD_DURATION>` of one another.  By default `<THRESHOLD_DURATION>` is `time.Millisecond` but you can specify a custom value.
  1432  
  1433  - `Ω(ACTUAL).Should(BeTemporally(">", EXPECTED_TIME))`:
  1434      asserts that `ACTUAL` is after `EXPECTED_TIME`.
  1435  
  1436  - `Ω(ACTUAL).Should(BeTemporally(">=", EXPECTED_TIME))`:
  1437      asserts that `ACTUAL` is after or at `EXPECTED_TIME`.
  1438  
  1439  - `Ω(ACTUAL).Should(BeTemporally("<", EXPECTED_TIME))`:
  1440      asserts that `ACTUAL` is before `EXPECTED_TIME`.
  1441  
  1442  - `Ω(ACTUAL).Should(BeTemporally("<=", EXPECTED_TIME))`:
  1443      asserts that `ACTUAL` is before or at `EXPECTED_TIME`.
  1444  
  1445  Any other comparator is an error.
  1446  
  1447  ### Working with Values
  1448  
  1449  #### HaveValue(matcher types.GomegaMatcher)
  1450  
  1451  `HaveValue` applies `MATCHER` to the value that results from dereferencing `ACTUAL` in case of a pointer or an interface, or otherwise `ACTUAL` itself. Pointers and interfaces are dereferenced multiple times as necessary, with a limit of at most 31 dereferences. It will fail if the pointer value is `nil`:
  1452  
  1453  ```go
  1454  Expect(ACTUAL).To(HaveValue(MATCHER))
  1455  ```
  1456  
  1457  For instance:
  1458  
  1459  ```go
  1460  i := 42
  1461  Expect(&i).To(HaveValue(Equal(42)))
  1462  Expect(i).To(HaveValue(Equal(42)))
  1463  ```
  1464  
  1465  `HaveValue` can be used, for instance, in tests and custom matchers where the it doesn't matter (as opposed to `PointTo`) if a value first needs to be dereferenced or not. This is especially useful to custom matchers that are to be used in mixed contexts of pointers as well as non-pointers.
  1466  
  1467  Please note that negating the outcome of `HaveValue(nil)` won't suppress any error; for instance, in order to assert not having a specific value while still accepting `nil` the following matcher expression might be used:
  1468  
  1469  ```go
  1470  Or(BeNil(), Not(HaveValue(...)))
  1471  ```
  1472  
  1473  ### Working with HTTP responses
  1474  
  1475  #### HaveHTTPStatus(expected interface{})
  1476  
  1477  ```go
  1478    Expect(ACTUAL).To(HaveHTTPStatus(EXPECTED, ...))
  1479  ```
  1480  
  1481  succeeds if the `Status` or `StatusCode` field of an HTTP response matches.
  1482  
  1483  `ACTUAL` must be either a `*http.Response` or `*httptest.ResponseRecorder`.
  1484  
  1485  `EXPECTED` must be one or more `int` or `string` types. An `int` is compared
  1486  to `StatusCode` and a `string` is compared to `Status`.
  1487  The matcher succeeds if any of the `EXPECTED` values match.
  1488  
  1489  Here are some examples:
  1490  
  1491  - `Expect(resp).To(HaveHTTPStatus(http.StatusOK, http.StatusNoContext))`:
  1492      asserts that `resp.StatusCode == 200` or `resp.StatusCode == 204`
  1493  
  1494  - `Expect(resp).To(HaveHTTPStatus("404 Not Found"))`:
  1495      asserts that `resp.Status == "404 Not Found"`.
  1496  
  1497  #### HaveHTTPBody(expected interface{})
  1498  
  1499  ```go
  1500  Expect(ACTUAL).To(HaveHTTPBody(EXPECTED))
  1501  ```
  1502  
  1503  Succeeds if the body of an HTTP Response matches.
  1504  
  1505  `ACTUAL` must be either a `*http.Response` or `*httptest.ResponseRecorder`.
  1506  
  1507  `EXPECTED` must be one of the following:
  1508  - A `string`
  1509  - A `[]byte`
  1510  - A matcher, in which case the matcher will be called with the body as a `[]byte`.
  1511  
  1512  Here are some examples:
  1513  
  1514  - `Expect(resp).To(HaveHTTPBody("bar"))`:
  1515      asserts that when `resp.Body` is read, it will equal `bar`.
  1516  
  1517  - `Expect(resp).To(HaveHTTPBody(MatchJSON("{\"some\":\"json\""))`:
  1518      asserts that when `resp.Body` is read, the `MatchJSON` matches it to `{"some":"json"}`.
  1519  
  1520  Note that the body is an `io.ReadCloser` and the `HaveHTTPBody()` will read it and the close it.
  1521  This means that subsequent attempts to read the body may have unexpected results.
  1522  
  1523  #### HaveHTTPHeaderWithValue(key string, value interface{})
  1524  
  1525  ```go
  1526  Expect(ACTUAL).To(HaveHTTPHeaderWithValue(KEY, VALUE))
  1527  ```
  1528  
  1529  Succeeds if the HTTP Response has a matching header and value.
  1530  
  1531  `ACTUAL` must be either a `*http.Response` or `*httptest.ResponseRecorder`.
  1532  
  1533  `KEY` must be a `string`. It is passed to
  1534  [`http.Header.Get(key string)`](https://pkg.go.dev/net/http#Header.Get),
  1535  and will have the same behaviors regarding order of headers and capitalization.
  1536  
  1537  `VALUE` must be one of the following:
  1538  - A `string`
  1539  - A matcher, in which case the matcher will be called to match the value.
  1540  
  1541  Here are some examples:
  1542  
  1543  - `Expect(resp).To(HaveHTTPHeaderWithValue("Content-Type", "application/json"))`:
  1544      asserts that the `Content-Type` header has exactly the value `application/json`.
  1545  
  1546  - `Expect(resp).To(HaveHTTPHeaderWithValue(ContainSubstring("json")))`:
  1547      asserts that the `Content-Type` header contains the substring `json`.
  1548  
  1549  ### Asserting on Panics
  1550  
  1551  #### Panic()
  1552  
  1553  ```go
  1554  Ω(ACTUAL).Should(Panic())
  1555  ```
  1556  
  1557  succeeds if `ACTUAL` is a function that, when invoked, panics.  `ACTUAL` must be a function that takes no arguments and returns no result -- any other type for `ACTUAL` is an error.
  1558  
  1559  #### PanicWith()
  1560  
  1561  ```go
  1562  Ω(ACTUAL).Should(PanicWith(VALUE))
  1563  ```
  1564  
  1565  succeeds if `ACTUAL` is a function that, when invoked, panics with a value of `VALUE`.  `ACTUAL` must be a function that takes no arguments and returns no result -- any other type for `ACTUAL` is an error.
  1566  
  1567  By default `PanicWith()` uses the `Equal()` matcher under the hood to assert equality between `ACTUAL`'s panic value and `VALUE`.  You can change this, however, by passing `PanicWith` a `GomegaMatcher`. For example, to check that the panic value matches a regular expression:
  1568  
  1569  ```go
  1570  Ω(func() { panic("FooBarBaz") }).Should(PanicWith(MatchRegexp(`.+Baz$`)))
  1571  ```
  1572  
  1573  ### Composing Matchers
  1574  
  1575  You may form larger matcher expressions using the following operators: `And()`, `Or()`, `Not()` and `WithTransform()`.
  1576  
  1577  Note: `And()` and `Or()` can also be referred to as `SatisfyAll()` and `SatisfyAny()`, respectively.
  1578  
  1579  With these operators you can express multiple requirements in a single `Expect()` or `Eventually()` statement. For example:
  1580  
  1581  ```go
  1582  Expect(number).To(SatisfyAll(
  1583              BeNumerically(">", 0),
  1584              BeNumerically("<", 10)))
  1585  
  1586  Expect(msg).To(SatisfyAny(
  1587              Equal("Success"),
  1588              MatchRegexp(`^Error .+$`)))
  1589  ```
  1590  
  1591  It can also provide a lightweight syntax to create new matcher types from existing ones. For example:
  1592  
  1593  ```go
  1594  func BeBetween(min, max int) GomegaMatcher {
  1595      return SatisfyAll(
  1596              BeNumerically(">", min),
  1597              BeNumerically("<", max))
  1598  }
  1599  
  1600  Ω(number).Should(BeBetween(0, 10))
  1601  ```
  1602  
  1603  #### And(matchers ...GomegaMatcher)
  1604  
  1605  #### SatisfyAll(matchers ...GomegaMatcher)
  1606  
  1607  ```go
  1608  Ω(ACTUAL).Should(And(MATCHER1, MATCHER2, ...))
  1609  ```
  1610  
  1611  or
  1612  
  1613  ```go
  1614  Ω(ACTUAL).Should(SatisfyAll(MATCHER1, MATCHER2, ...))
  1615  ```
  1616  
  1617  succeeds if `ACTUAL` satisfies all of the specified matchers (similar to a logical AND).
  1618  
  1619  Tests the given matchers in order, returning immediately if one fails, without needing to test the remaining matchers.
  1620  
  1621  #### Or(matchers ...GomegaMatcher)
  1622  
  1623  #### SatisfyAny(matchers ...GomegaMatcher)
  1624  
  1625  ```go
  1626  Ω(ACTUAL).Should(Or(MATCHER1, MATCHER2, ...))
  1627  ```
  1628  
  1629  or
  1630  
  1631  ```go
  1632  Ω(ACTUAL).Should(SatisfyAny(MATCHER1, MATCHER2, ...))
  1633  ```
  1634  
  1635  succeeds if `ACTUAL` satisfies any of the specified matchers (similar to a logical OR).
  1636  
  1637  Tests the given matchers in order, returning immediately if one succeeds, without needing to test the remaining matchers.
  1638  
  1639  #### Not(matcher GomegaMatcher)
  1640  
  1641  ```go
  1642  Ω(ACTUAL).Should(Not(MATCHER))
  1643  ```
  1644  
  1645  succeeds if `ACTUAL` does **not** satisfy the specified matcher (similar to a logical NOT).
  1646  
  1647  #### WithTransform(transform interface{}, matcher GomegaMatcher)
  1648  
  1649  ```go
  1650  Ω(ACTUAL).Should(WithTransform(TRANSFORM, MATCHER))
  1651  ```
  1652  
  1653  succeeds if applying the `TRANSFORM` function to `ACTUAL` (i.e. the value of `TRANSFORM(ACTUAL)`) will satisfy the given `MATCHER`. For example:
  1654  
  1655  ```go
  1656  GetColor := func(e Element) Color { return e.Color }
  1657  
  1658  Ω(element).Should(WithTransform(GetColor, Equal(BLUE)))
  1659  ```
  1660  
  1661  Or the same thing expressed by introducing a new, lightweight matcher:
  1662  
  1663  ```go
  1664  // HaveColor returns a matcher that expects the element to have the given color.
  1665  func HaveColor(c Color) GomegaMatcher {
  1666      return WithTransform(func(e Element) Color {
  1667          return e.Color
  1668      }, Equal(c))
  1669  }
  1670  
  1671  Ω(element).Should(HaveColor(BLUE)))
  1672  ```
  1673  
  1674  `TRANSFORM` functions optionally can return an additional error value in case a transformation is not possible, avoiding the need to `panic`. Returning errors can be useful when using `WithTransform` to build lightweight matchers that accept different value types and that can gracefully fail when presented the wrong value type.
  1675  
  1676  As before, such a `TRANSFORM` expects a single actual value. But now it returns the transformed value together with an error value. This follows the common Go idiom to communicate errors via an explicit, separate return value.
  1677  
  1678  The following lightweight matcher expects to be used either on a `Sprocket` value or `*Sprocket` pointer. It gracefully fails when the actual value is something else.
  1679  
  1680  ```go
  1681  // HaveSprocketName returns a matcher that expects the actual value to be
  1682  // either a Sprocket or a *Sprocket, having the specified name.
  1683  func HaveSprocketName(name string) GomegaMatcher {
  1684      return WithTransform(
  1685          func(actual interface{}) (string, error) {
  1686              switch sprocket := actual.(type) {
  1687              case *Sprocket:
  1688                  return Sprocket.Name, nil
  1689              case Sprocket:
  1690                  return Sprocket.Name, nil
  1691              default:
  1692                  return "", fmt.Errorf("HaveSprocketName expects a Sprocket or *Sprocket, but got %T", actual)
  1693              }
  1694          }, Equal(name))
  1695  }
  1696  
  1697  Ω(element).Should(HaveSprocketName("gomega")))
  1698  ```
  1699  
  1700  #### Satisfy(predicate interface{})
  1701  
  1702  ```go
  1703  Ω(ACTUAL).Should(Satisfy(PREDICATE))
  1704  ```
  1705  
  1706  succeeds if applying the `PREDICATE` function to `ACTUAL` (i.e. the value of `PREDICATE(ACTUAL)`) will return `true`. For example:
  1707  
  1708  ```go
  1709  IsEven := func(i int) bool { return i%2==0 }
  1710  
  1711  Ω(number).Should(Satisfy(IsEven))
  1712  ```
  1713  
  1714  ## Adding Your Own Matchers
  1715  
  1716  A matcher, in Gomega, is any type that satisfies the `GomegaMatcher` interface:
  1717  
  1718  ```go
  1719  type GomegaMatcher interface {
  1720      Match(actual interface{}) (success bool, err error)
  1721      FailureMessage(actual interface{}) (message string)
  1722      NegatedFailureMessage(actual interface{}) (message string)
  1723  }
  1724  ```
  1725  
  1726  For the simplest cases, new matchers can be [created by composition](#composing-matchers).  Please also take a look at the [Building Custom Matchers](https://onsi.github.io/ginkgo/#building-custom-matchers) section of the Ginkgo and Gomega patterns chapter in the Ginkgo docs for additional examples.
  1727  
  1728  In addition to composition, however, it is fairly straightforward to build domain-specific custom matchers.  You can create new types that satisfy the `GomegaMatcher` interface *or* you can use the `gcustom` package to build matchers out of simple functions.
  1729  
  1730  Let's work through an example and illustrate both approaches.
  1731  
  1732  ### A Custom Matcher: RepresentJSONifiedObject(EXPECTED interface{})
  1733  
  1734  Say you're working on a JSON API and you want to assert that your server returns the correct JSON representation.  Rather than marshal/unmarshal JSON in your tests, you want to write an expressive matcher that checks that the received response is a JSON representation for the object in question.  This is what the `RepresentJSONifiedObject` matcher could look like:
  1735  
  1736  ```go
  1737  package json_response_matcher
  1738  
  1739  import (
  1740      "github.com/onsi/gomega/types"
  1741  
  1742      "encoding/json"
  1743      "fmt"
  1744      "net/http"
  1745      "reflect"
  1746  )
  1747  
  1748  func RepresentJSONifiedObject(expected interface{}) types.GomegaMatcher {
  1749      return &representJSONMatcher{
  1750          expected: expected,
  1751      }
  1752  }
  1753  
  1754  type representJSONMatcher struct {
  1755      expected interface{}
  1756  }
  1757  
  1758  func (matcher *representJSONMatcher) Match(actual interface{}) (success bool, err error) {
  1759      response, ok := actual.(*http.Response)
  1760      if !ok {
  1761          return false, fmt.Errorf("RepresentJSONifiedObject matcher expects an http.Response")
  1762      }
  1763  
  1764      pointerToObjectOfExpectedType := reflect.New(reflect.TypeOf(matcher.expected)).Interface()
  1765      err = json.NewDecoder(response.Body).Decode(pointerToObjectOfExpectedType)
  1766  
  1767      if err != nil {
  1768          return false, fmt.Errorf("Failed to decode JSON: %s", err.Error())
  1769      }
  1770  
  1771      decodedObject := reflect.ValueOf(pointerToObjectOfExpectedType).Elem().Interface()
  1772  
  1773      return reflect.DeepEqual(decodedObject, matcher.expected), nil
  1774  }
  1775  
  1776  func (matcher *representJSONMatcher) FailureMessage(actual interface{}) (message string) {
  1777      return fmt.Sprintf("Expected\n\t%#v\nto contain the JSON representation of\n\t%#v", actual, matcher.expected)
  1778  }
  1779  
  1780  func (matcher *representJSONMatcher) NegatedFailureMessage(actual interface{}) (message string) {
  1781      return fmt.Sprintf("Expected\n\t%#v\nnot to contain the JSON representation of\n\t%#v", actual, matcher.expected)
  1782  }
  1783  ```
  1784  
  1785  Let's break this down:
  1786  
  1787  - Most matchers have a constructor function that returns an instance of the matcher.  In this case we've created `RepresentJSONifiedObject`.  Where possible, your constructor function should take explicit types or interfaces.  For our use case, however, we need to accept any possible expected type so `RepresentJSONifiedObject` takes an argument with the generic `interface{}` type.
  1788  - The constructor function then initializes and returns an instance of our matcher: the `representJSONMatcher`.  These rarely need to be exported outside of your matcher package.
  1789  - The `representJSONMatcher` must satisfy the `GomegaMatcher` interface.  It does this by implementing the `Match`, `FailureMessage`, and `NegatedFailureMessage` method:
  1790      - If the `GomegaMatcher` receives invalid inputs `Match` returns a non-nil error explaining the problems with the input.  This allows Gomega to fail the assertion whether the assertion is for the positive or negative case.
  1791      - If the `actual` and `expected` values match, `Match` should return `true`.
  1792      - Similarly, if the `actual` and `expected` values do not match, `Match` should return `false`.
  1793      - If the `GomegaMatcher` was testing the `Should` case, and `Match` returned `false`, `FailureMessage` will be called to print a message explaining the failure.
  1794      - Likewise, if the `GomegaMatcher` was testing the `ShouldNot` case, and `Match` returned `true`, `NegatedFailureMessage` will be called.
  1795      - It is guaranteed that `FailureMessage` and `NegatedFailureMessage` will only be called *after* `Match`, so you can save off any state you need to compute the messages in `Match`.
  1796  - Finally, it is common for matchers to make extensive use of the `reflect` library to interpret the generic inputs they receive.  In this case, the `representJSONMatcher` goes through some `reflect` gymnastics to create a pointer to a new object with the same type as the `expected` object, read and decode JSON from `actual` into that pointer, and then deference the pointer and compare the result to the `expected` object.
  1797  
  1798  ### gcustom: A convenient mechanism for building custom matchers
  1799  
  1800  [`gcustom`](https://github.com/onsi/gomega/tree/master/gcustom) is a package that makes building custom matchers easy.  Rather than define new types, you can simply provide `gcustom.MakeMatcher` with a function.  The [godocs](https://pkg.go.dev/github.com/onsi/gomega/gcustom) for `gcustom` have all the details but here's how `RepresentJSONifiedObject` could be implemented with `gcustom`:
  1801  
  1802  
  1803  ```go
  1804  package json_response_matcher
  1805  
  1806  import (
  1807      "github.com/onsi/gomega/types"
  1808      "github.com/onsi/gomega/gcustom"
  1809  
  1810      "encoding/json"
  1811      "fmt"
  1812      "net/http"
  1813      "reflect"
  1814  )
  1815  
  1816  func RepresentJSONifiedObject(expected interface{}) types.GomegaMatcher {
  1817      return gcustom.MakeMatcher(func(response *http.Response) (bool, err) {
  1818          pointerToObjectOfExpectedType := reflect.New(reflect.TypeOf(matcher.expected)).Interface()
  1819          err = json.NewDecoder(response.Body).Decode(pointerToObjectOfExpectedType)
  1820          if err != nil {
  1821              return false, fmt.Errorf("Failed to decode JSON: %w", err.Error())
  1822          }
  1823  
  1824          decodedObject := reflect.ValueOf(pointerToObjectOfExpectedType).Elem().Interface()
  1825          return reflect.DeepEqual(decodedObject, matcher.expected), nil        
  1826      }).WithTemplate("Expected:\n{{.FormattedActual}}\n{{.To}} contain the JSON representation of\n{{format .Data 1}}").WithTemplateData(expected)
  1827  }
  1828  ```
  1829  
  1830  The [`gcustom` godocs](https://pkg.go.dev/github.com/onsi/gomega/gcustom) go into much more detail but we can point out a few of the convenient features of `gcustom` here:
  1831  
  1832  - `gcustom` can take a matcher function that accepts a concrete type.  In our case `func(response *https.Response) (bool, err)` - when this is done, the matcher built by `gcustom` takes care of all the type-checking for you and will only call your match function if an object of the correct type is asserted against.  If you want to do your own type-checking (or want to build a matcher that works with multiple types) you can use `func(actual any) (bool, err)` instead.
  1833  - Rather than implement different functions for the two different failure messages you can provide a single template.  `gcustom` provides template variables to help you render the failure messages depending on positive failures vs negative failures.  For example, the variable `{{.To}}` will render "to" for positive failures and "not to" for negative failures.
  1834  - You can pass additional data to your template with `WithTemplateData(<data>)` - in this case we pass in the expected object so that the template can include it in the output.  We do this with the expression `{{format .Data 1}}`.  gcustom provides the `format` template function to render objects using Ginkgo's object formatting system (the `1` here denotes the level of indentation).
  1835  
  1836  `gcustom` also supports a simpler mechanism for generating messages: `.WithMessage()` simply takes a string and builds a canned message out of that string.  You can also provide precompiled templates if you want to avoid the cost of compiling a template every time the matcher is called.
  1837  
  1838  ### Testing Custom Matchers
  1839  
  1840  Whether you create a new `representJSONMatcher` type, or use `gcustom` you might test drive this matcher while writing it using Ginkgo.  Your test might look like:
  1841  
  1842  ```go
  1843  package json_response_matcher_test
  1844  
  1845  import (
  1846      . "github.com/onsi/ginkgo"
  1847      . "github.com/onsi/gomega"
  1848      . "jsonresponsematcher"
  1849  
  1850      "bytes"
  1851      "encoding/json"
  1852      "io/ioutil"
  1853      "net/http"
  1854      "strings"
  1855  
  1856      "testing"
  1857  )
  1858  
  1859  func TestCustomMatcher(t *testing.T) {
  1860      RegisterFailHandler(Fail)
  1861      RunSpecs(t, "Custom Matcher Suite")
  1862  }
  1863  
  1864  type Book struct {
  1865      Title  string `json:"title"`
  1866      Author string `json:"author"`
  1867  }
  1868  
  1869  var _ = Describe("RepresentJSONified Object", func() {
  1870      var (
  1871          book     Book
  1872          bookJSON []byte
  1873          response *http.Response
  1874      )
  1875  
  1876      BeforeEach(func() {
  1877          book = Book{
  1878              Title:  "Les Miserables",
  1879              Author: "Victor Hugo",
  1880          }
  1881  
  1882          var err error
  1883          bookJSON, err = json.Marshal(book)
  1884          Ω(err).ShouldNot(HaveOccurred())
  1885      })
  1886  
  1887      Context("when actual is not an http response", func() {
  1888          It("should error", func() {
  1889              _, err := RepresentJSONifiedObject(book).Match("not a response")
  1890              Ω(err).Should(HaveOccurred())
  1891          })
  1892      })
  1893  
  1894      Context("when actual is an http response", func() {
  1895          BeforeEach(func() {
  1896              response = &http.Response{}
  1897          })
  1898  
  1899          Context("with a body containing the JSON representation of actual", func() {
  1900              BeforeEach(func() {
  1901                  response.ContentLength = int64(len(bookJSON))
  1902                  response.Body = ioutil.NopCloser(bytes.NewBuffer(bookJSON))
  1903              })
  1904  
  1905              It("should succeed", func() {
  1906                  Ω(response).Should(RepresentJSONifiedObject(book))
  1907              })
  1908          })
  1909  
  1910          Context("with a body containing the JSON representation of something else", func() {
  1911              BeforeEach(func() {
  1912                  reader := strings.NewReader(`{}`)
  1913                  response.ContentLength = int64(reader.Len())
  1914                  response.Body = ioutil.NopCloser(reader)
  1915              })
  1916  
  1917              It("should fail", func() {
  1918                  Ω(response).ShouldNot(RepresentJSONifiedObject(book))
  1919              })
  1920          })
  1921  
  1922          Context("with a body containing invalid JSON", func() {
  1923              BeforeEach(func() {
  1924                  reader := strings.NewReader(`floop`)
  1925                  response.ContentLength = int64(reader.Len())
  1926                  response.Body = ioutil.NopCloser(reader)
  1927              })
  1928  
  1929              It("should error", func() {
  1930                  _, err := RepresentJSONifiedObject(book).Match(response)
  1931                  Ω(err).Should(HaveOccurred())
  1932              })
  1933          })
  1934      })
  1935  })
  1936  ```
  1937  
  1938  This also offers an example of what using the matcher would look like in your tests.  Note that testing the cases when the matcher returns an error involves creating the matcher and invoking `Match` manually (instead of using an `Ω` or `Expect` assertion).
  1939  
  1940  ### Aborting Eventually/Consistently
  1941  
  1942  **Note: This section documents the `MatchMayChangeInTheFuture` method for aborting `Eventually`/`Consistently`.  A more up-to-date approach that uses the `StopTrying` error is documented [earlier](#bailing-out-early--matchers).**
  1943  
  1944  There are sometimes instances where `Eventually` or `Consistently` should stop polling a matcher because the result of the match simply cannot change.
  1945  
  1946  For example, consider a test that looks like:
  1947  
  1948  ```go
  1949  Eventually(myChannel).Should(Receive(Equal("bar")))
  1950  ```
  1951  
  1952  `Eventually` will repeatedly invoke the `Receive` matcher against `myChannel` until the match succeeds.  However, if the channel becomes *closed* there is *no way* for the match to ever succeed.  Allowing `Eventually` to continue polling is inefficient and slows the test suite down.
  1953  
  1954  To get around this, a matcher can optionally implement:
  1955  
  1956  ```go
  1957  MatchMayChangeInTheFuture(actual interface{}) bool
  1958  ```
  1959  
  1960  This is not part of the `GomegaMatcher` interface and, in general, most matchers do not need to implement `MatchMayChangeInTheFuture`.
  1961  
  1962  If implemented, however, `MatchMayChangeInTheFuture` will be called with the appropriate `actual` value by `Eventually` and `Consistently` *after* the call to `Match` during every polling interval.  If `MatchMayChangeInTheFuture` returns `true`, `Eventually` and `Consistently` will continue polling.  If, however, `MatchMayChangeInTheFuture` returns `false`, `Eventually` and `Consistently` will stop polling and either fail or pass as appropriate.
  1963  
  1964  If you'd like to look at a simple example of `MatchMayChangeInTheFuture` check out [`gexec`'s `Exit` matcher](https://github.com/onsi/gomega/tree/master/gexec/exit_matcher.go).  Here, `MatchMayChangeInTheFuture` returns true if the `gexec.Session` under test has not exited yet, but returns false if it has.  Because of this, if a process exits with status code 3, but an assertion is made of the form:
  1965  
  1966  ```go
  1967  Eventually(session, 30).Should(gexec.Exit(0))
  1968  ```
  1969  
  1970  `Eventually` will not block for 30 seconds but will return (and fail, correctly) as soon as the mismatched exit code arrives!
  1971  
  1972  > Note: `Eventually` and `Consistently` only exercise the `MatchMayChangeInTheFuture` method *if* they are passed a bare value.  If they are passed functions to be polled it is not possible to guarantee that the return value of the function will not change between polling intervals.  In this case, `MatchMayChangeInTheFuture` is not called and the polling continues until either a match is found or the timeout elapses.
  1973  
  1974  ### Contributing to Gomega
  1975  
  1976  Contributions are more than welcome.  Either [open an issue](http://github.com/onsi/gomega/issues) for a matcher you'd like to see or, better yet, test drive the matcher and [send a pull request](https://github.com/onsi/gomega/pulls).
  1977  
  1978  When adding a new matcher please mimic the style use in Gomega's current matchers: you should use the `format` package to format your output, put the matcher and its tests in the `matchers` package, and the constructor in the `matchers.go` file in the top-level package.
  1979  
  1980  ## Extending Gomega
  1981  
  1982  The default Gomega can be wrapped by replacing it with an object that implements both the `gomega.Gomega` interface and the `inner` interface:
  1983  
  1984  ```go
  1985  type inner interface {
  1986      Inner() Gomega
  1987  }
  1988  ```
  1989  
  1990  The `Inner()` method must return the actual `gomega.Default`. For Gomega to function properly your wrapper methods must call the same method on the real `gomega.Default`  This allows you to wrap every Gomega method call (e.g. `Expect()`) with your own code across your test suite.  You can use this to add random delays, additional logging, or just for tracking the number of `Expect()` calls made.
  1991  
  1992  ```go
  1993  func init() {
  1994      gomega.Default = &gomegaWrapper{
  1995          inner: gomega.Default,
  1996      }
  1997  }
  1998  
  1999  type gomegaWrapper struct {
  2000      inner gomega.Gomega
  2001  }
  2002  func (g *gomegaWrapper) Inner() gomega.Gomega {
  2003      return g.inner
  2004  }
  2005  func (g *gomegaWrapper) Ω(actual interface{}, extra ...interface{}) types.Assertion {
  2006      // You now have an opportunity to add a random delay to help identify any timing
  2007      // dependencies in your tests or can add additional logging.
  2008      return g.inner.Ω(actual, extra...)
  2009  }
  2010  ...
  2011  ```
  2012  
  2013  ## `ghttp`: Testing HTTP Clients
  2014  The `ghttp` package provides support for testing http *clients*.  The typical pattern in Go for testing http clients entails spinning up an `httptest.Server` using the `net/http/httptest` package and attaching test-specific handlers that perform assertions.
  2015  
  2016  `ghttp` provides `ghttp.Server` - a wrapper around `httptest.Server` that allows you to easily build up a stack of test handlers.  These handlers make assertions against the incoming request and return a pre-fabricated response.  `ghttp` provides a number of prebuilt handlers that cover the most common assertions.  You can combine these handlers to build out full-fledged assertions that test multiple aspects of the incoming requests.
  2017  
  2018  The goal of this documentation is to provide you with an adequate mental model to use `ghttp` correctly.  For a full reference of all the available handlers and the various methods on `ghttp.Server` look at the [godoc](https://godoc.org/github.com/onsi/gomega/ghttp) documentation.
  2019  
  2020  ### Making assertions against an incoming request
  2021  
  2022  Let's start with a simple example.  Say you are building an API client that provides a `FetchSprockets(category string)` method that makes an http request to a remote server to fetch sprockets of a given category.
  2023  
  2024  For now, let's not worry about the values returned by `FetchSprockets` but simply assert that the correct request was made.  Here's the setup for our `ghttp`-based Ginkgo test:
  2025  
  2026  ```go
  2027  Describe("The sprockets client", func() {
  2028      var server *ghttp.Server
  2029      var client *sprockets.Client
  2030  
  2031      BeforeEach(func() {
  2032          server = ghttp.NewServer()
  2033          client = sprockets.NewClient(server.URL())
  2034      })
  2035  
  2036      AfterEach(func() {
  2037          //shut down the server between tests
  2038          server.Close()
  2039      })
  2040  })
  2041  ```
  2042  
  2043  Note that the server's URL is auto-generated and varies between test runs.  Because of this, you must always inject the server URL into your client.  Let's add a simple test that asserts that `FetchSprockets` hits the correct endpoint with the correct HTTP verb:
  2044  
  2045  ```go
  2046  Describe("The sprockets client", func() {
  2047      //...see above
  2048  
  2049      Describe("fetching sprockets", func() {
  2050          BeforeEach(func() {
  2051              server.AppendHandlers(
  2052                  ghttp.VerifyRequest("GET", "/sprockets"),
  2053              )
  2054          })
  2055  
  2056          It("should make a request to fetch sprockets", func() {
  2057              client.FetchSprockets("")
  2058              Ω(server.ReceivedRequests()).Should(HaveLen(1))
  2059          })
  2060      })
  2061  })
  2062  ```
  2063  
  2064  Here we append a `VerifyRequest` handler to the `server` and call `client.FetchSprockets`.  This call (assuming it's a blocking call) will make a round-trip to the test `server` before returning.  The test `server` receives the request and passes it through the `VerifyRequest` handler which will validate that the request is a `GET` request hitting the `/sprockets` endpoint.  If it's not, the test will fail.
  2065  
  2066  Note that the test can pass trivially if `client.FetchSprockets()` doesn't actually make a request.  To guard against this you can assert that the `server` has actually received a request.  All the requests received by the server are saved off and made available via `server.ReceivedRequests()`.  We use this to assert that there should have been exactly one received requests.
  2067  
  2068  > Guarding against the trivial "false positive"  case outlined above isn't really necessary.  Just good practice when test *driving*.
  2069  
  2070  Let's add some more to our example.  Let's make an assertion that `FetchSprockets` can request sprockets filtered by a particular category:
  2071  
  2072  ```go
  2073  Describe("The sprockets client", func() {
  2074      //...see above
  2075  
  2076      Describe("fetching sprockets", func() {
  2077          BeforeEach(func() {
  2078              server.AppendHandlers(
  2079                  ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators"),
  2080              )
  2081          })
  2082  
  2083          It("should make a request to fetch sprockets", func() {
  2084              client.FetchSprockets("encabulators")
  2085              Ω(server.ReceivedRequests()).Should(HaveLen(1))
  2086          })
  2087      })
  2088  })
  2089  ```
  2090  
  2091  `ghttp.VerifyRequest` takes an optional third parameter that is matched against the request `URL`'s `RawQuery`.
  2092  
  2093  Let's extend the example some more.  In addition to asserting that the request is a `GET` request to the correct endpoint with the correct query params, let's also assert that it includes the correct `BasicAuth` information and a correct custom header.  Here's the complete example:
  2094  
  2095  ```go
  2096  Describe("The sprockets client", func() {
  2097      var (
  2098          server *ghttp.Server
  2099          client *sprockets.Client
  2100          username, password string
  2101      )
  2102  
  2103      BeforeEach(func() {
  2104          username, password = "gopher", "tacoshell"
  2105          server = ghttp.NewServer()
  2106          client = sprockets.NewClient(server.URL(), username, password)
  2107      })
  2108  
  2109      AfterEach(func() {
  2110          server.Close()
  2111      })
  2112  
  2113      Describe("fetching sprockets", func() {
  2114          BeforeEach(func() {
  2115              server.AppendHandlers(
  2116                  ghttp.CombineHandlers(
  2117                      ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators"),
  2118                      ghttp.VerifyBasicAuth(username, password),
  2119                      ghttp.VerifyHeader(http.Header{
  2120                          "X-Sprocket-API-Version": []string{"1.0"},
  2121                      }),
  2122                  )
  2123              )
  2124          })
  2125  
  2126          It("should make a request to fetch sprockets", func() {
  2127              client.FetchSprockets("encabulators")
  2128              Ω(server.ReceivedRequests()).Should(HaveLen(1))
  2129          })
  2130      })
  2131  })
  2132  ```
  2133  
  2134  This example *combines* multiple `ghttp` verify handlers using `ghttp.CombineHandlers`.  Under the hood, this returns a new handler that wraps and invokes the three passed in verify handlers.  The request sent by the client will pass through each of these verify handlers and must pass them all for the test to pass.
  2135  
  2136  Note that you can easily add your own verify handler into the mix.  Just pass in a regular `http.HandlerFunc` and make assertions against the received request.
  2137  
  2138  > It's important to understand that you must pass `AppendHandlers` **one** handler *per* incoming request (see [below](#handling-multiple-requests)).  In order to apply multiple handlers to a single request we must first combine them with `ghttp.CombineHandlers` and then pass that *one* wrapper handler in to `AppendHandlers`.
  2139  
  2140  ### Providing responses
  2141  
  2142  So far, we've only made assertions about the outgoing request.  Clients are also responsible for parsing responses and returning valid data.  Let's say that `FetchSprockets()` returns two things: a slice `[]Sprocket` and an `error`.  Here's what a happy path test that asserts the correct data is returned might look like:
  2143  
  2144  ```go
  2145  Describe("The sprockets client", func() {
  2146      //...
  2147      Describe("fetching sprockets", func() {
  2148          BeforeEach(func() {
  2149              server.AppendHandlers(
  2150                  ghttp.CombineHandlers(
  2151                      ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators"),
  2152                      ghttp.VerifyBasicAuth(username, password),
  2153                      ghttp.VerifyHeader(http.Header{
  2154                          "X-Sprocket-API-Version": []string{"1.0"},
  2155                      }),
  2156                      ghttp.RespondWith(http.StatusOK, `[
  2157                          {"name": "entropic decoupler", "color": "red"},
  2158                          {"name": "defragmenting ramjet", "color": "yellow"}
  2159                      ]`),
  2160                  )
  2161              )
  2162          })
  2163  
  2164          It("should make a request to fetch sprockets", func() {
  2165              sprockets, err := client.FetchSprockets("encabulators")
  2166              Ω(err).ShouldNot(HaveOccurred())
  2167              Ω(sprockets).Should(Equal([]Sprocket{
  2168                  sprockets.Sprocket{Name: "entropic decoupler", Color: "red"},
  2169                  sprockets.Sprocket{Name: "defragmenting ramjet", Color: "yellow"},
  2170              }))
  2171          })
  2172      })
  2173  })
  2174  ```
  2175  
  2176  We use `ghttp.RespondWith` to specify the response return by the server.  In this case we're passing back a status code of `200` (`http.StatusOK`) and a pile of JSON.  We then assert, in the test, that the client succeeds and returns the correct set of sprockets.
  2177  
  2178  The fact that details of the JSON encoding are bleeding into this test is somewhat unfortunate, and there's a lot of repetition going on.  `ghttp` provides a `RespondWithJSONEncoded` handler that accepts an arbitrary object and JSON encodes it for you.  Here's a cleaner test:
  2179  
  2180  ```go
  2181  Describe("The sprockets client", func() {
  2182      //...
  2183      Describe("fetching sprockets", func() {
  2184          var returnedSprockets []Sprocket
  2185          BeforeEach(func() {
  2186              returnedSprockets = []Sprocket{
  2187                  sprockets.Sprocket{Name: "entropic decoupler", Color: "red"},
  2188                  sprockets.Sprocket{Name: "defragmenting ramjet", Color: "yellow"},
  2189              }
  2190  
  2191              server.AppendHandlers(
  2192                  ghttp.CombineHandlers(
  2193                      ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators"),
  2194                      ghttp.VerifyBasicAuth(username, password),
  2195                      ghttp.VerifyHeader(http.Header{
  2196                          "X-Sprocket-API-Version": []string{"1.0"},
  2197                      }),
  2198                      ghttp.RespondWithJSONEncoded(http.StatusOK, returnedSprockets),
  2199                  )
  2200              )
  2201          })
  2202  
  2203          It("should make a request to fetch sprockets", func() {
  2204              sprockets, err := client.FetchSprockets("encabulators")
  2205              Ω(err).ShouldNot(HaveOccurred())
  2206              Ω(sprockets).Should(Equal(returnedSprockets))
  2207          })
  2208      })
  2209  })
  2210  ```
  2211  
  2212  ### Testing different response scenarios
  2213  
  2214  Our test currently only handles the happy path where the server returns a `200`.  We should also test a handful of sad paths.  In particular, we'd like to return a `SprocketsErrorNotFound` error when the server `404`s and a `SprocketsErrorUnauthorized` error when the server returns a `401`.  But how to do this without redefining our server handler three times?
  2215  
  2216  `ghttp` provides `RespondWithPtr` and `RespondWithJSONEncodedPtr` for just this use case.  Both take *pointers* to status codes and respond bodies (objects for the `JSON` case).  Here's the more complete test:
  2217  
  2218  ```go
  2219  Describe("The sprockets client", func() {
  2220      //...
  2221      Describe("fetching sprockets", func() {
  2222          var returnedSprockets []Sprocket
  2223          var statusCode int
  2224  
  2225          BeforeEach(func() {
  2226              returnedSprockets = []Sprocket{
  2227                  sprockets.Sprocket{Name: "entropic decoupler", Color: "red"},
  2228                  sprockets.Sprocket{Name: "defragmenting ramjet", Color: "yellow"},
  2229              }
  2230  
  2231              server.AppendHandlers(
  2232                  ghttp.CombineHandlers(
  2233                      ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators"),
  2234                      ghttp.VerifyBasicAuth(username, password),
  2235                      ghttp.VerifyHeader(http.Header{
  2236                          "X-Sprocket-API-Version": []string{"1.0"},
  2237                      }),
  2238                      ghttp.RespondWithJSONEncodedPtr(&statusCode, &returnedSprockets),
  2239                  )
  2240              )
  2241          })
  2242  
  2243          Context("when the request succeeds", func() {
  2244              BeforeEach(func() {
  2245                  statusCode = http.StatusOK
  2246              })
  2247  
  2248              It("should return the fetched sprockets without erroring", func() {
  2249                  sprockets, err := client.FetchSprockets("encabulators")
  2250                  Ω(err).ShouldNot(HaveOccurred())
  2251                  Ω(sprockets).Should(Equal(returnedSprockets))
  2252              })
  2253          })
  2254  
  2255          Context("when the response is unauthorized", func() {
  2256              BeforeEach(func() {
  2257                  statusCode = http.StatusUnauthorized
  2258              })
  2259  
  2260              It("should return the SprocketsErrorUnauthorized error", func() {
  2261                  sprockets, err := client.FetchSprockets("encabulators")
  2262                  Ω(sprockets).Should(BeEmpty())
  2263                  Ω(err).Should(MatchError(SprocketsErrorUnauthorized))
  2264              })
  2265          })
  2266  
  2267          Context("when the response is not found", func() {
  2268              BeforeEach(func() {
  2269                  statusCode = http.StatusNotFound
  2270              })
  2271  
  2272              It("should return the SprocketsErrorNotFound error", func() {
  2273                  sprockets, err := client.FetchSprockets("encabulators")
  2274                  Ω(sprockets).Should(BeEmpty())
  2275                  Ω(err).Should(MatchError(SprocketsErrorNotFound))
  2276              })
  2277          })
  2278      })
  2279  })
  2280  ```
  2281  
  2282  In this way, the status code and returned value (not shown here) can be changed in sub-contexts without having to modify the original test setup.
  2283  
  2284  ### Handling multiple requests
  2285  
  2286  So far, we've only seen examples where one request is made per test.  `ghttp` supports handling *multiple* requests too.  `server.AppendHandlers` can be passed multiple handlers and these handlers are evaluated in order as requests come in.
  2287  
  2288  This can be helpful in cases where it is not possible (or desirable) to have calls to the client under test only generate *one* request.  A common example is pagination.  If the sprockets API is paginated it may be desirable for `FetchSprockets` to provide a simpler interface that simply fetches all available sprockets.
  2289  
  2290  Here's what a test might look like:
  2291  
  2292  ```go
  2293  Describe("fetching sprockets from a paginated endpoint", func() {
  2294      var returnedSprockets []Sprocket
  2295      var firstResponse, secondResponse PaginatedResponse
  2296  
  2297      BeforeEach(func() {
  2298          returnedSprockets = []Sprocket{
  2299              sprockets.Sprocket{Name: "entropic decoupler", Color: "red"},
  2300              sprockets.Sprocket{Name: "defragmenting ramjet", Color: "yellow"},
  2301              sprockets.Sprocket{Name: "parametric demuxer", Color: "blue"},
  2302          }
  2303  
  2304          firstResponse = sprockets.PaginatedResponse{
  2305              Sprockets: returnedSprockets[0:2], //first batch
  2306              PaginationToken: "get-second-batch", //some opaque non-empty token
  2307          }
  2308  
  2309          secondResponse = sprockets.PaginatedResponse{
  2310              Sprockets: returnedSprockets[2:], //second batch
  2311              PaginationToken: "", //signifies the last batch
  2312          }
  2313  
  2314          server.AppendHandlers(
  2315              ghttp.CombineHandlers(
  2316                  ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators"),
  2317                  ghttp.RespondWithJSONEncoded(http.StatusOK, firstResponse),
  2318              ),
  2319              ghttp.CombineHandlers(
  2320                  ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators&pagination-token=get-second-batch"),
  2321                  ghttp.RespondWithJSONEncoded(http.StatusOK, secondResponse),
  2322              ),
  2323          )
  2324      })
  2325  
  2326      It("should fetch all the sprockets", func() {
  2327          sprockets, err := client.FetchSprockets("encabulators")
  2328          Ω(err).ShouldNot(HaveOccurred())
  2329          Ω(sprockets).Should(Equal(returnedSprockets))
  2330      })
  2331  })
  2332  ```
  2333  
  2334  By default the `ghttp` server fails the test if the number of requests received exceeds the number of handlers registered, so this test ensures that the `client` stops sending requests after receiving the second (and final) set of paginated data.
  2335  
  2336  ### MUXing Routes to Handlers
  2337  
  2338  `AppendHandlers` allows you to make ordered assertions about incoming requests.  This places a strong constraint on all incoming requests: namely that exactly the right requests have to arrive in exactly the right order and that no additional requests are allowed.
  2339  
  2340  One can take a different testing strategy, however.  Instead of asserting that requests come in in a predefined order, you may which to build a test server that can handle arbitrarily many requests to a set of predefined routes.  In fact, there may be some circumstances where you want to make ordered assertions on *some* requests (via `AppendHandlers`) but still support sending particular responses to *other* requests that may interleave the ordered assertions.
  2341  
  2342  `ghttp` supports these sorts of usecases via `server.RouteToHandler(method, path, handler)`.
  2343  
  2344  Let's cook up an example.  Perhaps, instead of authenticating via basic auth our sprockets client logs in and fetches a token from the server when performing requests that require authentication.  We could pepper our `AppendHandlers` calls with a handler that handles these requests (this is not a terrible idea, of course!) *or* we could set up a single route at the top of our tests.
  2345  
  2346  Here's what such a test might look like:
  2347  
  2348  ```go
  2349  Describe("CRUDing sprockes", func() {
  2350      BeforeEach(func() {
  2351          server.RouteToHandler("POST", "/login", ghttp.CombineHandlers(
  2352              ghttp.VerifyRequest("POST", "/login", "user=bob&password=password"),
  2353              ghttp.RespondWith(http.StatusOK, "your-auth-token"),
  2354          ))
  2355      })
  2356      Context("GETting sprockets", func() {
  2357          var returnedSprockets []Sprocket
  2358  
  2359          BeforeEach(func() {
  2360              returnedSprockets = []Sprocket{
  2361                  sprockets.Sprocket{Name: "entropic decoupler", Color: "red"},
  2362                  sprockets.Sprocket{Name: "defragmenting ramjet", Color: "yellow"},
  2363                  sprockets.Sprocket{Name: "parametric demuxer", Color: "blue"},
  2364              }
  2365  
  2366              server.AppendHandlers(
  2367                  ghttp.CombineHandlers(
  2368                      ghttp.VerifyRequest("GET", "/sprockets", "category=encabulators"),
  2369                      ghttp.RespondWithJSONEncoded(http.StatusOK, returnedSprockets),
  2370                  ),
  2371              )
  2372          })
  2373  
  2374          It("should fetch all the sprockets", func() {
  2375              sprockets, err := client.FetchSprockes("encabulators")
  2376              Ω(err).ShouldNot(HaveOccurred())
  2377              Ω(sprockets).Should(Equal(returnedSprockets))
  2378          })
  2379      })
  2380  
  2381      Context("POSTing sprockets", func() {
  2382          var sprocketToSave Sprocket
  2383          BeforeEach(func() {
  2384              sprocketToSave = sprockets.Sprocket{Name: "endothermic penambulator", Color: "purple"}
  2385  
  2386              server.AppendHandlers(
  2387                  ghttp.CombineHandlers(
  2388                      ghttp.VerifyRequest("POST", "/sprocket", "token=your-auth-token"),
  2389                      ghttp.VerifyJSONRepresenting(sprocketToSave)
  2390                      ghttp.RespondWithJSONEncoded(http.StatusOK, nil),
  2391                  ),
  2392              )
  2393          })
  2394  
  2395          It("should save the sprocket", func() {
  2396              err := client.SaveSprocket(sprocketToSave)
  2397              Ω(err).ShouldNot(HaveOccurred())
  2398          })
  2399      })
  2400  })
  2401  ```
  2402  
  2403  Here, saving a sprocket triggers authentication, which is handled by the registered `RouteToHandler` handler whereas fetching the list of sprockets does not.
  2404  
  2405  > `RouteToHandler` can take either a string as a route (as seen in this example) or a `regexp.Regexp`.
  2406  
  2407  ### Allowing unhandled requests
  2408  
  2409  By default, `ghttp`'s server marks the test as failed if a request is made for which there is no registered handler.
  2410  
  2411  It is sometimes useful to have a fake server that simply returns a fixed status code for all unhandled incoming requests.  `ghttp` supports this: just call `server.SetAllowUnhandledRequests(true)` and `server.SetUnhandledRequestStatusCode(statusCode)`, passing whatever status code you'd like to return.
  2412  
  2413  In addition to returning the registered status code, `ghttp`'s server will also save all received requests.  These can be accessed by calling `server.ReceivedRequests()`.  This is useful for cases where you may want to make assertions against requests *after* they've been made.
  2414  
  2415  To bring it all together: there are three ways to instruct a `ghttp` server to handle requests: you can map routes to handlers using `RouteToHandler`, you can append handlers via `AppendHandlers`, and you can `SetAllowUnhandledRequests` and specify the status code by calling `SetUnhandledRequestStatusCode`.
  2416  
  2417  When a `ghttp` server receives a request it first checks against the set of handlers registered via `RouteToHandler` if there is no such handler it proceeds to pop an `AppendHandlers` handler off the stack, if the stack of ordered handlers is empty, it will check whether `GetAllowUnhandledRequests` returns `true` or `false`.  If `false` the test fails.  If `true`, a response is sent with whatever `GetUnhandledRequestStatusCode` returns.
  2418  
  2419  ## `gbytes`: Testing Streaming Buffers
  2420  
  2421  `gbytes` implements `gbytes.Buffer` - an `io.WriteCloser` that captures all input to an in-memory buffer.
  2422  
  2423  When used in concert with the `gbytes.Say` matcher, the `gbytes.Buffer` allows you make *ordered* assertions against streaming data.
  2424  
  2425  What follows is a contrived example.  `gbytes` is best paired with [`gexec`](#gexec-testing-external-processes).
  2426  
  2427  Say you have an integration test that is streaming output from an external API.  You can feed this stream into a `gbytes.Buffer` and make ordered assertions like so:
  2428  
  2429  ```go
  2430  Describe("attach to the data stream", func() {
  2431      var (
  2432          client *apiclient.Client
  2433          buffer *gbytes.Buffer
  2434      )
  2435      BeforeEach(func() {
  2436          buffer = gbytes.NewBuffer()
  2437          client := apiclient.New()
  2438          go client.AttachToDataStream(buffer)
  2439      })
  2440  
  2441      It("should stream data", func() {
  2442          Eventually(buffer).Should(gbytes.Say(`Attached to stream as client \d+`))
  2443  
  2444          client.ReticulateSplines()
  2445          Eventually(buffer).Should(gbytes.Say(`reticulating splines`))
  2446          client.EncabulateRetros(7)
  2447          Eventually(buffer).Should(gbytes.Say(`encabulating 7 retros`))
  2448      })
  2449  })
  2450  ```
  2451  
  2452  These assertions will only pass if the strings passed to `Say` (which are interpreted as regular expressions - make sure to escape characters appropriately!) appear in the buffer.  An opaque read cursor (that you cannot access or modify) is fast-forwarded as successful assertions are made. So, for example:
  2453  
  2454  ```go
  2455  Eventually(buffer).Should(gbytes.Say(`reticulating splines`))
  2456  Consistently(buffer).ShouldNot(gbytes.Say(`reticulating splines`))
  2457  ```
  2458  
  2459  will (counterintuitively) pass.  This allows you to write tests like:
  2460  
  2461  ```go
  2462  client.ReticulateSplines()
  2463  Eventually(buffer).Should(gbytes.Say(`reticulating splines`))
  2464  client.ReticulateSplines()
  2465  Eventually(buffer).Should(gbytes.Say(`reticulating splines`))
  2466  ```
  2467  
  2468  and ensure that the test is correctly asserting that `reticulating splines` appears *twice*.
  2469  
  2470  At any time, you can access the entire contents written to the buffer via `buffer.Contents()`.  This includes *everything* ever written to the buffer regardless of the current position of the read cursor.
  2471  
  2472  ### Handling branches
  2473  
  2474  Sometimes (rarely!) you must write a test that must perform different actions depending on the output streamed to the buffer.  This can be accomplished using `buffer.Detect`. Here's a contrived example:
  2475  
  2476  ```go
  2477  func LoginIfNecessary() {
  2478      client.Authorize()
  2479      select {
  2480      case <-buffer.Detect("You are not logged in"):
  2481          client.Login()
  2482      case <-buffer.Detect("Success"):
  2483          return
  2484      case <-time.After(time.Second):
  2485          ginkgo.Fail("timed out waiting for output")
  2486      }
  2487      buffer.CancelDetects()
  2488  }
  2489  ```
  2490  
  2491  `buffer.Detect` takes a string (interpreted as a regular expression) and returns a channel that will fire *once* if the requested string is detected.  Upon detection, the buffer's opaque read cursor is fast-forwarded so subsequent uses of `gbytes.Say` will pick up from where the succeeding `Detect` left off.  You *must* call `buffer.CancelDetects()` to clean up afterwards (`buffer` spawns one goroutine per call to `Detect`).
  2492  
  2493  ### Testing `io.Reader`s, `io.Writer`s, and `io.Closer`s
  2494  
  2495  Implementations of `io.Reader`, `io.Writer`, and `io.Closer` are expected to be blocking.  This makes the following class of tests unsafe:
  2496  
  2497  ```go
  2498  It("should read something", func() {
  2499      p := make([]byte, 5)
  2500      _, err := reader.Read(p)  //unsafe! this could block forever
  2501      Ω(err).ShouldNot(HaveOccurred())
  2502      Ω(p).Should(Equal([]byte("abcde")))
  2503  })
  2504  ```
  2505  
  2506  It is safer to wrap `io.Reader`s, `io.Writer`s, and `io.Closer`s with explicit timeouts.  You can do this with `gbytes.TimeoutReader`, `gbytes.TimeoutWriter`, and `gbytes.TimeoutCloser` like so:
  2507  
  2508  ```go
  2509  It("should read something", func() {
  2510      p := make([]byte, 5)
  2511      _, err := gbytes.TimeoutReader(reader, time.Second).Read(p)
  2512      Ω(err).ShouldNot(HaveOccurred())
  2513      Ω(p).Should(Equal([]byte("abcde")))
  2514  })
  2515  ```
  2516  
  2517  The `gbytes` wrappers will return `gbytes.ErrTimeout` if a timeout occurs.
  2518  
  2519  In the case of `io.Reader`s you can leverage the `Say` matcher and the functionality of `gbytes.Buffer` by building a `gbytes.Buffer` that reads from the `io.Reader` asynchronously.  You can do this with the `gbytes` package like so:
  2520  
  2521  ```go
  2522  It("should read something", func() {
  2523      Eventually(gbytes.BufferReader(reader)).Should(gbytes.Say("abcde"))
  2524  })
  2525  ```
  2526  
  2527  `gbytes.BufferReader` takes an `io.Reader` and returns a `gbytes.Buffer`.  Under the hood an `io.Copy` goroutine is launched to copy data from the `io.Reader` into the `gbytes.Buffer`.  The `gbytes.Buffer` is closed when the `io.Copy` completes.  Because the `io.Copy` is launched asynchronously you *must* make assertions against the reader using `Eventually`.
  2528  
  2529  
  2530  ## `gexec`: Testing External Processes
  2531  
  2532  `gexec` simplifies testing external processes.  It can help you [compile go binaries](#compiling-external-binaries), [start external processes](#starting-external-processes), [send signals and wait for them to exit](#sending-signals-and-waiting-for-the-process-to-exit), make [assertions against the exit code](#asserting-against-exit-code), and stream output into `gbytes.Buffer`s to allow you [make assertions against output](#making-assertions-against-the-process-output).
  2533  
  2534  ### Compiling external binaries
  2535  
  2536  You use `gexec.Build()` to compile Go binaries.  These are built using `go build` and are stored off in a temporary directory.  You'll want to `gexec.CleanupBuildArtifacts()` when you're done with the test.
  2537  
  2538  A common pattern is to compile binaries once at the beginning of the test using `BeforeSuite` and to clean up once at the end of the test using `AfterSuite`:
  2539  
  2540  ```go
  2541  var pathToSprocketCLI string
  2542  
  2543  BeforeSuite(func() {
  2544      var err error
  2545      pathToSprocketCLI, err = gexec.Build("github.com/spacely/sprockets")
  2546      Ω(err).ShouldNot(HaveOccurred())
  2547  })
  2548  
  2549  AfterSuite(func() {
  2550      gexec.CleanupBuildArtifacts()
  2551  })
  2552  ```
  2553  
  2554  > By default, `gexec.Build` uses the GOPATH specified in your environment.  You can also use `gexec.BuildIn(gopath string, packagePath string)` to specify a custom GOPATH for the build command.  This is useful to, for example, build a binary against its vendored Go dependencies.
  2555  
  2556  > You can specify arbitrary environment variables for the build command – such as GOOS and GOARCH for building on other platforms – using `gexec.BuildWithEnvironment(packagePath string, envs []string)`.
  2557  
  2558  ### Starting external processes
  2559  
  2560  `gexec` provides a `Session` that wraps `exec.Cmd`.  `Session` includes a number of features that will be explored in the next few sections.  You create a `Session` by instructing `gexec` to start a command:
  2561  
  2562  ```go
  2563  command := exec.Command(pathToSprocketCLI, "-api=127.0.0.1:8899")
  2564  session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
  2565  Ω(err).ShouldNot(HaveOccurred())
  2566  ```
  2567  
  2568  `gexec.Start` calls `command.Start` for you and forwards the command's `stdout` and `stderr` to `io.Writer`s that you provide. In the code above, we pass in Ginkgo's `GinkgoWriter`.  This makes working with external processes quite convenient: when a test passes no output is printed to screen, however if a test fails then any output generated by the command will be provided.
  2569  
  2570  > If you want to see all your output regardless of test status, just run `ginkgo` in verbose mode (`-v`) - now everything written to `GinkgoWriter` makes it onto the screen.
  2571  
  2572  ### Sending signals and waiting for the process to exit
  2573  
  2574  `gexec.Session` makes it easy to send signals to your started command:
  2575  
  2576  ```go
  2577  session.Kill() //sends SIGKILL
  2578  session.Interrupt() //sends SIGINT
  2579  session.Terminate() //sends SIGTERM
  2580  session.Signal(signal) //sends the passed in os.Signal signal
  2581  ```
  2582  
  2583  If the process has already exited these signal calls are no-ops.
  2584  
  2585  In addition to starting the wrapped command, `gexec.Session` also *monitors* the command until it exits.  You can ask `gexec.Session` to `Wait` until the process exits:
  2586  
  2587  ```go
  2588  session.Wait()
  2589  ```
  2590  
  2591  this will block until the session exits and will *fail* if it does not exit within the default `Eventually` timeout.  You can override this timeout by specifying a custom one:
  2592  
  2593  ```go
  2594  session.Wait(5 * time.Second)
  2595  ```
  2596  
  2597  > Though you can access the wrapped command using `session.Command` you should not attempt to `Wait` on it yourself.  `gexec` has already called `Wait` in order to monitor your process for you.
  2598  
  2599  > Under the hood `session.Wait` simply uses `Eventually`.
  2600  
  2601  
  2602  Since the signaling methods return the session you can chain calls together:
  2603  
  2604  ```go
  2605  session.Terminate().Wait()
  2606  ```
  2607  
  2608  will send `SIGTERM` and then wait for the process to exit.
  2609  
  2610  ### Asserting against exit code
  2611  
  2612  Once a session has exited you can fetch its exit code with `session.ExitCode()`.  You can subsequently make assertions against the exit code.
  2613  
  2614  A more idiomatic way to assert that a command has exited is to use the `gexec.Exit()` matcher:
  2615  
  2616  ```go
  2617  Eventually(session).Should(Exit())
  2618  ```
  2619  
  2620  Will verify that the `session` exits within `Eventually`'s default timeout.  You can assert that the process exits with a specified exit code too:
  2621  
  2622  ```go
  2623  Eventually(session).Should(Exit(0))
  2624  ```
  2625  
  2626  > If the process has not exited yet, `session.ExitCode()` returns `-1`
  2627  
  2628  ### Making assertions against the process output
  2629  
  2630  In addition to streaming output to the passed in `io.Writer`s (the `GinkgoWriter` in our example above), `gexec.Start` attaches `gbytes.Buffer`s to the command's output streams.  These are available on the `session` object via:
  2631  
  2632  ```go
  2633  session.Out //a gbytes.Buffer connected to the command's stdout
  2634  session.Err //a gbytes.Buffer connected to the command's stderr
  2635  ```
  2636  
  2637  This allows you to make assertions against the stream of output:
  2638  
  2639  ```go
  2640  Eventually(session.Out).Should(gbytes.Say("hello [A-Za-z], nice to meet you"))
  2641  Eventually(session.Err).Should(gbytes.Say("oops!"))
  2642  ```
  2643  
  2644  Since `gexec.Session` is a `gbytes.BufferProvider` that provides the `Out` buffer you can write assertions against `stdout` output like so:
  2645  
  2646  ```go
  2647  Eventually(session).Should(gbytes.Say("hello [A-Za-z], nice to meet you"))
  2648  ```
  2649  
  2650  Using the `Say` matcher is convenient when making *ordered* assertions against a stream of data generated by a live process.  Sometimes, however, all you need is to
  2651  wait for the process to exit and then make assertions against the entire contents of its output.  Since `Wait()` returns `session` you can wait for the process to exit, then grab all its stdout as a `[]byte` buffer with a simple one-liner:
  2652  
  2653  ```go
  2654  Ω(session.Wait().Out.Contents()).Should(ContainSubstring("finished successfully"))
  2655  ```
  2656  
  2657  ### Signaling all processes
  2658  `gexec` provides methods to track and send signals to all processes that it starts.
  2659  
  2660  ```go
  2661  gexec.Kill() //sends SIGKILL to all processes
  2662  gexec.Terminate() //sends SIGTERM to all processes
  2663  gexec.Signal(int)  //sends the passed in os.Signal signal to all the processes
  2664  gexec.Interrupt() //sends SIGINT to all processes
  2665  ```
  2666  
  2667  If the any of the processes have already exited these signal calls are no-ops.
  2668  
  2669  `gexec` also provides methods to cleanup and wait for all the processes it started.
  2670  
  2671  ```go
  2672  gexec.KillAndWait()
  2673  gexec.TerminateAndWait()
  2674  ```
  2675  
  2676  You can specify a custom timeout by:
  2677  
  2678  ```go
  2679  gexec.KillAndWait(5 * time.Second)
  2680  gexec.TerminateAndWait(2 * time.Second)
  2681  ```
  2682  
  2683  The timeout is applied for each of the processes.
  2684  
  2685  It is considered good practice to ensure all of your processes have been killed before the end of the test suite. If you are using `ginkgo` you can use:
  2686  
  2687  ```go
  2688  AfterSuite(func(){
  2689      gexec.KillAndWait()
  2690  })
  2691  ```
  2692  
  2693  Due to the global nature of these methods, keep in mind that signaling processes will affect all processes started by `gexec`, in any context. For example if these methods where used in an `AfterEach`, then processes started in `BeforeSuite` would also be signaled.
  2694  
  2695  ## `gstruct`: Testing Complex Data Types
  2696  
  2697  `gstruct` simplifies testing large and nested structs and slices. It is used for building up complex matchers that apply different tests to each field or element.
  2698  
  2699  ### Testing type `struct`
  2700  
  2701  `gstruct` provides the `FieldsMatcher` through the `MatchAllFields` and `MatchFields` functions for applying a separate matcher to each field of a struct:
  2702  
  2703  ```go
  2704  actual := struct{
  2705      A int
  2706      B bool
  2707      C string
  2708  }{5, true, "foo"}
  2709  Expect(actual).To(MatchAllFields(Fields{
  2710      "A": BeNumerically("<", 10),
  2711      "B": BeTrue(),
  2712      "C": Equal("foo"),
  2713  }))
  2714  ```
  2715  
  2716  `MatchAllFields` requires that every field is matched, and each matcher is mapped to a field. To match a subset or superset of a struct, you should use the `MatchFields` function with the `IgnoreExtras` and `IgnoreMissing` options. `IgnoreExtras` will ignore fields that don't map to a matcher, e.g.
  2717  
  2718  ```go
  2719  Expect(actual).To(MatchFields(IgnoreExtras, Fields{
  2720      "A": BeNumerically("<", 10),
  2721      "B": BeTrue(),
  2722      // Ignore lack of "C" in the matcher.
  2723  }))
  2724  ```
  2725  
  2726  `IgnoreMissing` will ignore matchers that don't map to a field, e.g.
  2727  
  2728  ```go
  2729  Expect(actual).To(MatchFields(IgnoreMissing, Fields{
  2730      "A": BeNumerically("<", 10),
  2731      "B": BeTrue(),
  2732      "C": Equal("foo"),
  2733      "D": Equal("bar"), // Ignored, since actual.D does not exist.
  2734  }))
  2735  ```
  2736  
  2737  The options can be combined with the binary or: `IgnoreMissing|IgnoreExtras`.
  2738  
  2739  ### Testing type slice
  2740  
  2741  `gstruct` provides the `ElementsMatcher` through the `MatchAllElements` and `MatchElements` function for applying a separate matcher to each element, identified by an `Identifier` function:
  2742  
  2743  ```go
  2744  actual := []string{
  2745      "A: foo bar baz",
  2746      "B: once upon a time",
  2747      "C: the end",
  2748  }
  2749  id := func(element interface{}) string {
  2750      return string(element.(string)[0])
  2751  }
  2752  Expect(actual).To(MatchAllElements(id, Elements{
  2753      "A": Not(BeZero()),
  2754      "B": MatchRegexp("[A-Z]: [a-z ]+"),
  2755      "C": ContainSubstring("end"),
  2756  }))
  2757  ```
  2758  
  2759  `MatchAllElements` requires that there is a 1:1 mapping from every element to every matcher. To match a subset or superset of elements, you should use the `MatchElements` function with the `IgnoreExtras` and `IgnoreMissing` options. `IgnoreExtras` will ignore elements that don't map to a matcher, e.g.
  2760  
  2761  ```go
  2762  Expect(actual).To(MatchElements(id, IgnoreExtras, Elements{
  2763      "A": Not(BeZero()),
  2764      "B": MatchRegexp("[A-Z]: [a-z ]+"),
  2765      // Ignore lack of "C" in the matcher.
  2766  }))
  2767  ```
  2768  
  2769  `IgnoreMissing` will ignore matchers that don't map to an element, e.g.
  2770  
  2771  ```go
  2772  Expect(actual).To(MatchElements(id, IgnoreMissing, Elements{
  2773      "A": Not(BeZero()),
  2774      "B": MatchRegexp("[A-Z]: [a-z ]+"),
  2775      "C": ContainSubstring("end"),
  2776      "D": Equal("bar"), // Ignored, since actual.D does not exist.
  2777  }))
  2778  ```
  2779  
  2780  You can also use the flag `AllowDuplicates` to permit multiple elements in your slice to map to a single key and matcher in your fields (this flag is not meaningful when applied to structs).
  2781  
  2782  ```go
  2783  everyElementID := func(element interface{}) string {
  2784      return "a constant" // Every element will map to the same key in this case; you can group them into multiple keys, however.
  2785  }
  2786  Expect(actual).To(MatchElements(everyElementID, AllowDuplicates, Elements{
  2787      "a constant": ContainSubstring(": "), // Because every element passes this test
  2788  }))
  2789  Expect(actual).NotTo(MatchElements(everyElementID, AllowDuplicates, Elements{
  2790      "a constant": ContainSubstring("foo bar baz"), // Only the first element passes this test
  2791  }))
  2792  ```
  2793  
  2794  The options can be combined with the binary or: `IgnoreMissing|IgnoreExtras|AllowDuplicates`.
  2795  
  2796  Additionally, `gstruct` provides `MatchAllElementsWithIndex` and `MatchElementsWithIndex` function for applying a matcher with index to each element, identified by an `IdentifierWithIndex` function. A helper function is also included with `gstruct` called `IndexIdentity` that provides the functionality of the just using the index as your identifier as seen below.
  2797  
  2798  ```go
  2799  actual := []string{
  2800      "A: foo bar baz",
  2801      "B: once upon a time",
  2802      "C: the end",
  2803  }
  2804  id := func(index int, _ interface{}) string {
  2805      return strconv.Itoa(index)
  2806  }
  2807  Expect(actual).To(MatchAllElementsWithIndex(id, Elements{
  2808      "0": Not(BeZero()),
  2809      "1": MatchRegexp("[A-Z]: [a-z ]+"),
  2810      "2": ContainSubstring("end"),
  2811  }))
  2812  // IndexIdentity is a helper function equivalent to id in this example
  2813  Expect(actual).To(MatchAllElementsWithIndex(IndexIdentity, Elements{
  2814      "0": Not(BeZero()),
  2815      "1": MatchRegexp("[A-Z]: [a-z ]+"),
  2816      "2": ContainSubstring("end"),
  2817  }))
  2818  ```
  2819  
  2820   The `WithIndex` variants take the same options as the other functions.
  2821  
  2822  ### Testing type `map`
  2823  
  2824  All of the `*Fields` functions and types have a corresponding definitions `*Keys` which can perform analogous tests against map types:
  2825  
  2826  ```go
  2827  actual := map[string]string{
  2828      "A": "correct",
  2829      "B": "incorrect",
  2830  }
  2831  
  2832  // fails, because `actual` includes the key B
  2833  Expect(actual).To(MatchAllKeys(Keys{
  2834      "A": Equal("correct"),
  2835  }))
  2836  
  2837  // passes
  2838  Expect(actual).To(MatchAllKeys(Keys{
  2839      "A": Equal("correct"),
  2840      "B": Equal("incorrect"),
  2841  }))
  2842  
  2843  // passes
  2844  Expect(actual).To(MatchKeys(IgnoreMissing, Keys{
  2845      "A": Equal("correct"),
  2846      "B": Equal("incorrect"),
  2847      "C": Equal("whatever"), // ignored, because `actual` doesn't have this key
  2848  }))
  2849  ```
  2850  
  2851  ### Testing pointer values
  2852  
  2853  `gstruct` provides the `PointTo` function to apply a matcher to the value pointed-to. It will fail if the pointer value is `nil`:
  2854  
  2855      foo := 5
  2856      Expect(&foo).To(PointTo(Equal(5)))
  2857      var bar *int
  2858      Expect(bar).NotTo(PointTo(BeNil()))
  2859  
  2860  ### Putting it all together: testing complex structures
  2861  
  2862  The `gstruct` matchers are intended to be composable, and can be combined to apply fuzzy-matching to large and deeply nested structures. The additional `Ignore()` and `Reject()` matchers are provided for ignoring (always succeed) fields and elements, or rejecting (always fail) fields and elements.
  2863  
  2864  Example:
  2865  
  2866  ```go
  2867  coreID := func(element interface{}) string {
  2868      return strconv.Itoa(element.(CoreStats).Index)
  2869  }
  2870  Expect(actual).To(MatchAllFields(Fields{
  2871    "Name":      Ignore(),
  2872    "StartTime": BeTemporally(">=", time.Now().Add(-100 * time.Hour)),
  2873    "CPU": PointTo(MatchAllFields(Fields{
  2874          "Time":                 BeTemporally(">=", time.Now().Add(-time.Hour)),
  2875          "UsageNanoCores":       BeNumerically("~", 1E9, 1E8),
  2876          "UsageCoreNanoSeconds": BeNumerically(">", 1E6),
  2877          "Cores": MatchElements(coreID, IgnoreExtras, Elements{
  2878              "0": MatchAllFields(Fields{
  2879                  Index: Ignore(),
  2880                "UsageNanoCores":       BeNumerically("<", 1E9),
  2881                "UsageCoreNanoSeconds": BeNumerically(">", 1E5),
  2882              }),
  2883              "1": MatchAllFields(Fields{
  2884                  Index: Ignore(),
  2885                "UsageNanoCores":       BeNumerically("<", 1E9),
  2886                "UsageCoreNanoSeconds": BeNumerically(">", 1E5),
  2887              }),
  2888          }),
  2889      })),
  2890      "Memory": PointTo(MatchAllFields(Fields{
  2891    "Time": BeTemporally(">=", time.Now().Add(-time.Hour)),
  2892    "AvailableBytes":  BeZero(),
  2893    "UsageBytes":      BeNumerically(">", 5E6),
  2894    "WorkingSetBytes": BeNumerically(">", 5E6),
  2895    "RSSBytes":        BeNumerically("<", 1E9),
  2896    "PageFaults":      BeNumerically("~", 1000, 100),
  2897    "MajorPageFaults": BeNumerically("~", 100, 50),
  2898      })),
  2899      "Rootfs":             m.Ignore(),
  2900      "Logs":               m.Ignore(),
  2901  }))
  2902  ```
  2903  
  2904  ## `gmeasure`: Benchmarking Code
  2905  
  2906  `gmeasure` provides support for measuring and recording benchmarks of your code and tests.  It can be used as a simple standalone benchmarking framework, or as part of your code's test suite.  `gmeasure` integrates cleanly with Ginkgo V2 to enable rich benchmarking of code alongside your tests.
  2907  
  2908  ### A Mental Model for `gmeasure`
  2909  
  2910  `gmeasure` is organized around the metaphor of `Experiment`s that can each record multiple `Measurement`s.  To use `gmeasure` you create a `NewExperiment` and use the resulting `experiment` object to record values and durations.  You can then print out the `experiment` to get a report of all measurements or access specific measurements and their statistical aggregates to perform comparisons and/or make assertions.
  2911  
  2912  An `experiment` can record _multiple_ `Measurement`s.  Each `Measurement` has a `Name`, a `Type` (either `MeasurementTypeDuration` or `MeasurementTypeValue`), and a collection of recorded data points (of type `float64` for Value measurements and `time.Duration` for Duration measurements).  In this way an experiment might describe a system or context being measured and can contain multiple measurements - one for each aspect of the system in question.
  2913  
  2914  `Experiment`s can either record values and durations that the user passes in directly.  Or they can invoke callbacks and accept their return values as Value data points, or measure their runtimes to compute Duration data points.  `Experiment`s can also _sample_ callbacks, calling them repeatedly to get an ensemble of data points.
  2915  
  2916  A `Measurement` is created when its first data point is recorded by an `Experiment`.  Subsequent data points with the same measurement name are appended to the measurement:
  2917  
  2918  ```go
  2919  experiment := gmeasure.NewExperiment("My Experiment")
  2920  experiment.RecordDuration("runtime", 3*time.Second) //creates a new Measurement called "runtime"
  2921  experiment.RecordDuration("runtime", 5*time.Second) //appends a data point to "runtime"
  2922  ```
  2923  
  2924  As described below, Measurements can be decorated with additional information.  This includes information about the `Units` for the measurement, the `Precision` with which to render the measurement, and any `Style` to apply when rendering the measurement.  Individual data points can also be decorated with an `Annotation` - an arbitrary string that is associated with that data point and gives it context.  Decorations are applied as typed variadic arguments:
  2925  
  2926  ```go
  2927  experiment := gmeasure.NewExperiment("My Experiment")
  2928  
  2929  // The first call to `RecordValue` for a measurement must set up any units, style, or precision decorations
  2930  experiment.RecordValue("length", 3.141, gmeasure.Units("inches"), gmeasure.Style("{{blue}}"), gmeasure.Precision(2), gmeasure.Annotation("box A)"))
  2931  
  2932  // Subsequent calls can attach an annotation.  In this call a new data-point of `2.71` is added to the `length` measurement with the annotation `box B`.
  2933  experiment.RecordValue("length", 2.71, gmeasure.Annotation("box B"))
  2934  ```
  2935  
  2936  Once recorded, `Measurements` can be fetched from the `experiment` by name via `experiment.Get("name")`.  The returned `Measurement` object includes all the data points.  To get a statistical summary of the data points (that includes the min, max, median, mean, and standard deviation) call `measurement.Stats()` or `experiment.GetStats("name")`.  These statistical summaries can also be rank-ordered with `RankStats()`.
  2937  
  2938  `gmeasure` is designed to integrate with Ginkgo.  This is done by registering `Experiment`s, `Measurement`s and `Ranking`s as `ReportEntry`s via Ginkgo's `AddReportEntry`.  This will cause Ginkgo to emit nicely formatted and styled summaries of each of these objects when generating the test report.
  2939  
  2940  Finally, `gmeasure` provides a mechanism to cache `Experiment`s to disk with a specified version number.  This enables multiple use-cases.  You can cache expensive experiments to avoid rerunning them while you iterate on other experiments.  You can also compare experiments to cached experiments to explore whether changes in performance have been introduced to the codebase under test.
  2941  
  2942  `gmeasure` includes detailed [godoc documentation](https://pkg.go.dev/github.com/onsi/gomega/gmeasure) - this narrative documentation is intended to help you get started with `gmeasure`.
  2943  
  2944  ### Measuring Values
  2945  
  2946  `Experiment`s can record arbitrary `float64` values.  You can do this by directly providing a `float64` via `experiment.RecordValue(measurementName string, value float64, decorators ...interface{})` or by providing a callback that returns a float64 via `experiment.MeasureValue(measurementName string, callback func() float64, decorators ...interface{})`.
  2947  
  2948  You can apply `Units`, `Style`, and `Precision` decorators to control the appearance of the `Measurement` when reports are generated.  These decorators must be applied when the first data point is recorded but can be elided thereafter.  You can also associate an `Annotation` decoration with any recorded data point.
  2949  
  2950  `Experiment`s are thread-safe so you can call `RecordValue` and `MeasureValue` from any goroutine.
  2951  
  2952  ### Measuring Durations
  2953  
  2954  `Experiment`s can record arbitrary `time.Duration` durations.  You can do this by directly providing a `time.Duration` via `experiment.RecordDuration(measurementName string, duration time.Duration, decorators ...interface{})` or by providing a callback via `experiment.MeasureDuration(measurementName string, callback func(), decorators ...interface{})`.  `gmeasure` will run the callback and measure how long it takes to complete.
  2955  
  2956  You can apply `Style` and `Precision` decorators to control the appearance of the `Measurement` when reports are generated.  These decorators must be applied when the first data point is recorded but can be elided thereafter.  You can also associate an `Annotation` decoration with any recorded data point.
  2957  
  2958  `Experiment`s are thread-safe so you can call `RecordDuration` and `MeasureDuration` from any goroutine.
  2959  
  2960  ### Sampling
  2961  
  2962  `Experiment`s support sampling callback functions repeatedly to build an ensemble of data points.  All the sampling methods are configured by passing in a `SamplingConfig`:
  2963  
  2964  ```go
  2965  type SamplingConfig struct {
  2966      N int
  2967      Duration time.Duration
  2968      NumParallel int
  2969      MinSamplingInterval time.Duration
  2970  }
  2971  ```
  2972  
  2973  Setting `SamplingConfig.N` limits the total number of samples to perform to `N`.  Setting `SamplingConfig.Duration` limits the total time spent sampling to `Duration`.  At least one of these fields must be set.  If both are set then `gmeasure` will `sample` until the first limiting condition is met.  Setting `SamplingConfig.MinSamplingInterval` causes `gmeasure` to wait until at least `MinSamplingInterval` has elapsed between subsequent samples.
  2974  
  2975  By default, the `Experiment`'s sampling methods will run their callbacks serially within the calling goroutine.  If `NumParallel` greater than `1`, however, the sampling methods will spin up `NumParallel` goroutines and farm the work among them.  You cannot use `NumParallel` with `MinSamplingInterval`.
  2976  
  2977  The basic sampling method is `experiment.Sample(callback func(idx int), samplingConfig SamplingConfig)`.  This will call the callback function repeatedly, passing in an `idx` counter that increments between each call.  The sampling will end based on the conditions provided in `SamplingConfig`.  Note that `experiment.Sample` is not explicitly associated with a measurement.  You can use `experiment.Sample` whenever you want to repeatedly invoke a callback up to a limit of `N` and/or `Duration`.  You can then record arbitrarily many value or duration measurements in the body of the callback.
  2978  
  2979  A common use-case, however, is to invoke a callback repeatedly to measure its duration or record its returned value and thereby generate an ensemble of data-points.  This is supported via the `SampleX` family of methods built on top of `Sample`:
  2980  
  2981  ```go
  2982  experiment.SampleValue(measurementName string, callback func(idx int) float64, samplingConfig SamplingConfig, decorations ...interface{})
  2983  experiment.SampleDuration(measurementName string, callback func(idx int), samplingConfig SamplingConfig, decorations ...interface{})
  2984  experiment.SampleAnnotatedValue(measurementName string, callback func(idx int) (float64, Annotation), samplingConfig SamplingConfig, decorations ...interface{})
  2985  experiment.SampleAnnotatedDuration(measurementName string, callback func(idx int) Annotation, samplingConfig SamplingConfig, decorations ...interface{})
  2986  ```
  2987  
  2988  each of these will contribute data points to the `Measurement` with name `measurementName`.  `SampleValue` records the `float64` values returned by its callback.  `SampleDuration` times each invocation of its callback and records the measured duration.  `SampleAnnotatedValue` and `SampleAnnotatedDuration` expect their callbacks to return `Annotation`s.  These are attached to each generated data point.
  2989  
  2990  All these methods take the same decorators as their corresponding `RecordX` methods.
  2991  
  2992  ### Measuring Durations with `Stopwatch`
  2993  
  2994  In addition to `RecordDuration` and `MeasureDuration`, `gmeasure` also provides a `Stopwatch`-based abstraction for recording durations.  To motivate `Stopwatch` consider the following example.  Let's say we want to measure the end-to-end performance of a web-server.  Here's the code we'd like to measure:
  2995  
  2996  ```go
  2997  It("measures the end-to-end performance of the web-server", func() {
  2998      model, err := client.Fetch("model-id-17")
  2999      Expect(err).NotTo(HaveOccurred())
  3000  
  3001      err = model.ReticulateSpines()
  3002      Expect(err).NotTo(HaveOccurred())
  3003  
  3004      Expect(client.Save(model)).To(Succeed())
  3005  
  3006      reticulatedModels, err := client.List("reticulated-models")
  3007      Expect(err).NotTo(HaveOccurred())
  3008      Expect(reticulatedModels).To(ContainElement(model))
  3009  })
  3010  ```
  3011  
  3012  One approach would be to use `MeasureDuration`:
  3013  
  3014  ```go
  3015  It("measures the end-to-end performance of the web-server", func() {
  3016      experiment := gmeasure.NewExperiment("end-to-end web-server performance")
  3017      AddReportEntry(experiment.Name, experiment)
  3018  
  3019      var model Model
  3020      var err error
  3021      experiment.MeasureDuration("fetch", func() {
  3022          model, err = client.Fetch("model-id-17")
  3023      })
  3024      Expect(err).NotTo(HaveOccurred())
  3025  
  3026      err = model.ReticulateSpines()
  3027      Expect(err).NotTo(HaveOccurred())
  3028  
  3029      experiment.MeasureDuration("save", func() {
  3030          Expect(client.Save(model)).To(Succeed())
  3031      })
  3032  
  3033      var reticulatedModels []Models
  3034      experiment.MeasureDuration("list", func() {
  3035          reticulatedModels, err = client.List("reticulated-models")
  3036      })
  3037      Expect(err).NotTo(HaveOccurred())
  3038      Expect(reticulatedModels).To(ContainElement(model))
  3039  })
  3040  ```
  3041  
  3042  this... _works_.  But all those closures and local variables make the test a bit harder to read.  We can clean it up with a `Stopwatch`:
  3043  
  3044  ```go
  3045  It("measures the end-to-end performance of the web-server", func() {
  3046      experiment := gmeasure.NewExperiment("end-to-end web-server performance")
  3047      AddReportEntry(experiment.Name, experiment)
  3048  
  3049      stopwatch := experiment.NewStopwatch() // start the stopwatch
  3050  
  3051      model, err := client.Fetch("model-id-17")
  3052      stopwatch.Record("fetch") // record the amount of time elapsed and store it in a Measurement named fetch
  3053      Expect(err).NotTo(HaveOccurred())
  3054  
  3055      err = model.ReticulateSpines()
  3056      Expect(err).NotTo(HaveOccurred())
  3057  
  3058      stopwatch.Reset() // reset the stopwatch
  3059      Expect(client.Save(model)).To(Succeed())
  3060      stopwatch.Record("save").Reset() // record the amount of time elapsed since the last Reset and store it in a Measurement named save, then reset the stopwatch 
  3061  
  3062      reticulatedModels, err := client.List("reticulated-models")
  3063      stopwatch.Record("list")
  3064      Expect(err).NotTo(HaveOccurred())
  3065      Expect(reticulatedModels).To(ContainElement(model))
  3066  })
  3067  ```
  3068  
  3069  that's now much cleaner and easier to reason about.  If we wanted to sample the server's performance concurrently we could now simply wrap the relevant code in an `experiment.Sample`:
  3070  
  3071  ```go
  3072  It("measures the end-to-end performance of the web-server", func() {
  3073      experiment := gmeasure.NewExperiment("end-to-end web-server performance")
  3074      AddReportEntry(experiment.Name, experiment)
  3075  
  3076      experiment.Sample(func(idx int) {
  3077          defer GinkgoRecover() // necessary since these will launch as goroutines and contain assertions
  3078          stopwatch := experiment.NewStopwatch() // we make a new stopwatch for each sample.  Experiments are threadsafe, but Stopwatches are not.
  3079  
  3080          model, err := client.Fetch("model-id-17")
  3081          stopwatch.Record("fetch")
  3082          Expect(err).NotTo(HaveOccurred())
  3083  
  3084          err = model.ReticulateSpines()
  3085          Expect(err).NotTo(HaveOccurred())
  3086  
  3087          stopwatch.Reset()
  3088          Expect(client.Save(model)).To(Succeed())
  3089          stopwatch.Record("save").Reset()
  3090  
  3091          reticulatedModels, err := client.List("reticulated-models")
  3092          stopwatch.Record("list")
  3093          Expect(err).NotTo(HaveOccurred())
  3094          Expect(reticulatedModels).To(ContainElement(model))
  3095      }, gmeasure.SamplingConfig{N:100, Duration:time.Minute, NumParallel:8})
  3096  })
  3097  ```
  3098  
  3099  Check out the [godoc documentation](https://pkg.go.dev/github.com/onsi/gomega/gmeasure#Stopwatch) for more details about `Stopwatch` including support for `Pause`ing and `Resume`ing the stopwatch.
  3100  
  3101  ### Stats and Rankings: Comparing Measurements
  3102  
  3103  Once you've recorded a few measurements you'll want to try to understand and interpret them.  `gmeasure` allows you to quickly compute statistics for a given measurement.  Consider the following example.  Let's say we have two different ideas for how to implement a sorting algorithm and want to hone in on the algorithm with the shortest median runtime.  We could run an experiment:
  3104  
  3105  ```go
  3106  It("identifies the fastest algorithm", func() {
  3107      experiment := gmeasure.NewExperiment("dueling algorithms")
  3108      AddReportEntry(experiment.Name, experiment)
  3109  
  3110      experiment.SampleDuration("runtime: algorithm 1", func(_ int) {
  3111          RunAlgorithm1()
  3112      }, gmeasure.SamplingConfig{N:1000})
  3113  
  3114      experiment.SampleDuration("runtime: algorithm 2", func(_ int) {
  3115          RunAlgorithm2()
  3116      }, gmeasure.SamplingConfig{N:1000})
  3117  })
  3118  ```
  3119  
  3120  This will sample the two competing tables and print out a tabular representation of the resulting statistics.  (Note - you don't need to use Ginkgo here, you could just use `gmeasure` in your code directly and then `fmt.Println` the `experiment` to get the tabular report).
  3121  
  3122  We could compare the tables by eye manually - or ask `gmeasure` to pick the winning algorithm for us:
  3123  
  3124  ```go
  3125  It("identifies the fastest algorithm", func() {
  3126      experiment := gmeasure.NewExperiment("dueling algorithms")
  3127      AddReportEntry(experiment.Name, experiment)
  3128  
  3129      experiment.SampleDuration("runtime: algorithm 1", func(_ int) {
  3130          RunAlgorithm1()
  3131      }, gmeasure.SamplingConfig{N:1000})
  3132  
  3133      experiment.SampleDuration("runtime: algorithm 2", func(_ int) {
  3134          RunAlgorithm2()
  3135      }, gmeasure.SamplingConfig{N:1000})
  3136  
  3137      ranking := gmeasure.RankStats(gmeasure.LowerMedianIsBetter, experiment.GetStats("runtime: algorithm 1"), experiment.GetStats("runtime: algorithm 2"))
  3138      AddReportEntry("Ranking", ranking)
  3139  })
  3140  ```
  3141  
  3142  This will now emit a ranking result that will highlight the winning algorithm (in this case, the algorithm with the lower Median).  `RankStats` supports the following `RankingCriteria`:
  3143  
  3144  - `LowerMeanIsBetter`
  3145  - `HigherMeanIsBetter`
  3146  - `LowerMedianIsBetter`
  3147  - `HigherMedianIsBetter`
  3148  - `LowerMinIsBetter`
  3149  - `HigherMinIsBetter`
  3150  - `LowerMaxIsBetter`
  3151  - `HigherMaxIsBetter`
  3152  
  3153  We can also inspect the statistics of the two algorithms programatically.  `experiment.GetStats` returns a `Stats` object that provides access to the following `Stat`s:
  3154  
  3155  - `StatMin` - the data point with the smallest value
  3156  - `StatMax` - the data point with the highest values
  3157  - `StatMedian` - the median data point
  3158  - `StatMean` - the mean of all the data points
  3159  - `StatStdDev` - the standard deviation of all the data points
  3160  
  3161  `Stats` can represent either Value Measurements or Duration Measurements.  When inspecting a Value Measurement you can pull out the requested `Stat` (say, `StatMedian`) via `stats.ValueFor(StatMedian)` - this returns a `float64`.  When inspecting Duration Measurements you can fetch `time.Duration` statistics via `stats.DurationFor(StatX)`.  For either type you can fetch an appropriately formatted string representation of the stat via `stats.StringFor(StatX)`.  You can also get a `float64` for either type by calling `stats.FloatFor(StatX)` (this simply returns a `float64(time.Duration)` for Duration Measurements and can be useful when you need to do some math with the stats).
  3162  
  3163  Going back to our dueling algorithms example.  Lets say we find that Algorithm 2 is the winner with a median runtime of around 3 seconds - and we want to be alerted by a failing test should the winner ever change, or the median runtime vary substantially.  We can do that by writing a few assertions:
  3164  
  3165  ```go
  3166  It("identifies the fastest algorithm", func() {
  3167      experiment := gmeasure.NewExperiment("dueling algorithms")
  3168      AddReportEntry(experiment.Name, experiment)
  3169  
  3170      experiment.SampleDuration("runtime: algorithm 1", func(_ int) {
  3171          RunAlgorithm1()
  3172      }, gmeasure.SamplingConfig{N:1000})
  3173  
  3174      experiment.SampleDuration("runtime: algorithm 2", func(_ int) {
  3175          RunAlgorithm2()
  3176      }, gmeasure.SamplingConfig{N:1000})
  3177  
  3178      ranking := gmeasure.RankStats(gmeasure.LowerMedianIsBetter, experiment.GetStats("runtime: algorithm 1"), experiment.GetStats("runtime: algorithm 2"))
  3179      AddReportEntry("Ranking", ranking)
  3180  
  3181      //assert that algorithm 2 is the winner
  3182      Expect(ranking.Winner().MeasurementName).To(Equal("runtime: algorithm 2"))
  3183  
  3184      //assert that algorithm 2's median is within 0.5 seconds of 3 seconds
  3185      Expect(experiment.GetStats("runtime: algorithm 2").DurationFor(gmeasure.StatMedian)).To(BeNumerically("~", 3*time.Second, 500*time.Millisecond))
  3186  })
  3187  ```
  3188  
  3189  ### Formatting Experiment and Measurement Output
  3190  
  3191  `gmeasure` can produce formatted tabular output for `Experiment`s, `Measurement`s, and `Ranking`s.  Each of these objects provides a `String()` method and a `ColorableString()` method.  The `String()` method returns a string that does not include any styling tags whereas the `ColorableString()` method returns a string that includes Ginkgo's console styling tags (e.g. Ginkgo will render a string like `{{blue}}{{bold}}hello{{/}} there` as a bold blue "hello" followed by a default-styled " there").  `ColorableString()` is called for you automatically when you register any of these `gmeasure` objects as Ginkgo `ReportEntry`s.
  3192  
  3193  When printing out `Experiment`s, `gmeasure` will produce a table whose columns correspond to the key statistics provided by `gmeasure.Stats` and whose rows are the various `Measurement`s recorded by the `Experiment`.  Users can also record and emit notes - contextual information about the experiment - by calling `experiment.RecordNote(note string)`.  Each note will get its own row in the table.
  3194  
  3195  When printing out `Measurement`s, `gmeasure` will produce a table that includes _all_ the data points and annotations for the `Measurement`.
  3196  
  3197  When printing out `Ranking`s, `gmeasure` will produce a table similar to the `Experiment` table with the `Measurement`s sorted by `RankingCriteria`.
  3198  
  3199  Users can adjust a few aspects of `gmeasure`s output.  This is done by providing decorators to the `Experiment` methods that record data points:
  3200  
  3201  - `Units(string)` - the `Units` decorator allows you to associate a set of units with a measurement.  Subsequent renderings of the measurement's name will include the units in `[]` square brackets.
  3202  - `Precision(int or time.Duration)` - the `Precision` decorator controls the rendering of numerical information.  For Value Measurements an `int` is used to express the number of decimal points to print.  For example `Precision(3)` will render values with `fmt.Sprintf("%.3f", value)`.  For Duration Measurements a `time.Duration` is used to round durations before rendering them.  For example `Precision(time.Second)` will render durations via `duration.Round(time.Second).String()`.
  3203  - `Style(string)` - the `Style` decorator allows you to associate a Ginkgo console style to a measurement.  The measurement's row will be rendered with this style.  For example `Style("{{green}}")` will emit a green row.
  3204  
  3205  These formatting decorators **must** be applied to the _first_ data point recorded for a given Measurement (this is when the Measurement object is initialized and its style, precision, and units fields are populated).
  3206  
  3207  Just to get concrete here's a fleshed out example that uses all the things:
  3208  
  3209  ```go
  3210  It("explores a complex object", func() {
  3211      experiment := gmeasure.NewExperiment("exploring the encabulator")
  3212      AddReportEntry(experiment.Name, experiment)
  3213  
  3214      experiment.RecordNote("Encabulation Properties")
  3215      experiment.Sample(func(idx int) {
  3216          stopwatch := experiment.NewStopwatch()
  3217          encabulator.Encabulate()
  3218          stopwatch.Record("Encabulate Runtime", gmeasure.Style("{{green}}"), gmeasure.Precision(time.Millisecond))
  3219  
  3220          var m runtime.MemStats
  3221          runtime.ReadMemStats(&m)
  3222          experiment.RecordValue("Encabulate Memory Usage", float64(m.Alloc / 1024 / 1024), gmeasure.Style("{{red}}"), gmeasure.Precision(3), gmeasure.Units("MB"), gmeasure.Annotation(fmt.Sprintf("%d", idx)))
  3223      }, gmeasure.SamplingConfig{N:1000, NumParallel:4})
  3224  
  3225      experiment.RecordNote("Encabulation Teardown")
  3226      experiment.MeasureDuration("Teardown Runtime", func() {
  3227          encabulator.Teardown()
  3228      }, gmeasure.Style("{{yellow}}"))
  3229  
  3230      memoryStats := experiment.GetStats("Encabulate Memory Usage")
  3231      minMemory := memoryStats.ValueFor(gmeasure.StatMin)
  3232      maxMemory := memoryStats.ValueFor(gmeasure.StatMax)
  3233      Expect(maxMemory - minMemory).To(BeNumerically("<=", 10), "Should not see memory fluctuations exceeding 10 megabytes")        
  3234  })
  3235  ```
  3236  
  3237  ### Ginkgo Integration
  3238  
  3239  The examples throughout this documentation have illustrated how `gmeasure` interoperates with Ginkgo.  In short - you can emit output for `Experiment`, `Measurement`s, and `Ranking`s by registering them as Ginkgo `ReportEntry`s via `AddReportEntry()`.
  3240  
  3241  This simple connection point ensures that the output is appropriately formatted and associated with the spec in question.  It also ensures that Ginkgo's machine readable reports will include appropriately encoded versions of these `gmeasure` objects.  So, for example, `ginkgo --json-report=report.json` will include JSON encoded `Experiment`s in `report.json` if you remember to `AddReportEntry` the `Experiment`s.
  3242  
  3243  ### Caching Experiments 
  3244  
  3245  `gmeasure` supports caching experiments to local disk.  Experiments can be stored and retrieved from the cache by name and version number.  Caching allows you to skip rerunning expensive experiments and versioned caching allows you to bust the cache by incrementing the version number.  Under the hood, the cache is simply a set of files in a directory.  Each file contains a JSON encoded header with the experiment's name and version number followed by the JSON-encoded experiment.  The various cache methods are documented over at [pkg.go.dev](https://pkg.go.dev/github.com/onsi/gomega/gmeasure#ExperimentCache).
  3246  
  3247  Using an `ExperimentCache` with Ginkgo takes a little bit of wiring.  Here's an example:
  3248  
  3249  ```go
  3250  const EXPERIMENT_VERSION = 1 //bump this to bust the cache and recompute _all_ experiments
  3251  
  3252  Describe("some experiments", func() {
  3253      var cache gmeasure.ExperimentCache
  3254      var experiment *gmeasure.Experiment
  3255  
  3256      BeforeEach(func() {
  3257          cache = gmeasure.NewExperimentCache("./gmeasure-cache")
  3258          name := CurrentSpecReport().LeafNodeText // we use the text in each It block as the name of the experiment
  3259          experiment = cache.Load(name, EXPERIMENT_VERSION) // we try to load the experiment from the cache
  3260          if experiment != nil {
  3261              // we have a cache hit - report on the experiment and skip this test.
  3262              AddReportEntry(experiment)
  3263              Skip("cached")
  3264          }
  3265          //we have a cache miss, make a new experiment and proceed with the test.
  3266          experiment = gmeasure.NewExperiment(name)
  3267          AddReportEntry(experiment)
  3268      })
  3269  
  3270      It("measures foo runtime", func() {
  3271          experiment.SampleDuration("runtime", func() {
  3272              //do stuff
  3273          }, gmeasure.SamplingConfig{N:100})
  3274      })
  3275  
  3276      It("measures bar runtime", func() {
  3277          experiment.SampleDuration("runtime", func() {
  3278              //do stuff
  3279          }, gmeasure.SamplingConfig{N:100})
  3280      })
  3281  
  3282      AfterEach(func() {
  3283          // AfterEaches always run, even for tests that call `Skip`.  So we make sure we aren't a skipped test then save the experiment to the cache
  3284          if !CurrentSpecReport().State.Is(types.SpecStateSkipped) {
  3285              cache.Save(experiment.Name, EXPERIMENT_VERSION, experiment)
  3286          }
  3287      })
  3288  })
  3289  ```
  3290  
  3291  this test will load the experiment from the cache if it's available or run the experiment and store it in the cache if it is not.  Incrementing `EXPERIMENT_VERSION` will force all experiments to rerun.
  3292  
  3293  Another usecase for `ExperimentCache` is to cache and commit experiments to source control for use as future baselines.  Your code can assert that measurements are within a certain range of the stored baseline.  For example:
  3294  
  3295  ```go
  3296  Describe("server performance", func() {
  3297      It("ensures a performance regression has not been introduced", func() {
  3298          // make an experiment
  3299          experiment := gmeasure.NewExperiment("performance regression test")
  3300          AddReportEntry(experiment.Name, experiment)
  3301  
  3302          // measure the performance of one endpoint
  3303          experiment.SampleDuration("fetching one", func() {
  3304              model, err := client.Get("id-1")
  3305              Expect(err).NotTo(HaveOccurred())
  3306              Expect(model.Id).To(Equal("id-1"))
  3307          }, gmeasure.SamplingConfig{N:100})
  3308  
  3309          // measure the performance of another endpoint
  3310          experiment.SampleDuration("listing", func() {
  3311              models, err := client.List()
  3312              Expect(err).NotTo(HaveOccurred())
  3313              Expect(models).To(HaveLen(30))
  3314          }, gmeasure.SamplingConfig{N:100})
  3315  
  3316          cache := gmeasure.NewExperimentCache("./gemasure-cache")
  3317          baseline := cache.Load("performance regression test", 1)
  3318          if baseline == nil {
  3319              // this is the first run, let's store a baseline
  3320              cache.Save("performacne regression test", 1, experiment)
  3321          } else {
  3322              for _, m := range []string{"fetching one", "listing"} {
  3323                  baselineStats := baseline.GetStats(m)
  3324                  currentStats := experiment.GetStats(m)
  3325  
  3326                  //make sure the mean of the current performance measure is within one standard deviation of the baseline
  3327                  Expect(currentStats.DurationFor(gmeasure.StatMean)).To(BeNumerically("~", baselineStats.DurationFor(gmeasure.StatsMean), baselineStats.DurationFor(gmeasure.StatsStdDev)), m)
  3328              }
  3329          }
  3330      })        
  3331  })
  3332  ```
  3333  
  3334  ## `gleak`: Finding Leaked Goroutines
  3335  
  3336  ![Leakiee](./images/leakiee.png)
  3337  
  3338  The `gleak` package provides support for goroutine leak detection.
  3339  
  3340  > **Please note:** gleak is an experimental new Gomega package.
  3341  
  3342  ### Basics
  3343  
  3344  Calling `Goroutines` returns information about all goroutines of a program at
  3345  this moment. `Goroutines` typically gets invoked in the form of
  3346  `Eventually(Goroutines).ShouldNot(...)`. Please note the missing `()` after
  3347  `Goroutines`, as it must be called by `Eventually` and **not before it** with
  3348  its results passed to `Eventually` only once. This does not preclude calling
  3349  `Goroutines()`, such as for taking goroutines snapshots.
  3350  
  3351  Leaked goroutines are then detected by using `gleak`'s `HaveLeaked` matcher on
  3352  the goroutines information. `HaveLeaked` checks the actual list of goroutines
  3353  against a built-in list of well-known runtime and testing framework goroutines,
  3354  as well as against any optionally additional goroutines specifications passed to
  3355  `HaveLeaked`. Good, and thus "non-leaky", Goroutines can be identified in
  3356  multiple ways: such as by the name of a topmost function on a goroutine stack or
  3357  a snapshot of goroutine information taken before a test. Non-leaky goroutines
  3358  can also be identified using basically any Gomega matcher, with `HaveField` or
  3359  `WithTransform` being highly useful in test-specific situations.
  3360  
  3361  The `HaveLeaked` matcher _succeeds_ if it finds any goroutines that are neither
  3362  in the integrated list of well-known goroutines nor in the optionally specified
  3363  `HaveLeaked` arguments. In consequence, any _success_ of `HaveLeaked` actually
  3364  is meant to be a _failure_, because of leaked goroutines. `HaveLeaked` is thus
  3365  mostly used in combination with `ShouldNot` and `NotTo`/`ToNot`.
  3366  
  3367  ### Testing for Goroutine Leaks
  3368  
  3369  In its most simple form, just run a goroutine discovery with a leak check right
  3370  _after_ each test in `AfterEach`:
  3371  
  3372  > **Important:** always use `Goroutines` and not `Goroutines()` in the call to
  3373  > `Eventually`. This ensures that the goroutine discovery is correctly done
  3374  > repeatedly as needed and not just a single time before calling `Eventually`.
  3375  
  3376  ```go
  3377  AfterEach(func() {
  3378      Eventually(Goroutines).ShouldNot(HaveLeaked())
  3379  })
  3380  ```
  3381  
  3382  Using `Eventually` instead of `Ω`/`Expect` has the benefit of retrying the leak
  3383  check periodically until there is no leak or until a timeout occurs. This
  3384  ensures that goroutines that are (still) in the process of winding down can
  3385  correctly terminate without triggering false positives. Please refer to the
  3386  [`Eventually`](#eventually) section for details on how to change the timeout
  3387  interval (which defaults to 1s) and the polling interval (which defaults to
  3388  10ms).
  3389  
  3390  Please note that this simplest form of goroutine leak test can cause false
  3391  positives in situations where a test suite or dependency module uses additional
  3392  goroutines. This simple form only looks at all goroutines _after_ a test has run
  3393  and filters out all _well-known_ "non-leaky" goroutines, such as goroutines from
  3394  Go's runtime and the testing frameworks (such as Go's own testing package and
  3395  Gomega).
  3396  
  3397  ### Ginkgo -p
  3398  
  3399  In case you intend to run multiple package tests in parallel using `ginkgo -p
  3400  ...`, you'll need to update any existing `BeforeSuite` or add new `BeforeSuite`s
  3401  in each of your packages. Calling `gleak.IgnoreGinkgoParallelClient` at the
  3402  beginning of `BeforeSuite` ensures that `gleak` updates its internal ignore list
  3403  to ignore a background goroutine related to the communication between Ginkgo and
  3404  the parallel packages under test.
  3405  
  3406  ```go
  3407  var _ = BeforeSuite(func() {
  3408      IgnoreGinkgoParallelClient()
  3409  })
  3410  ```
  3411  
  3412  ### Using Goroutine Snapshots in Leak Testing
  3413  
  3414  Often, it might be sufficient to cover for additional "non-leaky" goroutines by
  3415  taking a "snapshot" of goroutines _before_ a test and then _afterwards_ use the
  3416  snapshot to filter out the supposedly "non-leaky" goroutines.
  3417  
  3418  Using Ginkgo's v2 `DeferCleanup` this can be expressed in a compact manner and
  3419  without the need for explicitly declaring a variable to carry the list of known
  3420  goroutines over from `BeforeEach` to `AfterEach`. This keeps all things declared
  3421  neatly in a single place.
  3422  
  3423  ```go
  3424  BeforeEach(func() {
  3425      goods := Goroutines()
  3426      DeferCleanup(func() {
  3427          Eventually(Goroutines).ShouldNot(HaveLeaked(goods))
  3428      })
  3429  })
  3430  ```
  3431  
  3432  ### `HaveLeaked` Matcher
  3433  
  3434  ```go
  3435  Eventually(ACTUAL).ShouldNot(HaveLeaked(NONLEAKY1, NONLEAKY2, NONLEAKY3, ...))
  3436  ```
  3437  
  3438  causes a test to fail if `ACTUAL` after filtering out the well-known "good" (and
  3439  non-leaky) goroutines of the Go runtime and test frameworks, as well as
  3440  filtering out the additional non-leaky goroutines passed to the matcher, still
  3441  results in one or more goroutines. The ordering of the goroutines does not
  3442  matter.
  3443  
  3444  `HaveLeaked` always takes the built-in list of well-known good goroutines into
  3445  consideration and this list can neither be overridden nor disabled. Additional
  3446  known non-leaky goroutines `NONLEAKY1`, ...  can be passed to `HaveLeaks` either
  3447  in form of `GomegaMatcher`s or in shorthand notation:
  3448  
  3449  - `"foo.bar"` is shorthand for `IgnoringTopFunction("foo.bar")` and filters out
  3450    any (non-leaky) goroutine with its topmost function on the backtrace stack
  3451    having the exact name `foo.bar`.
  3452  
  3453  - `"foo.bar..."` is shorthand for `IgnoringTopFunction("foo.bar...")` and
  3454    filters out any (non-leaky) goroutine with its topmost function on the
  3455    backtrace stack beginning with the prefix `foo.bar.`; please notice the
  3456    trailing `.` dot.
  3457  
  3458  - `"foo.bar [chan receive]"` is shorthand for `IgnoringTopFunction("foo.bar
  3459    [chan receive]")` and filters out any (non-leaky) goroutine where its topmost
  3460    function on the backtrace stack has the exact name `foo.bar` _and_ the
  3461    goroutine is in a state beginning with `chan receive`.
  3462  
  3463  - `[]Goroutine` is shorthand for
  3464    `IgnoringGoroutines(<SLICEOFGOROUTINES>)`: it filters out the specified
  3465    goroutines, considering them to be non-leaky. The goroutines are identified by
  3466    their [goroutine IDs](#goroutine-ids).
  3467  
  3468  - `IgnoringInBacktrace("foo.bar.baz")` filters out any (non-leaky) goroutine
  3469    with `foo.bar.baz` _anywhere_ in its backtrace.
  3470  
  3471  - additionally, any other `GomegaMatcher` can be passed to `HaveLeaked()`, as
  3472    long as this matcher can work on a passed-in actual value of type
  3473    `Goroutine`.
  3474  
  3475  ### Goroutine Matchers
  3476  
  3477  The `gleak` packages comes with a set of predefined Goroutine matchers, to be
  3478  used with `HaveLeaked`. If these matchers succeed (that is, they match on a
  3479  certain `Goroutine`), then `HaveLeaked` considers the matched goroutine to be
  3480  non-leaky.
  3481  
  3482  #### IgnoringTopFunction(topfname string)
  3483  
  3484  ```go
  3485  Eventually(ACTUAL).ShouldNot(HaveLeaked(IgnoringTopFunction(TOPFNAME)))
  3486  ```
  3487  
  3488  In its most basic form, `IgnoringTopFunction` succeeds if `ACTUAL` contains a
  3489  goroutine where the name of the topmost function on its call stack (backtrace)
  3490  is `TOPFNAME`, causing `HaveLeaked` to filter out the matched goroutine as
  3491  non-leaky. Different forms of `TOPFNAME` describe different goroutine matching
  3492  criteria:
  3493  
  3494  - `"foo.bar"` matches only if a goroutine's topmost function has this exact name
  3495    (ignoring any function parameters).
  3496  - `"foo.bar..."` matches if a goroutine's topmost function name starts with the
  3497    prefix `"foo.bar."`; it doesn't match `"foo.bar"` though.
  3498  - `"foo.bar [state]"` matches if a goroutine's topmost function has this exact
  3499    name and the goroutine's state begins with the specified state string.
  3500  
  3501  `ACTUAL` must be an array or slice of `Goroutine`s.
  3502  
  3503  #### IgnoringGoroutines(goroutines []Goroutine)
  3504  
  3505  ```go
  3506  Eventually(ACTUAL).ShouldNot(HaveLeaked(IgnoringGoroutines(GOROUTINES)))
  3507  ```
  3508  
  3509  `IgnoringGoroutines` succeeds if `ACTUAL` contains one or more goroutines which
  3510  are elements of `GOROUTINES`, causing `HaveLeaked` to filter out the matched
  3511  goroutine(s) as non-leaky. `IgnoringGoroutines` compares goroutines by their
  3512  `ID`s (see [Goroutine IDs](#gorotuine-ids) for background information).
  3513  
  3514  `ACTUAL` must be an array or slice of `Goroutine`s.
  3515  
  3516  #### IgnoringInBacktrace(fname string)
  3517  
  3518  ```go
  3519  Eventually(Goroutines).ShouldNot(HaveLeaked(IgnoringInBacktrace(FNAME)))
  3520  ```
  3521  
  3522  `IgnoringInBacktrace` succeeds if `ACTUAL` contains a goroutine where `FNAME` is
  3523  contained anywhere within its call stack (backtrace), causing `HaveLeaked` to
  3524  filter out the matched goroutine as non-leaky. Please note that
  3525  `IgnoringInBacktrace` uses a (somewhat lazy) `strings.Contains` to check for any
  3526  occurrence of `FNAME` in backtraces.
  3527  
  3528  `ACTUAL` must be an array or slice of `Goroutine`s.
  3529  
  3530  #### IgnoringCreator(creatorname string)
  3531  
  3532  ```go
  3533  Eventually(Goroutines).ShouldNot(HaveLeaked(IgnoringCreator(CREATORNAME)))
  3534  ```
  3535  
  3536  In its most basic form, `IgnoringCreator` succeeds if `ACTUAL` contains a
  3537  goroutine where the name of the function creating the goroutine matches
  3538  `CREATORNAME`, causing `HaveLeaked` to filter out the matched goroutine(s) as
  3539  non-leaky. `IgnoringCreator` uses `==` for comparing the creator function name.
  3540  
  3541  Different forms of `CREATORNAME` describe different goroutine matching
  3542  criteria:
  3543  
  3544  - `"foo.bar"` matches only if a goroutine's creator function has this exact name
  3545    (ignoring any function parameters).
  3546  - `"foo.bar..."` matches if a goroutine's creator function name starts with the
  3547    prefix `"foo.bar."`; it doesn't match `"foo.bar"` though.
  3548  
  3549  ### Adjusting Leaky Goroutine Reporting
  3550  
  3551  When `HaveLeaked` finds leaked goroutines, `gleak` prints out a description of
  3552  (only) the _leaked_ goroutines. This is different from panic output that
  3553  contains backtraces of all goroutines.
  3554  
  3555  However, `noleak`'s goroutine dump deliberately is not subject to Gomega's usual
  3556  object rendition controls, such as `format.MaxLength` (see also [Adjusting
  3557  Output](#adjusting-output)).
  3558  
  3559  `noleak` will print leaked goroutine backtraces in a more compact form, with
  3560  function calls and locations combined into single lines. Additionally, `noleak`
  3561  defaults to reporting only the package plus file name and line number, but not
  3562  the full file path. For instance:
  3563  
  3564      main.foo.func1() at foo/bar.go:123
  3565  
  3566  Setting `noleak.ReportFilenameWithPath` to `true` will instead report full
  3567  source code file paths:
  3568  
  3569      main.foo.func1() at /home/coolprojects/ohmyleak/mymodule/foo/bar.go:123
  3570  
  3571  ### Well-Known Non-Leaky Goroutines
  3572  
  3573  The well-known good (and therefore "non-leaky") goroutines are identified by the
  3574  names of the topmost functions on their stacks (backtraces):
  3575  
  3576  - signal handling:
  3577    - `os/signal.signal_recv` and `os/signal.loop` (covering
  3578    varying state),
  3579    - as well as `runtime.ensureSigM`.
  3580  - Go's built-in [`testing`](https://pkg.go.dev/testing) framework:
  3581    - `testing.RunTests [chan receive]`,
  3582    - `testing.(*T).Run [chan receive]`,
  3583    - and `testing.(*T).Parallel [chan receive]`.
  3584  - the [Ginkgo testing framework](https://onsi.github.io/ginkgo/):
  3585    - `github.com/onsi/ginkgo/v2/internal.(*Suite).runNode` (including anonymous
  3586    inner functions),
  3587    - the anonymous inner functions of
  3588    `github.com/onsi/ginkgo/v2/internal/interrupt_handler.(*InterruptHandler).registerForInterrupts`,
  3589    - the creators `github.com/onsi/ginkgo/v2/internal.(*genericOutputInterceptor).ResumeIntercepting` and `github.com/onsi/ginkgo/v2/internal.(*genericOutputInterceptor).ResumeIntercepting...`,
  3590    - the creator `github.com/onsi/ginkgo/v2/internal.RegisterForProgressSignal`,
  3591    - and finally
  3592    `github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).registerForInterrupts`
  3593    (for v1 support).
  3594  
  3595  Additionally, any goroutines with `runtime.ReadTrace` in their backtrace stack
  3596  are also considered to be non-leaky.
  3597  
  3598  ### Goroutine IDs
  3599  
  3600  In order to detect goroutine identities, we use what is generally termed
  3601  "goroutine IDs". These IDs appear in runtime stack dumps ("backtrace"). But …
  3602  are these goroutine IDs even unambiguous? What are their "guarantees", if there
  3603  are any at all?
  3604  
  3605  First, Go's runtime code uses the identifier (and thus term) [`goid` for
  3606  Goroutine
  3607  IDs](https://github.com/golang/go/search?q=goidgen&unscoped_q=goidgen). Good to
  3608  know in case you need to find your way around Go's runtime code.
  3609  
  3610  Now, based on [Go's `goid` runtime allocation
  3611  code](https://github.com/golang/go/blob/release-branch.go1.18/src/runtime/proc.go#L4130),
  3612  goroutine IDs never get reused – unless you manage to make the 64bit "master
  3613  counter" of the Go runtime scheduler to wrap around. However, not all goroutine
  3614  IDs up to the largest one currently seen might ever be used, because as an
  3615  optimization goroutine IDs are always assigned to Go's "P" processors for
  3616  assignment to newly created "G" goroutines in batches of 16. In consequence,
  3617  there may be gaps and later goroutines might have lower goroutine IDs if they
  3618  get created from a different P.
  3619  
  3620  Finally, there's [Scott Mansfield's blog post on Goroutine
  3621  IDs](https://blog.sgmansfield.com/2015/12/goroutine-ids/). To sum up Scott's
  3622  point of view: don't use goroutine IDs. He spells out good reasons for why you
  3623  should not use them. Yet, logging, debugging and testing looks like a sane and
  3624  solid exemption from his rule, not least `runtime.Stack` includes the `goids`
  3625  for
  3626  some reason.
  3627  
  3628  ### Credits
  3629  
  3630  The _Leakiee the gopher_ mascot clearly has been inspired by the Go gopher art
  3631  work of [Renee French](http://reneefrench.blogspot.com/).
  3632  
  3633  The `gleak` package was heavily inspired by Uber's fine
  3634  [goleak](https://github.com/uber-go/goleak) goroutine leak detector package.
  3635  While `goleak` can be used with Gomega and Ginkgo in a very specific form, it
  3636  unfortunately was never designed to be (optionally) used with a matcher library
  3637  to unlock the full potential of reasoning about leaky goroutines. In fact, the
  3638  crucial element of discovering goroutines is kept internal in `goleak`. In
  3639  consequence, Gomega's `gleak` package uses its own goroutine discovery and is
  3640  explicitly designed to perfectly blend in with Gomega (and Ginkgo).
  3641  
  3642  {% endraw  %}