catch_capture_matchers.h 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. #include "catch_capture.hpp"
  11. #include "catch_matchers.h"
  12. #include "catch_matchers_exception.hpp"
  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. namespace Catch {
  19. template<typename ArgT, typename MatcherT>
  20. class MatchExpr : public ITransientExpression {
  21. ArgT const& m_arg;
  22. MatcherT m_matcher;
  23. StringRef m_matcherString;
  24. public:
  25. MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
  26. : ITransientExpression{ true, matcher.match( arg ) },
  27. m_arg( arg ),
  28. m_matcher( matcher ),
  29. m_matcherString( matcherString )
  30. {}
  31. void streamReconstructedExpression( std::ostream &os ) const override {
  32. auto matcherAsString = m_matcher.toString();
  33. os << Catch::Detail::stringify( m_arg ) << ' ';
  34. if( matcherAsString == Detail::unprintableString )
  35. os << m_matcherString;
  36. else
  37. os << matcherAsString;
  38. }
  39. };
  40. using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  41. void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
  42. template<typename ArgT, typename MatcherT>
  43. auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
  44. return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
  45. }
  46. } // namespace Catch
  47. ///////////////////////////////////////////////////////////////////////////////
  48. #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
  49. do { \
  50. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  51. INTERNAL_CATCH_TRY { \
  52. catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
  53. } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  54. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  55. } while( false )
  56. ///////////////////////////////////////////////////////////////////////////////
  57. #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
  58. do { \
  59. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  60. if( catchAssertionHandler.allowThrows() ) \
  61. try { \
  62. static_cast<void>(__VA_ARGS__ ); \
  63. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  64. } \
  65. catch( exceptionType const& ex ) { \
  66. catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
  67. } \
  68. catch( ... ) { \
  69. catchAssertionHandler.handleUnexpectedInflightException(); \
  70. } \
  71. else \
  72. catchAssertionHandler.handleThrowingCallSkipped(); \
  73. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  74. } while( false )
  75. #endif // TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED