TODO: - log_message() - respond to queries - honor remaining options - more attributes in tags
| 5732 | // - honor remaining options |
| 5733 | // - more attributes in tags |
| 5734 | struct JUnitReporter : public IReporter |
| 5735 | { |
| 5736 | XmlWriter xml; |
| 5737 | DOCTEST_DECLARE_MUTEX(mutex) |
| 5738 | Timer timer; |
| 5739 | std::vector<String> deepestSubcaseStackNames; |
| 5740 | |
| 5741 | struct JUnitTestCaseData |
| 5742 | { |
| 5743 | static std::string getCurrentTimestamp() { |
| 5744 | // Beware, this is not reentrant because of backward compatibility issues |
| 5745 | // Also, UTC only, again because of backward compatibility (%z is C++11) |
| 5746 | time_t rawtime; |
| 5747 | std::time(&rawtime); |
| 5748 | auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); |
| 5749 | |
| 5750 | std::tm timeInfo; |
| 5751 | #ifdef DOCTEST_PLATFORM_WINDOWS |
| 5752 | gmtime_s(&timeInfo, &rawtime); |
| 5753 | #else // DOCTEST_PLATFORM_WINDOWS |
| 5754 | gmtime_r(&rawtime, &timeInfo); |
| 5755 | #endif // DOCTEST_PLATFORM_WINDOWS |
| 5756 | |
| 5757 | char timeStamp[timeStampSize]; |
| 5758 | const char* const fmt = "%Y-%m-%dT%H:%M:%SZ"; |
| 5759 | |
| 5760 | std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); |
| 5761 | return std::string(timeStamp); |
| 5762 | } |
| 5763 | |
| 5764 | struct JUnitTestMessage |
| 5765 | { |
| 5766 | JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details) |
| 5767 | : message(_message), type(_type), details(_details) {} |
| 5768 | |
| 5769 | JUnitTestMessage(const std::string& _message, const std::string& _details) |
| 5770 | : message(_message), type(), details(_details) {} |
| 5771 | |
| 5772 | std::string message, type, details; |
| 5773 | }; |
| 5774 | |
| 5775 | struct JUnitTestCase |
| 5776 | { |
| 5777 | JUnitTestCase(const std::string& _classname, const std::string& _name) |
| 5778 | : classname(_classname), name(_name), time(0), failures() {} |
| 5779 | |
| 5780 | std::string classname, name; |
| 5781 | double time; |
| 5782 | std::vector<JUnitTestMessage> failures, errors; |
| 5783 | }; |
| 5784 | |
| 5785 | void add(const std::string& classname, const std::string& name) { |
| 5786 | testcases.emplace_back(classname, name); |
| 5787 | } |
| 5788 | |
| 5789 | void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) { |
| 5790 | for(auto& curr: nameStack) |
| 5791 | if(curr.size()) |
nothing calls this directly
no outgoing calls
no test coverage detected