2014-05-28 19:53:01 +02: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_interfaces_config.h"
# include "catch_interfaces_capture.h"
# include "catch_interfaces_registry_hub.h"
2015-07-13 16:03:04 +02:00
# include "catch_wildcard_pattern.hpp"
2014-05-28 19:53:01 +02:00
namespace Catch {
2015-07-13 07:34:41 +02:00
std : : string capturedExpressionWithSecondArgument ( std : : string const & capturedExpression , std : : string const & secondArg ) {
2015-07-16 00:02:25 +02:00
return secondArg . empty ( ) | | secondArg = = " \" \" "
2015-07-13 07:34:41 +02:00
? capturedExpression
2015-07-16 00:02:25 +02:00
: capturedExpression + " , " + secondArg ;
2015-07-13 07:34:41 +02:00
}
2014-05-28 19:53:01 +02:00
ResultBuilder : : ResultBuilder ( char const * macroName ,
SourceLineInfo const & lineInfo ,
char const * capturedExpression ,
2015-07-13 07:34:41 +02:00
ResultDisposition : : Flags resultDisposition ,
char const * secondArg )
2015-11-20 09:31:17 +01:00
: m_runContext ( getCurrentRunContext ( ) ) ,
m_assertionInfo ( macroName , lineInfo , capturedExpressionWithSecondArgument ( capturedExpression , secondArg ) , resultDisposition ) ,
2014-05-29 08:50:19 +02: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 19:53:01 +02:00
void ResultBuilder : : useActiveException ( ResultDisposition : : Flags resultDisposition ) {
m_assertionInfo . resultDisposition = resultDisposition ;
2014-05-29 08:50:19 +02:00
m_stream . oss < < Catch : : translateActiveException ( ) ;
2014-05-28 19:53:01 +02:00
captureResult ( ResultWas : : ThrewException ) ;
}
void ResultBuilder : : captureResult ( ResultWas : : OfType resultType ) {
2014-05-29 08:50:19 +02:00
setResultType ( resultType ) ;
2014-05-28 19:53:01 +02:00
captureExpression ( ) ;
}
2015-07-13 07:34:41 +02:00
void ResultBuilder : : captureExpectedException ( std : : string const & expectedMessage ) {
2015-07-16 00:02:25 +02: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 19:01:28 +01:00
2015-07-13 07:34:41 +02:00
assert ( m_exprComponents . testFalse = = false ) ;
AssertionResultData data = m_data ;
data . resultType = ResultWas : : Ok ;
data . reconstructedExpression = m_assertionInfo . capturedExpression ;
2015-11-04 19:01:28 +01:00
2015-07-16 00:02:25 +02:00
std : : string actualMessage = Catch : : translateActiveException ( ) ;
if ( ! matcher . match ( actualMessage ) ) {
data . resultType = ResultWas : : ExpressionFailed ;
data . reconstructedExpression = actualMessage ;
2015-07-13 07:34:41 +02:00
}
AssertionResult result ( m_assertionInfo , data ) ;
handleResult ( result ) ;
}
2014-05-28 19:53:01 +02:00
void ResultBuilder : : captureExpression ( ) {
2014-05-29 08:50:19 +02:00
AssertionResult result = build ( ) ;
2015-07-13 07:34:41 +02:00
handleResult ( result ) ;
}
void ResultBuilder : : handleResult ( AssertionResult const & result )
{
2015-11-20 09:31:17 +01:00
m_runContext . assertionEnded ( result ) ;
2015-11-04 19:01:28 +01:00
2014-05-28 19:53:01 +02:00
if ( ! result . isOk ( ) ) {
2015-11-20 09:31:17 +01:00
if ( m_runContext . config ( ) . shouldDebugBreak ( ) )
2014-05-28 19:53:01 +02:00
m_shouldDebugBreak = true ;
2015-11-20 09:31:17 +01:00
if ( m_runContext . isAborting ( ) | | ( m_assertionInfo . resultDisposition & ResultDisposition : : Normal ) )
2014-05-28 19:53:01 +02:00
m_shouldThrow = true ;
}
}
void ResultBuilder : : react ( ) {
if ( m_shouldThrow )
throw Catch : : TestFailureException ( ) ;
}
bool ResultBuilder : : shouldDebugBreak ( ) const { return m_shouldDebugBreak ; }
2015-11-20 09:31:17 +01:00
bool ResultBuilder : : allowThrows ( ) const { return m_runContext . config ( ) . allowThrows ( ) ; }
2014-05-28 19:53:01 +02:00
2014-05-29 08:50:19 +02: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 09:00:20 +02: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 08:50:19 +02: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 19:53:01 +02:00
} // end namespace Catch
# endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED