Home | History | Annotate | Download | only in internal
      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:
     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 
     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