frankban / quicktest

Quick helpers for testing Go applications
MIT License
529 stars 27 forks source link

Check value is one of a set of possibilities #63

Closed anacrolix closed 4 years ago

anacrolix commented 4 years ago

I have the following check:

c.Check(err, qt.Any(qt.Equals), []error{nil, io.EOF})

I rushed into this assuming that it would test that it would pass if err matched any of nil and io.EOF. After reading the documentation I see that I got the operands reversed, but if I reverse them, the failure message is:

--- FAIL: TestShortFile (0.01s)
    quicktest.go:306: 
        error:
          no matching element found
        got:
          []error{
              nil,
              &errors.errorString{s:"EOF"},
          }
        want:
          e"unexpected EOF"
        stack:
          /Users/anacrolix/go/src/github.com/anacrolix/torrent/storage/file_test.go:41
            c.Check([]error{nil, io.EOF}, qt.Contains, err)

Which suggests that []error{nil, io.EOF} is expected to match err.

How can I check that err matches one of a list of values with the builtin checkers?

frankban commented 4 years ago

It seems that the check is doing what you want (e"unexpected EOF" is not e"EOF"), and the only confusing part is that the container is called "got" when qt.Contains is used. See https://play.golang.org/p/oHVE-hZOJXL

Perhaps we should just rename the argument name at https://play.golang.org/p/oHVE-hZOJXL ?

anacrolix commented 4 years ago

Hm I'm not sure. It's definitely only the argument name that is confusing. Isn't it possible to write a checker that is Any the other way around?

anacrolix commented 4 years ago

Maybe something like IsIn.

frankban commented 4 years ago

We try not to have two different ways of doing the same check in quicktest itself, but a nice feature of the library is that anyone can write their own checkers to use with qt.Assert or qt.Check fairly easily.

anacrolix commented 4 years ago

That's fair, it seems pretty common. Perhaps a checker that allows you to reverse the arguments? That might fix many such instances in one go.

anacrolix commented 4 years ago

Here's the code I'm hoping to move to quicktest, if you're curious: https://github.com/anacrolix/torrent/blob/7fe199992c7efabba3ce947902e41382bff33bf1/storage/file_test.go#L37-L43.

frankban commented 4 years ago

If you don't want to define your own checker, and if you don't want to just use qt.Assert([]error{nil, io.EOF}, qt.Contains, err), there is an expressive alternative using qt.Satisfies, like:

func isNilOrEOF(err error) bool {
    return err == nil || err == io.EOF
}

c.Assert(err, qt.Satisfies, isNilOrEOF)