#include "sarif.hpp" #include "nlohmann/json.hpp" #include #include int main() { const auto tests_path = boost::filesystem::canonical(JUCI_TESTS_PATH) / "sarif_test_files"; std::vector example_files = { tests_path / "example_run.sarif.json", tests_path / "example_run2.sarif.json", tests_path / "no_such_file.sarif.json", }; const auto output_file = tests_path / "merged.sarif.json"; boost::filesystem::remove(output_file); g_assert(!boost::filesystem::exists(output_file)); auto results = SARIF::merge_files(output_file, example_files); g_assert_cmpuint(results.size(), ==, 2U); results = SARIF::results_for_file(output_file, "/home/user/jucipp/src/source_base.cpp"); g_assert_cmpuint(results.size(), ==, 1U); const auto &result = results.front(); g_assert(result.rule_id == "alpha.cplusplus.IteratorRange"); g_assert(result.message.text == "Past-the-end iterator dereferenced"); g_assert(result.message.arguments.empty()); g_assert(result.level == SARIF::Result::Level::warning); g_assert(result.help_uri == "https://clang.llvm.org/docs/analyzer/checkers.html#alpha-cplusplus-iteratorrange"); g_assert_cmpuint(result.locations.size(), ==, 1); const auto &loc = result.locations.front(); g_assert(loc.artifact_location == "/home/user/jucipp/src/source_base.cpp"); g_assert_cmpuint(loc.region.start_line, ==, 1940); g_assert_cmpuint(loc.region.end_line, ==, 1940); g_assert_cmpuint(loc.region.start_column, ==, 35); g_assert_cmpuint(loc.region.end_column, ==, 57); g_assert(loc.message.text.empty()); g_assert(loc.message.arguments.empty()); g_assert(result.get_message(loc, false) == "Past-the-end iterator dereferenced (clang-analyze: alpha.cplusplus.IteratorRange)"); g_assert(result.get_message(loc, true) == "Past-the-end iterator dereferenced [(clang-analyze: alpha.cplusplus.IteratorRange)](https://clang.llvm.org/docs/analyzer/checkers.html#alpha-cplusplus-iteratorrange)"); g_assert_cmpuint(result.code_flows.size(), ==, 1); const auto &codeFlow = result.code_flows.front(); g_assert_cmpuint(codeFlow.thread_flows.size(), ==, 1); const auto &threadFlow = codeFlow.thread_flows.front(); g_assert_cmpuint(threadFlow.locations.size(), ==, 14); const auto &firstLoc = threadFlow.locations.front(); g_assert(firstLoc.importance == SARIF::ThreadFlowLocation::Importance::unimportant); g_assert(firstLoc.location.message.text == "Taking false branch"); g_assert(firstLoc.location.message.arguments.empty()); g_assert(firstLoc.location.artifact_location == "/home/user/jucipp/src/source_base.cpp"); g_assert(firstLoc.location.region.start_line == 1875); g_assert(firstLoc.location.region.end_line == 1875); g_assert(firstLoc.location.region.start_column == 3); g_assert(firstLoc.location.region.end_column == 3); const auto &lastLoc = threadFlow.locations.back(); g_assert(lastLoc.importance == SARIF::ThreadFlowLocation::Importance::essential); g_assert(lastLoc.location.message.text == "Past-the-end iterator dereferenced"); g_assert(lastLoc.location.message.arguments.empty()); g_assert(lastLoc.location.artifact_location == "/home/user/jucipp/src/source_base.cpp"); g_assert(lastLoc.location.region.start_line == 1940); g_assert(lastLoc.location.region.end_line == 1940); g_assert(lastLoc.location.region.start_column == 35); g_assert(lastLoc.location.region.end_column == 57); }