/** * @file tests/tests_events.h * @brief Declarations for SunshineEventListener. */ #pragma once #include "tests_common.h" struct SunshineEventListener: testing::EmptyTestEventListener { SunshineEventListener() { sink = boost::make_shared(); sink_buffer = boost::make_shared(); sink->locked_backend()->add_stream(sink_buffer); sink->set_formatter(&logging::formatter); } void OnTestProgramStart(const testing::UnitTest &unit_test) override { boost::log::core::get()->add_sink(sink); } void OnTestProgramEnd(const testing::UnitTest &unit_test) override { boost::log::core::get()->remove_sink(sink); } void OnTestStart(const testing::TestInfo &test_info) override { BOOST_LOG(tests) << "From " << test_info.file() << ":" << test_info.line(); BOOST_LOG(tests) << " " << test_info.test_suite_name() << "/" << test_info.name() << " started"; } void OnTestPartResult(const testing::TestPartResult &test_part_result) override { std::string file = test_part_result.file_name(); BOOST_LOG(tests) << "At " << file << ":" << test_part_result.line_number(); auto result_text = test_part_result.passed() ? "Success" : test_part_result.nonfatally_failed() ? "Non-fatal failure" : test_part_result.fatally_failed() ? "Failure" : "Skip"; std::string summary = test_part_result.summary(); std::string message = test_part_result.message(); BOOST_LOG(tests) << " " << result_text << ": " << summary; if (message != summary) { BOOST_LOG(tests) << " " << message; } } void OnTestEnd(const testing::TestInfo &test_info) override { auto &result = *test_info.result(); auto result_text = result.Passed() ? "passed" : result.Skipped() ? "skipped" : "failed"; BOOST_LOG(tests) << test_info.test_suite_name() << "/" << test_info.name() << " " << result_text; if (result.Failed()) { std::cout << sink_buffer->str(); } sink_buffer->str(""); sink_buffer->clear(); } using sink_t = boost::log::sinks::synchronous_sink; boost::shared_ptr sink; boost::shared_ptr sink_buffer; };