Boost logo

Boost :

Subject: [boost] Unittest capability for meta-programs feedback request
From: Ben Robinson (icaretaker_at_[hidden])
Date: 2011-09-27 02:43:36


This submission would make it possible to write a complete set of unit
tests for meta-programs, to test both the positive, compiling statements,
and the negative, non-compiling statements. These tests will all compile,
and the negative tests can throw an exception instead of failing to compile.

The submission source is available at https://github.com/icaretaker/Metatest.
 The provided examples are based on the factorial metafunction from Chapter
8 of "C++ Template Metaprogramming" by David Abrahams and Aleksey Gurtovoy
- http://www.boostpro.com/mplbook/. Chapter 8 explains the rational behind
the BOOST_MPL_ASSERT_* macros. This submission complements these macros by
allowing the writing of regression unit tests, to ensure the user will
encounter the mpl formatted compiler error, if the library types are
incorrectly instantiated.

Currently, many meta-programs are written using one of the
BOOST_MPL_ASSERT_* macros. Unit tests for these metaprograms must of course
compile, therefore unittests for these programs can verify that valid types
produce the correct run-time behavior. This submission provides the
following four complementary macros:

BOOST_METATEST(pred)
BOOST_METATEST_NOT(pred)
BOOST_METATEST_RELATION(x, rel, y)
BOOST_METATEST_MSG(cond, msg, types)

Meta-program authors can use these macros to assert
predicates/relations/conditions exactly as done with BOOST_MPL_ASSERT_*. In
shipped library code, these four macros exactly forward to their
BOOST_MPL_ASSERT_*
counterparts, since the BOOST_MPL_ASSERT_* macros do an excellent job of
providing maximally informative compiler error messages.

In unit test code (where BOOST_METATEST_RUNTIME will need to be defined),
these macros will instead instantiate an object, which will throw a runtime
exception if the predicate/relation/condition fails. Now meta-program
authors can write unittests like the following:

BOOST_AUTO_TEST_CASE(factorials_should_not_be_negative) {
    BOOST_CHECK_THROW( factorial<mpl::int_<-1> > instance;,
metatest_exception );
}

As you can see, this unit test validates that the factorial meta-function
will in fact fail to compile. All exceptions are subclassed from
boost::metatest_exception. If the user would instead like to supply their
own exception types for individual assertions, one of the following four
macros can be used alternatively:

BOOST_METATEST_EXP(pred, exp)
BOOST_METATEST_NOT_EXP(pred, exp)
BOOST_METATEST_RELATION_EXP(x, rel, y, exp)
BOOST_METATEST_MSG_EXP(cond, msg, types, exp)

Another feature of this library, is that it is independent of any unit
testing framework, provided the framework can catch exceptions by type. The
examples provided show how this is done with Boost Test. The submission
files also show how to use try/catch directly should your unit test
framework not have such a capability.

I look forward to your feedback. Thank you,

Ben Robinson, Ph.D.


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