diff --git a/tools/test/source/main.cpp b/tools/test/source/main.cpp index f277c3d2..b97d75f9 100644 --- a/tools/test/source/main.cpp +++ b/tools/test/source/main.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace psemek::test { @@ -58,8 +59,34 @@ namespace psemek::test } +static bool terminal_has_color() +{ + std::string_view term; + if (auto t = std::getenv("TERM")) + term = t; + + return term == "linux" || term.starts_with("xterm"); +} + int main(int argc, char ** argv) { + std::string_view bold; + std::string_view red; + std::string_view green; + std::string_view yellow; + std::string_view cyan; + std::string_view normal; + + if (terminal_has_color()) + { + bold = "\033[1m"; + red = "\033[1;31m"; + green = "\033[1;32m"; + yellow = "\033[33m"; + cyan = "\033[36m"; + normal = "\033[0m"; + } + std::set tests; if (argc == 1) { @@ -113,8 +140,8 @@ int main(int argc, char ** argv) ++i; std::cout - << '[' << std::setfill(' ') << std::setw(test_index_len) << std::right << i << '/' << test_count << "] " - << std::left << std::setfill('.') << std::setw(max_name_length + 5) << name; + << bold << '[' << std::setfill(' ') << std::setw(test_index_len) << std::right << i << '/' << test_count << "] " << name + << normal << std::string(max_name_length + 5 - name.size(), '.'); psemek::test::context ctx; @@ -127,7 +154,7 @@ int main(int argc, char ** argv) { psemek::test::tests[name](ctx); auto end = clock::now(); - std::cout << "ok " << psemek::util::pretty(end - start, std::chrono::milliseconds{1}); + std::cout << green << "ok " << normal << psemek::util::pretty(end - start, std::chrono::milliseconds{1}); auto filter = [](auto const & m){ return m.first >= psemek::log::level::info; }; if (std::count_if(sink_ptr->messages.begin(), sink_ptr->messages.end(), filter) == 1) @@ -142,19 +169,19 @@ int main(int argc, char ** argv) catch (psemek::test::failure const & e) { auto end = clock::now(); - std::cout << "failure " << psemek::util::pretty(end - start, std::chrono::milliseconds{1}) << std::endl; - std::cout << indent << "Reason: " << e.message() << std::endl; - std::cout << indent << "Location: " << e.location() << std::endl; + std::cout << red << "failure " << normal << psemek::util::pretty(end - start, std::chrono::milliseconds{1}) << std::endl; + std::cout << indent << "Reason: " << yellow << e.message() << normal << std::endl; + std::cout << indent << "Location: " << cyan << e.location() << normal << std::endl; } catch (std::exception const & e) { auto end = clock::now(); - std::cout << "failure: " << e.what() << " " << psemek::util::pretty(end - start, std::chrono::milliseconds{1}) << std::endl; + std::cout << red << "failure: " << e.what() << normal << " " << psemek::util::pretty(end - start, std::chrono::milliseconds{1}) << std::endl; } catch (...) { auto end = clock::now(); - std::cout << "failure: (unknown exception) " << psemek::util::pretty(end - start, std::chrono::milliseconds{1}) << std::endl; + std::cout << red << "failure: (unknown exception) " << normal << psemek::util::pretty(end - start, std::chrono::milliseconds{1}) << std::endl; } sink = psemek::log::remove_sink(sink_ptr); @@ -183,7 +210,7 @@ int main(int argc, char ** argv) auto all_end = clock::now(); std::cout << std::endl; - std::cout << (success == test_count ? "Success: " : "Failure: ") << success << '/' << test_count << " passed (" + std::cout << (success == test_count ? green : red) << (success == test_count ? "Success: " : "Failure: ") << normal << success << '/' << test_count << " passed (" << psemek::util::pretty(all_end - all_start, std::chrono::milliseconds{1}) << ")" << std::endl; if (success <= test_count)