exception translators considered even for types deriving from std::exception, now

- also added docs for exception translators
- updated approvals
This commit is contained in:
Phil Nash 2015-11-18 08:39:21 +00:00
parent ed6e9128a4
commit a49f088032
8 changed files with 101 additions and 28 deletions

View File

@ -55,6 +55,16 @@ namespace Catch {
} }
``` ```
## Exceptions
By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:
```
CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
return ex.message();
}
```
--- ---
[Home](Readme.md) [Home](Readme.md)

View File

@ -32,13 +32,13 @@ namespace Catch {
#ifdef __OBJC__ #ifdef __OBJC__
// In Objective-C try objective-c exceptions first // In Objective-C try objective-c exceptions first
@try { @try {
throw; return tryTranslators();
} }
@catch (NSException *exception) { @catch (NSException *exception) {
return Catch::toString( [exception description] ); return Catch::toString( [exception description] );
} }
#else #else
throw; return tryTranslators();
#endif #endif
} }
catch( TestFailureException& ) { catch( TestFailureException& ) {
@ -54,20 +54,15 @@ namespace Catch {
return msg; return msg;
} }
catch(...) { catch(...) {
return tryTranslators( m_translators.begin() ); return "Unknown exception";
} }
} }
std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const { std::string tryTranslators() const {
if( it == m_translators.end() ) if( m_translators.empty() )
return "Unknown exception"; throw;
else
try { return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
return (*it)->translate();
}
catch(...) {
return tryTranslators( it+1 );
}
} }
private: private:

View File

@ -9,15 +9,20 @@
#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
#include <string> #include <string>
#include <vector>
#include "catch_interfaces_registry_hub.h" #include "catch_interfaces_registry_hub.h"
namespace Catch { namespace Catch {
typedef std::string(*exceptionTranslateFunction)(); typedef std::string(*exceptionTranslateFunction)();
struct IExceptionTranslator;
typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
struct IExceptionTranslator { struct IExceptionTranslator {
virtual ~IExceptionTranslator(); virtual ~IExceptionTranslator();
virtual std::string translate() const = 0; virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
}; };
struct IExceptionTranslatorRegistry { struct IExceptionTranslatorRegistry {
@ -35,9 +40,12 @@ namespace Catch {
: m_translateFunction( translateFunction ) : m_translateFunction( translateFunction )
{} {}
virtual std::string translate() const { virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
try { try {
throw; if( it == itEnd )
throw;
else
return (*it)->translate( it+1, itEnd );
} }
catch( T& ex ) { catch( T& ex ) {
return m_translateFunction( ex ); return m_translateFunction( ex );

View File

@ -356,7 +356,7 @@ due to unexpected exception with message:
expected exception expected exception
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Unexpected custom exceptions can be translated Non-std exceptions can be translated
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
ExceptionTests.cpp:<line number> ExceptionTests.cpp:<line number>
............................................................................... ...............................................................................
@ -365,6 +365,16 @@ ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message: due to unexpected exception with message:
custom exception custom exception
-------------------------------------------------------------------------------
Custom std-exceptions can be custom translated
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message:
custom std exception
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Custom exceptions can be translated when testing for nothrow Custom exceptions can be translated when testing for nothrow
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -820,6 +830,6 @@ with expansion:
"first" == "second" "first" == "second"
=============================================================================== ===============================================================================
test cases: 165 | 123 passed | 41 failed | 1 failed as expected test cases: 166 | 123 passed | 42 failed | 1 failed as expected
assertions: 912 | 817 passed | 82 failed | 13 failed as expected assertions: 913 | 817 passed | 83 failed | 13 failed as expected

View File

@ -1217,7 +1217,7 @@ due to unexpected exception with message:
expected exception expected exception
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Unexpected custom exceptions can be translated Non-std exceptions can be translated
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
ExceptionTests.cpp:<line number> ExceptionTests.cpp:<line number>
............................................................................... ...............................................................................
@ -1226,6 +1226,16 @@ ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message: due to unexpected exception with message:
custom exception custom exception
-------------------------------------------------------------------------------
Custom std-exceptions can be custom translated
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message:
custom std exception
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Custom exceptions can be translated when testing for nothrow Custom exceptions can be translated when testing for nothrow
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -9024,6 +9034,6 @@ with expansion:
1 > 0 1 > 0
=============================================================================== ===============================================================================
test cases: 165 | 122 passed | 42 failed | 1 failed as expected test cases: 166 | 122 passed | 43 failed | 1 failed as expected
assertions: 914 | 817 passed | 84 failed | 13 failed as expected assertions: 915 | 817 passed | 85 failed | 13 failed as expected

View File

@ -1,5 +1,5 @@
<testsuites> <testsuites>
<testsuite name="CatchSelfTest" errors="12" failures="72" tests="914" hostname="tbd" time="{duration}" timestamp="tbd"> <testsuite name="CatchSelfTest" errors="13" failures="72" tests="915" hostname="tbd" time="{duration}" timestamp="tbd">
<testcase classname="global" name="toString(enum)" time="{duration}"/> <testcase classname="global" name="toString(enum)" time="{duration}"/>
<testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/> <testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/>
<testcase classname="global" name="toString(enum class)" time="{duration}"/> <testcase classname="global" name="toString(enum class)" time="{duration}"/>
@ -226,9 +226,15 @@ expected exception
ExceptionTests.cpp:<line number> ExceptionTests.cpp:<line number>
</error> </error>
</testcase> </testcase>
<testcase classname="global" name="Unexpected custom exceptions can be translated" time="{duration}"> <testcase classname="global" name="Non-std exceptions can be translated" time="{duration}">
<error type="TEST_CASE"> <error type="TEST_CASE">
custom exception custom exception
ExceptionTests.cpp:<line number>
</error>
</testcase>
<testcase classname="global" name="Custom std-exceptions can be custom translated" time="{duration}">
<error type="TEST_CASE">
custom std exception
ExceptionTests.cpp:<line number> ExceptionTests.cpp:<line number>
</error> </error>
</testcase> </testcase>

View File

@ -1545,12 +1545,18 @@
<TestCase name="When unchecked exceptions are thrown, but caught, they do not affect the test"> <TestCase name="When unchecked exceptions are thrown, but caught, they do not affect the test">
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<TestCase name="Unexpected custom exceptions can be translated"> <TestCase name="Non-std exceptions can be translated">
<Exception filename="projects/SelfTest/ExceptionTests.cpp" > <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
custom exception custom exception
</Exception> </Exception>
<OverallResult success="false"/> <OverallResult success="false"/>
</TestCase> </TestCase>
<TestCase name="Custom std-exceptions can be custom translated">
<Exception filename="projects/SelfTest/ExceptionTests.cpp" >
custom std exception
</Exception>
<OverallResult success="false"/>
</TestCase>
<TestCase name="Custom exceptions can be translated when testing for nothrow"> <TestCase name="Custom exceptions can be translated when testing for nothrow">
<Expression success="false" type="REQUIRE_NOTHROW" filename="projects/SelfTest/ExceptionTests.cpp" > <Expression success="false" type="REQUIRE_NOTHROW" filename="projects/SelfTest/ExceptionTests.cpp" >
<Original> <Original>
@ -9496,7 +9502,7 @@ there"
</Section> </Section>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<OverallResults successes="817" failures="84" expectedFailures="13"/> <OverallResults successes="817" failures="85" expectedFailures="13"/>
</Group> </Group>
<OverallResults successes="817" failures="84" expectedFailures="13"/> <OverallResults successes="817" failures="85" expectedFailures="13"/>
</Catch> </Catch>

View File

@ -106,22 +106,50 @@ private:
std::string m_msg; std::string m_msg;
}; };
class CustomStdException : public std::exception
{
public:
CustomStdException( const std::string& msg )
: m_msg( msg )
{}
std::string getMessage() const
{
return m_msg;
}
private:
std::string m_msg;
};
CATCH_TRANSLATE_EXCEPTION( CustomException& ex ) CATCH_TRANSLATE_EXCEPTION( CustomException& ex )
{ {
return ex.getMessage(); return ex.getMessage();
} }
CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex )
{
return ex.getMessage();
}
CATCH_TRANSLATE_EXCEPTION( double& ex ) CATCH_TRANSLATE_EXCEPTION( double& ex )
{ {
return Catch::toString( ex ); return Catch::toString( ex );
} }
TEST_CASE("Unexpected custom exceptions can be translated", "[.][failing]" ) TEST_CASE("Non-std exceptions can be translated", "[.][failing]" )
{ {
if( Catch::alwaysTrue() ) if( Catch::alwaysTrue() )
throw CustomException( "custom exception" ); throw CustomException( "custom exception" );
} }
TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing]" )
{
if( Catch::alwaysTrue() )
throw CustomException( "custom std exception" );
}
inline void throwCustom() { inline void throwCustom() {
if( Catch::alwaysTrue() ) if( Catch::alwaysTrue() )
throw CustomException( "custom exception - not std" ); throw CustomException( "custom exception - not std" );