1 /*
2  *  Created by Phil on 28/5/2014.
3  *  Copyright 2014 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_RESULT_BUILDER_H_INCLUDED
9 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
10 
11 #include "catch_result_type.h"
12 #include "catch_assertionresult.h"
13 #include "catch_common.h"
14 #include "catch_matchers.hpp"
15 
16 namespace Catch {
17 
18     struct TestFailureException{};
19 
20     template<typename T> class ExpressionLhs;
21 
22     struct CopyableStream {
CopyableStreamCopyableStream23         CopyableStream() {}
CopyableStreamCopyableStream24         CopyableStream( CopyableStream const& other ) {
25             oss << other.oss.str();
26         }
27         CopyableStream& operator=( CopyableStream const& other ) {
28             oss.str(std::string());
29             oss << other.oss.str();
30             return *this;
31         }
32         std::ostringstream oss;
33     };
34 
35     class ResultBuilder : public DecomposedExpression {
36     public:
37         ResultBuilder(  char const* macroName,
38                         SourceLineInfo const& lineInfo,
39                         char const* capturedExpression,
40                         ResultDisposition::Flags resultDisposition,
41                         char const* secondArg = "" );
42         ~ResultBuilder();
43 
44         template<typename T>
45         ExpressionLhs<T const&> operator <= ( T const& operand );
46         ExpressionLhs<bool> operator <= ( bool value );
47 
48         template<typename T>
49         ResultBuilder& operator << ( T const& value ) {
50             stream().oss << value;
51             return *this;
52         }
53 
54         ResultBuilder& setResultType( ResultWas::OfType result );
55         ResultBuilder& setResultType( bool result );
56 
57         void endExpression( DecomposedExpression const& expr );
58 
59         virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
60 
61         AssertionResult build() const;
62         AssertionResult build( DecomposedExpression const& expr ) const;
63 
64         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
65         void captureResult( ResultWas::OfType resultType );
66         void captureExpression();
67         void captureExpectedException( std::string const& expectedMessage );
68         void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
69         void handleResult( AssertionResult const& result );
70         void react();
71         bool shouldDebugBreak() const;
72         bool allowThrows() const;
73 
74         template<typename ArgT, typename MatcherT>
75         void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
76 
77         void setExceptionGuard();
78         void unsetExceptionGuard();
79 
80     private:
81         AssertionInfo m_assertionInfo;
82         AssertionResultData m_data;
83 
stream()84         CopyableStream &stream()
85         {
86             if(!m_usedStream)
87             {
88                 m_usedStream = true;
89                 m_stream().oss.str("");
90             }
91             return m_stream();
92         }
93 
m_stream()94         static CopyableStream &m_stream()
95         {
96             static CopyableStream s;
97             return s;
98         }
99 
100         bool m_shouldDebugBreak;
101         bool m_shouldThrow;
102         bool m_guardException;
103         bool m_usedStream;
104     };
105 
106 } // namespace Catch
107 
108 // Include after due to circular dependency:
109 #include "catch_expression_lhs.hpp"
110 
111 namespace Catch {
112 
113     template<typename T>
114     ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
115         return ExpressionLhs<T const&>( *this, operand );
116     }
117 
118     inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
119         return ExpressionLhs<bool>( *this, value );
120     }
121 
122     template<typename ArgT, typename MatcherT>
captureMatch(ArgT const & arg,MatcherT const & matcher,char const * matcherString)123     void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
124                                              char const* matcherString ) {
125         MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString );
126         setResultType( matcher.match( arg ) );
127         endExpression( expr );
128     }
129 
130 
131 } // namespace Catch
132 
133 #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
134