bump catch2 headers to v2.13.9 (#25678)
	
		
	
				
					
				
			
							parent
							
								
									69e9b285b3
								
							
						
					
					
						commit
						9fb2c40cfd
					
				
				 5 changed files with 1153 additions and 982 deletions
			
			
		
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						| @ -1,62 +1,62 @@ | |||||||
| /*
 | /*
 | ||||||
|  *  Created by Justin R. Wilson on 2/19/2017. |  *  Created by Justin R. Wilson on 2/19/2017. | ||||||
|  *  Copyright 2017 Justin R. Wilson. All rights reserved. |  *  Copyright 2017 Justin R. Wilson. All rights reserved. | ||||||
|  * |  * | ||||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying |  *  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)
 |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||||||
|  */ |  */ | ||||||
| #ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED | #ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED | ||||||
| 
 | 
 | ||||||
| // Don't #include any Catch headers here - we can assume they are already
 | // Don't #include any Catch headers here - we can assume they are already
 | ||||||
| // included before this header.
 | // included before this header.
 | ||||||
| // This is not good practice in general but is necessary in this case so this
 | // This is not good practice in general but is necessary in this case so this
 | ||||||
| // file can be distributed as a single header that works with the main
 | // file can be distributed as a single header that works with the main
 | ||||||
| // Catch single header.
 | // Catch single header.
 | ||||||
| 
 | 
 | ||||||
| namespace Catch { | namespace Catch { | ||||||
| 
 | 
 | ||||||
|     struct AutomakeReporter : StreamingReporterBase<AutomakeReporter> { |     struct AutomakeReporter : StreamingReporterBase<AutomakeReporter> { | ||||||
|         AutomakeReporter( ReporterConfig const& _config ) |         AutomakeReporter( ReporterConfig const& _config ) | ||||||
|           :   StreamingReporterBase( _config ) |           :   StreamingReporterBase( _config ) | ||||||
|         {} |         {} | ||||||
| 
 | 
 | ||||||
|         ~AutomakeReporter() override; |         ~AutomakeReporter() override; | ||||||
| 
 | 
 | ||||||
|         static std::string getDescription() { |         static std::string getDescription() { | ||||||
|             return "Reports test results in the format of Automake .trs files"; |             return "Reports test results in the format of Automake .trs files"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void assertionStarting( AssertionInfo const& ) override {} |         void assertionStarting( AssertionInfo const& ) override {} | ||||||
| 
 | 
 | ||||||
|         bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) override { return true; } |         bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) override { return true; } | ||||||
| 
 | 
 | ||||||
|         void testCaseEnded( TestCaseStats const& _testCaseStats ) override { |         void testCaseEnded( TestCaseStats const& _testCaseStats ) override { | ||||||
|             // Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
 |             // Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
 | ||||||
|             stream << ":test-result: "; |             stream << ":test-result: "; | ||||||
|             if (_testCaseStats.totals.assertions.allPassed()) { |             if (_testCaseStats.totals.assertions.allPassed()) { | ||||||
|                 stream << "PASS"; |                 stream << "PASS"; | ||||||
|             } else if (_testCaseStats.totals.assertions.allOk()) { |             } else if (_testCaseStats.totals.assertions.allOk()) { | ||||||
|                 stream << "XFAIL"; |                 stream << "XFAIL"; | ||||||
|             } else { |             } else { | ||||||
|                 stream << "FAIL"; |                 stream << "FAIL"; | ||||||
|             } |             } | ||||||
|             stream << ' ' << _testCaseStats.testInfo.name << '\n'; |             stream << ' ' << _testCaseStats.testInfo.name << '\n'; | ||||||
|             StreamingReporterBase::testCaseEnded( _testCaseStats ); |             StreamingReporterBase::testCaseEnded( _testCaseStats ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void skipTest( TestCaseInfo const& testInfo ) override { |         void skipTest( TestCaseInfo const& testInfo ) override { | ||||||
|             stream << ":test-result: SKIP " << testInfo.name << '\n'; |             stream << ":test-result: SKIP " << testInfo.name << '\n'; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| #ifdef CATCH_IMPL | #ifdef CATCH_IMPL | ||||||
|     AutomakeReporter::~AutomakeReporter() {} |     AutomakeReporter::~AutomakeReporter() {} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     CATCH_REGISTER_REPORTER( "automake", AutomakeReporter) |     CATCH_REGISTER_REPORTER( "automake", AutomakeReporter) | ||||||
| 
 | 
 | ||||||
| } // end namespace Catch
 | } // end namespace Catch
 | ||||||
| 
 | 
 | ||||||
| #endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
 | #endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
 | ||||||
|  | |||||||
| @ -1,181 +1,181 @@ | |||||||
| /*
 | /*
 | ||||||
|  *  Created by Daniel Garcia on 2018-12-04. |  *  Created by Daniel Garcia on 2018-12-04. | ||||||
|  *  Copyright Social Point SL. All rights reserved. |  *  Copyright Social Point SL. All rights reserved. | ||||||
|  * |  * | ||||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying |  *  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)
 |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||||||
|  */ |  */ | ||||||
| #ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED | #ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED | ||||||
| #define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED | #define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // Don't #include any Catch headers here - we can assume they are already
 | // Don't #include any Catch headers here - we can assume they are already
 | ||||||
| // included before this header.
 | // included before this header.
 | ||||||
| // This is not good practice in general but is necessary in this case so this
 | // This is not good practice in general but is necessary in this case so this
 | ||||||
| // file can be distributed as a single header that works with the main
 | // file can be distributed as a single header that works with the main
 | ||||||
| // Catch single header.
 | // Catch single header.
 | ||||||
| 
 | 
 | ||||||
| #include <map> | #include <map> | ||||||
| 
 | 
 | ||||||
| namespace Catch { | namespace Catch { | ||||||
| 
 | 
 | ||||||
|     struct SonarQubeReporter : CumulativeReporterBase<SonarQubeReporter> { |     struct SonarQubeReporter : CumulativeReporterBase<SonarQubeReporter> { | ||||||
| 
 | 
 | ||||||
|         SonarQubeReporter(ReporterConfig const& config) |         SonarQubeReporter(ReporterConfig const& config) | ||||||
|         : CumulativeReporterBase(config) |         : CumulativeReporterBase(config) | ||||||
|         , xml(config.stream()) { |         , xml(config.stream()) { | ||||||
|             m_reporterPrefs.shouldRedirectStdOut = true; |             m_reporterPrefs.shouldRedirectStdOut = true; | ||||||
|             m_reporterPrefs.shouldReportAllAssertions = true; |             m_reporterPrefs.shouldReportAllAssertions = true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         ~SonarQubeReporter() override; |         ~SonarQubeReporter() override; | ||||||
| 
 | 
 | ||||||
|         static std::string getDescription() { |         static std::string getDescription() { | ||||||
|             return "Reports test results in the Generic Test Data SonarQube XML format"; |             return "Reports test results in the Generic Test Data SonarQube XML format"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         static std::set<Verbosity> getSupportedVerbosities() { |         static std::set<Verbosity> getSupportedVerbosities() { | ||||||
|             return { Verbosity::Normal }; |             return { Verbosity::Normal }; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void noMatchingTestCases(std::string const& /*spec*/) override {} |         void noMatchingTestCases(std::string const& /*spec*/) override {} | ||||||
| 
 | 
 | ||||||
|         void testRunStarting(TestRunInfo const& testRunInfo) override { |         void testRunStarting(TestRunInfo const& testRunInfo) override { | ||||||
|             CumulativeReporterBase::testRunStarting(testRunInfo); |             CumulativeReporterBase::testRunStarting(testRunInfo); | ||||||
|             xml.startElement("testExecutions"); |             xml.startElement("testExecutions"); | ||||||
|             xml.writeAttribute("version", "1"); |             xml.writeAttribute("version", "1"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void testGroupEnded(TestGroupStats const& testGroupStats) override { |         void testGroupEnded(TestGroupStats const& testGroupStats) override { | ||||||
|             CumulativeReporterBase::testGroupEnded(testGroupStats); |             CumulativeReporterBase::testGroupEnded(testGroupStats); | ||||||
|             writeGroup(*m_testGroups.back()); |             writeGroup(*m_testGroups.back()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void testRunEndedCumulative() override { |         void testRunEndedCumulative() override { | ||||||
|             xml.endElement(); |             xml.endElement(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void writeGroup(TestGroupNode const& groupNode) { |         void writeGroup(TestGroupNode const& groupNode) { | ||||||
|             std::map<std::string, TestGroupNode::ChildNodes> testsPerFile; |             std::map<std::string, TestGroupNode::ChildNodes> testsPerFile; | ||||||
|             for(auto const& child : groupNode.children) |             for(auto const& child : groupNode.children) | ||||||
|                 testsPerFile[child->value.testInfo.lineInfo.file].push_back(child); |                 testsPerFile[child->value.testInfo.lineInfo.file].push_back(child); | ||||||
| 
 | 
 | ||||||
|             for(auto const& kv : testsPerFile) |             for(auto const& kv : testsPerFile) | ||||||
|                 writeTestFile(kv.first.c_str(), kv.second); |                 writeTestFile(kv.first.c_str(), kv.second); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void writeTestFile(const char* filename, TestGroupNode::ChildNodes const& testCaseNodes) { |         void writeTestFile(const char* filename, TestGroupNode::ChildNodes const& testCaseNodes) { | ||||||
|             XmlWriter::ScopedElement e = xml.scopedElement("file"); |             XmlWriter::ScopedElement e = xml.scopedElement("file"); | ||||||
|             xml.writeAttribute("path", filename); |             xml.writeAttribute("path", filename); | ||||||
| 
 | 
 | ||||||
|             for(auto const& child : testCaseNodes) |             for(auto const& child : testCaseNodes) | ||||||
|                 writeTestCase(*child); |                 writeTestCase(*child); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void writeTestCase(TestCaseNode const& testCaseNode) { |         void writeTestCase(TestCaseNode const& testCaseNode) { | ||||||
|             // All test cases have exactly one section - which represents the
 |             // All test cases have exactly one section - which represents the
 | ||||||
|             // test case itself. That section may have 0-n nested sections
 |             // test case itself. That section may have 0-n nested sections
 | ||||||
|             assert(testCaseNode.children.size() == 1); |             assert(testCaseNode.children.size() == 1); | ||||||
|             SectionNode const& rootSection = *testCaseNode.children.front(); |             SectionNode const& rootSection = *testCaseNode.children.front(); | ||||||
|             writeSection("", rootSection, testCaseNode.value.testInfo.okToFail()); |             writeSection("", rootSection, testCaseNode.value.testInfo.okToFail()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void writeSection(std::string const& rootName, SectionNode const& sectionNode, bool okToFail) { |         void writeSection(std::string const& rootName, SectionNode const& sectionNode, bool okToFail) { | ||||||
|             std::string name = trim(sectionNode.stats.sectionInfo.name); |             std::string name = trim(sectionNode.stats.sectionInfo.name); | ||||||
|             if(!rootName.empty()) |             if(!rootName.empty()) | ||||||
|                 name = rootName + '/' + name; |                 name = rootName + '/' + name; | ||||||
| 
 | 
 | ||||||
|             if(!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) { |             if(!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) { | ||||||
|                 XmlWriter::ScopedElement e = xml.scopedElement("testCase"); |                 XmlWriter::ScopedElement e = xml.scopedElement("testCase"); | ||||||
|                 xml.writeAttribute("name", name); |                 xml.writeAttribute("name", name); | ||||||
|                 xml.writeAttribute("duration", static_cast<long>(sectionNode.stats.durationInSeconds * 1000)); |                 xml.writeAttribute("duration", static_cast<long>(sectionNode.stats.durationInSeconds * 1000)); | ||||||
| 
 | 
 | ||||||
|                 writeAssertions(sectionNode, okToFail); |                 writeAssertions(sectionNode, okToFail); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             for(auto const& childNode : sectionNode.childSections) |             for(auto const& childNode : sectionNode.childSections) | ||||||
|                 writeSection(name, *childNode, okToFail); |                 writeSection(name, *childNode, okToFail); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void writeAssertions(SectionNode const& sectionNode, bool okToFail) { |         void writeAssertions(SectionNode const& sectionNode, bool okToFail) { | ||||||
|             for(auto const& assertion : sectionNode.assertions) |             for(auto const& assertion : sectionNode.assertions) | ||||||
|                 writeAssertion( assertion, okToFail); |                 writeAssertion( assertion, okToFail); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void writeAssertion(AssertionStats const& stats, bool okToFail) { |         void writeAssertion(AssertionStats const& stats, bool okToFail) { | ||||||
|             AssertionResult const& result = stats.assertionResult; |             AssertionResult const& result = stats.assertionResult; | ||||||
|             if(!result.isOk()) { |             if(!result.isOk()) { | ||||||
|                 std::string elementName; |                 std::string elementName; | ||||||
|                 if(okToFail) { |                 if(okToFail) { | ||||||
|                     elementName = "skipped"; |                     elementName = "skipped"; | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|                     switch(result.getResultType()) { |                     switch(result.getResultType()) { | ||||||
|                         case ResultWas::ThrewException: |                         case ResultWas::ThrewException: | ||||||
|                         case ResultWas::FatalErrorCondition: |                         case ResultWas::FatalErrorCondition: | ||||||
|                             elementName = "error"; |                             elementName = "error"; | ||||||
|                             break; |                             break; | ||||||
|                         case ResultWas::ExplicitFailure: |                         case ResultWas::ExplicitFailure: | ||||||
|                             elementName = "failure"; |                             elementName = "failure"; | ||||||
|                             break; |                             break; | ||||||
|                         case ResultWas::ExpressionFailed: |                         case ResultWas::ExpressionFailed: | ||||||
|                             elementName = "failure"; |                             elementName = "failure"; | ||||||
|                             break; |                             break; | ||||||
|                         case ResultWas::DidntThrowException: |                         case ResultWas::DidntThrowException: | ||||||
|                             elementName = "failure"; |                             elementName = "failure"; | ||||||
|                             break; |                             break; | ||||||
| 
 | 
 | ||||||
|                             // We should never see these here:
 |                             // We should never see these here:
 | ||||||
|                         case ResultWas::Info: |                         case ResultWas::Info: | ||||||
|                         case ResultWas::Warning: |                         case ResultWas::Warning: | ||||||
|                         case ResultWas::Ok: |                         case ResultWas::Ok: | ||||||
|                         case ResultWas::Unknown: |                         case ResultWas::Unknown: | ||||||
|                         case ResultWas::FailureBit: |                         case ResultWas::FailureBit: | ||||||
|                         case ResultWas::Exception: |                         case ResultWas::Exception: | ||||||
|                             elementName = "internalError"; |                             elementName = "internalError"; | ||||||
|                             break; |                             break; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 XmlWriter::ScopedElement e = xml.scopedElement(elementName); |                 XmlWriter::ScopedElement e = xml.scopedElement(elementName); | ||||||
| 
 | 
 | ||||||
|                 ReusableStringStream messageRss; |                 ReusableStringStream messageRss; | ||||||
|                 messageRss << result.getTestMacroName() << "(" << result.getExpression() << ")"; |                 messageRss << result.getTestMacroName() << "(" << result.getExpression() << ")"; | ||||||
|                 xml.writeAttribute("message", messageRss.str()); |                 xml.writeAttribute("message", messageRss.str()); | ||||||
| 
 | 
 | ||||||
|                 ReusableStringStream textRss; |                 ReusableStringStream textRss; | ||||||
|                 if (stats.totals.assertions.total() > 0) { |                 if (stats.totals.assertions.total() > 0) { | ||||||
|                     textRss << "FAILED:\n"; |                     textRss << "FAILED:\n"; | ||||||
|                     if (result.hasExpression()) { |                     if (result.hasExpression()) { | ||||||
|                         textRss << "\t" << result.getExpressionInMacro() << "\n"; |                         textRss << "\t" << result.getExpressionInMacro() << "\n"; | ||||||
|                     } |                     } | ||||||
|                     if (result.hasExpandedExpression()) { |                     if (result.hasExpandedExpression()) { | ||||||
|                         textRss << "with expansion:\n\t" << result.getExpandedExpression() << "\n"; |                         textRss << "with expansion:\n\t" << result.getExpandedExpression() << "\n"; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if(!result.getMessage().empty()) |                 if(!result.getMessage().empty()) | ||||||
|                     textRss << result.getMessage() << "\n"; |                     textRss << result.getMessage() << "\n"; | ||||||
| 
 | 
 | ||||||
|                 for(auto const& msg : stats.infoMessages) |                 for(auto const& msg : stats.infoMessages) | ||||||
|                     if(msg.type == ResultWas::Info) |                     if(msg.type == ResultWas::Info) | ||||||
|                         textRss << msg.message << "\n"; |                         textRss << msg.message << "\n"; | ||||||
| 
 | 
 | ||||||
|                 textRss << "at " << result.getSourceInfo(); |                 textRss << "at " << result.getSourceInfo(); | ||||||
|                 xml.writeText(textRss.str(), XmlFormatting::Newline); |                 xml.writeText(textRss.str(), XmlFormatting::Newline); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         XmlWriter xml; |         XmlWriter xml; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| #ifdef CATCH_IMPL | #ifdef CATCH_IMPL | ||||||
|     SonarQubeReporter::~SonarQubeReporter() {} |     SonarQubeReporter::~SonarQubeReporter() {} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     CATCH_REGISTER_REPORTER( "sonarqube", SonarQubeReporter ) |     CATCH_REGISTER_REPORTER( "sonarqube", SonarQubeReporter ) | ||||||
| 
 | 
 | ||||||
| } // end namespace Catch
 | } // end namespace Catch
 | ||||||
| 
 | 
 | ||||||
| #endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
 | #endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
 | ||||||
| @ -1,254 +1,254 @@ | |||||||
| /*
 | /*
 | ||||||
|  *  Created by Colton Wolkins on 2015-08-15. |  *  Created by Colton Wolkins on 2015-08-15. | ||||||
|  *  Copyright 2015 Martin Moene. All rights reserved. |  *  Copyright 2015 Martin Moene. All rights reserved. | ||||||
|  * |  * | ||||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying |  *  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)
 |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||||||
|  */ |  */ | ||||||
| #ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED | #ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // Don't #include any Catch headers here - we can assume they are already
 | // Don't #include any Catch headers here - we can assume they are already
 | ||||||
| // included before this header.
 | // included before this header.
 | ||||||
| // This is not good practice in general but is necessary in this case so this
 | // This is not good practice in general but is necessary in this case so this
 | ||||||
| // file can be distributed as a single header that works with the main
 | // file can be distributed as a single header that works with the main
 | ||||||
| // Catch single header.
 | // Catch single header.
 | ||||||
| 
 | 
 | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| 
 | 
 | ||||||
| namespace Catch { | namespace Catch { | ||||||
| 
 | 
 | ||||||
|     struct TAPReporter : StreamingReporterBase<TAPReporter> { |     struct TAPReporter : StreamingReporterBase<TAPReporter> { | ||||||
| 
 | 
 | ||||||
|         using StreamingReporterBase::StreamingReporterBase; |         using StreamingReporterBase::StreamingReporterBase; | ||||||
| 
 | 
 | ||||||
|         TAPReporter( ReporterConfig const& config ): |         TAPReporter( ReporterConfig const& config ): | ||||||
|             StreamingReporterBase( config ) { |             StreamingReporterBase( config ) { | ||||||
|             m_reporterPrefs.shouldReportAllAssertions = true; |             m_reporterPrefs.shouldReportAllAssertions = true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         ~TAPReporter() override; |         ~TAPReporter() override; | ||||||
| 
 | 
 | ||||||
|         static std::string getDescription() { |         static std::string getDescription() { | ||||||
|             return "Reports test results in TAP format, suitable for test harnesses"; |             return "Reports test results in TAP format, suitable for test harnesses"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void noMatchingTestCases( std::string const& spec ) override { |         void noMatchingTestCases( std::string const& spec ) override { | ||||||
|             stream << "# No test cases matched '" << spec << "'" << std::endl; |             stream << "# No test cases matched '" << spec << "'" << std::endl; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void assertionStarting( AssertionInfo const& ) override {} |         void assertionStarting( AssertionInfo const& ) override {} | ||||||
| 
 | 
 | ||||||
|         bool assertionEnded( AssertionStats const& _assertionStats ) override { |         bool assertionEnded( AssertionStats const& _assertionStats ) override { | ||||||
|             ++counter; |             ++counter; | ||||||
| 
 | 
 | ||||||
|             stream << "# " << currentTestCaseInfo->name << std::endl; |             stream << "# " << currentTestCaseInfo->name << std::endl; | ||||||
|             AssertionPrinter printer( stream, _assertionStats, counter ); |             AssertionPrinter printer( stream, _assertionStats, counter ); | ||||||
|             printer.print(); |             printer.print(); | ||||||
| 
 | 
 | ||||||
|             stream << std::endl; |             stream << std::endl; | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void testRunEnded( TestRunStats const& _testRunStats ) override { |         void testRunEnded( TestRunStats const& _testRunStats ) override { | ||||||
|             printTotals( _testRunStats.totals ); |             printTotals( _testRunStats.totals ); | ||||||
|             stream << "\n" << std::endl; |             stream << "\n" << std::endl; | ||||||
|             StreamingReporterBase::testRunEnded( _testRunStats ); |             StreamingReporterBase::testRunEnded( _testRunStats ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         std::size_t counter = 0; |         std::size_t counter = 0; | ||||||
|         class AssertionPrinter { |         class AssertionPrinter { | ||||||
|         public: |         public: | ||||||
|             AssertionPrinter& operator= ( AssertionPrinter const& ) = delete; |             AssertionPrinter& operator= ( AssertionPrinter const& ) = delete; | ||||||
|             AssertionPrinter( AssertionPrinter const& ) = delete; |             AssertionPrinter( AssertionPrinter const& ) = delete; | ||||||
|             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, std::size_t _counter ) |             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, std::size_t _counter ) | ||||||
|             : stream( _stream ) |             : stream( _stream ) | ||||||
|             , result( _stats.assertionResult ) |             , result( _stats.assertionResult ) | ||||||
|             , messages( _stats.infoMessages ) |             , messages( _stats.infoMessages ) | ||||||
|             , itMessage( _stats.infoMessages.begin() ) |             , itMessage( _stats.infoMessages.begin() ) | ||||||
|             , printInfoMessages( true ) |             , printInfoMessages( true ) | ||||||
|             , counter(_counter) |             , counter(_counter) | ||||||
|             {} |             {} | ||||||
| 
 | 
 | ||||||
|             void print() { |             void print() { | ||||||
|                 itMessage = messages.begin(); |                 itMessage = messages.begin(); | ||||||
| 
 | 
 | ||||||
|                 switch( result.getResultType() ) { |                 switch( result.getResultType() ) { | ||||||
|                     case ResultWas::Ok: |                     case ResultWas::Ok: | ||||||
|                         printResultType( passedString() ); |                         printResultType( passedString() ); | ||||||
|                         printOriginalExpression(); |                         printOriginalExpression(); | ||||||
|                         printReconstructedExpression(); |                         printReconstructedExpression(); | ||||||
|                         if ( ! result.hasExpression() ) |                         if ( ! result.hasExpression() ) | ||||||
|                             printRemainingMessages( Colour::None ); |                             printRemainingMessages( Colour::None ); | ||||||
|                         else |                         else | ||||||
|                             printRemainingMessages(); |                             printRemainingMessages(); | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::ExpressionFailed: |                     case ResultWas::ExpressionFailed: | ||||||
|                         if (result.isOk()) { |                         if (result.isOk()) { | ||||||
|                             printResultType(passedString()); |                             printResultType(passedString()); | ||||||
|                         } else { |                         } else { | ||||||
|                             printResultType(failedString()); |                             printResultType(failedString()); | ||||||
|                         } |                         } | ||||||
|                         printOriginalExpression(); |                         printOriginalExpression(); | ||||||
|                         printReconstructedExpression(); |                         printReconstructedExpression(); | ||||||
|                         if (result.isOk()) { |                         if (result.isOk()) { | ||||||
|                             printIssue(" # TODO"); |                             printIssue(" # TODO"); | ||||||
|                         } |                         } | ||||||
|                         printRemainingMessages(); |                         printRemainingMessages(); | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::ThrewException: |                     case ResultWas::ThrewException: | ||||||
|                         printResultType( failedString() ); |                         printResultType( failedString() ); | ||||||
|                         printIssue( "unexpected exception with message:" ); |                         printIssue( "unexpected exception with message:" ); | ||||||
|                         printMessage(); |                         printMessage(); | ||||||
|                         printExpressionWas(); |                         printExpressionWas(); | ||||||
|                         printRemainingMessages(); |                         printRemainingMessages(); | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::FatalErrorCondition: |                     case ResultWas::FatalErrorCondition: | ||||||
|                         printResultType( failedString() ); |                         printResultType( failedString() ); | ||||||
|                         printIssue( "fatal error condition with message:" ); |                         printIssue( "fatal error condition with message:" ); | ||||||
|                         printMessage(); |                         printMessage(); | ||||||
|                         printExpressionWas(); |                         printExpressionWas(); | ||||||
|                         printRemainingMessages(); |                         printRemainingMessages(); | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::DidntThrowException: |                     case ResultWas::DidntThrowException: | ||||||
|                         printResultType( failedString() ); |                         printResultType( failedString() ); | ||||||
|                         printIssue( "expected exception, got none" ); |                         printIssue( "expected exception, got none" ); | ||||||
|                         printExpressionWas(); |                         printExpressionWas(); | ||||||
|                         printRemainingMessages(); |                         printRemainingMessages(); | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::Info: |                     case ResultWas::Info: | ||||||
|                         printResultType( "info" ); |                         printResultType( "info" ); | ||||||
|                         printMessage(); |                         printMessage(); | ||||||
|                         printRemainingMessages(); |                         printRemainingMessages(); | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::Warning: |                     case ResultWas::Warning: | ||||||
|                         printResultType( "warning" ); |                         printResultType( "warning" ); | ||||||
|                         printMessage(); |                         printMessage(); | ||||||
|                         printRemainingMessages(); |                         printRemainingMessages(); | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::ExplicitFailure: |                     case ResultWas::ExplicitFailure: | ||||||
|                         printResultType( failedString() ); |                         printResultType( failedString() ); | ||||||
|                         printIssue( "explicitly" ); |                         printIssue( "explicitly" ); | ||||||
|                         printRemainingMessages( Colour::None ); |                         printRemainingMessages( Colour::None ); | ||||||
|                         break; |                         break; | ||||||
|                     // These cases are here to prevent compiler warnings
 |                     // These cases are here to prevent compiler warnings
 | ||||||
|                     case ResultWas::Unknown: |                     case ResultWas::Unknown: | ||||||
|                     case ResultWas::FailureBit: |                     case ResultWas::FailureBit: | ||||||
|                     case ResultWas::Exception: |                     case ResultWas::Exception: | ||||||
|                         printResultType( "** internal error **" ); |                         printResultType( "** internal error **" ); | ||||||
|                         break; |                         break; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         private: |         private: | ||||||
|             static Colour::Code dimColour() { return Colour::FileName; } |             static Colour::Code dimColour() { return Colour::FileName; } | ||||||
| 
 | 
 | ||||||
|             static const char* failedString() { return "not ok"; } |             static const char* failedString() { return "not ok"; } | ||||||
|             static const char* passedString() { return "ok"; } |             static const char* passedString() { return "ok"; } | ||||||
| 
 | 
 | ||||||
|             void printSourceInfo() const { |             void printSourceInfo() const { | ||||||
|                 Colour colourGuard( dimColour() ); |                 Colour colourGuard( dimColour() ); | ||||||
|                 stream << result.getSourceInfo() << ":"; |                 stream << result.getSourceInfo() << ":"; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             void printResultType( std::string const& passOrFail ) const { |             void printResultType( std::string const& passOrFail ) const { | ||||||
|                 if( !passOrFail.empty() ) { |                 if( !passOrFail.empty() ) { | ||||||
|                     stream << passOrFail << ' ' << counter << " -"; |                     stream << passOrFail << ' ' << counter << " -"; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             void printIssue( std::string const& issue ) const { |             void printIssue( std::string const& issue ) const { | ||||||
|                 stream << " " << issue; |                 stream << " " << issue; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             void printExpressionWas() { |             void printExpressionWas() { | ||||||
|                 if( result.hasExpression() ) { |                 if( result.hasExpression() ) { | ||||||
|                     stream << ";"; |                     stream << ";"; | ||||||
|                     { |                     { | ||||||
|                         Colour colour( dimColour() ); |                         Colour colour( dimColour() ); | ||||||
|                         stream << " expression was:"; |                         stream << " expression was:"; | ||||||
|                     } |                     } | ||||||
|                     printOriginalExpression(); |                     printOriginalExpression(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             void printOriginalExpression() const { |             void printOriginalExpression() const { | ||||||
|                 if( result.hasExpression() ) { |                 if( result.hasExpression() ) { | ||||||
|                     stream << " " << result.getExpression(); |                     stream << " " << result.getExpression(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             void printReconstructedExpression() const { |             void printReconstructedExpression() const { | ||||||
|                 if( result.hasExpandedExpression() ) { |                 if( result.hasExpandedExpression() ) { | ||||||
|                     { |                     { | ||||||
|                         Colour colour( dimColour() ); |                         Colour colour( dimColour() ); | ||||||
|                         stream << " for: "; |                         stream << " for: "; | ||||||
|                     } |                     } | ||||||
|                     std::string expr = result.getExpandedExpression(); |                     std::string expr = result.getExpandedExpression(); | ||||||
|                     std::replace( expr.begin(), expr.end(), '\n', ' '); |                     std::replace( expr.begin(), expr.end(), '\n', ' '); | ||||||
|                     stream << expr; |                     stream << expr; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             void printMessage() { |             void printMessage() { | ||||||
|                 if ( itMessage != messages.end() ) { |                 if ( itMessage != messages.end() ) { | ||||||
|                     stream << " '" << itMessage->message << "'"; |                     stream << " '" << itMessage->message << "'"; | ||||||
|                     ++itMessage; |                     ++itMessage; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             void printRemainingMessages( Colour::Code colour = dimColour() ) { |             void printRemainingMessages( Colour::Code colour = dimColour() ) { | ||||||
|                 if (itMessage == messages.end()) { |                 if (itMessage == messages.end()) { | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 const auto itEnd = messages.cend(); |                 const auto itEnd = messages.cend(); | ||||||
|                 const auto N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) ); |                 const auto N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) ); | ||||||
| 
 | 
 | ||||||
|                 { |                 { | ||||||
|                     Colour colourGuard( colour ); |                     Colour colourGuard( colour ); | ||||||
|                     stream << " with " << pluralise( N, "message" ) << ":"; |                     stream << " with " << pluralise( N, "message" ) << ":"; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 while( itMessage != itEnd ) { |                 while( itMessage != itEnd ) { | ||||||
|                     // If this assertion is a warning ignore any INFO messages
 |                     // If this assertion is a warning ignore any INFO messages
 | ||||||
|                     if( printInfoMessages || itMessage->type != ResultWas::Info ) { |                     if( printInfoMessages || itMessage->type != ResultWas::Info ) { | ||||||
|                         stream << " '" << itMessage->message << "'"; |                         stream << " '" << itMessage->message << "'"; | ||||||
|                         if ( ++itMessage != itEnd ) { |                         if ( ++itMessage != itEnd ) { | ||||||
|                             Colour colourGuard( dimColour() ); |                             Colour colourGuard( dimColour() ); | ||||||
|                             stream << " and"; |                             stream << " and"; | ||||||
|                         } |                         } | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|                     ++itMessage; |                     ++itMessage; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         private: |         private: | ||||||
|             std::ostream& stream; |             std::ostream& stream; | ||||||
|             AssertionResult const& result; |             AssertionResult const& result; | ||||||
|             std::vector<MessageInfo> messages; |             std::vector<MessageInfo> messages; | ||||||
|             std::vector<MessageInfo>::const_iterator itMessage; |             std::vector<MessageInfo>::const_iterator itMessage; | ||||||
|             bool printInfoMessages; |             bool printInfoMessages; | ||||||
|             std::size_t counter; |             std::size_t counter; | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         void printTotals( const Totals& totals ) const { |         void printTotals( const Totals& totals ) const { | ||||||
|             stream << "1.." << totals.assertions.total(); |             stream << "1.." << totals.assertions.total(); | ||||||
|             if( totals.testCases.total() == 0 ) { |             if( totals.testCases.total() == 0 ) { | ||||||
|                 stream << " # Skipped: No tests ran."; |                 stream << " # Skipped: No tests ran."; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| #ifdef CATCH_IMPL | #ifdef CATCH_IMPL | ||||||
|     TAPReporter::~TAPReporter() {} |     TAPReporter::~TAPReporter() {} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     CATCH_REGISTER_REPORTER( "tap", TAPReporter ) |     CATCH_REGISTER_REPORTER( "tap", TAPReporter ) | ||||||
| 
 | 
 | ||||||
| } // end namespace Catch
 | } // end namespace Catch
 | ||||||
| 
 | 
 | ||||||
| #endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
 | #endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
 | ||||||
|  | |||||||
| @ -1,219 +1,219 @@ | |||||||
| /*
 | /*
 | ||||||
|  *  Created by Phil Nash on 19th December 2014 |  *  Created by Phil Nash on 19th December 2014 | ||||||
|  *  Copyright 2014 Two Blue Cubes Ltd. All rights reserved. |  *  Copyright 2014 Two Blue Cubes Ltd. All rights reserved. | ||||||
|  * |  * | ||||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying |  *  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)
 |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||||||
|  */ |  */ | ||||||
| #ifndef TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED | #ifndef TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED | ||||||
| 
 | 
 | ||||||
| // Don't #include any Catch headers here - we can assume they are already
 | // Don't #include any Catch headers here - we can assume they are already
 | ||||||
| // included before this header.
 | // included before this header.
 | ||||||
| // This is not good practice in general but is necessary in this case so this
 | // This is not good practice in general but is necessary in this case so this
 | ||||||
| // file can be distributed as a single header that works with the main
 | // file can be distributed as a single header that works with the main
 | ||||||
| // Catch single header.
 | // Catch single header.
 | ||||||
| 
 | 
 | ||||||
| #include <cstring> | #include <cstring> | ||||||
| 
 | 
 | ||||||
| #ifdef __clang__ | #ifdef __clang__ | ||||||
| #   pragma clang diagnostic push | #   pragma clang diagnostic push | ||||||
| #   pragma clang diagnostic ignored "-Wpadded" | #   pragma clang diagnostic ignored "-Wpadded" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| namespace Catch { | namespace Catch { | ||||||
| 
 | 
 | ||||||
|     struct TeamCityReporter : StreamingReporterBase<TeamCityReporter> { |     struct TeamCityReporter : StreamingReporterBase<TeamCityReporter> { | ||||||
|         TeamCityReporter( ReporterConfig const& _config ) |         TeamCityReporter( ReporterConfig const& _config ) | ||||||
|         :   StreamingReporterBase( _config ) |         :   StreamingReporterBase( _config ) | ||||||
|         { |         { | ||||||
|             m_reporterPrefs.shouldRedirectStdOut = true; |             m_reporterPrefs.shouldRedirectStdOut = true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         static std::string escape( std::string const& str ) { |         static std::string escape( std::string const& str ) { | ||||||
|             std::string escaped = str; |             std::string escaped = str; | ||||||
|             replaceInPlace( escaped, "|", "||" ); |             replaceInPlace( escaped, "|", "||" ); | ||||||
|             replaceInPlace( escaped, "'", "|'" ); |             replaceInPlace( escaped, "'", "|'" ); | ||||||
|             replaceInPlace( escaped, "\n", "|n" ); |             replaceInPlace( escaped, "\n", "|n" ); | ||||||
|             replaceInPlace( escaped, "\r", "|r" ); |             replaceInPlace( escaped, "\r", "|r" ); | ||||||
|             replaceInPlace( escaped, "[", "|[" ); |             replaceInPlace( escaped, "[", "|[" ); | ||||||
|             replaceInPlace( escaped, "]", "|]" ); |             replaceInPlace( escaped, "]", "|]" ); | ||||||
|             return escaped; |             return escaped; | ||||||
|         } |         } | ||||||
|         ~TeamCityReporter() override; |         ~TeamCityReporter() override; | ||||||
| 
 | 
 | ||||||
|         static std::string getDescription() { |         static std::string getDescription() { | ||||||
|             return "Reports test results as TeamCity service messages"; |             return "Reports test results as TeamCity service messages"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void skipTest( TestCaseInfo const& /* testInfo */ ) override { |         void skipTest( TestCaseInfo const& /* testInfo */ ) override { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void noMatchingTestCases( std::string const& /* spec */ ) override {} |         void noMatchingTestCases( std::string const& /* spec */ ) override {} | ||||||
| 
 | 
 | ||||||
|         void testGroupStarting( GroupInfo const& groupInfo ) override { |         void testGroupStarting( GroupInfo const& groupInfo ) override { | ||||||
|             StreamingReporterBase::testGroupStarting( groupInfo ); |             StreamingReporterBase::testGroupStarting( groupInfo ); | ||||||
|             stream << "##teamcity[testSuiteStarted name='" |             stream << "##teamcity[testSuiteStarted name='" | ||||||
|                 << escape( groupInfo.name ) << "']\n"; |                 << escape( groupInfo.name ) << "']\n"; | ||||||
|         } |         } | ||||||
|         void testGroupEnded( TestGroupStats const& testGroupStats ) override { |         void testGroupEnded( TestGroupStats const& testGroupStats ) override { | ||||||
|             StreamingReporterBase::testGroupEnded( testGroupStats ); |             StreamingReporterBase::testGroupEnded( testGroupStats ); | ||||||
|             stream << "##teamcity[testSuiteFinished name='" |             stream << "##teamcity[testSuiteFinished name='" | ||||||
|                 << escape( testGroupStats.groupInfo.name ) << "']\n"; |                 << escape( testGroupStats.groupInfo.name ) << "']\n"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         void assertionStarting( AssertionInfo const& ) override {} |         void assertionStarting( AssertionInfo const& ) override {} | ||||||
| 
 | 
 | ||||||
|         bool assertionEnded( AssertionStats const& assertionStats ) override { |         bool assertionEnded( AssertionStats const& assertionStats ) override { | ||||||
|             AssertionResult const& result = assertionStats.assertionResult; |             AssertionResult const& result = assertionStats.assertionResult; | ||||||
|             if( !result.isOk() ) { |             if( !result.isOk() ) { | ||||||
| 
 | 
 | ||||||
|                 ReusableStringStream msg; |                 ReusableStringStream msg; | ||||||
|                 if( !m_headerPrintedForThisSection ) |                 if( !m_headerPrintedForThisSection ) | ||||||
|                     printSectionHeader( msg.get() ); |                     printSectionHeader( msg.get() ); | ||||||
|                 m_headerPrintedForThisSection = true; |                 m_headerPrintedForThisSection = true; | ||||||
| 
 | 
 | ||||||
|                 msg << result.getSourceInfo() << "\n"; |                 msg << result.getSourceInfo() << "\n"; | ||||||
| 
 | 
 | ||||||
|                 switch( result.getResultType() ) { |                 switch( result.getResultType() ) { | ||||||
|                     case ResultWas::ExpressionFailed: |                     case ResultWas::ExpressionFailed: | ||||||
|                         msg << "expression failed"; |                         msg << "expression failed"; | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::ThrewException: |                     case ResultWas::ThrewException: | ||||||
|                         msg << "unexpected exception"; |                         msg << "unexpected exception"; | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::FatalErrorCondition: |                     case ResultWas::FatalErrorCondition: | ||||||
|                         msg << "fatal error condition"; |                         msg << "fatal error condition"; | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::DidntThrowException: |                     case ResultWas::DidntThrowException: | ||||||
|                         msg << "no exception was thrown where one was expected"; |                         msg << "no exception was thrown where one was expected"; | ||||||
|                         break; |                         break; | ||||||
|                     case ResultWas::ExplicitFailure: |                     case ResultWas::ExplicitFailure: | ||||||
|                         msg << "explicit failure"; |                         msg << "explicit failure"; | ||||||
|                         break; |                         break; | ||||||
| 
 | 
 | ||||||
|                     // We shouldn't get here because of the isOk() test
 |                     // We shouldn't get here because of the isOk() test
 | ||||||
|                     case ResultWas::Ok: |                     case ResultWas::Ok: | ||||||
|                     case ResultWas::Info: |                     case ResultWas::Info: | ||||||
|                     case ResultWas::Warning: |                     case ResultWas::Warning: | ||||||
|                         CATCH_ERROR( "Internal error in TeamCity reporter" ); |                         CATCH_ERROR( "Internal error in TeamCity reporter" ); | ||||||
|                     // These cases are here to prevent compiler warnings
 |                     // These cases are here to prevent compiler warnings
 | ||||||
|                     case ResultWas::Unknown: |                     case ResultWas::Unknown: | ||||||
|                     case ResultWas::FailureBit: |                     case ResultWas::FailureBit: | ||||||
|                     case ResultWas::Exception: |                     case ResultWas::Exception: | ||||||
|                         CATCH_ERROR( "Not implemented" ); |                         CATCH_ERROR( "Not implemented" ); | ||||||
|                 } |                 } | ||||||
|                 if( assertionStats.infoMessages.size() == 1 ) |                 if( assertionStats.infoMessages.size() == 1 ) | ||||||
|                     msg << " with message:"; |                     msg << " with message:"; | ||||||
|                 if( assertionStats.infoMessages.size() > 1 ) |                 if( assertionStats.infoMessages.size() > 1 ) | ||||||
|                     msg << " with messages:"; |                     msg << " with messages:"; | ||||||
|                 for( auto const& messageInfo : assertionStats.infoMessages ) |                 for( auto const& messageInfo : assertionStats.infoMessages ) | ||||||
|                     msg << "\n  \"" << messageInfo.message << "\""; |                     msg << "\n  \"" << messageInfo.message << "\""; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|                 if( result.hasExpression() ) { |                 if( result.hasExpression() ) { | ||||||
|                     msg << |                     msg << | ||||||
|                         "\n  " << result.getExpressionInMacro() << "\n" |                         "\n  " << result.getExpressionInMacro() << "\n" | ||||||
|                         "with expansion:\n" << |                         "with expansion:\n" << | ||||||
|                         "  " << result.getExpandedExpression() << "\n"; |                         "  " << result.getExpandedExpression() << "\n"; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if( currentTestCaseInfo->okToFail() ) { |                 if( currentTestCaseInfo->okToFail() ) { | ||||||
|                     msg << "- failure ignore as test marked as 'ok to fail'\n"; |                     msg << "- failure ignore as test marked as 'ok to fail'\n"; | ||||||
|                     stream << "##teamcity[testIgnored" |                     stream << "##teamcity[testIgnored" | ||||||
|                            << " name='" << escape( currentTestCaseInfo->name )<< "'" |                            << " name='" << escape( currentTestCaseInfo->name )<< "'" | ||||||
|                            << " message='" << escape( msg.str() ) << "'" |                            << " message='" << escape( msg.str() ) << "'" | ||||||
|                            << "]\n"; |                            << "]\n"; | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|                     stream << "##teamcity[testFailed" |                     stream << "##teamcity[testFailed" | ||||||
|                            << " name='" << escape( currentTestCaseInfo->name )<< "'" |                            << " name='" << escape( currentTestCaseInfo->name )<< "'" | ||||||
|                            << " message='" << escape( msg.str() ) << "'" |                            << " message='" << escape( msg.str() ) << "'" | ||||||
|                            << "]\n"; |                            << "]\n"; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             stream.flush(); |             stream.flush(); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void sectionStarting( SectionInfo const& sectionInfo ) override { |         void sectionStarting( SectionInfo const& sectionInfo ) override { | ||||||
|             m_headerPrintedForThisSection = false; |             m_headerPrintedForThisSection = false; | ||||||
|             StreamingReporterBase::sectionStarting( sectionInfo ); |             StreamingReporterBase::sectionStarting( sectionInfo ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void testCaseStarting( TestCaseInfo const& testInfo ) override { |         void testCaseStarting( TestCaseInfo const& testInfo ) override { | ||||||
|             m_testTimer.start(); |             m_testTimer.start(); | ||||||
|             StreamingReporterBase::testCaseStarting( testInfo ); |             StreamingReporterBase::testCaseStarting( testInfo ); | ||||||
|             stream << "##teamcity[testStarted name='" |             stream << "##teamcity[testStarted name='" | ||||||
|                 << escape( testInfo.name ) << "']\n"; |                 << escape( testInfo.name ) << "']\n"; | ||||||
|             stream.flush(); |             stream.flush(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void testCaseEnded( TestCaseStats const& testCaseStats ) override { |         void testCaseEnded( TestCaseStats const& testCaseStats ) override { | ||||||
|             StreamingReporterBase::testCaseEnded( testCaseStats ); |             StreamingReporterBase::testCaseEnded( testCaseStats ); | ||||||
|             if( !testCaseStats.stdOut.empty() ) |             if( !testCaseStats.stdOut.empty() ) | ||||||
|                 stream << "##teamcity[testStdOut name='" |                 stream << "##teamcity[testStdOut name='" | ||||||
|                     << escape( testCaseStats.testInfo.name ) |                     << escape( testCaseStats.testInfo.name ) | ||||||
|                     << "' out='" << escape( testCaseStats.stdOut ) << "']\n"; |                     << "' out='" << escape( testCaseStats.stdOut ) << "']\n"; | ||||||
|             if( !testCaseStats.stdErr.empty() ) |             if( !testCaseStats.stdErr.empty() ) | ||||||
|                 stream << "##teamcity[testStdErr name='" |                 stream << "##teamcity[testStdErr name='" | ||||||
|                     << escape( testCaseStats.testInfo.name ) |                     << escape( testCaseStats.testInfo.name ) | ||||||
|                     << "' out='" << escape( testCaseStats.stdErr ) << "']\n"; |                     << "' out='" << escape( testCaseStats.stdErr ) << "']\n"; | ||||||
|             stream << "##teamcity[testFinished name='" |             stream << "##teamcity[testFinished name='" | ||||||
|                     << escape( testCaseStats.testInfo.name ) << "' duration='" |                     << escape( testCaseStats.testInfo.name ) << "' duration='" | ||||||
|                     << m_testTimer.getElapsedMilliseconds() << "']\n"; |                     << m_testTimer.getElapsedMilliseconds() << "']\n"; | ||||||
|             stream.flush(); |             stream.flush(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         void printSectionHeader( std::ostream& os ) { |         void printSectionHeader( std::ostream& os ) { | ||||||
|             assert( !m_sectionStack.empty() ); |             assert( !m_sectionStack.empty() ); | ||||||
| 
 | 
 | ||||||
|             if( m_sectionStack.size() > 1 ) { |             if( m_sectionStack.size() > 1 ) { | ||||||
|                 os << getLineOfChars<'-'>() << "\n"; |                 os << getLineOfChars<'-'>() << "\n"; | ||||||
| 
 | 
 | ||||||
|                 std::vector<SectionInfo>::const_iterator |                 std::vector<SectionInfo>::const_iterator | ||||||
|                 it = m_sectionStack.begin()+1, // Skip first section (test case)
 |                 it = m_sectionStack.begin()+1, // Skip first section (test case)
 | ||||||
|                 itEnd = m_sectionStack.end(); |                 itEnd = m_sectionStack.end(); | ||||||
|                 for( ; it != itEnd; ++it ) |                 for( ; it != itEnd; ++it ) | ||||||
|                     printHeaderString( os, it->name ); |                     printHeaderString( os, it->name ); | ||||||
|                 os << getLineOfChars<'-'>() << "\n"; |                 os << getLineOfChars<'-'>() << "\n"; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; |             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; | ||||||
| 
 | 
 | ||||||
|             os << lineInfo << "\n"; |             os << lineInfo << "\n"; | ||||||
|             os << getLineOfChars<'.'>() << "\n\n"; |             os << getLineOfChars<'.'>() << "\n\n"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // if string has a : in first line will set indent to follow it on
 |         // if string has a : in first line will set indent to follow it on
 | ||||||
|         // subsequent lines
 |         // subsequent lines
 | ||||||
|         static void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) { |         static void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) { | ||||||
|             std::size_t i = _string.find( ": " ); |             std::size_t i = _string.find( ": " ); | ||||||
|             if( i != std::string::npos ) |             if( i != std::string::npos ) | ||||||
|                 i+=2; |                 i+=2; | ||||||
|             else |             else | ||||||
|                 i = 0; |                 i = 0; | ||||||
|             os << Column( _string ) |             os << Column( _string ) | ||||||
|                            .indent( indent+i) |                            .indent( indent+i) | ||||||
|                            .initialIndent( indent ) << "\n"; |                            .initialIndent( indent ) << "\n"; | ||||||
|         } |         } | ||||||
|     private: |     private: | ||||||
|         bool m_headerPrintedForThisSection = false; |         bool m_headerPrintedForThisSection = false; | ||||||
|         Timer m_testTimer; |         Timer m_testTimer; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| #ifdef CATCH_IMPL | #ifdef CATCH_IMPL | ||||||
|     TeamCityReporter::~TeamCityReporter() {} |     TeamCityReporter::~TeamCityReporter() {} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter ) |     CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter ) | ||||||
| 
 | 
 | ||||||
| } // end namespace Catch
 | } // end namespace Catch
 | ||||||
| 
 | 
 | ||||||
| #ifdef __clang__ | #ifdef __clang__ | ||||||
| #   pragma clang diagnostic pop | #   pragma clang diagnostic pop | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
 | #endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
 | ||||||
|  | |||||||
					Loading…
					
					
				
		Reference in new issue