| /* |
| * Created by Phil on 28/5/2014. |
| * Copyright 2014 Two Blue Cubes Ltd. All rights reserved. |
| * |
| * 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) |
| */ |
| #ifndef TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED |
| #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED |
| |
| #include "catch_result_builder.h" |
| #include "catch_context.h" |
| #include "catch_interfaces_config.h" |
| #include "catch_interfaces_runner.h" |
| #include "catch_interfaces_capture.h" |
| #include "catch_interfaces_registry_hub.h" |
| #include "catch_wildcard_pattern.hpp" |
| |
| namespace Catch { |
| |
| std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) { |
| return secondArg.empty() || secondArg == "\"\"" |
| ? capturedExpression |
| : capturedExpression + ", " + secondArg; |
| } |
| ResultBuilder::ResultBuilder( char const* macroName, |
| SourceLineInfo const& lineInfo, |
| char const* capturedExpression, |
| ResultDisposition::Flags resultDisposition, |
| char const* secondArg ) |
| : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ), |
| m_shouldDebugBreak( false ), |
| m_shouldThrow( false ) |
| {} |
| |
| ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { |
| m_data.resultType = result; |
| return *this; |
| } |
| ResultBuilder& ResultBuilder::setResultType( bool result ) { |
| m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; |
| return *this; |
| } |
| ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) { |
| m_exprComponents.lhs = lhs; |
| return *this; |
| } |
| ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) { |
| m_exprComponents.rhs = rhs; |
| return *this; |
| } |
| ResultBuilder& ResultBuilder::setOp( std::string const& op ) { |
| m_exprComponents.op = op; |
| return *this; |
| } |
| |
| void ResultBuilder::endExpression() { |
| m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition ); |
| captureExpression(); |
| } |
| |
| void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { |
| m_assertionInfo.resultDisposition = resultDisposition; |
| m_stream.oss << Catch::translateActiveException(); |
| captureResult( ResultWas::ThrewException ); |
| } |
| |
| void ResultBuilder::captureResult( ResultWas::OfType resultType ) { |
| setResultType( resultType ); |
| captureExpression(); |
| } |
| void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { |
| if( expectedMessage.empty() ) |
| captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() ); |
| else |
| captureExpectedException( Matchers::Equals( expectedMessage ) ); |
| } |
| |
| void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) { |
| |
| assert( m_exprComponents.testFalse == false ); |
| AssertionResultData data = m_data; |
| data.resultType = ResultWas::Ok; |
| data.reconstructedExpression = m_assertionInfo.capturedExpression; |
| |
| std::string actualMessage = Catch::translateActiveException(); |
| if( !matcher.match( actualMessage ) ) { |
| data.resultType = ResultWas::ExpressionFailed; |
| data.reconstructedExpression = actualMessage; |
| } |
| AssertionResult result( m_assertionInfo, data ); |
| handleResult( result ); |
| } |
| |
| void ResultBuilder::captureExpression() { |
| AssertionResult result = build(); |
| handleResult( result ); |
| } |
| void ResultBuilder::handleResult( AssertionResult const& result ) |
| { |
| getResultCapture().assertionEnded( result ); |
| |
| if( !result.isOk() ) { |
| if( getCurrentContext().getConfig()->shouldDebugBreak() ) |
| m_shouldDebugBreak = true; |
| if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) |
| m_shouldThrow = true; |
| } |
| } |
| void ResultBuilder::react() { |
| if( m_shouldThrow ) |
| throw Catch::TestFailureException(); |
| } |
| |
| bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } |
| bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } |
| |
| AssertionResult ResultBuilder::build() const |
| { |
| assert( m_data.resultType != ResultWas::Unknown ); |
| |
| AssertionResultData data = m_data; |
| |
| // Flip bool results if testFalse is set |
| if( m_exprComponents.testFalse ) { |
| if( data.resultType == ResultWas::Ok ) |
| data.resultType = ResultWas::ExpressionFailed; |
| else if( data.resultType == ResultWas::ExpressionFailed ) |
| data.resultType = ResultWas::Ok; |
| } |
| |
| data.message = m_stream.oss.str(); |
| data.reconstructedExpression = reconstructExpression(); |
| if( m_exprComponents.testFalse ) { |
| if( m_exprComponents.op == "" ) |
| data.reconstructedExpression = "!" + data.reconstructedExpression; |
| else |
| data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; |
| } |
| return AssertionResult( m_assertionInfo, data ); |
| } |
| std::string ResultBuilder::reconstructExpression() const { |
| if( m_exprComponents.op == "" ) |
| return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.lhs; |
| else if( m_exprComponents.op == "matches" ) |
| return m_exprComponents.lhs + " " + m_exprComponents.rhs; |
| else if( m_exprComponents.op != "!" ) { |
| if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && |
| m_exprComponents.lhs.find("\n") == std::string::npos && |
| m_exprComponents.rhs.find("\n") == std::string::npos ) |
| return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; |
| else |
| return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; |
| } |
| else |
| return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}"; |
| } |
| |
| } // end namespace Catch |
| |
| #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED |