1 /*
2  *  Created by Phil on 28/10/2010.
3  *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
9 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
10 
11 #include <string>
12 #include "catch_result_type.h"
13 
14 namespace Catch {
15 
16     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
17 
18     struct DecomposedExpression
19     {
~DecomposedExpressionDecomposedExpression20         virtual ~DecomposedExpression() {}
isBinaryExpressionDecomposedExpression21         virtual bool isBinaryExpression() const {
22             return false;
23         }
24         virtual void reconstructExpression( std::string& dest ) const = 0;
25 
26         // Only simple binary comparisons can be decomposed.
27         // If more complex check is required then wrap sub-expressions in parentheses.
28         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
29         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
30         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
31         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
32         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
33         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
34         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
35     };
36 
37     struct AssertionInfo
38     {
AssertionInfoAssertionInfo39         AssertionInfo() {}
40         AssertionInfo(  std::string const& _macroName,
41                         SourceLineInfo const& _lineInfo,
42                         std::string const& _capturedExpression,
43                         ResultDisposition::Flags _resultDisposition );
44 
45         std::string macroName;
46         SourceLineInfo lineInfo;
47         std::string capturedExpression;
48         ResultDisposition::Flags resultDisposition;
49     };
50 
51     struct AssertionResultData
52     {
AssertionResultDataAssertionResultData53         AssertionResultData() : decomposedExpression( CATCH_NULL )
54                               , resultType( ResultWas::Unknown )
55                               , negated( false )
56                               , parenthesized( false ) {}
57 
negateAssertionResultData58         void negate( bool parenthesize ) {
59             negated = !negated;
60             parenthesized = parenthesize;
61             if( resultType == ResultWas::Ok )
62                 resultType = ResultWas::ExpressionFailed;
63             else if( resultType == ResultWas::ExpressionFailed )
64                 resultType = ResultWas::Ok;
65         }
66 
reconstructExpressionAssertionResultData67         std::string const& reconstructExpression() const {
68             if( decomposedExpression != CATCH_NULL ) {
69                 decomposedExpression->reconstructExpression( reconstructedExpression );
70                 if( parenthesized ) {
71                     reconstructedExpression.insert( 0, 1, '(' );
72                     reconstructedExpression.append( 1, ')' );
73                 }
74                 if( negated ) {
75                     reconstructedExpression.insert( 0, 1, '!' );
76                 }
77                 decomposedExpression = CATCH_NULL;
78             }
79             return reconstructedExpression;
80         }
81 
82         mutable DecomposedExpression const* decomposedExpression;
83         mutable std::string reconstructedExpression;
84         std::string message;
85         ResultWas::OfType resultType;
86         bool negated;
87         bool parenthesized;
88     };
89 
90     class AssertionResult {
91     public:
92         AssertionResult();
93         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
94         ~AssertionResult();
95 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
96          AssertionResult( AssertionResult const& )              = default;
97          AssertionResult( AssertionResult && )                  = default;
98          AssertionResult& operator = ( AssertionResult const& ) = default;
99          AssertionResult& operator = ( AssertionResult && )     = default;
100 #  endif
101 
102         bool isOk() const;
103         bool succeeded() const;
104         ResultWas::OfType getResultType() const;
105         bool hasExpression() const;
106         bool hasMessage() const;
107         std::string getExpression() const;
108         std::string getExpressionInMacro() const;
109         bool hasExpandedExpression() const;
110         std::string getExpandedExpression() const;
111         std::string getMessage() const;
112         SourceLineInfo getSourceInfo() const;
113         std::string getTestMacroName() const;
114         void discardDecomposedExpression() const;
115         void expandDecomposedExpression() const;
116 
117     protected:
118         AssertionInfo m_info;
119         AssertionResultData m_resultData;
120     };
121 
122 } // end namespace Catch
123 
124 #endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
125