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     private:
37         DecomposedExpression& operator = (DecomposedExpression const&);
38     };
39 
40     struct AssertionInfo
41     {
42         AssertionInfo();
43         AssertionInfo(  char const * _macroName,
44                         SourceLineInfo const& _lineInfo,
45                         char const * _capturedExpression,
46                         ResultDisposition::Flags _resultDisposition,
47                         char const * _secondArg = "");
48 
49         char const * macroName;
50         SourceLineInfo lineInfo;
51         char const * capturedExpression;
52         ResultDisposition::Flags resultDisposition;
53         char const * secondArg;
54     };
55 
56     struct AssertionResultData
57     {
AssertionResultDataAssertionResultData58         AssertionResultData() : decomposedExpression( CATCH_NULL )
59                               , resultType( ResultWas::Unknown )
60                               , negated( false )
61                               , parenthesized( false ) {}
62 
negateAssertionResultData63         void negate( bool parenthesize ) {
64             negated = !negated;
65             parenthesized = parenthesize;
66             if( resultType == ResultWas::Ok )
67                 resultType = ResultWas::ExpressionFailed;
68             else if( resultType == ResultWas::ExpressionFailed )
69                 resultType = ResultWas::Ok;
70         }
71 
reconstructExpressionAssertionResultData72         std::string const& reconstructExpression() const {
73             if( decomposedExpression != CATCH_NULL ) {
74                 decomposedExpression->reconstructExpression( reconstructedExpression );
75                 if( parenthesized ) {
76                     reconstructedExpression.insert( 0, 1, '(' );
77                     reconstructedExpression.append( 1, ')' );
78                 }
79                 if( negated ) {
80                     reconstructedExpression.insert( 0, 1, '!' );
81                 }
82                 decomposedExpression = CATCH_NULL;
83             }
84             return reconstructedExpression;
85         }
86 
87         mutable DecomposedExpression const* decomposedExpression;
88         mutable std::string reconstructedExpression;
89         std::string message;
90         ResultWas::OfType resultType;
91         bool negated;
92         bool parenthesized;
93     };
94 
95     class AssertionResult {
96     public:
97         AssertionResult();
98         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
99         ~AssertionResult();
100 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
101          AssertionResult( AssertionResult const& )              = default;
102          AssertionResult( AssertionResult && )                  = default;
103          AssertionResult& operator = ( AssertionResult const& ) = default;
104          AssertionResult& operator = ( AssertionResult && )     = default;
105 #  endif
106 
107         bool isOk() const;
108         bool succeeded() const;
109         ResultWas::OfType getResultType() const;
110         bool hasExpression() const;
111         bool hasMessage() const;
112         std::string getExpression() const;
113         std::string getExpressionInMacro() const;
114         bool hasExpandedExpression() const;
115         std::string getExpandedExpression() const;
116         std::string getMessage() const;
117         SourceLineInfo getSourceInfo() const;
118         std::string getTestMacroName() const;
119         void discardDecomposedExpression() const;
120         void expandDecomposedExpression() const;
121 
122     protected:
123         AssertionInfo m_info;
124         AssertionResultData m_resultData;
125     };
126 
127 } // end namespace Catch
128 
129 #endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
130