Boost logo

Boost :

Subject: Re: [boost] [test] Interest in 'hamcrest'-style checks?
From: Richard (legalize+jeeves_at_[hidden])
Date: 2013-12-29 17:44:18


[Please do not mail me a copy of your followup]

boost_at_[hidden] spake the secret code
<723640C3-500C-4962-BC07-5E590357D2C4_at_[hidden]> thusly:

>I put together a version of the Hamcrest matchers, and the only ones
>that I've ended up using are:
> * SameSequence -- I find the "equal collections" macro to be awkward
>(mainly due to the use of iterators)

Iterators are the mechanism used by the standard library to walk
arbitrary containers. Unfortunately the heavy use of macros by
Boost.Test makes it impossible to do things like use overloading. I
would rather that the container comparison were done with a predicate
function instead of a macro and then the predicate could be overloaded
for the standard containers to provide more convenient shortcuts.

> * SameSequenceAnyOrder -- when the order of the result is not known
>(or relevant); the custom error strings are very helpful here
> * FutureReady/FutureNotReady -- shorthand for
>"BOOST_CHECK_EQUAL(future.wait_for(...),
>std::future_status::ready/timeout)"
>
>But, it is very Java-esque, so I understand no one else was very excited
>about adding these. But, I figured I'd ask :)

A question I asked long ago (to which I have only just stumbled upon
the answer now) was how to write custom predicates that can supply
meaningful messages and still have the framework report the location
of the failure at the point of invocation of the predicate.

Suppose I wrote something like this:

bool SameSequenceAnyOrder(Sequence const& expected, Sequence const& actual)
{
        if (expected.size() != actual.size())
        {
                return false;
        }
        
        // check elements
        return true;
}

and then use

BOOST_ASSERT(SameSequenceAnyOrder(expected, actual))

I don't get a useful message that tells me if the size didn't match or
if the contents of the sequences didn't match. The way to get this is
to use boost::test_tools::predicate_result instead of bool as the
return type from the predicate:

boost::test_tools::predicate_result
SameSequenceAnyOrder(Sequence const& expected, Sequence const& actual)
{
        boost::test_tools::predicate_result result = true;
        if (expected.size() != actual.size())
        {
                result = false;
                result.message() << "size mismatch; expected "
                        << expected.size() << ", actual "
                        << actual.size();
                return result;
        }
        
        // check elements
        return result;
}

If you do this, then your custom message will be output when the
assertion fails.

This gets you the main missing benefit of Hamcrest style matchers in
the context of Boost.Test -- detailed diagnostics when assertions
fail.

-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
         The Terminals Wiki <http://terminals.classiccmp.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk