Browse Source

Improvements for coverage display and error handling

merge-requests/413/head
doe300 2 years ago
parent
commit
5b6149ad1e
  1. 33
      src/coverage.cpp
  2. 2
      src/coverage.hpp
  3. 4
      src/source_coverage.cpp

33
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::LineCoverage> 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<const Project::CMakeBuild *>(&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<Coverage::LineCoverage>{};
}
@ -173,7 +196,7 @@ std::vector<Coverage::LineCoverage> Coverage::analyze(Project::Build &build, con
if(language_id == "rust" && dynamic_cast<Project::CargoBuild *>(&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<Coverage::LineCoverage>{};
}
for(const auto &file : boost::filesystem::directory_iterator(tarpaulin_folder)) {
@ -182,7 +205,7 @@ std::vector<Coverage::LineCoverage> 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<Coverage::LineCoverage>{};
}
return {};

2
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;

4
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();

Loading…
Cancel
Save