File indexing completed on 2025-01-18 09:54:06
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_MATCHERS_IMPL_HPP_INCLUDED
0009 #define CATCH_MATCHERS_IMPL_HPP_INCLUDED
0010
0011 #include <catch2/internal/catch_assertion_handler.hpp>
0012 #include <catch2/internal/catch_source_line_info.hpp>
0013 #include <catch2/internal/catch_decomposer.hpp>
0014 #include <catch2/internal/catch_preprocessor_internal_stringify.hpp>
0015 #include <catch2/internal/catch_move_and_forward.hpp>
0016
0017 #include <string>
0018
0019 namespace Catch {
0020
0021 template<typename ArgT, typename MatcherT>
0022 class MatchExpr : public ITransientExpression {
0023 ArgT && m_arg;
0024 MatcherT const& m_matcher;
0025 public:
0026 MatchExpr( ArgT && arg, MatcherT const& matcher )
0027 : ITransientExpression{ true, matcher.match( arg ) },
0028 m_arg( CATCH_FORWARD(arg) ),
0029 m_matcher( matcher )
0030 {}
0031
0032 void streamReconstructedExpression( std::ostream& os ) const override {
0033 os << Catch::Detail::stringify( m_arg )
0034 << ' '
0035 << m_matcher.toString();
0036 }
0037 };
0038
0039 namespace Matchers {
0040 template <typename ArgT>
0041 class MatcherBase;
0042 }
0043
0044 using StringMatcher = Matchers::MatcherBase<std::string>;
0045
0046 void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher );
0047
0048 template<typename ArgT, typename MatcherT>
0049 auto makeMatchExpr( ArgT && arg, MatcherT const& matcher ) -> MatchExpr<ArgT, MatcherT> {
0050 return MatchExpr<ArgT, MatcherT>( CATCH_FORWARD(arg), matcher );
0051 }
0052
0053 }
0054
0055
0056
0057 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
0058 do { \
0059 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
0060 INTERNAL_CATCH_TRY { \
0061 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher ) ); \
0062 } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
0063 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
0064 } while( false )
0065
0066
0067
0068 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
0069 do { \
0070 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
0071 if( catchAssertionHandler.allowThrows() ) \
0072 try { \
0073 static_cast<void>(__VA_ARGS__ ); \
0074 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
0075 } \
0076 catch( exceptionType const& ex ) { \
0077 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher ) ); \
0078 } \
0079 catch( ... ) { \
0080 catchAssertionHandler.handleUnexpectedInflightException(); \
0081 } \
0082 else \
0083 catchAssertionHandler.handleThrowingCallSkipped(); \
0084 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
0085 } while( false )
0086
0087
0088 #endif