2014-05-28 18:53:01 +01:00
/*
* 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"
2015-07-13 15:03:04 +01:00
#include "catch_wildcard_pattern.hpp"
2014-05-28 18:53:01 +01:00
namespace Catch {
2015-07-13 06:34:41 +01:00
std :: string capturedExpressionWithSecondArgument ( std :: string const & capturedExpression , std :: string const & secondArg ) {
2015-07-15 23:02:25 +01:00
return secondArg . empty () || secondArg == " \"\" "
2015-07-13 06:34:41 +01:00
? capturedExpression
2015-07-15 23:02:25 +01:00
: capturedExpression + ", " + secondArg ;
2015-07-13 06:34:41 +01:00
}
2014-05-28 18:53:01 +01:00
ResultBuilder :: ResultBuilder ( char const * macroName ,
SourceLineInfo const & lineInfo ,
char const * capturedExpression ,
2015-07-13 06:34:41 +01:00
ResultDisposition :: Flags resultDisposition ,
char const * secondArg )
: m_assertionInfo ( macroName , lineInfo , capturedExpressionWithSecondArgument ( capturedExpression , secondArg ), resultDisposition ),
2014-05-29 07:50:19 +01:00
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 ();
}
2014-05-28 18:53:01 +01:00
void ResultBuilder :: useActiveException ( ResultDisposition :: Flags resultDisposition ) {
m_assertionInfo . resultDisposition = resultDisposition ;
2014-05-29 07:50:19 +01:00
m_stream . oss << Catch :: translateActiveException ();
2014-05-28 18:53:01 +01:00
captureResult ( ResultWas :: ThrewException );
}
void ResultBuilder :: captureResult ( ResultWas :: OfType resultType ) {
2014-05-29 07:50:19 +01:00
setResultType ( resultType );
2014-05-28 18:53:01 +01:00
captureExpression ();
}
2015-07-13 06:34:41 +01:00
void ResultBuilder :: captureExpectedException ( std :: string const & expectedMessage ) {
2015-07-15 23:02:25 +01:00
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 ) {
2015-11-04 18:01:28 +00:00
2015-07-13 06:34:41 +01:00
assert ( m_exprComponents . testFalse == false );
AssertionResultData data = m_data ;
data . resultType = ResultWas :: Ok ;
data . reconstructedExpression = m_assertionInfo . capturedExpression ;
2015-11-04 18:01:28 +00:00
2015-07-15 23:02:25 +01:00
std :: string actualMessage = Catch :: translateActiveException ();
if ( ! matcher . match ( actualMessage ) ) {
data . resultType = ResultWas :: ExpressionFailed ;
data . reconstructedExpression = actualMessage ;
2015-07-13 06:34:41 +01:00
}
AssertionResult result ( m_assertionInfo , data );
handleResult ( result );
}
2014-05-28 18:53:01 +01:00
void ResultBuilder :: captureExpression () {
2014-05-29 07:50:19 +01:00
AssertionResult result = build ();
2015-07-13 06:34:41 +01:00
handleResult ( result );
}
void ResultBuilder :: handleResult ( AssertionResult const & result )
{
2014-05-28 18:53:01 +01:00
getResultCapture (). assertionEnded ( result );
2015-11-04 18:01:28 +00:00
2014-05-28 18:53:01 +01:00
if ( ! result . isOk () ) {
if ( getCurrentContext (). getConfig () -> shouldDebugBreak () )
m_shouldDebugBreak = true ;
2015-04-29 13:54:47 +03:00
if ( getCurrentContext (). getRunner () -> aborting () || ( m_assertionInfo . resultDisposition & ResultDisposition :: Normal ) )
2014-05-28 18:53:01 +01:00
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 (); }
2014-05-29 07:50:19 +01:00
AssertionResult ResultBuilder :: build () const
{
assert ( m_data . resultType != ResultWas :: Unknown );
AssertionResultData data = m_data ;
// Flip bool results if testFalse is set
2014-05-29 08:00:20 +01:00
if ( m_exprComponents . testFalse ) {
if ( data . resultType == ResultWas :: Ok )
data . resultType = ResultWas :: ExpressionFailed ;
else if ( data . resultType == ResultWas :: ExpressionFailed )
data . resultType = ResultWas :: Ok ;
}
2014-05-29 07:50:19 +01:00
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 . op + 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}" ;
}
2014-05-28 18:53:01 +01:00
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED