1
0
forked from Alepha/Alepha
Files
Alepha/Testing/TableTest.test/test2.cc
ADAM David Alan Martin 26eb1b080e Basic support for exception verification in tests
This probably needs to be expanded upon.  The basic functionality
added is to permit a test expectation clause to be a function which
takes some kind of exception type.  That function can then
perform any arbitrary checks and analyses it needs to confirm that
the exception which was caught passes muster for that test case.
2024-06-12 00:08:14 -04:00

101 lines
3.2 KiB
C++

static_assert( __cplusplus > 2020'99 );
#include <Alepha/Testing/TableTest.h>
#include <Alepha/Testing/test.h>
#include <Alepha/Utility/evaluation_helpers.h>
#include <Alepha/IOStreams/delimiters.h>
#include <Alepha/IOStreams/OStreamable.h>
#include <Alepha/comparisons.h>
namespace
{
using namespace Alepha::Testing::exports;
using namespace Alepha::Utility::exports::evaluation_helpers_m;
int
add( int a, int b )
{
return a + b;
}
auto basic_test= "basic_test"_test <=[]
{
return 0;
};
auto test= "addition.two.test"_test <=TableTest< add >::Cases
{
{ "Basic Smoke Test", { 2, 2 }, 4 },
{ "Lefthand identity", { 0, 25 }, 25 },
{ "Righthand identity", { 25, 0 }, 25 },
};
template< typename= Alepha::Capabilities< Alepha::IOStreams::OStreamable, Alepha::comparable > >
struct Aggregate_core
{
int x, y, z;
friend bool operator == ( Aggregate_core, Aggregate_core ) noexcept= default;
};
using Aggregate= Aggregate_core<>;
auto alltests= enroll <=[]
{
"addition.two.local"_test <=TableTest< add >::Cases
{
{ "Negative case", { -10, -20 }, -30 },
};
struct DerivedError : std::runtime_error
{
using std::runtime_error::runtime_error;
std::optional< int > value_;
explicit DerivedError( const std::string &s, int value_ ) : std::runtime_error{ s }, value_( value_ ) {}
int value() const { return value_.value(); }
};
"Can we use Aggregates with universal cases, correctly?"_test <=
TableTest
<
[]( const int x )
{
if( x < 0 ) throw DerivedError{ "Cannot be negative.", x };
return Aggregate{ x, x, x };
}
>
::UniversalCases
{
{ "Basic value case", { 42 }, { 42, 42, 42 } },
{ "Ignore exceptions case (`std::nothrow`)", { 42 }, std::nothrow },
{ "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 exception", { -42 }, std::type_identity< std::exception >{} },
{ "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 (loose)", { -42 },
[]( const DerivedError &e )
{
return e.value() == -42;
} },
/* These cases should fail, but we don't want to fail them in normal builds. */
/* A few different ways of disabling these tests are shown below. */
{ Skip <="Basic value case", { -42 }, { 42, 42, 42 } },
{ !!Disable <="Ignore exceptions case (`std::nothrow`)", { -42 }, std::nothrow },
{ -Enable <="Ignore exceptions case (`std::type_identity< void >`)", { -42 }, std::type_identity< void >{} },
{ -"Expect exception type runtime_error"_case, { 42 }, std::type_identity< std::runtime_error >{} },
{ Disable <="Expect exception type exception", { 42 }, std::type_identity< std::exception >{} },
{ !"Expect exception value specific"_case, { 42 }, DerivedError{ "Cannot be negative." } },
{ Skip <="Expect exception value specific (loose)", { 42 }, std::runtime_error{ "Cannot be negative." } },
{ Skip <="Expect exception value specific (wrong)", { -42 }, std::logic_error{ "Cannot be negative." } },
};
};
}