<commit_before>#ifndef TESTPP_H
#define TESTPP_H

#include <iostream>


#define TESTPP( test_func ) \
bool test_func(); \
bool test_func##_result = test_func(); \
bool test_func()


template < typename T >
class expectation
{
public:
	expectation( const T& expected_val )
	: m_expected( expected_val )
	, m_file( NULL )
	, m_line( 0 )
	{}

	expectation( const T& expected_val, const char *file, int line )
	: m_expected( expected_val )
	, m_file( file )
	, m_line( line )
	{}

	void operator == ( const T& actual )
	{
		if ( m_expected != actual ) {
			// throw this;
			std::cerr << m_file << ":" << m_line << " -- ";
			std::cerr << "expected " << m_expected << " != <" << actual << ">\n";
		}
	}

	bool operator != ( const T& actual );
	bool operator < ( const T& actual );
	bool operator > ( const T& actual );
	bool operator <= ( const T& actual );
	bool operator >= ( const T& actual );
	void between( const T& lesser, const T& greater );
	void within( const T& value, const T& delta );

private:
	const T& m_expected;
	const char *m_file;
	int m_line;
	std::string m_message;
};

template < typename T >
expectation< T > create_expectation( const T& expected_val, const char *file, int line )
{
	return expectation< T >( expected_val, file, line );
}

#define expect( typ, val ) create_expectation< typ >( val, __FILE__, __LINE__ )

// sample usage
#if 0
TESTPP( constructor_1 )<commit_msg>split testpp error reporting into separate functions to avoid duplication<commit_after>#ifndef TESTPP_H
#define TESTPP_H

#include <iostream>


#define TESTPP( test_func ) \
void test_func(); \
int test_func##_result = testpp_wrapper( test_func, #test_func ); \
void test_func()

int testpp_wrapper( void (*func)(), const char *test_name )
{
	std::cout << "testpp: " << test_name << std::endl;
	func();
	return 0;
}

template < typename T >
class expectation
{
public:
	expectation( const T& expected_val )
	: m_expected( expected_val )
	, m_file( NULL )
	, m_line( 0 )
	{}

	expectation( const T& expected_val, const char *file, int line )
	: m_expected( expected_val )
	, m_file( file )
	, m_line( line )
	{}

	void operator == ( const T& actual )
	{
		if ( m_expected != actual ) {
			// throw this;
			print_file_line();
			std::cout << "expected " << m_expected << " != <" << actual << ">\n";
		}
	}

	bool operator != ( const T& actual );
	bool operator < ( const T& actual );
	bool operator > ( const T& actual );
	bool operator <= ( const T& actual );
	bool operator >= ( const T& actual );
	void between( const T& lesser, const T& greater );
	void within( const T& value, const T& delta );

private:
	void print_file_line()
	{
		std::cout << "\tfailure @ " << m_file << ":" << m_line << " -- ";
	}

	const T& m_expected;
	const char *m_file;
	int m_line;
	std::string m_message;
};

template < typename T >
expectation< T > create_expectation( const T& expected_val, const char *file, int line )
{
	return expectation< T >( expected_val, file, line );
}

#define expect( typ, val ) create_expectation< typ >( val, __FILE__, __LINE__ )

// sample usage
#if 0
TESTPP( constructor_1 )
{'fraction_non_alphanumeric': 0.1457725947521866, 'fraction_numerical': 0.0022675736961451248, 'mean_word_length': 3.8174726989079564, 'pattern_counts': {'":': 2, '<': 65, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2522562', 'n_tokens_mistral': 1108, 'n_tokens_neox': 1070, 'n_words': 333}