diff --git a/src/coverage.cpp b/src/coverage.cpp index e41e497..8b4b230 100644 --- a/src/coverage.cpp +++ b/src/coverage.cpp @@ -40,7 +40,7 @@ bool Coverage::LineCoverage::operator<(const LineCoverage &other) const noexcept } static bool is_not_covered(const Coverage::BranchCoverage &branch) { - return branch.count > 0; + return branch.count == 0; } bool Coverage::LineCoverage::fully_covered() const noexcept { @@ -55,6 +55,21 @@ bool Coverage::LineCoverage::not_covered() const noexcept { return count == 0; } +std::string Coverage::LineCoverage::branch_type(std::size_t branchIndex) const { + // If there are only 2 branches, one "exceptional" and the other "fall-through", report the "fall-through" branch as default. + if(branches.size() == 2 && branches[branchIndex].is_fallthrough && branches[branchIndex ^ 1].is_throw) { + return "Default "; + } + std::string type = ""; + if(branches[branchIndex].is_fallthrough) { + type += "Fall-through "; + } + if(branches[branchIndex].is_throw) { + type += "Exceptional "; + } + return type; +} + static JSON run_gcov(const boost::filesystem::path &build_path, const boost::filesystem::path &object_file) { auto command = Config::get().project.gcov_command + ' ' + filesystem::escape_argument(filesystem::get_short_path(object_file).string()); std::stringstream stdin_stream, stdout_stream, stderr_stream; @@ -63,7 +78,10 @@ static JSON run_gcov(const boost::filesystem::path &build_path, const boost::fil Terminal::get().print("\e[31mError\e[m: executable not found: " + command + "\n", true); } if(!stderr_stream.eof()) { - Terminal::get().async_print("\e[31mWarnings/Errors in gcov\e[m: " + stderr_stream.str(), true); + auto errorOutput = stderr_stream.str(); + if(!errorOutput.empty()) { + Terminal::get().async_print("\e[31mWarnings/Errors in gcov\e[m: " + errorOutput + "\n", true); + } } return JSON(stdout_stream); @@ -163,7 +181,12 @@ std::vector Coverage::analyze(Project::Build &build, con } } if(object_file.empty()) { - Terminal::get().async_print(file_path.filename().string() + ": could not find the C/C++ object file", true); + if(dynamic_cast(&build)) { + Terminal::get().async_print(file_path.filename().string() + ": could not find the C/C++ object file, you may need to enable the CMake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON switch\n", true); + } + else { + Terminal::get().async_print(file_path.filename().string() + ": could not find the C/C++ object file\n", true); + } return std::vector{}; } @@ -173,7 +196,7 @@ std::vector Coverage::analyze(Project::Build &build, con if(language_id == "rust" && dynamic_cast(&build)) { auto tarpaulin_folder = filesystem::get_canonical_path(build.get_default_path() / ".." / "tarpaulin"); if(!boost::filesystem::exists(tarpaulin_folder) || !boost::filesystem::is_directory(tarpaulin_folder)) { - Terminal::get().async_print("Directory '" + tarpaulin_folder.string() + "' does not exist, you may need to generate the coverage report via: cargo tarpaulin", true); + Terminal::get().async_print("Directory '" + tarpaulin_folder.string() + "' does not exist, you may need to generate the coverage report via: cargo tarpaulin\n", true); return std::vector{}; } for(const auto &file : boost::filesystem::directory_iterator(tarpaulin_folder)) { @@ -182,7 +205,7 @@ std::vector Coverage::analyze(Project::Build &build, con } } - Terminal::get().async_print("No JSON coverage file found in '" + tarpaulin_folder.string() + "', you may need to generate the coverage report via: cargo tarpaulin", true); + Terminal::get().async_print("No JSON coverage file found in '" + tarpaulin_folder.string() + "', you may need to generate the coverage report via: cargo tarpaulin\n", true); return std::vector{}; } return {}; diff --git a/src/coverage.hpp b/src/coverage.hpp index db96374..940d173 100644 --- a/src/coverage.hpp +++ b/src/coverage.hpp @@ -27,6 +27,8 @@ namespace Coverage { bool partially_covered() const noexcept; bool not_covered() const noexcept; + std::string branch_type(std::size_t branchIndex) const; + unsigned long line; unsigned long count; bool has_unexecuted_statements; diff --git a/src/source_coverage.cpp b/src/source_coverage.cpp index 9c2afd7..6640b95 100644 --- a/src/source_coverage.cpp +++ b/src/source_coverage.cpp @@ -149,8 +149,8 @@ std::string Source::CoverageView::update_tooltip(const Coverage::LineCoverage &l if(!line_coverage.branches.empty()) { ss << ", with branches:"; - for(const auto &branch : line_coverage.branches) { - ss << "\n- " << (branch.is_fallthrough ? "Fall-through " : "") << (branch.is_throw ? "Exceptional " : "") << "Branch executed " << branch.count << " times"; + for(std::size_t i = 0; i < line_coverage.branches.size(); ++i) { + ss << "\n- " << line_coverage.branch_type(i) << "Branch executed " << line_coverage.branches[i].count << " times"; } } return ss.str();