90 lines
2.8 KiB
C++
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));
|
|
}
|