TestRegistrations.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright Catch2 Authors
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // https://www.boost.org/LICENSE_1_0.txt)
  5. // SPDX-License-Identifier: BSL-1.0
  6. #include <catch2/catch_tag_alias_autoregistrar.hpp>
  7. #include <catch2/reporters/catch_reporter_event_listener.hpp>
  8. #include <catch2/internal/catch_enforce.hpp>
  9. #include <catch2/catch_test_case_info.hpp>
  10. #include <catch2/reporters/catch_reporter_registrars.hpp>
  11. // Some example tag aliases
  12. CATCH_REGISTER_TAG_ALIAS("[@nhf]", "[failing]~[.]")
  13. CATCH_REGISTER_TAG_ALIAS("[@tricky]", "[tricky]~[.]")
  14. #ifdef __clang__
  15. # pragma clang diagnostic ignored "-Wpadded"
  16. # pragma clang diagnostic ignored "-Wweak-vtables"
  17. # pragma clang diagnostic ignored "-Wc++98-compat"
  18. #endif
  19. /**
  20. * Event listener that internally counts and validates received events.
  21. *
  22. * Currently only performs validation by counting received events, rather
  23. * than performing full matching. This means that it won't fail if the *Ended
  24. * events are provided in wrong order, as long as they come in the right amount
  25. * and with the right nesting.
  26. */
  27. class ValidatingTestListener : public Catch::EventListenerBase {
  28. struct EventCounter {
  29. int starting = 0;
  30. int ended = 0;
  31. bool hasActiveEvent() const {
  32. return starting > ended;
  33. }
  34. bool hasSingleActiveEvent() const {
  35. return starting - 1 == ended;
  36. }
  37. bool allEventsEnded() const {
  38. return starting == ended;
  39. }
  40. };
  41. public:
  42. static std::string getDescription() {
  43. return "Validates ordering of Catch2's listener events";
  44. }
  45. ValidatingTestListener(Catch::IConfig const* config) :
  46. EventListenerBase(config) {
  47. m_preferences.shouldReportAllAssertions = true;
  48. }
  49. void testRunStarting( Catch::TestRunInfo const& ) override {
  50. CATCH_ENFORCE( m_testRunCounter.starting == 0,
  51. "Test run can only start once" );
  52. ++m_testRunCounter.starting;
  53. }
  54. void testCaseStarting(Catch::TestCaseInfo const&) override {
  55. CATCH_ENFORCE( m_testRunCounter.hasActiveEvent(),
  56. "Test case can only be started if the test run has already started" );
  57. CATCH_ENFORCE( m_testCaseCounter.allEventsEnded(),
  58. "Test case cannot start if there is an unfinished one" );
  59. ++m_testCaseCounter.starting;
  60. // Reset the part tracking for partial test case events
  61. m_lastSeenPartNumber = uint64_t(-1);
  62. }
  63. void testCasePartialStarting(Catch::TestCaseInfo const&,
  64. uint64_t partNumber) override {
  65. CATCH_ENFORCE( m_testCaseCounter.hasSingleActiveEvent(),
  66. "Test case can only be partially started if the test case has fully started already" );
  67. CATCH_ENFORCE( m_lastSeenPartNumber + 1 == partNumber,
  68. "Partial test case started out of order" );
  69. ++m_testCasePartialCounter.starting;
  70. m_lastSeenPartNumber = partNumber;
  71. }
  72. void sectionStarting(Catch::SectionInfo const&) override {
  73. CATCH_ENFORCE( m_testCaseCounter.hasSingleActiveEvent(),
  74. "Section can only start in a test case" );
  75. CATCH_ENFORCE( m_testCasePartialCounter.hasSingleActiveEvent(),
  76. "Section can only start in a test case" );
  77. ++m_sectionCounter.starting;
  78. }
  79. void assertionStarting(Catch::AssertionInfo const&) override {
  80. CATCH_ENFORCE( m_testCaseCounter.hasSingleActiveEvent(),
  81. "Assertion can only start if test case is started" );
  82. ++m_assertionCounter.starting;
  83. }
  84. void assertionEnded(Catch::AssertionStats const&) override {
  85. // todo:
  86. // * Check that assertions are balanced
  87. // * Check that assertions has started
  88. ++m_assertionCounter.ended;
  89. }
  90. void sectionEnded(Catch::SectionStats const&) override {
  91. CATCH_ENFORCE( m_sectionCounter.hasActiveEvent(),
  92. "Section ended without corresponding start" );
  93. // TODO: Check that all assertions ended
  94. ++m_sectionCounter.ended;
  95. }
  96. void testCasePartialEnded(Catch::TestCaseStats const&,
  97. uint64_t partNumber) override {
  98. CATCH_ENFORCE( m_lastSeenPartNumber == partNumber,
  99. "Partial test case ended out of order" );
  100. CATCH_ENFORCE( m_testCasePartialCounter.hasSingleActiveEvent(),
  101. "Partial test case ended without corresponding start" );
  102. CATCH_ENFORCE( m_sectionCounter.allEventsEnded(),
  103. "Partial test case ended with unbalanced sections" );
  104. // TODO: Check that all assertions ended
  105. ++m_testCasePartialCounter.ended;
  106. }
  107. void testCaseEnded(Catch::TestCaseStats const&) override {
  108. CATCH_ENFORCE( m_testCaseCounter.hasSingleActiveEvent(),
  109. "Test case end is not matched with test case start" );
  110. CATCH_ENFORCE( m_testCasePartialCounter.allEventsEnded(),
  111. "A partial test case has not ended" );
  112. CATCH_ENFORCE( m_sectionCounter.allEventsEnded(),
  113. "Test case ended with unbalanced sections" );
  114. // TODO: Check that all assertions ended
  115. ++m_testCaseCounter.ended;
  116. }
  117. void testRunEnded( Catch::TestRunStats const& ) override {
  118. CATCH_ENFORCE( m_testRunCounter.hasSingleActiveEvent(),
  119. "Test run end is not matched with test run start" );
  120. CATCH_ENFORCE( m_testRunCounter.ended == 0,
  121. "Test run can only end once" );
  122. ++m_testRunCounter.ended;
  123. }
  124. ~ValidatingTestListener() override;
  125. private:
  126. EventCounter m_testRunCounter;
  127. EventCounter m_testCaseCounter;
  128. EventCounter m_testCasePartialCounter;
  129. uint64_t m_lastSeenPartNumber = 0;
  130. EventCounter m_sectionCounter;
  131. EventCounter m_assertionCounter;
  132. };
  133. ValidatingTestListener::~ValidatingTestListener() {
  134. // Throwing from noexcept destructor terminates, but we don't mind
  135. // because this is test-only check and we don't need to try and recover
  136. // from assumption violation here.
  137. CATCH_ENFORCE( m_testRunCounter.ended < 2,
  138. "Test run should be started at most once" );
  139. CATCH_ENFORCE( m_testRunCounter.allEventsEnded(),
  140. "The test run has not finished" );
  141. CATCH_ENFORCE( m_testCaseCounter.allEventsEnded(),
  142. "A test case did not finish" );
  143. // TODO: other counters being balanced?
  144. }
  145. CATCH_REGISTER_LISTENER( ValidatingTestListener )