Files
cargoxx/tests/brute_scan_parse.cpp

90 lines
2.8 KiB
C++

#include <catch2/catch_test_macros.hpp>
import cargoxx.resolver;
import cargoxx.util;
import std;
using cargoxx::resolver::brute_scan;
using cargoxx::util::ErrorCode;
namespace {
auto fresh_store() -> std::filesystem::path {
auto d = std::filesystem::temp_directory_path() /
std::format("cargoxx-brute-scan-{}", std::random_device{}());
std::filesystem::create_directories(d / "lib");
std::filesystem::create_directories(d / "include");
return d;
}
void touch_lib(const std::filesystem::path& store, std::string_view name) {
std::ofstream{store / "lib" / std::string{name}};
}
void touch_include(const std::filesystem::path& store, std::string_view rel) {
auto p = store / "include" / rel;
std::filesystem::create_directories(p.parent_path());
std::ofstream{p};
}
} // namespace
TEST_CASE("brute_scan collects lib*.a and lib*.so files",
"[resolver][brute_scan]") {
auto store = fresh_store();
touch_lib(store, "libfoo.a");
touch_lib(store, "libbar.so");
touch_lib(store, "libbaz.so.1.2.3");
touch_lib(store, "not-a-lib.txt");
touch_include(store, "foo.h");
auto r = brute_scan(store, "foo");
REQUIRE(r.has_value());
REQUIRE(r->lib_files.size() == 3);
auto has = [&](std::string_view suffix) {
return std::ranges::any_of(r->lib_files, [&](const auto& p) {
return std::string_view{p}.ends_with(suffix);
});
};
REQUIRE(has("libfoo.a"));
REQUIRE(has("libbar.so"));
REQUIRE(has("libbaz.so.1.2.3"));
}
TEST_CASE("brute_scan exposes include/ as a single search directory",
"[resolver][brute_scan]") {
auto store = fresh_store();
touch_lib(store, "libsdl.a");
touch_include(store, "SDL2/SDL.h");
touch_include(store, "SDL2/SDL_video.h");
auto r = brute_scan(store, "sdl");
REQUIRE(r.has_value());
REQUIRE(r->include_dirs.size() == 1);
REQUIRE(std::string_view{r->include_dirs[0]}.ends_with("/include"));
}
TEST_CASE("brute_scan errors when neither libs nor headers are present",
"[resolver][brute_scan]") {
auto d = std::filesystem::temp_directory_path() /
std::format("cargoxx-brute-empty-{}", std::random_device{}());
std::filesystem::create_directories(d);
auto r = brute_scan(d, "ghost");
REQUIRE_FALSE(r.has_value());
REQUIRE(r.error().code == ErrorCode::ResolutionUnknownPackage);
}
TEST_CASE("brute_scan emits sorted lib paths for deterministic codegen",
"[resolver][brute_scan]") {
auto store = fresh_store();
touch_lib(store, "libzz.a");
touch_lib(store, "libaa.a");
touch_lib(store, "libmm.so");
auto r = brute_scan(store, "x");
REQUIRE(r.has_value());
REQUIRE(r->lib_files.size() == 3);
REQUIRE(std::ranges::is_sorted(r->lib_files));
}