mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 12:17:11 +01:00 
			
		
		
		
	Fleshed out console reporter
This commit is contained in:
		| @@ -35,11 +35,13 @@ namespace Catch { | ||||
|         } | ||||
|         void lazyPrintGroupInfo() { | ||||
|             if( !unusedGroupInfo->name.empty() ) | ||||
|                 stream << "[Group: '" << unusedGroupInfo->name << "']" << std::endl; | ||||
| //                stream << "[Group: '" << unusedGroupInfo->name << "']" << std::endl; | ||||
|                 stream << "[Started group: '" << unusedGroupInfo->name << "']" << std::endl; | ||||
|             unusedGroupInfo.reset(); | ||||
|         } | ||||
|         void lazyPrintTestCaseInfo() { | ||||
|             stream << "[Test case: '" << unusedTestCaseInfo->name << "']" << std::endl; | ||||
| //            stream << "[Test case: '" << unusedTestCaseInfo->name << "']" << std::endl; | ||||
|             stream << "[Running: " << unusedTestCaseInfo->name << "]" << std::endl; | ||||
|             unusedTestCaseInfo.reset(); | ||||
|         } | ||||
|         std::string makeSectionPath( ThreadedSectionInfo const * section, std::string const& delimiter ) { | ||||
| @@ -49,6 +51,7 @@ namespace Catch { | ||||
|             return sectionPath; | ||||
|         } | ||||
|         void lazyPrintSectionInfo() { | ||||
|             // !TBD use printed flag | ||||
|             ThreadedSectionInfo* section = unusedSectionInfo.get(); | ||||
|  | ||||
|             std::string sectionPath = makeSectionPath( section, ", " ); | ||||
| @@ -58,6 +61,21 @@ namespace Catch { | ||||
|             stream << "[Section: " << sectionPath << "]" << std::endl; | ||||
|             unusedSectionInfo.reset(); | ||||
|         } | ||||
|          | ||||
|         void lazyPrintSectionInfoLegacy() { | ||||
|             std::vector<ThreadedSectionInfo*> sections; | ||||
|             for(    ThreadedSectionInfo* section = unusedSectionInfo.get(); | ||||
|                     section && !section->printed; | ||||
|                     section = section->parent.get() ) | ||||
|                 sections.push_back( section ); | ||||
|  | ||||
|             typedef std::vector<ThreadedSectionInfo*>::const_reverse_iterator It; | ||||
|             for( It it = sections.rbegin(), itEnd = sections.rend(); it != itEnd; ++it ) { | ||||
|                 stream << "[Started section: " << "'" + (*it)->name + "'" << "]" << std::endl; | ||||
|                 (*it)->printed = true; | ||||
|             } | ||||
|             unusedSectionInfo.reset(); | ||||
|         } | ||||
|         void lazyPrint() { | ||||
|             if( testRunInfo ) | ||||
|                 lazyPrintRunInfo(); | ||||
| @@ -65,17 +83,134 @@ namespace Catch { | ||||
|                 lazyPrintGroupInfo(); | ||||
|             if( unusedTestCaseInfo ) | ||||
|                 lazyPrintTestCaseInfo(); | ||||
|             if( unusedSectionInfo ) | ||||
|                 lazyPrintSectionInfo(); | ||||
|             if( currentSectionInfo && !currentSectionInfo->printed ) | ||||
|                 lazyPrintSectionInfoLegacy(); // !TBD | ||||
|         } | ||||
|  | ||||
|         virtual void assertionStarting( AssertionInfo const& _assertionInfo ) { | ||||
|         virtual void assertionStarting( AssertionInfo const& ) { | ||||
|         } | ||||
|         virtual void assertionEnded( Ptr<AssertionStats const> const& _assertionStats ) { | ||||
|             if( !_assertionStats->assertionResult.isOk() ) | ||||
|                 lazyPrint(); | ||||
|         } | ||||
|  | ||||
|             AssertionResult const& result = _assertionStats->assertionResult; | ||||
|              | ||||
|             // Drop out if result was successful and we're not printing those | ||||
|             if( !m_config.includeSuccessfulResults() && result.isOk() ) | ||||
|                 return; | ||||
|  | ||||
|             lazyPrint(); | ||||
|  | ||||
|             if( !result.getSourceInfo().empty() ) { | ||||
|                 TextColour colour( TextColour::FileName ); | ||||
|                 stream << result.getSourceInfo(); | ||||
|             } | ||||
|  | ||||
|             if( result.hasExpression() ) { | ||||
|                 TextColour colour( TextColour::OriginalExpression ); | ||||
|                 stream << result.getExpression(); | ||||
|                 if( result.succeeded() ) { | ||||
|                     TextColour successColour( TextColour::Success ); | ||||
|                     stream << " succeeded"; | ||||
|                 } | ||||
|                 else { | ||||
|                     TextColour errorColour( TextColour::Error ); | ||||
|                     stream << " failed"; | ||||
|                     if( result.isOk() ) { | ||||
|                         TextColour okAnywayColour( TextColour::Success ); | ||||
|                         stream << " - but was ok"; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             switch( result.getResultType() ) { | ||||
|                 case ResultWas::ThrewException: | ||||
|                 { | ||||
|                     TextColour colour( TextColour::Error ); | ||||
|                     if( result.hasExpression() ) | ||||
|                         stream << " with unexpected"; | ||||
|                     else | ||||
|                         stream << "Unexpected"; | ||||
|                     stream << " exception with message: '" << result.getMessage() << "'"; | ||||
|                 } | ||||
|                     break; | ||||
|                 case ResultWas::DidntThrowException: | ||||
|                 { | ||||
|                     TextColour colour( TextColour::Error ); | ||||
|                     if( result.hasExpression() ) | ||||
|                         stream << " because no exception was thrown where one was expected"; | ||||
|                     else | ||||
|                         stream << "No exception thrown where one was expected"; | ||||
|                 } | ||||
|                     break; | ||||
|                 case ResultWas::Info: | ||||
|                 { | ||||
|                     TextColour colour( TextColour::ReconstructedExpression ); | ||||
|                     streamVariableLengthText( "info", result.getMessage() ); | ||||
|                 } | ||||
|                     break; | ||||
|                 case ResultWas::Warning: | ||||
|                 { | ||||
|                     TextColour colour( TextColour::ReconstructedExpression ); | ||||
|                     streamVariableLengthText( "warning", result.getMessage() ); | ||||
|                 } | ||||
|                     break; | ||||
|                 case ResultWas::ExplicitFailure: | ||||
|                 { | ||||
|                     TextColour colour( TextColour::Error ); | ||||
|                     stream << "failed with message: '" << result.getMessage() << "'"; | ||||
|                 } | ||||
|                     break; | ||||
|                 case ResultWas::Unknown: // These cases are here to prevent compiler warnings | ||||
|                 case ResultWas::Ok: | ||||
|                 case ResultWas::FailureBit: | ||||
|                 case ResultWas::ExpressionFailed: | ||||
|                 case ResultWas::Exception: | ||||
|                     if( !result.hasExpression() ) { | ||||
|                         if( result.succeeded() ) { | ||||
|                             TextColour colour( TextColour::Success ); | ||||
|                             stream << " succeeded"; | ||||
|                         } | ||||
|                         else { | ||||
|                             TextColour colour( TextColour::Error ); | ||||
|                             stream << " failed"; | ||||
|                             if( result.isOk() ) { | ||||
|                                 TextColour okAnywayColour( TextColour::Success ); | ||||
|                                 stream << " - but was ok"; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     if( result.hasMessage() ) { | ||||
|                         stream << "\n"; | ||||
|                         TextColour colour( TextColour::ReconstructedExpression ); | ||||
|                         streamVariableLengthText( "with message", result.getMessage() ); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|             if( result.hasExpandedExpression() ) { | ||||
|                 stream << " for: "; | ||||
|                 if( result.getExpandedExpression().size() > 40 ) { | ||||
|                     stream << "\n"; | ||||
|                     if( result.getExpandedExpression().size() < 70 ) | ||||
|                         stream << "\t"; | ||||
|                 } | ||||
|                 TextColour colour( TextColour::ReconstructedExpression ); | ||||
|                 stream << result.getExpandedExpression(); | ||||
|             } | ||||
|              | ||||
|             stream << std::endl; | ||||
|         } | ||||
|          | ||||
|         void streamVariableLengthText( std::string const& prefix, std::string const& text ) { | ||||
|             std::string trimmed = trim( text ); | ||||
|             if( trimmed.find_first_of( "\r\n" ) == std::string::npos ) { | ||||
|                 stream << "[" << prefix << ": " << trimmed << "]"; | ||||
|             } | ||||
|             else { | ||||
|                 stream  << "\n[" << prefix << "] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" << trimmed | ||||
|                         << "\n[end of " << prefix << "] <<<<<<<<<<<<<<<<<<<<<<<<\n"; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         void printAssertionCounts( std::string const& label, Counts const& counts, std::string const& allPrefix = "All " ) { | ||||
|             if( counts.passed ) | ||||
|                 stream << counts.failed << " of " << counts.total() << " " << label << "s failed"; | ||||
| @@ -105,27 +240,58 @@ namespace Catch { | ||||
|         } | ||||
|  | ||||
|         virtual void sectionEnded( Ptr<SectionStats const> const& _sectionStats ) { | ||||
|             if( !unusedSectionInfo ) { | ||||
|                 stream << "[Summary for section '" << _sectionStats->sectionInfo.name << "': "; | ||||
|                 printAssertionCounts( "assertion", _sectionStats->assertions ); | ||||
|             if( _sectionStats->missingAssertions ) { | ||||
|                 lazyPrint(); | ||||
|                 TextColour colour( TextColour::ResultError ); | ||||
|                 stream << "\nNo assertions in section, '" << _sectionStats->sectionInfo.name << "'\n" << std::endl; | ||||
|             } | ||||
|             if( currentSectionInfo && currentSectionInfo->printed ) { | ||||
| //                stream << "[Summary for section '" << _sectionStats->sectionInfo.name << "': "; | ||||
|                 stream << "[End of section: '" << _sectionStats->sectionInfo.name << "' "; | ||||
|                 Counts const& assertions = _sectionStats->assertions; | ||||
|                 if( assertions.failed ) { | ||||
|                     TextColour colour( TextColour::ResultError ); | ||||
|                     printAssertionCounts( "assertion", assertions ); | ||||
|                 } | ||||
|                 else { | ||||
|                     TextColour colour( TextColour::ResultSuccess ); | ||||
|                     stream  << ( assertions.passed > 1 ? "All " : "" ) | ||||
|                             << pluralise( assertions.passed, "assertion" ) << " passed" ; | ||||
|                 } | ||||
|                 stream << "]\n" << std::endl; | ||||
|             } | ||||
|             AccumulatingReporter::sectionEnded( _sectionStats ); | ||||
|         } | ||||
|         virtual void testCaseEnded( Ptr<TestCaseStats const> const& _testCaseStats ) { | ||||
|             if( _testCaseStats->missingAssertions ) { | ||||
|                 lazyPrint(); | ||||
|                 TextColour colour( TextColour::ResultError ); | ||||
|                 stream << "\nNo assertions in test case, '" << _testCaseStats->testInfo.name << "'\n" << std::endl; | ||||
|             } | ||||
|             if( !unusedTestCaseInfo ) { | ||||
|                 stream << "[Summary for test case '" << _testCaseStats->testInfo.name << "': "; | ||||
| //                stream << "[Summary for test case '" << _testCaseStats->testInfo.name << "': "; | ||||
|                 stream << "[Finished: '" << _testCaseStats->testInfo.name << "' "; | ||||
|                 printTotals( _testCaseStats->totals ); | ||||
|                 stream << "]\n" << std::endl; | ||||
|             } | ||||
|             AccumulatingReporter::testCaseEnded( _testCaseStats ); | ||||
|         } | ||||
|         virtual void testGroupEnded( Ptr<TestGroupStats const> const& _testGroupStats ) { | ||||
|             // !TBD | ||||
|             if( !unusedGroupInfo ) { | ||||
| //                stream << "[Summary for group '" << _testGroupStats->groupInfo.name << "': "; | ||||
|                 stream << "[End of group '" << _testGroupStats->groupInfo.name << "'. "; | ||||
|                 printTotals( _testGroupStats->totals ); | ||||
|                 stream << "]\n" << std::endl; | ||||
|             } | ||||
|             AccumulatingReporter::testGroupEnded( _testGroupStats ); | ||||
|         } | ||||
|         virtual void testRunEnded( Ptr<TestRunStats const> const& _testRunStats ) { | ||||
|             // !TBD | ||||
|             if( !unusedTestCaseInfo ) { | ||||
| //                stream << "[Summary for '" << _testRunStats->runInfo.name << "': "; | ||||
|                 stream << "[Testing completed. "; | ||||
|                 printTotals( _testRunStats->totals ); | ||||
|                 stream << "]\n" << std::endl; | ||||
|             } | ||||
|             AccumulatingReporter::testRunEnded( _testRunStats ); | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash