Added ReporterPreferences and started some SectionInfo refactoring

This commit is contained in:
Phil Nash 2012-11-29 09:05:51 +00:00
parent 994e64c217
commit c4ba6757d9
4 changed files with 93 additions and 58 deletions

View File

@ -36,6 +36,15 @@ namespace Catch
ConfigData m_fullConfig; ConfigData m_fullConfig;
}; };
struct ReporterPreferences
{
ReporterPreferences()
: shouldRedirectStdOut( false )
{}
bool shouldRedirectStdOut;
};
struct AssertionStats { struct AssertionStats {
AssertionStats( const AssertionResult& _assertionResult, AssertionStats( const AssertionResult& _assertionResult,
const Totals& _totals ) const Totals& _totals )
@ -102,6 +111,8 @@ namespace Catch
// !Work In progress // !Work In progress
struct IStreamingReporter : IShared { struct IStreamingReporter : IShared {
virtual ~IStreamingReporter(); virtual ~IStreamingReporter();
virtual ReporterPreferences getPreferences() const = 0;
virtual void testRunStarting( const std::string& runName ) = 0; virtual void testRunStarting( const std::string& runName ) = 0;
virtual void testGroupStarting( const std::string& groupName ) = 0; virtual void testGroupStarting( const std::string& groupName ) = 0;
@ -160,8 +171,13 @@ namespace Catch
m_config( config ) m_config( config )
{} {}
virtual ~LegacyReporterAdapter(); virtual ~LegacyReporterAdapter();
virtual ReporterPreferences getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
return prefs;
}
virtual void testRunStarting( const std::string& ) { virtual void testRunStarting( const std::string& ) {
m_legacyReporter->StartTesting(); m_legacyReporter->StartTesting();
} }

View File

@ -109,7 +109,7 @@ namespace Catch {
LegacyReporterAdapter reporter( m_reporter, ReporterConfig( m_config.stream(), m_config.data() ) ); LegacyReporterAdapter reporter( m_reporter, ReporterConfig( m_config.stream(), m_config.data() ) );
reporter.testCaseStarting( testInfo ); reporter.testCaseStarting( testInfo );
m_runningTest = new RunningTest( &testCase ); m_runningTest = new RunningTest( testCase );
do { do {
do { do {
@ -202,6 +202,10 @@ namespace Catch {
m_lastAssertionInfo.lineInfo = lineInfo; m_lastAssertionInfo.lineInfo = lineInfo;
// !TBD: ------------
std::string className = m_runningTest->getTestCase().getTestCaseInfo().className;
TestCaseInfo sectionInfo( name, className, description, std::set<std::string>(), false, lineInfo );
m_reporter->StartSection( name, description ); m_reporter->StartSection( name, description );
assertions = m_totals.assertions; assertions = m_totals.assertions;
@ -272,7 +276,8 @@ namespace Catch {
try { try {
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", m_runningTest->getTestCase().getTestCaseInfo().lineInfo, "", ResultDisposition::Normal ); m_lastAssertionInfo = AssertionInfo( "TEST_CASE", m_runningTest->getTestCase().getTestCaseInfo().lineInfo, "", ResultDisposition::Normal );
m_runningTest->reset(); m_runningTest->reset();
if( m_reporter->shouldRedirectStdout() ) { LegacyReporterAdapter reporter( m_reporter, ReporterConfig( m_config.stream(), m_config.data() ) );
if( reporter.getPreferences().shouldRedirectStdOut ) {
StreamRedirect coutRedir( std::cout, redirectedCout ); StreamRedirect coutRedir( std::cout, redirectedCout );
StreamRedirect cerrRedir( std::cerr, redirectedCerr ); StreamRedirect cerrRedir( std::cerr, redirectedCerr );
m_runningTest->getTestCase().invoke(); m_runningTest->getTestCase().invoke();

View File

@ -24,9 +24,10 @@ namespace Catch {
}; };
public: public:
explicit RunningTest( const TestCase* info = NULL ) explicit RunningTest( const TestCase& info )
: m_info( info ), : m_info( info ),
m_runStatus( RanAtLeastOneSection ), m_runStatus( RanAtLeastOneSection ),
m_rootSection( info.getTestCaseInfo().name ),
m_currentSection( &m_rootSection ), m_currentSection( &m_rootSection ),
m_changed( false ) m_changed( false )
{} {}
@ -71,12 +72,8 @@ namespace Catch {
if( m_runStatus == NothingRun ) if( m_runStatus == NothingRun )
m_runStatus = EncounteredASection; m_runStatus = EncounteredASection;
SectionInfo* thisSection = m_currentSection->findSubSection( name ); SectionInfo* thisSection = m_currentSection->findOrAddSubSection( name, m_changed );
if( !thisSection ) {
thisSection = m_currentSection->addSubSection( name );
m_changed = true;
}
if( !wasSectionSeen() && thisSection->shouldRun() ) { if( !wasSectionSeen() && thisSection->shouldRun() ) {
m_currentSection = thisSection; m_currentSection = thisSection;
m_lastSectionToRun = NULL; m_lastSectionToRun = NULL;
@ -98,16 +95,16 @@ namespace Catch {
} }
const TestCase& getTestCase() const { const TestCase& getTestCase() const {
return *m_info; return m_info;
} }
bool hasUntestedSections() const { bool hasUntestedSections() const {
return m_runStatus == RanAtLeastOneSection || return m_runStatus == RanAtLeastOneSection ||
( m_rootSection.hasUntestedSections() && m_changed ); ( m_rootSection.hasUntestedSections() && m_changed );
} }
private: private:
const TestCase* m_info; const TestCase& m_info;
RunStatus m_runStatus; RunStatus m_runStatus;
SectionInfo m_rootSection; SectionInfo m_rootSection;
SectionInfo* m_currentSection; SectionInfo* m_currentSection;

View File

@ -15,10 +15,17 @@
namespace Catch { namespace Catch {
class SectionInfo { struct ISectionInfo {
virtual ~ISectionInfo() {}
virtual std::string getName() const = 0;
virtual const ISectionInfo* getParent() const = 0;
};
class SectionInfo : ISectionInfo {
public: public:
enum Status { enum State {
Root, Root,
Unknown, Unknown,
Branch, Branch,
@ -26,61 +33,40 @@ namespace Catch {
TestedLeaf TestedLeaf
}; };
SectionInfo( SectionInfo* parent ) SectionInfo( SectionInfo* parent, const std::string& name )
: m_status( Unknown ), : m_state( Unknown ),
m_parent( parent ) m_parent( parent ),
m_name( name )
{} {}
SectionInfo() SectionInfo( const std::string& name )
: m_status( Root ), : m_state( Root ),
m_parent( NULL ) m_parent( NULL ),
m_name( name )
{} {}
~SectionInfo() { ~SectionInfo() {
deleteAllValues( m_subSections ); deleteAllValues( m_subSections );
} }
virtual std::string getName() const {
return m_name;
}
bool shouldRun() const { bool shouldRun() const {
return m_status < TestedBranch; return m_state < TestedBranch;
} }
bool ran() {
if( m_status < Branch ) {
m_status = TestedLeaf;
return true;
}
return false;
}
bool isBranch() const { bool isBranch() const {
return m_status == Branch; return m_state == Branch;
} }
void ranToCompletion() { const SectionInfo* getParent() const {
if( m_status == Branch && !hasUntestedSections() )
m_status = TestedBranch;
}
SectionInfo* findSubSection( const std::string& name ) {
std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.find( name );
return it != m_subSections.end()
? it->second
: NULL;
}
SectionInfo* addSubSection( const std::string& name ) {
SectionInfo* subSection = new SectionInfo( this );
m_subSections.insert( std::make_pair( name, subSection ) );
m_status = Branch;
return subSection;
}
SectionInfo* getParent() {
return m_parent; return m_parent;
} }
bool hasUntestedSections() const { bool hasUntestedSections() const {
if( m_status == Unknown ) if( m_state == Unknown )
return true; return true;
std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.begin(); std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.begin();
@ -91,11 +77,42 @@ namespace Catch {
} }
return false; return false;
} }
// Mutable methods:
SectionInfo* getParent() {
return m_parent;
}
SectionInfo* findOrAddSubSection( const std::string& name, bool& changed ) {
std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.find( name );
if( it != m_subSections.end() )
return it->second;
SectionInfo* subSection = new SectionInfo( this, name );
m_subSections.insert( std::make_pair( name, subSection ) );
m_state = Branch;
changed = true;
return subSection;
}
bool ran() {
if( m_state < Branch ) {
m_state = TestedLeaf;
return true;
}
return false;
}
void ranToCompletion() {
if( m_state == Branch && !hasUntestedSections() )
m_state = TestedBranch;
}
private: private:
Status m_status; State m_state;
std::map<std::string, SectionInfo*> m_subSections;
SectionInfo* m_parent; SectionInfo* m_parent;
std::string m_name;
std::map<std::string, SectionInfo*> m_subSections;
}; };
} }