1
0
forked from Alepha/Alepha

Testing improvements.

This commit is contained in:
2023-11-12 00:12:40 -05:00
parent 50cc5b2857
commit 057aa27cb7
4 changed files with 108 additions and 34 deletions

36
Testing/TableTest.cc Normal file
View File

@ -0,0 +1,36 @@
static_assert( __cplusplus > 2020'99 );
#include "TableTest.h"
namespace Alepha::Hydrogen::Testing::detail::TableTest_m
{
int
UniversalCasesBase::operator() () const
{
int failureCount= 0;
for( const auto &[ comment, checker ]: tests )
{
const auto [result, supplement]= checker( comment );
if( result == TestResult::Failed )
{
++failureCount;
std::cout << " " << C::testFail << "FAILED CASE" << resetStyle << ": " << comment << std::endl;
if( supplement.has_value() )
{
std::cout << " " << C::testWarn << "DETAILS" << resetStyle << ": " << supplement.value() << std::endl;
}
}
else
{
std::cout << " " << C::testPass << "PASSED CASE" << resetStyle << ": " << comment << std::endl;
if( supplement.has_value() )
{
std::cout << " " << C::testWarn << "INFO: " << resetStyle << ": " << supplement.value() << std::endl;
}
}
breakpoint();
}
return failureCount;
}
}

View File

@ -15,9 +15,6 @@ static_assert( __cplusplus > 2020'99 );
#include <numeric> #include <numeric>
#include <iomanip> #include <iomanip>
#include <boost/core/demangle.hpp>
#include <boost/lexical_cast.hpp>
#include <Alepha/function_traits.h> #include <Alepha/function_traits.h>
#include <Alepha/template_for_each.h> #include <Alepha/template_for_each.h>
@ -25,6 +22,7 @@ static_assert( __cplusplus > 2020'99 );
#include <Alepha/Utility/evaluation_helpers.h> #include <Alepha/Utility/evaluation_helpers.h>
#include <Alepha/Utility/TupleAdapter.h> #include <Alepha/Utility/TupleAdapter.h>
#include <Alepha/Utility/fancyTypeName.h>
#include <Alepha/Reflection/tuplizeAggregate.h> #include <Alepha/Reflection/tuplizeAggregate.h>
@ -84,7 +82,7 @@ namespace Alepha::Hydrogen::Testing ::detail:: TableTest_m
} }
catch( const std::exception &ex ) catch( const std::exception &ex )
{ {
return ErrorMessage{ typeid( ex ).name() }; return ErrorMessage{ Utility::fancyTypeName( typeid( ex ) ) };
} }
catch( ... ) catch( ... )
{ {
@ -127,7 +125,7 @@ namespace Alepha::Hydrogen::Testing ::detail:: TableTest_m
} }
catch( const std::exception &ex ) catch( const std::exception &ex )
{ {
return ErrorMessage{ typeid( ex ).name() }; return ErrorMessage{ Utility::fancyTypeName( typeid( ex ) ) };
} }
catch( ... ) catch( ... )
{ {
@ -160,13 +158,26 @@ namespace Alepha::Hydrogen::Testing ::detail:: TableTest_m
{ {
try try
{ {
std::ignore= invoker(); try
breakpoint(); {
return { TestResult::Failed, std::nullopt }; std::ignore= invoker();
breakpoint();
return { TestResult::Failed, IOStreams::String() << "No exception was thrown, but " << Utility::fancyTypeName< T >() << " expected." };
}
catch( const T & )
{
return { TestResult::Passed, std::nullopt };
}
} }
catch( const T & ) catch( const std::exception &ex )
{ {
return { TestResult::Passed, std::nullopt }; return { TestResult::Failed, IOStreams::String() << "Incorrect exception type " << Utility::fancyTypeName( typeid( ex ) ) << " was thrown, but "
<< Utility::fancyTypeName< T >() << " was expected." };
}
catch( ... )
{
return { TestResult::Failed, IOStreams::String() << "Incorrect exception type (<Unknown>) was thrown, but "
<< Utility::fancyTypeName< T >() << " was expected." };
} }
} }
} }
@ -183,9 +194,15 @@ namespace Alepha::Hydrogen::Testing ::detail:: TableTest_m
std::ignore= invoker(); std::ignore= invoker();
return { TestResult::Passed, std::nullopt }; return { TestResult::Passed, std::nullopt };
} }
catch( const std::exception &ex )
{
return { TestResult::Failed, IOStreams::String() << "Exception type " << Utility::fancyTypeName( typeid( ex ) ) << " was thrown, but "
"no exception was expected." };
}
catch( ... ) catch( ... )
{ {
return { TestResult::Failed, std::nullopt }; return { TestResult::Failed, IOStreams::String() << "Exception type (<Unknown>) was thrown, but "
"no exception was expected." };
} }
} }
} }
@ -198,21 +215,34 @@ namespace Alepha::Hydrogen::Testing ::detail:: TableTest_m
{ {
try try
{ {
invoker(); try
return { TestResult::Failed,
IOStreams::String{} << "expected exception `" << typeid( T ).name() << "` wasn't thrown." };
}
catch( const T &ex )
{
const std::string witness= ex.what();
const TestResult rv= witness == expected ? TestResult::Passed : TestResult::Failed;
std::ostringstream oss;
if( rv == TestResult::Failed )
{ {
oss << "expected message did not match." << std::endl; invoker();
streamDebugging< outputMode >( oss, witness, expected ); return { TestResult::Failed,
IOStreams::String{} << "expected exception `" << Utility::fancyTypeName< T >() << "` wasn't thrown." };
} }
return { rv, oss.str().empty() ? std::optional< std::string >{} : std::move( oss ).str() }; catch( const T &ex )
{
const std::string witness= ex.what();
const TestResult rv= witness == expected ? TestResult::Passed : TestResult::Failed;
std::ostringstream oss;
if( rv == TestResult::Failed )
{
oss << "expected message did not match." << std::endl;
streamDebugging< outputMode >( oss, witness, expected );
}
return { rv, oss.str().empty() ? std::optional< std::string >{} : std::move( oss ).str() };
}
}
catch( const std::exception &ex )
{
return { TestResult::Failed, IOStreams::String() << "Incorrect exception type " << Utility::fancyTypeName( typeid( ex ) ) << " was thrown, but "
<< Utility::fancyTypeName< T >() << " was expected." };
}
catch( ... )
{
return { TestResult::Failed, IOStreams::String() << "Incorrect exception type (<Unknown>) was thrown, but "
<< Utility::fancyTypeName< T >() << " was expected." };
} }
} }
} }
@ -303,7 +333,7 @@ namespace Alepha::Hydrogen::Testing ::detail:: TableTest_m
{ {
for( const auto [ comment, params, handler ]: initList ) for( const auto [ comment, params, handler ]: initList )
{ {
if( C::debugCaseTypes ) std::cerr << boost::core::demangle( typeid( params ).name() ) << std::endl; if( C::debugCaseTypes ) std::cerr << Utility::fancyTypeName( typeid( params ) ) << std::endl;
auto invoker= [=] auto invoker= [=]
{ {
breakpoint(); breakpoint();

View File

@ -50,12 +50,17 @@ namespace
{ "Negative case", { -10, -20 }, -30 }, { "Negative case", { -10, -20 }, -30 },
}; };
struct DerivedError : std::runtime_error
{
using std::runtime_error::runtime_error;
};
"Can we use Aggregates with universal cases, correctly?"_test <= "Can we use Aggregates with universal cases, correctly?"_test <=
TableTest TableTest
< <
[]( const int x ) []( const int x )
{ {
if( x < 0 ) throw std::runtime_error{ "Cannot be negative." }; if( x < 0 ) throw DerivedError{ "Cannot be negative." };
return Aggregate{ x, x, x }; return Aggregate{ x, x, x };
} }
> >
@ -66,16 +71,19 @@ namespace
{ "Ignore exceptions case (`std::type_identity< void >`)", { 42 }, std::type_identity< void >{} }, { "Ignore exceptions case (`std::type_identity< void >`)", { 42 }, std::type_identity< void >{} },
{ "Expect exception type runtime_error", { -42 }, std::type_identity< std::runtime_error >{} }, { "Expect exception type runtime_error", { -42 }, std::type_identity< std::runtime_error >{} },
{ "Expect exception type exception", { -42 }, std::type_identity< std::exception >{} }, { "Expect exception type exception", { -42 }, std::type_identity< std::exception >{} },
{ "Expect exception value specific", { -42 }, std::runtime_error{ "Cannot be negative." } }, { "Expect exception value specific", { -42 }, DerivedError{ "Cannot be negative." } },
{ "Expect exception value specific (loose)", { -42 }, std::runtime_error{ "Cannot be negative." } },
/* These cases should fail, but we don't want to fail them in normal builds. */ /* These cases should fail, but we don't want to fail them in normal builds. */
#if 0 #if 0
{ "Failing: Basic value case", { -42 }, { 42, 42, 42 } }, { "Basic value case", { -42 }, { 42, 42, 42 } },
{ "Failing: Ignore exceptions case (`std::nothrow`)", { -42 }, std::nothrow }, { "Ignore exceptions case (`std::nothrow`)", { -42 }, std::nothrow },
{ "Failing: Ignore exceptions case (`std::type_identity< void >`)", { -42 }, std::type_identity< void >{} }, { "Ignore exceptions case (`std::type_identity< void >`)", { -42 }, std::type_identity< void >{} },
{ "Failing: Expect exception type runtime_error", { 42 }, std::type_identity< std::runtime_error >{} }, { "Expect exception type runtime_error", { 42 }, std::type_identity< std::runtime_error >{} },
{ "Failing: Expect exception type exception", { 42 }, std::type_identity< std::exception >{} }, { "Expect exception type exception", { 42 }, std::type_identity< std::exception >{} },
{ "Failing: Expect exception value specific", { 42 }, std::runtime_error{ "Cannot be negative." } }, { "Expect exception value specific", { 42 }, DerivedError{ "Cannot be negative." } },
{ "Expect exception value specific (loose)", { 42 }, std::runtime_error{ "Cannot be negative." } },
{ "Expect exception value specific (wrong)", { -42 }, std::logic_error{ "Cannot be negative." } },
#endif #endif
}; };
}; };

View File

@ -7,7 +7,7 @@ static_assert( __cplusplus > 2020'99 );
namespace Alepha::Hydrogen::Utility::detail::fancyTypeName_m namespace Alepha::Hydrogen::Utility::detail::fancyTypeName_m
{ {
std::string std::string
fancyTypeName( const std::type_index idx ) exports::fancyTypeName( const std::type_index idx )
{ {
return boost::core::demangle( idx.name() ); return boost::core::demangle( idx.name() );
} }