129 lines
3.2 KiB
Plaintext
129 lines
3.2 KiB
Plaintext
#ifndef _EZPWD_ASSERTER
|
|
#define _EZPWD_ASSERTER
|
|
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
|
|
namespace ezpwd {
|
|
|
|
#define ISEQUAL( ... ) isequal(__FILE__, __LINE__, __VA_ARGS__ )
|
|
#define ISTRUE( ... ) istrue( __FILE__, __LINE__, __VA_ARGS__ )
|
|
#define ISFALSE( ... ) isfalse(__FILE__, __LINE__, __VA_ARGS__ )
|
|
#define ISNEAR( ... ) isnear( __FILE__, __LINE__, __VA_ARGS__ )
|
|
#define FAILURE( ... ) failure(__FILE__, __LINE__, __VA_ARGS__ )
|
|
|
|
struct asserter {
|
|
bool failed; // The last test failed
|
|
int failures; // Total number of failures
|
|
std::string out; // Last failure
|
|
|
|
asserter()
|
|
: failed( false )
|
|
, failures( 0 )
|
|
, out()
|
|
{
|
|
;
|
|
}
|
|
|
|
//
|
|
// output( <std::ostream> ) -- Output description of last failed test (or nothing if successful)
|
|
// <std::ostream> << <asserter>
|
|
//
|
|
std::ostream &output(
|
|
std::ostream &lhs )
|
|
const
|
|
{
|
|
return lhs << out;
|
|
}
|
|
|
|
//
|
|
// (bool) <asserter> -- Return status of last test
|
|
//
|
|
operator bool()
|
|
{
|
|
return failed;
|
|
}
|
|
|
|
template < typename T >
|
|
asserter &istrue( const char *file, int line, const T &a, const std::string &comment = std::string() )
|
|
{
|
|
return isequal( file, line, !!a, true, comment );
|
|
}
|
|
|
|
template < typename T >
|
|
asserter &isfalse( const char *file, int line, const T &a, const std::string &comment = std::string() )
|
|
{
|
|
return isequal( file, line, !!a, false, comment );
|
|
}
|
|
|
|
template < typename T >
|
|
asserter &isequal( const char *file, int line, const T &a, const T &b, const std::string &comment = std::string() )
|
|
{
|
|
if ( ! ( a == b )) {
|
|
std::ostringstream oss;
|
|
oss << a << " != " << b;
|
|
return failure( file, line, oss.str(), comment );
|
|
}
|
|
return success();
|
|
}
|
|
|
|
template < typename T >
|
|
asserter &isnear( const char *file, int line, const T &a, const T &b, const T &delta, const std::string &comment = std::string() )
|
|
{
|
|
T difference;
|
|
difference = ( a < b
|
|
? T( b - a )
|
|
: T( a - b ));
|
|
if ( ! ( difference < ( delta < T( 0 ) ? T( -delta ) : T( delta )))) {
|
|
std::ostringstream oss;
|
|
oss << std::setprecision( 13 ) << a << " != " << b << " +/- " << delta;
|
|
return failure( file, line, oss.str(), comment );
|
|
}
|
|
return success();
|
|
}
|
|
|
|
asserter &failure( const char *file, int line, const std::string &comparison,
|
|
const std::string &comment = std::string() )
|
|
{
|
|
++failures;
|
|
const char *needle = "/";
|
|
const char *slash = std::find_end( file, file + strlen( file ),
|
|
needle, needle + strlen( needle ));
|
|
if ( slash == file + strlen( file ))
|
|
slash = file;
|
|
else
|
|
slash += 1;
|
|
|
|
std::ostringstream oss;
|
|
oss
|
|
<< std::setw( 24 ) << slash << ", "
|
|
<< std::setw( -5 ) << line
|
|
<< "; FAILURE: " << comparison
|
|
<< ( comment.size() ? ": " : "" ) << comment
|
|
<< std::endl;
|
|
out = oss.str();
|
|
failed = true;
|
|
return *this;
|
|
}
|
|
|
|
asserter &success()
|
|
{
|
|
out.clear();
|
|
failed = false;
|
|
return *this;
|
|
}
|
|
}; // class asserter
|
|
} // namespace ezpwd
|
|
|
|
std::ostream &operator<<(
|
|
std::ostream &lhs,
|
|
ezpwd::asserter &rhs )
|
|
{
|
|
return rhs.output( lhs );
|
|
}
|
|
|
|
#endif // _EZPWD_ARRAY
|