Boost logo

Boost :

Subject: Re: [boost] [test] Interest in 'hamcrest'-style checks?
From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2013-09-15 02:45:13


Jared Grubb <jared.grubb <at> gmail.com> writes:

> > 3. Boost.Test already have this macro. It is called
> > BOOST_CHECK_PREDICATE
> >
> > BOOST_CHECK_PREDICATE( P, (a)(b)(c) );
> >
> > Very nice symmetry and most of your your other points covered
> > (stackability etc)
>
> I hadnt seen that one; I tried it, but it does require extra
> parens that I find distracting:

I find your asymmetry more distructing
 
> BOOST_CHECK_PREDICATE(vec, (Contains(42)));

This obviously is wrong syntax.
 

> However, there are a class of assertions that get a bit ugly in
> the BOOST_TEST form:
> * Contains(42) vs vec.find(42) != vec.end()
> * Any(Contains(42), Contains(43)) vs. ( vec.find(42) != vec.end() ||
vec.find(43) != vec.end())

I would use || and && and ! instead of Any, All, Not:

BOOST_CHECK_PREDICATE( contains(42) || contains(65), (container) );

BOOST_CHECK_PREDICATE( contains(5) && !contains(6), (container) );

> Using a higher level concept, rather than raw STL algorithm,
> also lets the failure messages be a bit more
> coherent.

There are 3 issues:

* We probably to do not want to replicate whole STL with "better error
message" predicates operating on containers instead of iterators
* What if I do want to use iterators?
* I wonder how will you combine generically messages from 3 different
predicates in And predicate? We failed because "error msg 1" and "err msg 2"
and "err msg 3". This can become ugly very fast.

> The partially-bound nature of these assertions ( where _THAT( a, A(x) )
> => "A(x)(a)" ) is useful because it
> means the value-under-test can be written once and, even more important,
> the value's expression is evaluated only once.

This is also true in BOOST_CHECK_PREDICATE case (both parts). I do not see
any single reason to use this asymmetric syntax.

Another complication to keep in mind is that you need to make all your
predicate "silently" bindable (here silently means an absence of bind
invocation. In other words both these should be valid:

BOOST_CHECK_PREDICATE( contains(1), (container) );
BOOST_CHECK_PREDICATE( contains, (container, 1) );

BOOST_CHECK_PREDICATE( within_range(1,10), (value) );
BOOST_CHECK_PREDICATE( !within_range, (value,1,10) );

Gennadiy


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