Matthias Andreas Benkard | 832a54e | 2019-01-29 09:27:38 +0100 | [diff] [blame] | 1 | package gomega |
| 2 | |
| 3 | import ( |
| 4 | "time" |
| 5 | |
| 6 | "github.com/onsi/gomega/matchers" |
| 7 | "github.com/onsi/gomega/types" |
| 8 | ) |
| 9 | |
| 10 | //Equal uses reflect.DeepEqual to compare actual with expected. Equal is strict about |
| 11 | //types when performing comparisons. |
| 12 | //It is an error for both actual and expected to be nil. Use BeNil() instead. |
| 13 | func Equal(expected interface{}) types.GomegaMatcher { |
| 14 | return &matchers.EqualMatcher{ |
| 15 | Expected: expected, |
| 16 | } |
| 17 | } |
| 18 | |
| 19 | //BeEquivalentTo is more lax than Equal, allowing equality between different types. |
| 20 | //This is done by converting actual to have the type of expected before |
| 21 | //attempting equality with reflect.DeepEqual. |
| 22 | //It is an error for actual and expected to be nil. Use BeNil() instead. |
| 23 | func BeEquivalentTo(expected interface{}) types.GomegaMatcher { |
| 24 | return &matchers.BeEquivalentToMatcher{ |
| 25 | Expected: expected, |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | //BeIdenticalTo uses the == operator to compare actual with expected. |
| 30 | //BeIdenticalTo is strict about types when performing comparisons. |
| 31 | //It is an error for both actual and expected to be nil. Use BeNil() instead. |
| 32 | func BeIdenticalTo(expected interface{}) types.GomegaMatcher { |
| 33 | return &matchers.BeIdenticalToMatcher{ |
| 34 | Expected: expected, |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | //BeNil succeeds if actual is nil |
| 39 | func BeNil() types.GomegaMatcher { |
| 40 | return &matchers.BeNilMatcher{} |
| 41 | } |
| 42 | |
| 43 | //BeTrue succeeds if actual is true |
| 44 | func BeTrue() types.GomegaMatcher { |
| 45 | return &matchers.BeTrueMatcher{} |
| 46 | } |
| 47 | |
| 48 | //BeFalse succeeds if actual is false |
| 49 | func BeFalse() types.GomegaMatcher { |
| 50 | return &matchers.BeFalseMatcher{} |
| 51 | } |
| 52 | |
| 53 | //HaveOccurred succeeds if actual is a non-nil error |
| 54 | //The typical Go error checking pattern looks like: |
| 55 | // err := SomethingThatMightFail() |
| 56 | // Expect(err).ShouldNot(HaveOccurred()) |
| 57 | func HaveOccurred() types.GomegaMatcher { |
| 58 | return &matchers.HaveOccurredMatcher{} |
| 59 | } |
| 60 | |
| 61 | //Succeed passes if actual is a nil error |
| 62 | //Succeed is intended to be used with functions that return a single error value. Instead of |
| 63 | // err := SomethingThatMightFail() |
| 64 | // Expect(err).ShouldNot(HaveOccurred()) |
| 65 | // |
| 66 | //You can write: |
| 67 | // Expect(SomethingThatMightFail()).Should(Succeed()) |
| 68 | // |
| 69 | //It is a mistake to use Succeed with a function that has multiple return values. Gomega's Ω and Expect |
| 70 | //functions automatically trigger failure if any return values after the first return value are non-zero/non-nil. |
| 71 | //This means that Ω(MultiReturnFunc()).ShouldNot(Succeed()) can never pass. |
| 72 | func Succeed() types.GomegaMatcher { |
| 73 | return &matchers.SucceedMatcher{} |
| 74 | } |
| 75 | |
| 76 | //MatchError succeeds if actual is a non-nil error that matches the passed in string/error. |
| 77 | // |
| 78 | //These are valid use-cases: |
| 79 | // Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error" |
| 80 | // Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual) |
| 81 | // |
| 82 | //It is an error for err to be nil or an object that does not implement the Error interface |
| 83 | func MatchError(expected interface{}) types.GomegaMatcher { |
| 84 | return &matchers.MatchErrorMatcher{ |
| 85 | Expected: expected, |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | //BeClosed succeeds if actual is a closed channel. |
| 90 | //It is an error to pass a non-channel to BeClosed, it is also an error to pass nil |
| 91 | // |
| 92 | //In order to check whether or not the channel is closed, Gomega must try to read from the channel |
| 93 | //(even in the `ShouldNot(BeClosed())` case). You should keep this in mind if you wish to make subsequent assertions about |
| 94 | //values coming down the channel. |
| 95 | // |
| 96 | //Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before |
| 97 | //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). |
| 98 | // |
| 99 | //Finally, as a corollary: it is an error to check whether or not a send-only channel is closed. |
| 100 | func BeClosed() types.GomegaMatcher { |
| 101 | return &matchers.BeClosedMatcher{} |
| 102 | } |
| 103 | |
| 104 | //Receive succeeds if there is a value to be received on actual. |
| 105 | //Actual must be a channel (and cannot be a send-only channel) -- anything else is an error. |
| 106 | // |
| 107 | //Receive returns immediately and never blocks: |
| 108 | // |
| 109 | //- If there is nothing on the channel `c` then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. |
| 110 | // |
| 111 | //- If the channel `c` is closed then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. |
| 112 | // |
| 113 | //- If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail. |
| 114 | // |
| 115 | //If you have a go-routine running in the background that will write to channel `c` you can: |
| 116 | // Eventually(c).Should(Receive()) |
| 117 | // |
| 118 | //This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`) |
| 119 | // |
| 120 | //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`: |
| 121 | // Consistently(c).ShouldNot(Receive()) |
| 122 | // |
| 123 | //You can pass `Receive` a matcher. If you do so, it will match the received object against the matcher. For example: |
| 124 | // Expect(c).Should(Receive(Equal("foo"))) |
| 125 | // |
| 126 | //When given a matcher, `Receive` will always fail if there is nothing to be received on the channel. |
| 127 | // |
| 128 | //Passing Receive a matcher is especially useful when paired with Eventually: |
| 129 | // |
| 130 | // Eventually(c).Should(Receive(ContainSubstring("bar"))) |
| 131 | // |
| 132 | //will repeatedly attempt to pull values out of `c` until a value matching "bar" is received. |
| 133 | // |
| 134 | //Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type: |
| 135 | // var myThing thing |
| 136 | // Eventually(thingChan).Should(Receive(&myThing)) |
| 137 | // Expect(myThing.Sprocket).Should(Equal("foo")) |
| 138 | // Expect(myThing.IsValid()).Should(BeTrue()) |
| 139 | func Receive(args ...interface{}) types.GomegaMatcher { |
| 140 | var arg interface{} |
| 141 | if len(args) > 0 { |
| 142 | arg = args[0] |
| 143 | } |
| 144 | |
| 145 | return &matchers.ReceiveMatcher{ |
| 146 | Arg: arg, |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | //BeSent succeeds if a value can be sent to actual. |
| 151 | //Actual must be a channel (and cannot be a receive-only channel) that can sent the type of the value passed into BeSent -- anything else is an error. |
| 152 | //In addition, actual must not be closed. |
| 153 | // |
| 154 | //BeSent never blocks: |
| 155 | // |
| 156 | //- If the channel `c` is not ready to receive then Expect(c).Should(BeSent("foo")) will fail immediately |
| 157 | //- 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 |
| 158 | //- If the channel `c` is closed then Expect(c).Should(BeSent("foo")) and Ω(c).ShouldNot(BeSent("foo")) will both fail immediately |
| 159 | // |
| 160 | //Of course, the 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). |
| 161 | //Rather, the point of `BeSent` is to make it possible to easily and expressively write tests that can timeout on blocked channel sends. |
| 162 | func BeSent(arg interface{}) types.GomegaMatcher { |
| 163 | return &matchers.BeSentMatcher{ |
| 164 | Arg: arg, |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | //MatchRegexp succeeds if actual is a string or stringer that matches the |
| 169 | //passed-in regexp. Optional arguments can be provided to construct a regexp |
| 170 | //via fmt.Sprintf(). |
| 171 | func MatchRegexp(regexp string, args ...interface{}) types.GomegaMatcher { |
| 172 | return &matchers.MatchRegexpMatcher{ |
| 173 | Regexp: regexp, |
| 174 | Args: args, |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | //ContainSubstring succeeds if actual is a string or stringer that contains the |
| 179 | //passed-in substring. Optional arguments can be provided to construct the substring |
| 180 | //via fmt.Sprintf(). |
| 181 | func ContainSubstring(substr string, args ...interface{}) types.GomegaMatcher { |
| 182 | return &matchers.ContainSubstringMatcher{ |
| 183 | Substr: substr, |
| 184 | Args: args, |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | //HavePrefix succeeds if actual is a string or stringer that contains the |
| 189 | //passed-in string as a prefix. Optional arguments can be provided to construct |
| 190 | //via fmt.Sprintf(). |
| 191 | func HavePrefix(prefix string, args ...interface{}) types.GomegaMatcher { |
| 192 | return &matchers.HavePrefixMatcher{ |
| 193 | Prefix: prefix, |
| 194 | Args: args, |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | //HaveSuffix succeeds if actual is a string or stringer that contains the |
| 199 | //passed-in string as a suffix. Optional arguments can be provided to construct |
| 200 | //via fmt.Sprintf(). |
| 201 | func HaveSuffix(suffix string, args ...interface{}) types.GomegaMatcher { |
| 202 | return &matchers.HaveSuffixMatcher{ |
| 203 | Suffix: suffix, |
| 204 | Args: args, |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | //MatchJSON succeeds if actual is a string or stringer of JSON that matches |
| 209 | //the expected JSON. The JSONs are decoded and the resulting objects are compared via |
| 210 | //reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. |
| 211 | func MatchJSON(json interface{}) types.GomegaMatcher { |
| 212 | return &matchers.MatchJSONMatcher{ |
| 213 | JSONToMatch: json, |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | //MatchXML succeeds if actual is a string or stringer of XML that matches |
| 218 | //the expected XML. The XMLs are decoded and the resulting objects are compared via |
| 219 | //reflect.DeepEqual so things like whitespaces shouldn't matter. |
| 220 | func MatchXML(xml interface{}) types.GomegaMatcher { |
| 221 | return &matchers.MatchXMLMatcher{ |
| 222 | XMLToMatch: xml, |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | //MatchYAML succeeds if actual is a string or stringer of YAML that matches |
| 227 | //the expected YAML. The YAML's are decoded and the resulting objects are compared via |
| 228 | //reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. |
| 229 | func MatchYAML(yaml interface{}) types.GomegaMatcher { |
| 230 | return &matchers.MatchYAMLMatcher{ |
| 231 | YAMLToMatch: yaml, |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | //BeEmpty succeeds if actual is empty. Actual must be of type string, array, map, chan, or slice. |
| 236 | func BeEmpty() types.GomegaMatcher { |
| 237 | return &matchers.BeEmptyMatcher{} |
| 238 | } |
| 239 | |
| 240 | //HaveLen succeeds if actual has the passed-in length. Actual must be of type string, array, map, chan, or slice. |
| 241 | func HaveLen(count int) types.GomegaMatcher { |
| 242 | return &matchers.HaveLenMatcher{ |
| 243 | Count: count, |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | //HaveCap succeeds if actual has the passed-in capacity. Actual must be of type array, chan, or slice. |
| 248 | func HaveCap(count int) types.GomegaMatcher { |
| 249 | return &matchers.HaveCapMatcher{ |
| 250 | Count: count, |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | //BeZero succeeds if actual is the zero value for its type or if actual is nil. |
| 255 | func BeZero() types.GomegaMatcher { |
| 256 | return &matchers.BeZeroMatcher{} |
| 257 | } |
| 258 | |
| 259 | //ContainElement succeeds if actual contains the passed in element. |
| 260 | //By default ContainElement() uses Equal() to perform the match, however a |
| 261 | //matcher can be passed in instead: |
| 262 | // Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar"))) |
| 263 | // |
| 264 | //Actual must be an array, slice or map. |
| 265 | //For maps, ContainElement searches through the map's values. |
| 266 | func ContainElement(element interface{}) types.GomegaMatcher { |
| 267 | return &matchers.ContainElementMatcher{ |
| 268 | Element: element, |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | //ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter. |
| 273 | //By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: |
| 274 | // |
| 275 | // Expect([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo")) |
| 276 | // Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Bar"), "Foo")) |
| 277 | // Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Foo"), ContainSubstring("Foo"))) |
| 278 | // |
| 279 | //Actual must be an array, slice or map. For maps, ConsistOf matches against the map's values. |
| 280 | // |
| 281 | //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 |
| 282 | //is the only element passed in to ConsistOf: |
| 283 | // |
| 284 | // Expect([]string{"Foo", "FooBar"}).Should(ConsistOf([]string{"FooBar", "Foo"})) |
| 285 | // |
| 286 | //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. |
| 287 | func ConsistOf(elements ...interface{}) types.GomegaMatcher { |
| 288 | return &matchers.ConsistOfMatcher{ |
| 289 | Elements: elements, |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | //HaveKey succeeds if actual is a map with the passed in key. |
| 294 | //By default HaveKey uses Equal() to perform the match, however a |
| 295 | //matcher can be passed in instead: |
| 296 | // Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`))) |
| 297 | func HaveKey(key interface{}) types.GomegaMatcher { |
| 298 | return &matchers.HaveKeyMatcher{ |
| 299 | Key: key, |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | //HaveKeyWithValue succeeds if actual is a map with the passed in key and value. |
| 304 | //By default HaveKeyWithValue uses Equal() to perform the match, however a |
| 305 | //matcher can be passed in instead: |
| 306 | // Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar")) |
| 307 | // Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar")) |
| 308 | func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher { |
| 309 | return &matchers.HaveKeyWithValueMatcher{ |
| 310 | Key: key, |
| 311 | Value: value, |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | //BeNumerically performs numerical assertions in a type-agnostic way. |
| 316 | //Actual and expected should be numbers, though the specific type of |
| 317 | //number is irrelevant (float32, float64, uint8, etc...). |
| 318 | // |
| 319 | //There are six, self-explanatory, supported comparators: |
| 320 | // Expect(1.0).Should(BeNumerically("==", 1)) |
| 321 | // Expect(1.0).Should(BeNumerically("~", 0.999, 0.01)) |
| 322 | // Expect(1.0).Should(BeNumerically(">", 0.9)) |
| 323 | // Expect(1.0).Should(BeNumerically(">=", 1.0)) |
| 324 | // Expect(1.0).Should(BeNumerically("<", 3)) |
| 325 | // Expect(1.0).Should(BeNumerically("<=", 1.0)) |
| 326 | func BeNumerically(comparator string, compareTo ...interface{}) types.GomegaMatcher { |
| 327 | return &matchers.BeNumericallyMatcher{ |
| 328 | Comparator: comparator, |
| 329 | CompareTo: compareTo, |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | //BeTemporally compares time.Time's like BeNumerically |
| 334 | //Actual and expected must be time.Time. The comparators are the same as for BeNumerically |
| 335 | // Expect(time.Now()).Should(BeTemporally(">", time.Time{})) |
| 336 | // Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second)) |
| 337 | func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Duration) types.GomegaMatcher { |
| 338 | return &matchers.BeTemporallyMatcher{ |
| 339 | Comparator: comparator, |
| 340 | CompareTo: compareTo, |
| 341 | Threshold: threshold, |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | //BeAssignableToTypeOf succeeds if actual is assignable to the type of expected. |
| 346 | //It will return an error when one of the values is nil. |
| 347 | // Expect(0).Should(BeAssignableToTypeOf(0)) // Same values |
| 348 | // Expect(5).Should(BeAssignableToTypeOf(-1)) // different values same type |
| 349 | // Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type |
| 350 | // Expect(struct{ Foo string }{}).Should(BeAssignableToTypeOf(struct{ Foo string }{})) |
| 351 | func BeAssignableToTypeOf(expected interface{}) types.GomegaMatcher { |
| 352 | return &matchers.AssignableToTypeOfMatcher{ |
| 353 | Expected: expected, |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | //Panic succeeds if actual is a function that, when invoked, panics. |
| 358 | //Actual must be a function that takes no arguments and returns no results. |
| 359 | func Panic() types.GomegaMatcher { |
| 360 | return &matchers.PanicMatcher{} |
| 361 | } |
| 362 | |
| 363 | //BeAnExistingFile succeeds if a file exists. |
| 364 | //Actual must be a string representing the abs path to the file being checked. |
| 365 | func BeAnExistingFile() types.GomegaMatcher { |
| 366 | return &matchers.BeAnExistingFileMatcher{} |
| 367 | } |
| 368 | |
| 369 | //BeARegularFile succeeds if a file exists and is a regular file. |
| 370 | //Actual must be a string representing the abs path to the file being checked. |
| 371 | func BeARegularFile() types.GomegaMatcher { |
| 372 | return &matchers.BeARegularFileMatcher{} |
| 373 | } |
| 374 | |
| 375 | //BeADirectory succeeds if a file exists and is a directory. |
| 376 | //Actual must be a string representing the abs path to the file being checked. |
| 377 | func BeADirectory() types.GomegaMatcher { |
| 378 | return &matchers.BeADirectoryMatcher{} |
| 379 | } |
| 380 | |
| 381 | //And succeeds only if all of the given matchers succeed. |
| 382 | //The matchers are tried in order, and will fail-fast if one doesn't succeed. |
| 383 | // Expect("hi").To(And(HaveLen(2), Equal("hi")) |
| 384 | // |
| 385 | //And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. |
| 386 | func And(ms ...types.GomegaMatcher) types.GomegaMatcher { |
| 387 | return &matchers.AndMatcher{Matchers: ms} |
| 388 | } |
| 389 | |
| 390 | //SatisfyAll is an alias for And(). |
| 391 | // Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi"))) |
| 392 | func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher { |
| 393 | return And(matchers...) |
| 394 | } |
| 395 | |
| 396 | //Or succeeds if any of the given matchers succeed. |
| 397 | //The matchers are tried in order and will return immediately upon the first successful match. |
| 398 | // Expect("hi").To(Or(HaveLen(3), HaveLen(2)) |
| 399 | // |
| 400 | //And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. |
| 401 | func Or(ms ...types.GomegaMatcher) types.GomegaMatcher { |
| 402 | return &matchers.OrMatcher{Matchers: ms} |
| 403 | } |
| 404 | |
| 405 | //SatisfyAny is an alias for Or(). |
| 406 | // Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2)) |
| 407 | func SatisfyAny(matchers ...types.GomegaMatcher) types.GomegaMatcher { |
| 408 | return Or(matchers...) |
| 409 | } |
| 410 | |
| 411 | //Not negates the given matcher; it succeeds if the given matcher fails. |
| 412 | // Expect(1).To(Not(Equal(2)) |
| 413 | // |
| 414 | //And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. |
| 415 | func Not(matcher types.GomegaMatcher) types.GomegaMatcher { |
| 416 | return &matchers.NotMatcher{Matcher: matcher} |
| 417 | } |
| 418 | |
| 419 | //WithTransform applies the `transform` to the actual value and matches it against `matcher`. |
| 420 | //The given transform must be a function of one parameter that returns one value. |
| 421 | // var plus1 = func(i int) int { return i + 1 } |
| 422 | // Expect(1).To(WithTransform(plus1, Equal(2)) |
| 423 | // |
| 424 | //And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. |
| 425 | func WithTransform(transform interface{}, matcher types.GomegaMatcher) types.GomegaMatcher { |
| 426 | return matchers.NewWithTransformMatcher(transform, matcher) |
| 427 | } |