LUMIERA.clone/src/lib/test/test-helper.hpp
Ichthyostega 5a5beebd15 marcro to indicate current test function on STDOUT
since our test.sh runner can be used to verify the
expected output printed by tests, working with these
output transcripts of larger tests can be hard at times.

These separators help to find who produced which output
and they prevent a regexp match to grep beyond the feed
of a single function (which can be a common problem
when using the self-diagnostic output of the facility
currently in test, which obviously will be similar
on any data printed.
2016-01-15 01:44:35 +01:00

186 lines
5.6 KiB
C++

/*
TEST-HELPER.hpp - collection of functions supporting unit testing
Copyright (C) Lumiera.org
2009, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file test-helper.hpp
** A collection of frequently used helper functions to support unit testing.
** Some are test data generators, some are diagnostics helpers to produce readable
** output. Some of these support meta programming to figure out the \em actual
** reference kind (value, lvalue, rvalue) of a template parameter instantiation.
** For GNU compatible compilers, we expose also the interface to the internal
** ABI for [demangling type names](\ref demangleCxx).
**
** @note this header is included into a large number of tests.
** @see TestHelper_test
** @see TestHelperDemangling_test
**
*/
#ifndef LIB_TEST_TEST_HELPER_H
#define LIB_TEST_TEST_HELPER_H
#include "lib/symbol.hpp"
#include "lib/time/timevalue.hpp"
#include "lib/format-obj.hpp"
#include <boost/lexical_cast.hpp>
#include <typeinfo>
#include <cstdlib>
#include <string>
namespace lib {
namespace test{
using lib::Literal;
using std::string;
using std::rand;
using lib::meta::demangleCxx;
/** for printing sizeof().
* prints the given size and name literally, without any further magic */
string
showSizeof (size_t siz, string name);
/** for printing sizeof(), possibly figuring out the type name automatically
* @param name when given, this name will be used for display,
* instead of auto detecting the type
*/
template<typename T>
inline string
showSizeof (T const* obj =0, const char* name =0)
{
return showSizeof (obj? sizeof(*obj) : sizeof(T),
name? name : util::typeStr(obj));
}
template<typename T>
inline meta::disable_if<std::is_pointer<T>,
string > // note:: force invocations with pointer to the first overload
showSizeof (T const& obj, const char* name=0)
{
return showSizeof (&obj, name);
}
template<typename T>
inline string
showSizeof (const char* name)
{
return showSizeof<T> (nullptr, name);
}
/** helper to discern the kind of reference of the argument type */
template<typename R>
string
showRefKind()
{
return std::is_lvalue_reference<R>::value? "REF"
: std::is_rvalue_reference<R>::value? "MOV"
: "VAL";
}
/** helper for investigating a variadic argument pack
* @warning always spell out the template arguments explicitly
* when invoking this diagnostics, e.g. \c showVariadicTypes<ARGS...>(args...)
* otherwise the template argument matching for functions might mess up the
* kind of reference you'll see in the diagnostics.
* @see test-helper-variadic-test.cpp
*/
template<typename... EMPTY>
inline string
showVariadicTypes ()
{
return " :.";
}
template<typename X, typename... XS>
inline string
showVariadicTypes (X const& x, XS const&... xs)
{
return " :---#"
+ boost::lexical_cast<string>(1 + sizeof...(xs))
+ " -- Type: " + util::typeStr(x)
+ " " + showRefKind<X>()
+ " Address* " + boost::lexical_cast<string>(&x)
+ "\n"
+ showVariadicTypes<XS...> (xs...);
}
/** create a random but not insane Time value */
inline lib::time::Time
randTime ()
{
return lib::time::Time (500 * (rand() % 2), (rand() % 600) + 1);
}
/** create garbage string of given length
* @return string containing arbitrary lower case letters and numbers
*/
string randStr (size_t len);
}} // namespace lib::test
/* === test helper macros === */
/**
* Macro to verify a statement indeed raises an exception.
* If no exception is thrown, the #NOTREACHED macro will trigger
* an assertion failure. In case of an exception, the #lumiera_error
* state is checked, cleared and verified.
*/
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT) \
try \
{ \
ERRONEOUS_STATEMENT ; \
NOTREACHED("expected '%s' failure in: %s", \
#ERROR_ID, #ERRONEOUS_STATEMENT); \
} \
catch (...) \
{ \
CHECK (lumiera_error_expect (LUMIERA_ERROR_##ERROR_ID));\
}
/**
* Macro to mark the current test function in STDOUT.
* This can be helpful to digest a long test output dump
*/
#define MARK_TEST_FUN \
cout << "|" << endl << "| »"<<__FUNCTION__<<"«" <<endl;
#endif /*LIB_TEST_TEST_HELPER_H*/