frankban/quicktest

Check value is one of a set of possibilities

anacrolix opened this issue · 7 comments

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?

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 ?

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?

Maybe something like IsIn.

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.

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.

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)