210-Evt-EventListeners.cpp 14 KB

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