First cut of custom exception support

This commit is contained in:
Phil Nash 2011-04-20 15:40:40 +01:00
parent d4117b9208
commit 9430a2c4c8
8 changed files with 192 additions and 2 deletions

View File

@ -62,3 +62,36 @@ TEST_CASE( "./succeeding/exceptions/implicit", "When unchecked exceptions are th
{ {
} }
} }
class CustomException
{
public:
CustomException( const std::string& msg )
: m_msg( msg )
{}
std::string getMessage() const
{
return m_msg;
}
private:
std::string m_msg;
};
namespace Catch
{
ExceptionTranslator<CustomException> translator;
template<>
std::string ExceptionTranslator<CustomException>::translate( CustomException& ex ) const
{
return ex.getMessage();
}
}
TEST_CASE_NORETURN( "./succeeding/exceptions/custom", "" )
{
throw CustomException( "custom exception" );
}

View File

@ -32,6 +32,8 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
4A13FF93135EBF0000EC5928 /* catch_exception_translator_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_exception_translator_registry.hpp; path = ../internal/catch_exception_translator_registry.hpp; sourceTree = SOURCE_ROOT; };
4A13FF94135EBF2600EC5928 /* catch_interfaces_exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = catch_interfaces_exception.h; path = ../internal/catch_interfaces_exception.h; sourceTree = SOURCE_ROOT; };
4A15D2B712E0418F0005EB03 /* catch_self_test.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_self_test.hpp; path = ../internal/catch_self_test.hpp; sourceTree = SOURCE_ROOT; }; 4A15D2B712E0418F0005EB03 /* catch_self_test.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_self_test.hpp; path = ../internal/catch_self_test.hpp; sourceTree = SOURCE_ROOT; };
4A15D4A812E4DF0D0005EB03 /* catch_stream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_stream.hpp; path = ../internal/catch_stream.hpp; sourceTree = SOURCE_ROOT; }; 4A15D4A812E4DF0D0005EB03 /* catch_stream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_stream.hpp; path = ../internal/catch_stream.hpp; sourceTree = SOURCE_ROOT; };
4A302DE312D5114900C84B67 /* catch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch.hpp; path = ../catch.hpp; sourceTree = SOURCE_ROOT; }; 4A302DE312D5114900C84B67 /* catch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch.hpp; path = ../catch.hpp; sourceTree = SOURCE_ROOT; };
@ -116,6 +118,15 @@
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
4A13FF92135EBED500EC5928 /* Exceptions */ = {
isa = PBXGroup;
children = (
4A13FF93135EBF0000EC5928 /* catch_exception_translator_registry.hpp */,
4A13FF94135EBF2600EC5928 /* catch_interfaces_exception.h */,
);
name = Exceptions;
sourceTree = "<group>";
};
4A302E3712D515B700C84B67 /* TestCase registration */ = { 4A302E3712D515B700C84B67 /* TestCase registration */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -216,6 +227,7 @@
4AFC341412809A1B003A0C29 /* Internal */ = { 4AFC341412809A1B003A0C29 /* Internal */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4A13FF92135EBED500EC5928 /* Exceptions */,
4A302E3912D5160400C84B67 /* Hub */, 4A302E3912D5160400C84B67 /* Hub */,
4A302E3812D515DF00C84B67 /* Running & Results */, 4A302E3812D515DF00C84B67 /* Running & Results */,
4A302E3712D515B700C84B67 /* TestCase registration */, 4A302E3712D515B700C84B67 /* TestCase registration */,

View File

@ -28,6 +28,7 @@
#include "internal/catch_capture.hpp" #include "internal/catch_capture.hpp"
#include "internal/catch_section.hpp" #include "internal/catch_section.hpp"
#include "internal/catch_generators.hpp" #include "internal/catch_generators.hpp"
#include "internal/catch_interfaces_exception.h"
////// //////

View File

@ -0,0 +1,63 @@
/*
* catch_exception_translator_registry.hpp
* Catch
*
* Created by Phil on 20/04/2011.
* Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_HPP_INCLUDED
#include "catch_interfaces_exception.h"
namespace Catch
{
class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry
{
///////////////////////////////////////////////////////////////////////
virtual void registerTranslator
(
IExceptionTranslator* translator
)
{
m_translators.push_back( translator );
}
///////////////////////////////////////////////////////////////////////
virtual std::string translateActiveException
()
const
{
return tryTranslators( m_translators.begin() );
}
///////////////////////////////////////////////////////////////////////
std::string tryTranslators
(
std::vector<IExceptionTranslator*>::const_iterator it
)
const
{
if( it == m_translators.end() )
return "Unknown exception";
try
{
return (*it)->translate();
}
catch(...)
{
return tryTranslators( it+1 );
}
}
private:
std::vector<IExceptionTranslator*> m_translators;
};
}
#endif // TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_HPP_INCLUDED

View File

@ -24,6 +24,7 @@ namespace Catch
struct IResultCapture; struct IResultCapture;
struct ITestCaseRegistry; struct ITestCaseRegistry;
struct IRunner; struct IRunner;
struct IExceptionTranslatorRegistry;
class GeneratorsForTest; class GeneratorsForTest;
class StreamBufBase : public std::streambuf class StreamBufBase : public std::streambuf
@ -58,6 +59,9 @@ namespace Catch
static ITestCaseRegistry& getTestCaseRegistry static ITestCaseRegistry& getTestCaseRegistry
(); ();
static IExceptionTranslatorRegistry& getExceptionTranslatorRegistry
();
static std::streambuf* createStreamBuf static std::streambuf* createStreamBuf
( const std::string& streamName ( const std::string& streamName
); );
@ -82,6 +86,7 @@ namespace Catch
std::auto_ptr<IReporterRegistry> m_reporterRegistry; std::auto_ptr<IReporterRegistry> m_reporterRegistry;
std::auto_ptr<ITestCaseRegistry> m_testCaseRegistry; std::auto_ptr<ITestCaseRegistry> m_testCaseRegistry;
std::auto_ptr<IExceptionTranslatorRegistry> m_exceptionTranslatorRegistry;
IRunner* m_runner; IRunner* m_runner;
IResultCapture* m_resultCapture; IResultCapture* m_resultCapture;
std::map<std::string, GeneratorsForTest*> m_generatorsByTestName; std::map<std::string, GeneratorsForTest*> m_generatorsByTestName;

View File

@ -12,6 +12,7 @@
#include "catch_hub.h" #include "catch_hub.h"
#include "catch_reporter_registry.hpp" #include "catch_reporter_registry.hpp"
#include "catch_test_case_registry_impl.hpp" #include "catch_test_case_registry_impl.hpp"
#include "catch_exception_translator_registry.hpp"
#include "catch_runner_impl.hpp" #include "catch_runner_impl.hpp"
#include "catch_generators_impl.hpp" #include "catch_generators_impl.hpp"
#include "catch_stream.hpp" #include "catch_stream.hpp"
@ -22,7 +23,8 @@ namespace Catch
Hub::Hub Hub::Hub
() ()
: m_reporterRegistry( new ReporterRegistry ), : m_reporterRegistry( new ReporterRegistry ),
m_testCaseRegistry( new TestRegistry ) m_testCaseRegistry( new TestRegistry ),
m_exceptionTranslatorRegistry( new ExceptionTranslatorRegistry )
{ {
} }
@ -73,6 +75,13 @@ namespace Catch
return *me().m_testCaseRegistry.get(); return *me().m_testCaseRegistry.get();
} }
///////////////////////////////////////////////////////////////////////////
IExceptionTranslatorRegistry& Hub::getExceptionTranslatorRegistry
()
{
return *me().m_exceptionTranslatorRegistry.get();
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
std::streambuf* Hub::createStreamBuf std::streambuf* Hub::createStreamBuf
( (

View File

@ -0,0 +1,67 @@
/*
* catch_exception_interfaces.h
* Catch
*
* Created by Phil on 20/04/2011.
* Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_INTERFACES_EXCEPTIONS_H_INCLUDED
#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTIONS_H_INCLUDED
#include <string>
namespace Catch
{
typedef std::string(*exceptionTranslateFunction)();
struct IExceptionTranslator
{
virtual ~IExceptionTranslator(){}
virtual std::string translate() const = 0;
};
struct IExceptionTranslatorRegistry
{
virtual ~IExceptionTranslatorRegistry
()
{}
virtual void registerTranslator
( IExceptionTranslator* translator
) = 0;
virtual std::string translateActiveException
() const = 0;
};
template<typename T>
class ExceptionTranslator : public IExceptionTranslator
{
public:
ExceptionTranslator()
{
Catch::Hub::getExceptionTranslatorRegistry().registerTranslator( this );
}
virtual std::string translate() const
{
try
{
throw;
}
catch( T& ex )
{
return translate( ex );
}
}
protected:
std::string translate( T& ex ) const;
};
}
#endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTIONS_H_INCLUDED

View File

@ -577,7 +577,7 @@ namespace Catch
} }
catch(...) catch(...)
{ {
acceptMessage( "unknown exception" ); acceptMessage( Catch::Hub::getExceptionTranslatorRegistry().translateActiveException() );
acceptResult( ResultWas::ThrewException ); acceptResult( ResultWas::ThrewException );
} }
m_info.clear(); m_info.clear();