2019-05-31 09:45:11 +00:00
/ *
Gomega is the Ginkgo BDD - style testing framework ' s preferred matcher library .
The godoc documentation describes Gomega ' s API . More comprehensive documentation ( with examples ! ) is available at http : //onsi.github.io/gomega/
Gomega on Github : http : //github.com/onsi/gomega
Learn more about Ginkgo online : http : //onsi.github.io/ginkgo
Ginkgo on Github : http : //github.com/onsi/ginkgo
Gomega is MIT - Licensed
* /
package gomega
import (
2021-09-01 13:50:18 +00:00
"errors"
2019-05-31 09:45:11 +00:00
"fmt"
"time"
2021-09-01 13:50:18 +00:00
"github.com/onsi/gomega/internal"
2019-05-31 09:45:11 +00:00
"github.com/onsi/gomega/types"
)
2024-11-04 20:10:45 +00:00
const GOMEGA_VERSION = "1.35.1"
2019-05-31 09:45:11 +00:00
2021-09-01 13:50:18 +00:00
const nilGomegaPanic = ` You are trying to make an assertion , but haven ' t registered Gomega ' s fail handler .
2019-05-31 09:45:11 +00:00
If you ' re using Ginkgo then you probably forgot to put your assertion in an It ( ) .
Alternatively , you may have forgotten to register a fail handler with RegisterFailHandler ( ) or RegisterTestingT ( ) .
Depending on your vendoring solution you may be inadvertently importing gomega and subpackages ( e . g . ghhtp , gexec , ... ) from different locations .
`
2021-09-01 13:50:18 +00:00
// Gomega describes the essential Gomega DSL. This interface allows libraries
// to abstract between the standard package-level function implementations
// and alternatives like *WithT.
//
2022-09-05 20:11:08 +00:00
// The types in the top-level DSL have gotten a bit messy due to earlier deprecations that avoid stuttering
2021-09-01 13:50:18 +00:00
// and due to an accidental use of a concrete type (*WithT) in an earlier release.
//
// As of 1.15 both the WithT and Ginkgo variants of Gomega are implemented by the same underlying object
// however one (the Ginkgo variant) is exported as an interface (types.Gomega) whereas the other (the withT variant)
// is shared as a concrete type (*WithT, which is aliased to *internal.Gomega). 1.15 did not clean this mess up to ensure
// that declarations of *WithT in existing code are not broken by the upgrade to 1.15.
type Gomega = types . Gomega
2019-05-31 09:45:11 +00:00
2021-09-01 13:50:18 +00:00
// DefaultGomega supplies the standard package-level implementation
var Default = Gomega ( internal . NewGomega ( internal . FetchDefaultDurationBundle ( ) ) )
// NewGomega returns an instance of Gomega wired into the passed-in fail handler.
// You generally don't need to use this when using Ginkgo - RegisterFailHandler will wire up the global gomega
// However creating a NewGomega with a custom fail handler can be useful in contexts where you want to use Gomega's
// rich ecosystem of matchers without causing a test to fail. For example, to aggregate a series of potential failures
// or for use in a non-test setting.
func NewGomega ( fail types . GomegaFailHandler ) Gomega {
2022-03-28 20:10:26 +00:00
return internal . NewGomega ( internalGomega ( Default ) . DurationBundle ) . ConfigureWithFailHandler ( fail )
2019-05-31 09:45:11 +00:00
}
2021-09-01 13:50:18 +00:00
// WithT wraps a *testing.T and provides `Expect`, `Eventually`, and `Consistently` methods. This allows you to leverage
// Gomega's rich ecosystem of matchers in standard `testing` test suites.
2019-05-31 09:45:11 +00:00
//
2021-09-01 13:50:18 +00:00
// Use `NewWithT` to instantiate a `WithT`
2019-05-31 09:45:11 +00:00
//
2021-09-01 13:50:18 +00:00
// As of 1.15 both the WithT and Ginkgo variants of Gomega are implemented by the same underlying object
// however one (the Ginkgo variant) is exported as an interface (types.Gomega) whereas the other (the withT variant)
// is shared as a concrete type (*WithT, which is aliased to *internal.Gomega). 1.15 did not clean this mess up to ensure
// that declarations of *WithT in existing code are not broken by the upgrade to 1.15.
type WithT = internal . Gomega
// GomegaWithT is deprecated in favor of gomega.WithT, which does not stutter.
type GomegaWithT = WithT
2022-03-28 20:10:26 +00:00
// inner is an interface that allows users to provide a wrapper around Default. The wrapper
// must implement the inner interface and return either the original Default or the result of
// a call to NewGomega().
type inner interface {
Inner ( ) Gomega
}
func internalGomega ( g Gomega ) * internal . Gomega {
if v , ok := g . ( inner ) ; ok {
return v . Inner ( ) . ( * internal . Gomega )
}
return g . ( * internal . Gomega )
}
2022-09-05 20:11:08 +00:00
// NewWithT takes a *testing.T and returns a `gomega.WithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with
2021-09-01 13:50:18 +00:00
// Gomega's rich ecosystem of matchers in standard `testing` test suits.
2019-05-31 09:45:11 +00:00
//
2022-11-01 15:23:27 +00:00
// func TestFarmHasCow(t *testing.T) {
// g := gomega.NewWithT(t)
2019-05-31 09:45:11 +00:00
//
2022-11-01 15:23:27 +00:00
// f := farm.New([]string{"Cow", "Horse"})
// g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow")
// }
2021-09-01 13:50:18 +00:00
func NewWithT ( t types . GomegaTestingT ) * WithT {
2022-03-28 20:10:26 +00:00
return internal . NewGomega ( internalGomega ( Default ) . DurationBundle ) . ConfigureWithT ( t )
2021-09-01 13:50:18 +00:00
}
// NewGomegaWithT is deprecated in favor of gomega.NewWithT, which does not stutter.
var NewGomegaWithT = NewWithT
// RegisterFailHandler connects Ginkgo to Gomega. When a matcher fails
// the fail handler passed into RegisterFailHandler is called.
func RegisterFailHandler ( fail types . GomegaFailHandler ) {
2022-03-28 20:10:26 +00:00
internalGomega ( Default ) . ConfigureWithFailHandler ( fail )
2021-09-01 13:50:18 +00:00
}
// RegisterFailHandlerWithT is deprecated and will be removed in a future release.
// users should use RegisterFailHandler, or RegisterTestingT
func RegisterFailHandlerWithT ( _ types . GomegaTestingT , fail types . GomegaFailHandler ) {
fmt . Println ( "RegisterFailHandlerWithT is deprecated. Please use RegisterFailHandler or RegisterTestingT instead." )
2022-03-28 20:10:26 +00:00
internalGomega ( Default ) . ConfigureWithFailHandler ( fail )
2021-09-01 13:50:18 +00:00
}
// RegisterTestingT connects Gomega to Golang's XUnit style
// Testing.T tests. It is now deprecated and you should use NewWithT() instead to get a fresh instance of Gomega for each test.
2019-05-31 09:45:11 +00:00
func RegisterTestingT ( t types . GomegaTestingT ) {
2022-03-28 20:10:26 +00:00
internalGomega ( Default ) . ConfigureWithT ( t )
2019-05-31 09:45:11 +00:00
}
// InterceptGomegaFailures runs a given callback and returns an array of
// failure messages generated by any Gomega assertions within the callback.
2022-09-05 20:11:08 +00:00
// Execution continues after the first failure allowing users to collect all failures
2021-09-01 13:50:18 +00:00
// in the callback.
2019-05-31 09:45:11 +00:00
//
// This is most useful when testing custom matchers, but can also be used to check
// on a value using a Gomega assertion without causing a test failure.
func InterceptGomegaFailures ( f func ( ) ) [ ] string {
2022-03-28 20:10:26 +00:00
originalHandler := internalGomega ( Default ) . Fail
2019-05-31 09:45:11 +00:00
failures := [ ] string { }
2022-03-28 20:10:26 +00:00
internalGomega ( Default ) . Fail = func ( message string , callerSkip ... int ) {
2019-05-31 09:45:11 +00:00
failures = append ( failures , message )
2021-09-01 13:50:18 +00:00
}
defer func ( ) {
2022-03-28 20:10:26 +00:00
internalGomega ( Default ) . Fail = originalHandler
2021-09-01 13:50:18 +00:00
} ( )
2019-05-31 09:45:11 +00:00
f ( )
return failures
}
2021-09-01 13:50:18 +00:00
// InterceptGomegaFailure runs a given callback and returns the first
// failure message generated by any Gomega assertions within the callback, wrapped in an error.
//
// The callback ceases execution as soon as the first failed assertion occurs, however Gomega
// does not register a failure with the FailHandler registered via RegisterFailHandler - it is up
// to the user to decide what to do with the returned error
func InterceptGomegaFailure ( f func ( ) ) ( err error ) {
2022-03-28 20:10:26 +00:00
originalHandler := internalGomega ( Default ) . Fail
internalGomega ( Default ) . Fail = func ( message string , callerSkip ... int ) {
2021-09-01 13:50:18 +00:00
err = errors . New ( message )
panic ( "stop execution" )
}
defer func ( ) {
2022-03-28 20:10:26 +00:00
internalGomega ( Default ) . Fail = originalHandler
2021-09-01 13:50:18 +00:00
if e := recover ( ) ; e != nil {
if err == nil {
panic ( e )
}
}
} ( )
f ( )
return err
}
func ensureDefaultGomegaIsConfigured ( ) {
2022-03-28 20:10:26 +00:00
if ! internalGomega ( Default ) . IsConfigured ( ) {
2021-09-01 13:50:18 +00:00
panic ( nilGomegaPanic )
}
}
2019-05-31 09:45:11 +00:00
// Ω wraps an actual value allowing assertions to be made on it:
2022-11-01 15:23:27 +00:00
//
// Ω("foo").Should(Equal("foo"))
2019-05-31 09:45:11 +00:00
//
// If Ω is passed more than one argument it will pass the *first* argument to the matcher.
// All subsequent arguments will be required to be nil/zero.
//
// This is convenient if you want to make an assertion on a method/function that returns
// a value and an error - a common patter in Go.
//
// For example, given a function with signature:
2022-11-01 15:23:27 +00:00
//
// func MyAmazingThing() (int, error)
2019-05-31 09:45:11 +00:00
//
// Then:
2022-11-01 15:23:27 +00:00
//
// Ω(MyAmazingThing()).Should(Equal(3))
//
2019-05-31 09:45:11 +00:00
// Will succeed only if `MyAmazingThing()` returns `(3, nil)`
//
// Ω and Expect are identical
func Ω ( actual interface { } , extra ... interface { } ) Assertion {
2021-09-01 13:50:18 +00:00
ensureDefaultGomegaIsConfigured ( )
return Default . Ω ( actual , extra ... )
2019-05-31 09:45:11 +00:00
}
// Expect wraps an actual value allowing assertions to be made on it:
2022-11-01 15:23:27 +00:00
//
// Expect("foo").To(Equal("foo"))
2019-05-31 09:45:11 +00:00
//
// If Expect is passed more than one argument it will pass the *first* argument to the matcher.
// All subsequent arguments will be required to be nil/zero.
//
// This is convenient if you want to make an assertion on a method/function that returns
2023-03-13 21:04:21 +00:00
// a value and an error - a common pattern in Go.
2019-05-31 09:45:11 +00:00
//
// For example, given a function with signature:
2022-11-01 15:23:27 +00:00
//
// func MyAmazingThing() (int, error)
2019-05-31 09:45:11 +00:00
//
// Then:
2022-11-01 15:23:27 +00:00
//
// Expect(MyAmazingThing()).Should(Equal(3))
//
2019-05-31 09:45:11 +00:00
// Will succeed only if `MyAmazingThing()` returns `(3, nil)`
//
// Expect and Ω are identical
func Expect ( actual interface { } , extra ... interface { } ) Assertion {
2021-09-01 13:50:18 +00:00
ensureDefaultGomegaIsConfigured ( )
return Default . Expect ( actual , extra ... )
2019-05-31 09:45:11 +00:00
}
// ExpectWithOffset wraps an actual value allowing assertions to be made on it:
2022-11-01 15:23:27 +00:00
//
// ExpectWithOffset(1, "foo").To(Equal("foo"))
2019-05-31 09:45:11 +00:00
//
// Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument
2021-11-08 20:26:59 +00:00
// that is used to modify the call-stack offset when computing line numbers. It is
// the same as `Expect(...).WithOffset`.
2019-05-31 09:45:11 +00:00
//
// This is most useful in helper functions that make assertions. If you want Gomega's
// error message to refer to the calling line in the test (as opposed to the line in the helper function)
// set the first argument of `ExpectWithOffset` appropriately.
func ExpectWithOffset ( offset int , actual interface { } , extra ... interface { } ) Assertion {
2021-09-01 13:50:18 +00:00
ensureDefaultGomegaIsConfigured ( )
return Default . ExpectWithOffset ( offset , actual , extra ... )
2019-05-31 09:45:11 +00:00
}
2021-09-01 13:50:18 +00:00
/ *
Eventually enables making assertions on asynchronous behavior .
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 .
2023-10-25 10:05:28 +00:00
The first optional argument is the timeout ( which defaults to 1 s ) , the second is the polling interval ( which defaults to 10 ms ) . Both intervals can be specified as time . Duration , parsable duration strings or floats / integers ( in which case they are interpreted as seconds ) . In addition an optional context . Context can be passed in - Eventually will keep trying until either the timeout expires or the context is cancelled , whichever comes first .
2021-09-01 13:50:18 +00:00
Eventually works with any Gomega compatible matcher and supports making assertions against three categories of actual value :
* * Category 1 : Making Eventually assertions on values * *
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 :
2022-11-01 15:23:27 +00:00
c := make ( chan bool )
go DoStuff ( c )
Eventually ( c , "50ms" ) . Should ( BeClosed ( ) )
2021-09-01 13:50:18 +00:00
will poll the channel repeatedly until it is closed . In this example ` Eventually ` will block until either the specified timeout of 50 ms has elapsed or the channel is closed , whichever comes first .
2022-09-05 20:11:08 +00:00
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 :
2021-09-01 13:50:18 +00:00
2022-11-01 15:23:27 +00:00
Eventually ( session ) . Should ( gexec . Exit ( 0 ) )
2021-09-01 13:50:18 +00:00
And the gomega / gbytes package allows you to monitor a streaming * gbytes . Buffer until a given string is seen :
Eventually ( buffer ) . Should ( gbytes . Say ( "hello there" ) )
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 :
// THIS IS NOT THREAD-SAFE
var s * string
go mutateStringEventually ( s )
Eventually ( s ) . Should ( Equal ( "I've changed" ) )
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 . For cases like this you can use channels or introduce your own locking around s by passing Eventually a function .
* * Category 2 : Make Eventually assertions on functions * *
2022-10-17 17:38:08 +00:00
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 .
2021-09-01 13:50:18 +00:00
For example :
2022-11-01 15:23:27 +00:00
Eventually ( func ( ) int {
return client . FetchCount ( )
} ) . Should ( BeNumerically ( ">=" , 17 ) )
2021-09-01 13:50:18 +00:00
2022-11-01 15:23:27 +00:00
will repeatedly poll client . FetchCount until the BeNumerically matcher is satisfied . ( Note that this example could have been written as Eventually ( client . FetchCount ) . Should ( BeNumerically ( ">=" , 17 ) ) )
2021-09-01 13:50:18 +00:00
2022-09-05 20:11:08 +00:00
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 .
2021-09-01 13:50:18 +00:00
For example , consider a method that returns a value and an error :
2022-11-01 15:23:27 +00:00
func FetchFromDB ( ) ( string , error )
2021-09-01 13:50:18 +00:00
Then
2022-11-01 15:23:27 +00:00
Eventually ( FetchFromDB ) . Should ( Equal ( "got it" ) )
2021-09-01 13:50:18 +00:00
will pass only if and when the returned error is nil * and * the returned string satisfies the matcher .
2022-10-17 17:38:08 +00:00
Eventually can also accept functions that take arguments , however you must provide those arguments using . WithArguments ( ) . For example , consider a function that takes a user - id and makes a network request to fetch a full name :
2022-11-01 15:23:27 +00:00
2022-10-17 17:38:08 +00:00
func FetchFullName ( userId int ) ( string , error )
You can poll this function like so :
2022-11-01 15:23:27 +00:00
2022-10-17 17:38:08 +00:00
Eventually ( FetchFullName ) . WithArguments ( 1138 ) . Should ( Equal ( "Wookie" ) )
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 . A common practice here is to use a context . Here ' s an example that combines Ginkgo ' s spec timeout support with Eventually :
It ( "fetches the correct count" , func ( ctx SpecContext ) {
2022-11-01 15:23:27 +00:00
Eventually ( ctx , func ( ) int {
2022-10-17 17:38:08 +00:00
return client . FetchCount ( ctx , "/users" )
2022-11-01 15:23:27 +00:00
} ) . Should ( BeNumerically ( ">=" , 17 ) )
2022-10-17 17:38:08 +00:00
} , SpecTimeout ( time . Second ) )
2023-10-25 10:05:28 +00:00
you an also use Eventually ( ) . WithContext ( ctx ) to pass in the context . Passed - in contexts play nicely with passed - in arguments as long as the context appears first . You can rewrite the above example as :
2022-10-17 17:38:08 +00:00
It ( "fetches the correct count" , func ( ctx SpecContext ) {
Eventually ( client . FetchCount ) . WithContext ( ctx ) . WithArguments ( "/users" ) . Should ( BeNumerically ( ">=" , 17 ) )
} , SpecTimeout ( time . Second ) )
2024-11-04 20:10:45 +00:00
Either way the context pasesd to Eventually is also passed to the underlying function . Now , when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit .
By default , when a context is passed to Eventually * without * an explicit timeout , Gomega will rely solely on the context ' s cancellation to determine when to stop polling . If you want to specify a timeout in addition to the context you can do so using the . WithTimeout ( ) method . For example :
Eventually ( client . FetchCount ) . WithContext ( ctx ) . WithTimeout ( 10 * time . Second ) . Should ( BeNumerically ( ">=" , 17 ) )
now either the context cacnellation or the timeout will cause Eventually to stop polling .
If , instead , you would like to opt out of this behavior and have Gomega ' s default timeouts govern Eventuallys that take a context you can call :
EnforceDefaultTimeoutsWhenUsingContexts ( )
in the DSL ( or on a Gomega instance ) . Now all calls to Eventually that take a context will fail if eitehr the context is cancelled or the default timeout elapses .
2021-09-01 13:50:18 +00:00
* * Category 3 : Making assertions _in_ the function passed into Eventually * *
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 .
2022-09-05 20:11:08 +00:00
Here ' s an example that makes some assertions and returns a value and error :
2021-09-01 13:50:18 +00:00
Eventually ( func ( g Gomega ) ( Widget , error ) {
ids , err := client . FetchIDs ( )
g . Expect ( err ) . NotTo ( HaveOccurred ( ) )
g . Expect ( ids ) . To ( ContainElement ( 1138 ) )
return client . FetchWidget ( 1138 )
} ) . Should ( Equal ( expectedWidget ) )
will pass only if all the assertions in the polled function pass and the return value satisfied the matcher .
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 .
For example :
2022-11-01 15:23:27 +00:00
Eventually ( func ( g Gomega ) {
model , err := client . Find ( 1138 )
g . Expect ( err ) . NotTo ( HaveOccurred ( ) )
g . Expect ( model . Reticulate ( ) ) . To ( Succeed ( ) )
g . Expect ( model . IsReticulated ( ) ) . To ( BeTrue ( ) )
g . Expect ( model . Save ( ) ) . To ( Succeed ( ) )
} ) . Should ( Succeed ( ) )
2021-09-01 13:50:18 +00:00
will rerun the function until all assertions pass .
2021-11-08 20:26:59 +00:00
2023-10-25 10:05:28 +00:00
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 :
2022-10-17 17:38:08 +00:00
Eventually ( func ( g Gomega , ctx context . Context , path string , expected ... string ) {
tok , err := client . GetToken ( ctx )
g . Expect ( err ) . NotTo ( HaveOccurred ( ) )
elements , err := client . Fetch ( ctx , tok , path )
g . Expect ( err ) . NotTo ( HaveOccurred ( ) )
g . Expect ( elements ) . To ( ConsistOf ( expected ) )
} ) . WithContext ( ctx ) . WithArguments ( "/names" , "Joe" , "Jane" , "Sam" ) . Should ( Succeed ( ) )
2023-01-30 20:05:01 +00:00
You can ensure that you get a number of consecutive successful tries before succeeding using ` MustPassRepeatedly(int) ` . For Example :
int count := 0
Eventually ( func ( ) bool {
count ++
return count > 2
} ) . MustPassRepeatedly ( 2 ) . Should ( BeTrue ( ) )
// Because we had to wait for 2 calls that returned true
Expect ( count ) . To ( Equal ( 3 ) )
2022-10-17 17:38:08 +00:00
Finally , in addition to passing timeouts and a context to Eventually you can be more explicit with Eventually ' s chaining configuration methods :
2024-06-24 20:58:34 +00:00
Eventually ( ... , "10s" , "2s" , ctx ) . Should ( ... )
2022-10-17 17:38:08 +00:00
is equivalent to
2024-06-24 20:58:34 +00:00
Eventually ( ... ) . WithTimeout ( 10 * time . Second ) . WithPolling ( 2 * time . Second ) . WithContext ( ctx ) . Should ( ... )
2021-09-01 13:50:18 +00:00
* /
2023-01-30 20:05:01 +00:00
func Eventually ( actualOrCtx interface { } , args ... interface { } ) AsyncAssertion {
2021-09-01 13:50:18 +00:00
ensureDefaultGomegaIsConfigured ( )
2023-01-30 20:05:01 +00:00
return Default . Eventually ( actualOrCtx , args ... )
2019-05-31 09:45:11 +00:00
}
// EventuallyWithOffset operates like Eventually but takes an additional
// initial argument to indicate an offset in the call stack. This is useful when building helper
// functions that contain matchers. To learn more, read about `ExpectWithOffset`.
2021-11-08 20:26:59 +00:00
//
// `EventuallyWithOffset` is the same as `Eventually(...).WithOffset`.
//
// `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are
// the same as `Eventually(...).WithOffset(...).WithTimeout` or
// `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`.
2023-01-30 20:05:01 +00:00
func EventuallyWithOffset ( offset int , actualOrCtx interface { } , args ... interface { } ) AsyncAssertion {
2021-09-01 13:50:18 +00:00
ensureDefaultGomegaIsConfigured ( )
2023-01-30 20:05:01 +00:00
return Default . EventuallyWithOffset ( offset , actualOrCtx , args ... )
2019-05-31 09:45:11 +00:00
}
2021-09-01 13:50:18 +00:00
/ *
Consistently , like Eventually , enables making assertions on asynchronous behavior .
Consistently blocks when called for a specified duration . During that duration Consistently repeatedly polls its matcher and ensures that it is satisfied . If the matcher is consistently satisfied , then Consistently will pass . Otherwise Consistently will fail .
2022-10-17 17:38:08 +00:00
Both the total waiting duration and the polling interval are configurable as optional arguments . The first optional argument is the duration that Consistently will run for ( defaults to 100 ms ) , and the second argument is the polling interval ( defaults to 10 ms ) . As with Eventually , these intervals can be passed in as time . Duration , parsable duration strings or an integer or float number of seconds . You can also pass in an optional context . Context - Consistently will exit early ( with a failure ) if the context is cancelled before the waiting duration expires .
2021-09-01 13:50:18 +00:00
Consistently accepts the same three categories of actual as Eventually , check the Eventually docs to learn more .
Consistently is useful in cases where you want to assert that something * does not happen * for a period of time . For example , you may want to assert that a goroutine does * not * send data down a channel . In this case you could write :
2022-11-01 15:23:27 +00:00
Consistently ( channel , "200ms" ) . ShouldNot ( Receive ( ) )
2021-09-01 13:50:18 +00:00
This will block for 200 milliseconds and repeatedly check the channel and ensure nothing has been received .
* /
2023-01-30 20:05:01 +00:00
func Consistently ( actualOrCtx interface { } , args ... interface { } ) AsyncAssertion {
2021-09-01 13:50:18 +00:00
ensureDefaultGomegaIsConfigured ( )
2023-01-30 20:05:01 +00:00
return Default . Consistently ( actualOrCtx , args ... )
2019-05-31 09:45:11 +00:00
}
2021-06-04 08:59:18 +00:00
// ConsistentlyWithOffset operates like Consistently but takes an additional
2019-05-31 09:45:11 +00:00
// initial argument to indicate an offset in the call stack. This is useful when building helper
// functions that contain matchers. To learn more, read about `ExpectWithOffset`.
2021-11-08 20:26:59 +00:00
//
// `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and
// optional `WithTimeout` and `WithPolling`.
2023-01-30 20:05:01 +00:00
func ConsistentlyWithOffset ( offset int , actualOrCtx interface { } , args ... interface { } ) AsyncAssertion {
2021-09-01 13:50:18 +00:00
ensureDefaultGomegaIsConfigured ( )
2023-01-30 20:05:01 +00:00
return Default . ConsistentlyWithOffset ( offset , actualOrCtx , args ... )
2019-05-31 09:45:11 +00:00
}
2022-10-17 17:38:08 +00:00
/ *
2022-11-01 15:23:27 +00:00
StopTrying can be used to signal to Eventually and Consistentlythat they should abort and stop trying . This always results in a failure of the assertion - and the failure message is the content of the StopTrying signal .
You can send the StopTrying signal by either returning StopTrying ( "message" ) as an error from your passed - in function _or_ by calling StopTrying ( "message" ) . Now ( ) to trigger a panic and end execution .
2022-10-17 17:38:08 +00:00
2022-11-01 15:23:27 +00:00
You can also wrap StopTrying around an error with ` StopTrying("message").Wrap(err) ` and can attach additional objects via ` StopTrying ( "message" ) . Attach ( "description" , object ) . When rendered , the signal will include the wrapped error and any attached objects rendered using Gomega ' s default formatting .
2022-10-17 17:38:08 +00:00
Here are a couple of examples . This is how you might use StopTrying ( ) as an error to signal that Eventually should stop :
playerIndex , numPlayers := 0 , 11
Eventually ( func ( ) ( string , error ) {
2022-11-01 15:23:27 +00:00
if playerIndex == numPlayers {
return "" , StopTrying ( "no more players left" )
}
name := client . FetchPlayer ( playerIndex )
playerIndex += 1
return name , nil
2022-10-17 17:38:08 +00:00
} ) . Should ( Equal ( "Patrick Mahomes" ) )
And here ' s an example where ` StopTrying().Now() ` is called to halt execution immediately :
Eventually ( func ( ) [ ] string {
names , err := client . FetchAllPlayers ( )
if err == client . IRRECOVERABLE_ERROR {
2022-11-01 15:23:27 +00:00
StopTrying ( "Irrecoverable error occurred" ) . Wrap ( err ) . Now ( )
2022-10-17 17:38:08 +00:00
}
return names
} ) . Should ( ContainElement ( "Patrick Mahomes" ) )
* /
var StopTrying = internal . StopTrying
2022-11-01 15:23:27 +00:00
/ *
TryAgainAfter ( < duration > ) allows you to adjust the polling interval for the _next_ iteration of ` Eventually ` or ` Consistently ` . Like ` StopTrying ` you can either return ` TryAgainAfter ` as an error or trigger it immedieately with ` .Now() `
When ` TryAgainAfter(<duration> ` is triggered ` Eventually ` and ` Consistently ` will wait for that duration . If a timeout occurs before the next poll is triggered both ` Eventually ` and ` Consistently ` will always fail with the content of the TryAgainAfter message . As with StopTrying you can ` .Wrap() ` and error and ` .Attach() ` additional objects to ` TryAgainAfter ` .
* /
var TryAgainAfter = internal . TryAgainAfter
/ *
PollingSignalError is the error returned by StopTrying ( ) and TryAgainAfter ( )
* /
type PollingSignalError = internal . PollingSignalError
2019-05-31 09:45:11 +00:00
// SetDefaultEventuallyTimeout sets the default timeout duration for Eventually. Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses.
func SetDefaultEventuallyTimeout ( t time . Duration ) {
2021-09-01 13:50:18 +00:00
Default . SetDefaultEventuallyTimeout ( t )
2019-05-31 09:45:11 +00:00
}
// SetDefaultEventuallyPollingInterval sets the default polling interval for Eventually.
func SetDefaultEventuallyPollingInterval ( t time . Duration ) {
2021-09-01 13:50:18 +00:00
Default . SetDefaultEventuallyPollingInterval ( t )
2019-05-31 09:45:11 +00:00
}
2019-09-20 10:45:13 +00:00
// SetDefaultConsistentlyDuration sets the default duration for Consistently. Consistently will verify that your condition is satisfied for this long.
2019-05-31 09:45:11 +00:00
func SetDefaultConsistentlyDuration ( t time . Duration ) {
2021-09-01 13:50:18 +00:00
Default . SetDefaultConsistentlyDuration ( t )
2019-05-31 09:45:11 +00:00
}
// SetDefaultConsistentlyPollingInterval sets the default polling interval for Consistently.
func SetDefaultConsistentlyPollingInterval ( t time . Duration ) {
2021-09-01 13:50:18 +00:00
Default . SetDefaultConsistentlyPollingInterval ( t )
2019-05-31 09:45:11 +00:00
}
2024-11-04 20:10:45 +00:00
// EnforceDefaultTimeoutsWhenUsingContexts forces `Eventually` to apply a default timeout even when a context is provided.
func EnforceDefaultTimeoutsWhenUsingContexts ( ) {
Default . EnforceDefaultTimeoutsWhenUsingContexts ( )
}
// DisableDefaultTimeoutsWhenUsingContext disables the default timeout when a context is provided to `Eventually`.
func DisableDefaultTimeoutsWhenUsingContext ( ) {
Default . DisableDefaultTimeoutsWhenUsingContext ( )
}
2019-05-31 09:45:11 +00:00
// AsyncAssertion is returned by Eventually and Consistently and polls the actual value passed into Eventually against
// the matcher passed to the Should and ShouldNot methods.
//
2020-01-14 10:38:55 +00:00
// Both Should and ShouldNot take a variadic optionalDescription argument.
// This argument allows you to make your failure messages more descriptive.
// If a single argument of type `func() string` is passed, this function will be lazily evaluated if a failure occurs
// and the returned string is used to annotate the failure message.
// Otherwise, this argument is passed on to fmt.Sprintf() and then used to annotate the failure message.
2019-05-31 09:45:11 +00:00
//
// Both Should and ShouldNot return a boolean that is true if the assertion passed and false if it failed.
//
// Example:
//
2022-11-01 15:23:27 +00:00
// Eventually(myChannel).Should(Receive(), "Something should have come down the pipe.")
// Consistently(myChannel).ShouldNot(Receive(), func() string { return "Nothing should have come down the pipe." })
2021-09-01 13:50:18 +00:00
type AsyncAssertion = types . AsyncAssertion
2019-05-31 09:45:11 +00:00
// GomegaAsyncAssertion is deprecated in favor of AsyncAssertion, which does not stutter.
2021-09-01 13:50:18 +00:00
type GomegaAsyncAssertion = types . AsyncAssertion
2019-05-31 09:45:11 +00:00
// Assertion is returned by Ω and Expect and compares the actual value to the matcher
// passed to the Should/ShouldNot and To/ToNot/NotTo methods.
//
// Typically Should/ShouldNot are used with Ω and To/ToNot/NotTo are used with Expect
// though this is not enforced.
//
2020-01-14 10:38:55 +00:00
// All methods take a variadic optionalDescription argument.
// This argument allows you to make your failure messages more descriptive.
// If a single argument of type `func() string` is passed, this function will be lazily evaluated if a failure occurs
// and the returned string is used to annotate the failure message.
// Otherwise, this argument is passed on to fmt.Sprintf() and then used to annotate the failure message.
2019-05-31 09:45:11 +00:00
//
2019-09-20 10:45:13 +00:00
// All methods return a bool that is true if the assertion passed and false if it failed.
2019-05-31 09:45:11 +00:00
//
// Example:
//
2022-11-01 15:23:27 +00:00
// Ω(farm.HasCow()).Should(BeTrue(), "Farm %v should have a cow", farm)
2021-09-01 13:50:18 +00:00
type Assertion = types . Assertion
2019-05-31 09:45:11 +00:00
// GomegaAssertion is deprecated in favor of Assertion, which does not stutter.
2021-09-01 13:50:18 +00:00
type GomegaAssertion = types . Assertion
2019-05-31 09:45:11 +00:00
// OmegaMatcher is deprecated in favor of the better-named and better-organized types.GomegaMatcher but sticks around to support existing code that uses it
2021-09-01 13:50:18 +00:00
type OmegaMatcher = types . GomegaMatcher