210-Evt-EventListeners.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. // 210-Evt-EventListeners.cpp
  2. // Contents:
  3. // 1. Printing of listener data
  4. // 2. My listener and registration
  5. // 3. Test cases
  6. #include <catch2/catch_test_macros.hpp>
  7. #include <catch2/reporters/catch_reporter_event_listener.hpp>
  8. #include <catch2/reporters/catch_reporter_registrars.hpp>
  9. #include <catch2/catch_test_case_info.hpp>
  10. #include <iostream>
  11. // -----------------------------------------------------------------------
  12. // 1. Printing of listener data:
  13. //
  14. namespace {
  15. std::string ws(int const level) {
  16. return std::string( 2 * level, ' ' );
  17. }
  18. std::ostream& operator<<(std::ostream& out, Catch::Tag t) {
  19. return out << "original: " << t.original;
  20. }
  21. template< typename T >
  22. std::ostream& operator<<( std::ostream& os, std::vector<T> const& v ) {
  23. os << "{ ";
  24. for ( const auto& x : v )
  25. os << x << ", ";
  26. return os << "}";
  27. }
  28. // struct SourceLineInfo {
  29. // char const* file;
  30. // std::size_t line;
  31. // };
  32. void print( std::ostream& os, int const level, std::string const& title, Catch::SourceLineInfo const& info ) {
  33. os << ws(level ) << title << ":\n"
  34. << ws(level+1) << "- file: " << info.file << "\n"
  35. << ws(level+1) << "- line: " << info.line << "\n";
  36. }
  37. //struct MessageInfo {
  38. // std::string macroName;
  39. // std::string message;
  40. // SourceLineInfo lineInfo;
  41. // ResultWas::OfType type;
  42. // unsigned int sequence;
  43. //};
  44. void print( std::ostream& os, int const level, Catch::MessageInfo const& info ) {
  45. os << ws(level+1) << "- macroName: '" << info.macroName << "'\n"
  46. << ws(level+1) << "- message '" << info.message << "'\n";
  47. print( os,level+1 , "- lineInfo", info.lineInfo );
  48. os << ws(level+1) << "- sequence " << info.sequence << "\n";
  49. }
  50. void print( std::ostream& os, int const level, std::string const& title, std::vector<Catch::MessageInfo> const& v ) {
  51. os << ws(level ) << title << ":\n";
  52. for ( const auto& x : v )
  53. {
  54. os << ws(level+1) << "{\n";
  55. print( os, level+2, x );
  56. os << ws(level+1) << "}\n";
  57. }
  58. // os << ws(level+1) << "\n";
  59. }
  60. // struct TestRunInfo {
  61. // std::string name;
  62. // };
  63. void print( std::ostream& os, int const level, std::string const& title, Catch::TestRunInfo const& info ) {
  64. os << ws(level ) << title << ":\n"
  65. << ws(level+1) << "- name: " << info.name << "\n";
  66. }
  67. // struct Counts {
  68. // std::size_t total() const;
  69. // bool allPassed() const;
  70. // bool allOk() const;
  71. //
  72. // std::size_t passed = 0;
  73. // std::size_t failed = 0;
  74. // std::size_t failedButOk = 0;
  75. // };
  76. void print( std::ostream& os, int const level, std::string const& title, Catch::Counts const& info ) {
  77. os << ws(level ) << title << ":\n"
  78. << ws(level+1) << "- total(): " << info.total() << "\n"
  79. << ws(level+1) << "- allPassed(): " << info.allPassed() << "\n"
  80. << ws(level+1) << "- allOk(): " << info.allOk() << "\n"
  81. << ws(level+1) << "- passed: " << info.passed << "\n"
  82. << ws(level+1) << "- failed: " << info.failed << "\n"
  83. << ws(level+1) << "- failedButOk: " << info.failedButOk << "\n";
  84. }
  85. // struct Totals {
  86. // Counts assertions;
  87. // Counts testCases;
  88. // };
  89. void print( std::ostream& os, int const level, std::string const& title, Catch::Totals const& info ) {
  90. os << ws(level) << title << ":\n";
  91. print( os, level+1, "- assertions", info.assertions );
  92. print( os, level+1, "- testCases" , info.testCases );
  93. }
  94. // struct TestRunStats {
  95. // TestRunInfo runInfo;
  96. // Totals totals;
  97. // bool aborting;
  98. // };
  99. void print( std::ostream& os, int const level, std::string const& title, Catch::TestRunStats const& info ) {
  100. os << ws(level) << title << ":\n";
  101. print( os, level+1 , "- runInfo", info.runInfo );
  102. print( os, level+1 , "- totals" , info.totals );
  103. os << ws(level+1) << "- aborting: " << info.aborting << "\n";
  104. }
  105. // struct Tag {
  106. // StringRef original, lowerCased;
  107. // };
  108. //
  109. //
  110. // enum class TestCaseProperties : uint8_t {
  111. // None = 0,
  112. // IsHidden = 1 << 1,
  113. // ShouldFail = 1 << 2,
  114. // MayFail = 1 << 3,
  115. // Throws = 1 << 4,
  116. // NonPortable = 1 << 5,
  117. // Benchmark = 1 << 6
  118. // };
  119. //
  120. //
  121. // struct TestCaseInfo : NonCopyable {
  122. //
  123. // bool isHidden() const;
  124. // bool throws() const;
  125. // bool okToFail() const;
  126. // bool expectedToFail() const;
  127. //
  128. //
  129. // std::string name;
  130. // std::string className;
  131. // std::vector<Tag> tags;
  132. // SourceLineInfo lineInfo;
  133. // TestCaseProperties properties = TestCaseProperties::None;
  134. // };
  135. void print( std::ostream& os, int const level, std::string const& title, Catch::TestCaseInfo const& info ) {
  136. os << ws(level ) << title << ":\n"
  137. << ws(level+1) << "- isHidden(): " << info.isHidden() << "\n"
  138. << ws(level+1) << "- throws(): " << info.throws() << "\n"
  139. << ws(level+1) << "- okToFail(): " << info.okToFail() << "\n"
  140. << ws(level+1) << "- expectedToFail(): " << info.expectedToFail() << "\n"
  141. << ws(level+1) << "- tagsAsString(): '" << info.tagsAsString() << "'\n"
  142. << ws(level+1) << "- name: '" << info.name << "'\n"
  143. << ws(level+1) << "- className: '" << info.className << "'\n"
  144. << ws(level+1) << "- tags: " << info.tags << "\n";
  145. print( os, level+1 , "- lineInfo", info.lineInfo );
  146. os << ws(level+1) << "- properties (flags): 0x" << std::hex << static_cast<uint32_t>(info.properties) << std::dec << "\n";
  147. }
  148. // struct TestCaseStats {
  149. // TestCaseInfo testInfo;
  150. // Totals totals;
  151. // std::string stdOut;
  152. // std::string stdErr;
  153. // bool aborting;
  154. // };
  155. void print( std::ostream& os, int const level, std::string const& title, Catch::TestCaseStats const& info ) {
  156. os << ws(level ) << title << ":\n";
  157. print( os, level+1 , "- testInfo", *info.testInfo );
  158. print( os, level+1 , "- totals" , info.totals );
  159. os << ws(level+1) << "- stdOut: " << info.stdOut << "\n"
  160. << ws(level+1) << "- stdErr: " << info.stdErr << "\n"
  161. << ws(level+1) << "- aborting: " << info.aborting << "\n";
  162. }
  163. // struct SectionInfo {
  164. // std::string name;
  165. // std::string description;
  166. // SourceLineInfo lineInfo;
  167. // };
  168. void print( std::ostream& os, int const level, std::string const& title, Catch::SectionInfo const& info ) {
  169. os << ws(level ) << title << ":\n"
  170. << ws(level+1) << "- name: " << info.name << "\n";
  171. print( os, level+1 , "- lineInfo", info.lineInfo );
  172. }
  173. // struct SectionStats {
  174. // SectionInfo sectionInfo;
  175. // Counts assertions;
  176. // double durationInSeconds;
  177. // bool missingAssertions;
  178. // };
  179. void print( std::ostream& os, int const level, std::string const& title, Catch::SectionStats const& info ) {
  180. os << ws(level ) << title << ":\n";
  181. print( os, level+1 , "- sectionInfo", info.sectionInfo );
  182. print( os, level+1 , "- assertions" , info.assertions );
  183. os << ws(level+1) << "- durationInSeconds: " << info.durationInSeconds << "\n"
  184. << ws(level+1) << "- missingAssertions: " << info.missingAssertions << "\n";
  185. }
  186. // struct AssertionInfo
  187. // {
  188. // StringRef macroName;
  189. // SourceLineInfo lineInfo;
  190. // StringRef capturedExpression;
  191. // ResultDisposition::Flags resultDisposition;
  192. // };
  193. void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionInfo const& info ) {
  194. os << ws(level ) << title << ":\n"
  195. << ws(level+1) << "- macroName: '" << info.macroName << "'\n";
  196. print( os, level+1 , "- lineInfo" , info.lineInfo );
  197. os << ws(level+1) << "- capturedExpression: '" << info.capturedExpression << "'\n"
  198. << ws(level+1) << "- resultDisposition (flags): 0x" << std::hex << info.resultDisposition << std::dec << "\n";
  199. }
  200. //struct AssertionResultData
  201. //{
  202. // std::string reconstructExpression() const;
  203. //
  204. // std::string message;
  205. // mutable std::string reconstructedExpression;
  206. // LazyExpression lazyExpression;
  207. // ResultWas::OfType resultType;
  208. //};
  209. void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionResultData const& info ) {
  210. os << ws(level ) << title << ":\n"
  211. << ws(level+1) << "- reconstructExpression(): '" << info.reconstructExpression() << "'\n"
  212. << ws(level+1) << "- message: '" << info.message << "'\n"
  213. << ws(level+1) << "- lazyExpression: '" << "(info.lazyExpression)" << "'\n"
  214. << ws(level+1) << "- resultType: '" << info.resultType << "'\n";
  215. }
  216. //class AssertionResult {
  217. // bool isOk() const;
  218. // bool succeeded() const;
  219. // ResultWas::OfType getResultType() const;
  220. // bool hasExpression() const;
  221. // bool hasMessage() const;
  222. // std::string getExpression() const;
  223. // std::string getExpressionInMacro() const;
  224. // bool hasExpandedExpression() const;
  225. // std::string getExpandedExpression() const;
  226. // std::string getMessage() const;
  227. // SourceLineInfo getSourceInfo() const;
  228. // std::string getTestMacroName() const;
  229. //
  230. // AssertionInfo m_info;
  231. // AssertionResultData m_resultData;
  232. //};
  233. void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionResult const& info ) {
  234. os << ws(level ) << title << ":\n"
  235. << ws(level+1) << "- isOk(): " << info.isOk() << "\n"
  236. << ws(level+1) << "- succeeded(): " << info.succeeded() << "\n"
  237. << ws(level+1) << "- getResultType(): " << info.getResultType() << "\n"
  238. << ws(level+1) << "- hasExpression(): " << info.hasExpression() << "\n"
  239. << ws(level+1) << "- hasMessage(): " << info.hasMessage() << "\n"
  240. << ws(level+1) << "- getExpression(): '" << info.getExpression() << "'\n"
  241. << ws(level+1) << "- getExpressionInMacro(): '" << info.getExpressionInMacro() << "'\n"
  242. << ws(level+1) << "- hasExpandedExpression(): " << info.hasExpandedExpression() << "\n"
  243. << ws(level+1) << "- getExpandedExpression(): " << info.getExpandedExpression() << "'\n"
  244. << ws(level+1) << "- getMessage(): '" << info.getMessage() << "'\n";
  245. print( os, level+1 , "- getSourceInfo(): ", info.getSourceInfo() );
  246. os << ws(level+1) << "- getTestMacroName(): '" << info.getTestMacroName() << "'\n";
  247. print( os, level+1 , "- *** m_info (AssertionInfo)", info.m_info );
  248. print( os, level+1 , "- *** m_resultData (AssertionResultData)", info.m_resultData );
  249. }
  250. // struct AssertionStats {
  251. // AssertionResult assertionResult;
  252. // std::vector<MessageInfo> infoMessages;
  253. // Totals totals;
  254. // };
  255. void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionStats const& info ) {
  256. os << ws(level ) << title << ":\n";
  257. print( os, level+1 , "- assertionResult", info.assertionResult );
  258. print( os, level+1 , "- infoMessages", info.infoMessages );
  259. print( os, level+1 , "- totals", info.totals );
  260. }
  261. // -----------------------------------------------------------------------
  262. // 2. My listener and registration:
  263. //
  264. char const * dashed_line =
  265. "--------------------------------------------------------------------------";
  266. struct MyListener : Catch::EventListenerBase {
  267. using EventListenerBase::EventListenerBase; // inherit constructor
  268. // Get rid of Wweak-tables
  269. ~MyListener() override;
  270. // The whole test run starting
  271. void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
  272. std::cout
  273. << std::boolalpha
  274. << "\nEvent: testRunStarting:\n";
  275. print( std::cout, 1, "- testRunInfo", testRunInfo );
  276. }
  277. // The whole test run ending
  278. void testRunEnded( Catch::TestRunStats const& testRunStats ) override {
  279. std::cout
  280. << dashed_line
  281. << "\nEvent: testRunEnded:\n";
  282. print( std::cout, 1, "- testRunStats", testRunStats );
  283. }
  284. // A test is being skipped (because it is "hidden")
  285. void skipTest( Catch::TestCaseInfo const& testInfo ) override {
  286. std::cout
  287. << dashed_line
  288. << "\nEvent: skipTest:\n";
  289. print( std::cout, 1, "- testInfo", testInfo );
  290. }
  291. // Test cases starting
  292. void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
  293. std::cout
  294. << dashed_line
  295. << "\nEvent: testCaseStarting:\n";
  296. print( std::cout, 1, "- testInfo", testInfo );
  297. }
  298. // Test cases ending
  299. void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
  300. std::cout << "\nEvent: testCaseEnded:\n";
  301. print( std::cout, 1, "testCaseStats", testCaseStats );
  302. }
  303. // Sections starting
  304. void sectionStarting( Catch::SectionInfo const& sectionInfo ) override {
  305. std::cout << "\nEvent: sectionStarting:\n";
  306. print( std::cout, 1, "- sectionInfo", sectionInfo );
  307. }
  308. // Sections ending
  309. void sectionEnded( Catch::SectionStats const& sectionStats ) override {
  310. std::cout << "\nEvent: sectionEnded:\n";
  311. print( std::cout, 1, "- sectionStats", sectionStats );
  312. }
  313. // Assertions before/ after
  314. void assertionStarting( Catch::AssertionInfo const& assertionInfo ) override {
  315. std::cout << "\nEvent: assertionStarting:\n";
  316. print( std::cout, 1, "- assertionInfo", assertionInfo );
  317. }
  318. void assertionEnded( Catch::AssertionStats const& assertionStats ) override {
  319. std::cout << "\nEvent: assertionEnded:\n";
  320. print( std::cout, 1, "- assertionStats", assertionStats );
  321. }
  322. };
  323. } // end anonymous namespace
  324. CATCH_REGISTER_LISTENER( MyListener )
  325. // Get rid of Wweak-tables
  326. MyListener::~MyListener() {}
  327. // -----------------------------------------------------------------------
  328. // 3. Test cases:
  329. //
  330. TEST_CASE( "1: Hidden testcase", "[.hidden]" ) {
  331. }
  332. TEST_CASE( "2: Testcase with sections", "[tag-A][tag-B]" ) {
  333. int i = 42;
  334. REQUIRE( i == 42 );
  335. SECTION("Section 1") {
  336. INFO("Section 1");
  337. i = 7;
  338. SECTION("Section 1.1") {
  339. INFO("Section 1.1");
  340. REQUIRE( i == 42 );
  341. }
  342. }
  343. SECTION("Section 2") {
  344. INFO("Section 2");
  345. REQUIRE( i == 42 );
  346. }
  347. WARN("At end of test case");
  348. }
  349. struct Fixture {
  350. int fortytwo() const {
  351. return 42;
  352. }
  353. };
  354. TEST_CASE_METHOD( Fixture, "3: Testcase with class-based fixture", "[tag-C][tag-D]" ) {
  355. REQUIRE( fortytwo() == 42 );
  356. }
  357. // Compile & run:
  358. // - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 210-Evt-EventListeners 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success
  359. // - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success
  360. // Expected compact output (all assertions):
  361. //
  362. // prompt> 210-Evt-EventListeners --reporter compact --success
  363. // result omitted for brevity.