| /* |
| * Created by Phil on 9/8/2017 |
| * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. |
| * |
| * Distributed under the Boost Software License, Version 1.0. (See accompanying |
| * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| */ |
| #ifndef TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED |
| #define TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED |
| |
| #include "catch_capture.hpp" |
| #include "catch_matchers.h" |
| #include "catch_matchers_floating.h" |
| #include "catch_matchers_generic.hpp" |
| #include "catch_matchers_string.h" |
| #include "catch_matchers_vector.h" |
| #include "catch_stringref.h" |
| |
| namespace Catch { |
| |
| template<typename ArgT, typename MatcherT> |
| class MatchExpr : public ITransientExpression { |
| ArgT const& m_arg; |
| MatcherT m_matcher; |
| StringRef m_matcherString; |
| public: |
| MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) |
| : ITransientExpression{ true, matcher.match( arg ) }, |
| m_arg( arg ), |
| m_matcher( matcher ), |
| m_matcherString( matcherString ) |
| {} |
| |
| void streamReconstructedExpression( std::ostream &os ) const override { |
| auto matcherAsString = m_matcher.toString(); |
| os << Catch::Detail::stringify( m_arg ) << ' '; |
| if( matcherAsString == Detail::unprintableString ) |
| os << m_matcherString; |
| else |
| os << matcherAsString; |
| } |
| }; |
| |
| using StringMatcher = Matchers::Impl::MatcherBase<std::string>; |
| |
| void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ); |
| |
| template<typename ArgT, typename MatcherT> |
| auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> { |
| return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString ); |
| } |
| |
| } // namespace Catch |
| |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ |
| do { \ |
| Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ |
| INTERNAL_CATCH_TRY { \ |
| catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \ |
| } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ |
| INTERNAL_CATCH_REACT( catchAssertionHandler ) \ |
| } while( false ) |
| |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ |
| do { \ |
| Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ |
| if( catchAssertionHandler.allowThrows() ) \ |
| try { \ |
| static_cast<void>(__VA_ARGS__ ); \ |
| catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ |
| } \ |
| catch( exceptionType const& ex ) { \ |
| catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \ |
| } \ |
| catch( ... ) { \ |
| catchAssertionHandler.handleUnexpectedInflightException(); \ |
| } \ |
| else \ |
| catchAssertionHandler.handleThrowingCallSkipped(); \ |
| INTERNAL_CATCH_REACT( catchAssertionHandler ) \ |
| } while( false ) |
| |
| #endif // TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED |