Added self-test for section ordering

Added MockReporter for tracking test runs.
Added intrusive smart pointer. Config holds reporter by smart pointer, so we can route the mock reporter through multiple test runs
This commit is contained in:
Phil Nash 2012-05-04 07:55:11 +01:00
parent 83a66a6255
commit b213202ad7
16 changed files with 432 additions and 67 deletions

View file

@ -14,19 +14,223 @@
#include "catch.hpp"
#include "set"
namespace Catch
{
class MockReporter : public SharedImpl<IReporter>
{
public:
static const std::string recordGroups;
static const std::string recordTestCases;
static const std::string recordSections;
void recordAll
()
{
addRecorder( recordGroups );
addRecorder( recordTestCases );
addRecorder( recordSections );
}
MockReporter
(
const IReporterConfig& config
)
{
recordAll();
}
MockReporter
()
{
recordAll();
}
void addRecorder
(
const std::string& recorder
)
{
m_recorders.insert( recorder );
}
static std::string getDescription
()
{
return "mock reporter";
}
std::string getLog
()
const
{
return m_log.str();
}
private: // IReporter
virtual bool shouldRedirectStdout
()
const
{
return false;
}
virtual void StartTesting
()
{
}
virtual void EndTesting
(
const Totals& totals
)
{
}
virtual void StartGroup
(
const std::string& groupName
)
{
if( shouldRecord( recordGroups ) )
m_log << recordGroups << "( " << groupName << " ){ ";
}
virtual void EndGroup
(
const std::string& groupName,
const Totals& totals
)
{
if( shouldRecord( recordGroups ) )
m_log << " } " << recordGroups << "( " << groupName << " )";
}
virtual void StartSection
(
const std::string& sectionName,
const std::string description
)
{
if( shouldRecord( recordSections ) )
m_log << recordSections << "( " << sectionName << " ){ ";
}
virtual void EndSection
(
const std::string& sectionName,
const Counts& assertions
)
{
if( shouldRecord( recordSections ) )
m_log << " } " << recordSections << "( " << sectionName << " )";
}
virtual void StartTestCase
(
const TestCaseInfo& testInfo
)
{
if( shouldRecord( recordTestCases ) )
m_log << recordTestCases << "( " << testInfo.getName() << " ){ ";
}
virtual void EndTestCase
(
const TestCaseInfo& testInfo,
const Totals& totals,
const std::string& stdOut,
const std::string& stdErr
)
{
if( shouldRecord( recordTestCases ) )
m_log << " } " << recordTestCases << "( " << testInfo.getName() << " )";
}
virtual void Result
(
const ResultInfo& resultInfo
)
{
if( resultInfo.getResultType() == ResultWas::Ok )
return;
switch( resultInfo.getResultType() )
{
case ResultWas::Info:
m_log << "Info";
break;
case ResultWas::Warning:
m_log << "Warning";
break;
case ResultWas::ExplicitFailure:
m_log << "ExplicitFailure";
break;
case ResultWas::ExpressionFailed:
m_log << "ExpressionFailed";
break;
case ResultWas::Unknown:
m_log << "Unknown";
break;
case ResultWas::ThrewException:
m_log << "ThrewException";
break;
case ResultWas::DidntThrowException:
m_log << "DidntThrowException";
break;
// We shouldn't ever see these
case ResultWas::Ok:
m_log << "Ok";
break;
case ResultWas::FailureBit:
m_log << "FailureBit";
break;
case ResultWas::Exception:
m_log << "Exception";
break;
default:
m_log << "{unrecognised ResultType enum value}";
break;
}
if( resultInfo.hasExpression() )
m_log << resultInfo.getExpression();
if( resultInfo.hasMessage() )
m_log << "'" << resultInfo.getMessage() << "'";
if( resultInfo.hasExpandedExpression() )
m_log << resultInfo.getExpandedExpression();
}
private:
bool shouldRecord( const std::string& recorder ) const
{
return m_recorders.find( recorder ) != m_recorders.end();
}
std::ostringstream m_log;
std::set<std::string> m_recorders;
};
class EmbeddedRunner
{
public:
///////////////////////////////////////////////////////////////////////////
EmbeddedRunner
()
: m_reporter( new MockReporter() )
{
}
std::size_t runMatching
( const std::string& rawTestSpec );
( const std::string& rawTestSpec,
const std::string& reporter = "basic" );
///////////////////////////////////////////////////////////////////////////
std::string getOutput
@ -42,10 +246,23 @@ namespace Catch
{
return m_totals;
}
///////////////////////////////////////////////////////////////////////////
void addRecorder( const std::string& recorder )
{
m_reporter->addRecorder( recorder );
}
///////////////////////////////////////////////////////////////////////////
std::string getLog() const
{
return m_reporter->getLog();
}
private:
Totals m_totals;
std::string m_output;
Ptr<MockReporter> m_reporter;
};
class MetaTestRunner
@ -60,6 +277,15 @@ namespace Catch
};
};
///////////////////////////////////////////////////////////////////////////
MetaTestRunner
(
Expected::Result expectedResult
)
: m_expectedResult( expectedResult )
{
}
///////////////////////////////////////////////////////////////////////////
static void runMatching
(
@ -71,15 +297,6 @@ namespace Catch
MetaTestRunner( expectedResult ) );
}
///////////////////////////////////////////////////////////////////////////
MetaTestRunner
(
Expected::Result expectedResult
)
: m_expectedResult( expectedResult )
{
}
///////////////////////////////////////////////////////////////////////////
void operator()
(
@ -163,6 +380,7 @@ namespace Catch
LineInfoRegistry::get().registerLineInfo( name, lineInfo );
}
};
}
#define CATCH_REGISTER_LINE_INFO( name ) ::Catch::LineInfoRegistrar INTERNAL_CATCH_UNIQUE_NAME( lineRegistrar )( name, ::Catch::SourceLineInfo( __FILE__, __LINE__ ) );