• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Created by Phil on 9/8/2017
3  *  Copyright 2017 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_CAPTURE_MATCHERS_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED
10 
11 #include "catch_capture.hpp"
12 #include "catch_matchers.h"
13 #include "catch_matchers_floating.h"
14 #include "catch_matchers_generic.hpp"
15 #include "catch_matchers_string.h"
16 #include "catch_matchers_vector.h"
17 #include "catch_stringref.h"
18 
19 namespace Catch {
20 
21     template<typename ArgT, typename MatcherT>
22     class MatchExpr : public ITransientExpression {
23         ArgT const& m_arg;
24         MatcherT m_matcher;
25         StringRef m_matcherString;
26     public:
MatchExpr(ArgT const & arg,MatcherT const & matcher,StringRef const & matcherString)27         MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
28         :   ITransientExpression{ true, matcher.match( arg ) },
29             m_arg( arg ),
30             m_matcher( matcher ),
31             m_matcherString( matcherString )
32         {}
33 
streamReconstructedExpression(std::ostream & os)34         void streamReconstructedExpression( std::ostream &os ) const override {
35             auto matcherAsString = m_matcher.toString();
36             os << Catch::Detail::stringify( m_arg ) << ' ';
37             if( matcherAsString == Detail::unprintableString )
38                 os << m_matcherString;
39             else
40                 os << matcherAsString;
41         }
42     };
43 
44     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
45 
46     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
47 
48     template<typename ArgT, typename MatcherT>
49     auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
50         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
51     }
52 
53 } // namespace Catch
54 
55 
56 ///////////////////////////////////////////////////////////////////////////////
57 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
58     do { \
59         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
60         INTERNAL_CATCH_TRY { \
61             catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
62         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
63         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
64     } while( false )
65 
66 
67 ///////////////////////////////////////////////////////////////////////////////
68 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
69     do { \
70         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
71         if( catchAssertionHandler.allowThrows() ) \
72             try { \
73                 static_cast<void>(__VA_ARGS__ ); \
74                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
75             } \
76             catch( exceptionType const& ex ) { \
77                 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
78             } \
79             catch( ... ) { \
80                 catchAssertionHandler.handleUnexpectedInflightException(); \
81             } \
82         else \
83             catchAssertionHandler.handleThrowingCallSkipped(); \
84         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
85     } while( false )
86 
87 #endif // TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED
88