2#ifndef __ASE_TESTING_HH__
3#define __ASE_TESTING_HH__
14#define TSTART(...) Ase::Test::test_output ('S', ::Ase::string_format (__VA_ARGS__))
15#define TDONE() Ase::Test::test_output ('D', "")
16#define TPASS(...) Ase::Test::test_output ('P', ::Ase::string_format (__VA_ARGS__))
17#define TBENCH(...) Ase::Test::test_output ('B', ::Ase::string_format (__VA_ARGS__))
18#define TNOTE(...) Ase::Test::test_output ('I', ::Ase::string_format (__VA_ARGS__))
19#define TCHECK(cond, ...) Ase::Test::test_output (bool (cond) ? 'P' : 'F', \
20 ::Ase::string_format (__VA_ARGS__))
21#define TCMPS(a,cmp,b) TCMP_op (a,cmp,b,#a,#b,Ase::Test::_as_strptr)
22#define TCMP(a,cmp,b) TCMP_op (a,cmp,b,#a,#b,)
23#define TASSERT(cond) TASSERT__AT (__LINE__, cond)
24#define TASSERT_AT(LINE, cond) TASSERT__AT (LINE, cond)
25#define TOK() do {} while (0)
27#define TFLOATS(a,b,eps) do { if (fabsl ((long double) (a) - (long double) (b)) > (long double) (eps)) TCMP (a,==,b); } while (0)
30#define TEST_ADD(fun) static const ::Ase::Test::TestChain ASE_CPP_PASTE2 (__Ase__Test__TestChain_, __LINE__) (fun, ASE_CPP_STRINGIFY (fun), ::Ase::Test::PLAIN)
31#define TEST_SLOW(fun) static const ::Ase::Test::TestChain ASE_CPP_PASTE2 (__Ase__Test__TestChain_, __LINE__) (fun, ASE_CPP_STRINGIFY (fun), ::Ase::Test::SLOW)
32#define TEST_BENCH(fun) static const ::Ase::Test::TestChain ASE_CPP_PASTE2 (__Ase__Test__TestChain_, __LINE__) (fun, ASE_CPP_STRINGIFY (fun), ::Ase::Test::BENCH)
33#define TEST_BROKEN(fun) static const ::Ase::Test::TestChain ASE_CPP_PASTE2 (__Ase__Test__TestChain_, __LINE__) (fun, ASE_CPP_STRINGIFY (fun), ::Ase::Test::BROKEN)
39 const double deadline_;
41 double test_duration_;
43 int64 loops_needed ();
45 void submit (
double elapsed,
int64 repetitions);
46 static double bench_time ();
49 explicit Timer (
double deadline_in_secs = 0);
60 template<
typename Callee>
76 ident (identi), flags (flagsi)
80TestEntries list_tests ();
88void test_output (
int kind,
const String &
string);
93template<
class A>
inline String stringify_arg (
const A &a,
const char *str_a) {
return str_a; }
94template<>
inline String stringify_arg<float> (
const float &a,
const char *str_a) {
return string_format (
"%.8g", a); }
95template<>
inline String stringify_arg<double> (
const double &a,
const char *str_a) {
return string_format (
"%.17g", a); }
96template<>
inline String stringify_arg<bool> (
const bool &a,
const char *str_a) {
return string_format (
"%u", a); }
97template<>
inline String stringify_arg<int8> (
const int8 &a,
const char *str_a) {
return string_format (
"%d", a); }
100template<>
inline String stringify_arg<int64> (
const int64 &a,
const char *str_a) {
return string_format (
"%lld", a); }
101template<>
inline String stringify_arg<uint8> (
const uint8 &a,
const char *str_a) {
return string_format (
"0x%02x", a); }
102template<>
inline String stringify_arg<uint16> (
const uint16 &a,
const char *str_a) {
return string_format (
"0x%04x", a); }
103template<>
inline String stringify_arg<uint32> (
const uint32 &a,
const char *str_a) {
return string_format (
"0x%08x", a); }
104template<>
inline String stringify_arg<uint64> (
const uint64 &a,
const char *str_a) {
return string_format (
"0x%08Lx", a); }
106inline const char* _as_strptr (
const char *s) {
return s; }
118#define TASSERT__AT(LINE, cond) \
119 do { if (ASE_ISLIKELY (cond)) break; \
120 ::Ase::assertion_failed (#cond); } while (0)
122#define TCMP_op(a,cmp,b,sa,sb,cast) \
124 const auto &__tcmp_va = a ; \
125 const auto &__tcmp_vb = b ; \
126 if (__tcmp_va cmp __tcmp_vb) break; \
127 Ase::String __tcmp_sa = Ase::Test::stringify_arg (cast (__tcmp_va), #a); \
128 Ase::String __tcmp_sb = Ase::Test::stringify_arg (cast (__tcmp_vb), #b), \
129 __tcmp_as = Ase::string_format ("'%s %s %s': %s %s %s", \
133 __tcmp_sb.c_str()); \
134 ::Ase::assertion_failed (__tcmp_as.c_str()); \
137template<
typename Callee>
double
141 for (
int64 runs = loops_needed(); runs; runs = loops_needed())
144 const double start = bench_time();
147 const double stop = bench_time();
148 submit (stop - start, runs);
156 static void run (ptrdiff_t internal_token,
const StringS *test_names);
157 const TestChain*
next ()
const {
return next_; }
159 int64 flags ()
const {
return kind_; }
160 void run ()
const { func_(); }
164 const TestChain *
const next_ = NULL;
double benchmark(Callee callee)
double min_elapsed() const
Minimum time benchmarked for a callee() call.
int64 n_reps() const
Number of benchmark repetitions to execute.
double max_elapsed() const
Maximum time benchmarked for a callee() call.
double test_elapsed() const
Seconds spent in benchmark()
#define ASE_ISLIKELY(expr)
Compiler hint to optimize for expr evaluating to true.
int run(const StringS &test_names)
Run named tests.
bool verbose()
Indicates whether tests should run verbosely.
int64_t random_irange(int64_t begin, int64_t end)
Return random int within range for reproduceble tests.
uint64_t random_int64()
Return random int for reproduceble tests.
int run(void)
Run all registered tests.
String stringify_arg(const char *a, const char *str_a)
== Stringify Args ==
double random_float()
Return random double for reproduceble tests.
double random_frange(double begin, double end)
Return random double within range for reproduceble tests.
bool slow()
Indicates whether slow tests should be run.
The Anklang C++ API namespace.
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
int32_t int32
A 32-bit signed integer.
int16_t int16
A 16-bit signed integer.
uint8_t uint8
An 8-bit unsigned integer.
int8_t int8
An 8-bit signed integer.
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
uint16_t uint16
A 16-bit unsigned integer.
std::string String
Convenience alias for std::string.
uint32_t uint32
A 32-bit unsigned integer.
String string_to_cquote(const String &str)
Returns a string as C string including double quotes.