#include import cargoxx.linkdb; import cargoxx.util; import std; using cargoxx::linkdb::Database; using cargoxx::linkdb::Recipe; using cargoxx::util::ErrorCode; namespace { auto fresh_overlay() -> std::filesystem::path { auto d = std::filesystem::temp_directory_path() / std::format("cargoxx-linkdb-test-{}", std::random_device{}()); std::filesystem::create_directories(d); return d / "overlay.sqlite"; } auto open_db() -> Database { auto r = Database::open(fresh_overlay()); REQUIRE(r.has_value()); return std::move(*r); } } // namespace TEST_CASE("Database::open succeeds against a fresh overlay path", "[linkdb]") { auto db = open_db(); (void)db; } TEST_CASE("resolve fails on an empty database", "[linkdb]") { auto db = open_db(); auto rec = db.resolve("fmt", "10.2.0"); REQUIRE_FALSE(rec.has_value()); REQUIRE(rec.error().code == ErrorCode::LinkdbUnknownPackage); } TEST_CASE("resolve returns a manually-added recipe", "[linkdb]") { auto db = open_db(); auto add = db.add_manual("fmt", ">=10.0.0", Recipe{ .nixpkgs_attr = "fmt_10", .find_package = "fmt CONFIG REQUIRED", .targets = {"fmt::fmt"}, .source = "manual", }); REQUIRE(add.has_value()); auto rec = db.resolve("fmt", "10.2.0"); REQUIRE(rec.has_value()); REQUIRE(rec->nixpkgs_attr == "fmt_10"); REQUIRE(rec->find_package == "fmt CONFIG REQUIRED"); REQUIRE(rec->targets == std::vector{"fmt::fmt"}); REQUIRE(rec->source == "manual"); } TEST_CASE("resolve fails when components are passed but the row is non-componentized", "[linkdb]") { auto db = open_db(); (void)db.add_manual("fmt", "*", Recipe{ .nixpkgs_attr = "fmt_10", .find_package = "fmt CONFIG REQUIRED", .targets = {"fmt::fmt"}, .source = "manual", }); auto rec = db.resolve("fmt", "10.2.0", {"core"}); REQUIRE_FALSE(rec.has_value()); REQUIRE(rec.error().code == ErrorCode::LinkdbComponentNotSupported); }