add user hooks to notify start and end of test cases

This commit is contained in:
François Moisan 2014-03-25 14:51:08 -04:00
parent af8cd98f20
commit 36bed7af00
4 changed files with 97 additions and 4 deletions

View File

@ -153,6 +153,15 @@ namespace Catch {
return m_filterSets; return m_filterSets;
} }
std::vector<ITestCaseHook*> const& userTestCaseHooks() const {
return m_userHooks;
}
void addUserHook(ITestCaseHook* hook)
{
m_userHooks.push_back(hook);
}
bool showHelp() const { return m_data.showHelp; } bool showHelp() const { return m_data.showHelp; }
// IConfig interface // IConfig interface
@ -163,13 +172,13 @@ namespace Catch {
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; } virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; } virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
private: private:
ConfigData m_data; ConfigData m_data;
Stream m_stream; Stream m_stream;
mutable std::ostream m_os; mutable std::ostream m_os;
std::vector<TestCaseFilters> m_filterSets; std::vector<TestCaseFilters> m_filterSets;
std::vector<ITestCaseHook*> m_userHooks;
}; };

View File

@ -10,11 +10,14 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector>
#include "catch_ptr.hpp" #include "catch_ptr.hpp"
namespace Catch { namespace Catch {
struct TestCaseInfo;
struct Verbosity { enum Level { struct Verbosity { enum Level {
NoOutput = 0, NoOutput = 0,
Quiet, Quiet,
@ -32,6 +35,14 @@ namespace Catch {
Never Never
}; }; }; };
struct ITestCaseHook
{
virtual ~ITestCaseHook() {}
virtual void sectionStarting(TestCaseInfo const & testCaseInfo) = 0;
virtual void sectionEnding(TestCaseInfo const & testCaseInfo) = 0;
};
struct IConfig : IShared { struct IConfig : IShared {
virtual ~IConfig(); virtual ~IConfig();
@ -44,6 +55,8 @@ namespace Catch {
virtual bool warnAboutMissingAssertions() const = 0; virtual bool warnAboutMissingAssertions() const = 0;
virtual int abortAfter() const = 0; virtual int abortAfter() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0; virtual ShowDurations::OrNot showDurations() const = 0;
virtual std::vector< ITestCaseHook* > const & userTestCaseHooks() const = 0;
}; };
} }

View File

@ -256,6 +256,26 @@ namespace Catch {
return action; return action;
} }
void runTestCaseStartingHook(TestCaseInfo const& testCaseInfo)
{
std::vector<ITestCaseHook*> const & validations = m_config->userTestCaseHooks();
for(std::vector<ITestCaseHook*>::const_iterator it = validations.begin(), end = validations.end(); it != end; ++it)
{
(*it)->sectionStarting(testCaseInfo);
}
}
void runTestCaseEndingHook(TestCaseInfo const& testCaseInfo)
{
std::vector<ITestCaseHook*> const & validations = m_config->userTestCaseHooks();
for(std::vector<ITestCaseHook*>::const_reverse_iterator it = validations.rbegin(), end = validations.rend(); it != end; ++it)
{
(*it)->sectionEnding(testCaseInfo);
}
}
void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
SectionInfo testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo ); SectionInfo testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo );
@ -266,6 +286,8 @@ namespace Catch {
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
TestCaseTracker::Guard guard( *m_testCaseTracker ); TestCaseTracker::Guard guard( *m_testCaseTracker );
runTestCaseStartingHook(testCaseInfo);
Timer timer; Timer timer;
timer.start(); timer.start();
if( m_reporter->getPreferences().shouldRedirectStdOut ) { if( m_reporter->getPreferences().shouldRedirectStdOut ) {
@ -277,6 +299,8 @@ namespace Catch {
m_activeTestCase->invoke(); m_activeTestCase->invoke();
} }
duration = timer.getElapsedSeconds(); duration = timer.getElapsedSeconds();
runTestCaseEndingHook(testCaseInfo);
} }
catch( TestFailureException& ) { catch( TestFailureException& ) {
// This just means the test was aborted due to failure // This just means the test was aborted due to failure

View File

@ -1,6 +1,6 @@
/* /*
* CATCH v1.0 build 33 (master branch) * CATCH v1.0 build 34 (master branch)
* Generated: 2014-03-24 18:11:50.426554 * Generated: 2014-03-25 14:43:34.962000
* ---------------------------------------------------------- * ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly * This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@ -1497,9 +1497,12 @@ namespace Catch {
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector>
namespace Catch { namespace Catch {
struct TestCaseInfo;
struct Verbosity { enum Level { struct Verbosity { enum Level {
NoOutput = 0, NoOutput = 0,
Quiet, Quiet,
@ -1517,6 +1520,14 @@ namespace Catch {
Never Never
}; }; }; };
struct ITestCaseHook
{
virtual ~ITestCaseHook() {}
virtual void sectionStarting(TestCaseInfo const & testCaseInfo) = 0;
virtual void sectionEnding(TestCaseInfo const & testCaseInfo) = 0;
};
struct IConfig : IShared { struct IConfig : IShared {
virtual ~IConfig(); virtual ~IConfig();
@ -1529,6 +1540,8 @@ namespace Catch {
virtual bool warnAboutMissingAssertions() const = 0; virtual bool warnAboutMissingAssertions() const = 0;
virtual int abortAfter() const = 0; virtual int abortAfter() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0; virtual ShowDurations::OrNot showDurations() const = 0;
virtual std::vector< ITestCaseHook* > const & userTestCaseHooks() const = 0;
}; };
} }
@ -2993,6 +3006,15 @@ namespace Catch {
return m_filterSets; return m_filterSets;
} }
std::vector<ITestCaseHook*> const& userTestCaseHooks() const {
return m_userHooks;
}
void addUserHook(ITestCaseHook* hook)
{
m_userHooks.push_back(hook);
}
bool showHelp() const { return m_data.showHelp; } bool showHelp() const { return m_data.showHelp; }
// IConfig interface // IConfig interface
@ -3009,6 +3031,7 @@ namespace Catch {
Stream m_stream; Stream m_stream;
mutable std::ostream m_os; mutable std::ostream m_os;
std::vector<TestCaseFilters> m_filterSets; std::vector<TestCaseFilters> m_filterSets;
std::vector<ITestCaseHook*> m_userHooks;
}; };
} // end namespace Catch } // end namespace Catch
@ -5024,6 +5047,26 @@ namespace Catch {
return action; return action;
} }
void runTestCaseStartingHook(TestCaseInfo const& testCaseInfo)
{
std::vector<ITestCaseHook*> const & validations = m_config->userTestCaseHooks();
for(std::vector<ITestCaseHook*>::const_iterator it = validations.begin(), end = validations.end(); it != end; ++it)
{
(*it)->sectionStarting(testCaseInfo);
}
}
void runTestCaseEndingHook(TestCaseInfo const& testCaseInfo)
{
std::vector<ITestCaseHook*> const & validations = m_config->userTestCaseHooks();
for(std::vector<ITestCaseHook*>::const_reverse_iterator it = validations.rbegin(), end = validations.rend(); it != end; ++it)
{
(*it)->sectionEnding(testCaseInfo);
}
}
void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
SectionInfo testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo ); SectionInfo testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo );
@ -5034,6 +5077,8 @@ namespace Catch {
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
TestCaseTracker::Guard guard( *m_testCaseTracker ); TestCaseTracker::Guard guard( *m_testCaseTracker );
runTestCaseStartingHook(testCaseInfo);
Timer timer; Timer timer;
timer.start(); timer.start();
if( m_reporter->getPreferences().shouldRedirectStdOut ) { if( m_reporter->getPreferences().shouldRedirectStdOut ) {
@ -5045,6 +5090,8 @@ namespace Catch {
m_activeTestCase->invoke(); m_activeTestCase->invoke();
} }
duration = timer.getElapsedSeconds(); duration = timer.getElapsedSeconds();
runTestCaseEndingHook(testCaseInfo);
} }
catch( TestFailureException& ) { catch( TestFailureException& ) {
// This just means the test was aborted due to failure // This just means the test was aborted due to failure
@ -6598,7 +6645,7 @@ namespace Catch {
namespace Catch { namespace Catch {
// These numbers are maintained by a script // These numbers are maintained by a script
Version libraryVersion( 1, 0, 33, "master" ); Version libraryVersion( 1, 0, 34, "master" );
} }
// #included from: catch_message.hpp // #included from: catch_message.hpp