[M5+] add resolver::devbox_resolve (search.devbox.sh)
This commit is contained in:
@@ -33,3 +33,5 @@ cargoxx_add_test(conan_probe_live)
|
||||
cargoxx_add_test(vcpkg_probe_parse)
|
||||
cargoxx_add_test(vcpkg_probe_live)
|
||||
cargoxx_add_test(verify_link_unit)
|
||||
cargoxx_add_test(devbox_resolve_parse)
|
||||
cargoxx_add_test(devbox_resolve_live)
|
||||
|
||||
44
tests/devbox_resolve_live.cpp
Normal file
44
tests/devbox_resolve_live.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Network-gated integration test for resolver::devbox_resolve.
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
import cargoxx.resolver;
|
||||
import cargoxx.util;
|
||||
import std;
|
||||
|
||||
namespace {
|
||||
|
||||
auto network_tests_enabled() -> bool {
|
||||
auto* env = std::getenv("CARGOXX_NETWORK_TESTS");
|
||||
return env != nullptr && std::string_view{env} == "1";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("devbox_resolve returns a commit_hash for fmt 10.2.1",
|
||||
"[resolver][network]") {
|
||||
if (!network_tests_enabled()) {
|
||||
SKIP("CARGOXX_NETWORK_TESTS != 1");
|
||||
}
|
||||
auto r = cargoxx::resolver::devbox_resolve("fmt", "10.2.1");
|
||||
REQUIRE(r.has_value());
|
||||
REQUIRE(r->name == "fmt");
|
||||
REQUIRE(r->version == "10.2.1");
|
||||
REQUIRE(r->commit_hash.size() == 40); // git sha
|
||||
// attr_paths should at minimum include the package name itself.
|
||||
REQUIRE(std::ranges::find(r->attr_paths, std::string{"fmt"}) !=
|
||||
r->attr_paths.end());
|
||||
}
|
||||
|
||||
TEST_CASE("devbox_resolve returns ResolutionUnknownPackage on 404",
|
||||
"[resolver][network]") {
|
||||
if (!network_tests_enabled()) {
|
||||
SKIP("CARGOXX_NETWORK_TESTS != 1");
|
||||
}
|
||||
auto r = cargoxx::resolver::devbox_resolve(
|
||||
"definitely_not_a_real_pkg_cargoxx_xyzzy", "1.0");
|
||||
REQUIRE_FALSE(r.has_value());
|
||||
INFO("error msg: " << r.error().message);
|
||||
REQUIRE(r.error().code ==
|
||||
cargoxx::util::ErrorCode::ResolutionUnknownPackage);
|
||||
}
|
||||
85
tests/devbox_resolve_parse.cpp
Normal file
85
tests/devbox_resolve_parse.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
import cargoxx.resolver;
|
||||
import cargoxx.util;
|
||||
import std;
|
||||
|
||||
using cargoxx::resolver::parse_devbox_resolve;
|
||||
using cargoxx::util::ErrorCode;
|
||||
|
||||
TEST_CASE("parse_devbox_resolve extracts the canonical fields",
|
||||
"[resolver][devbox]") {
|
||||
// Trimmed shape of the real response for `fmt 10.2.1` from
|
||||
// https://search.devbox.sh/v1/resolve?name=fmt&version=10.2.1
|
||||
constexpr std::string_view input = R"({
|
||||
"commit_hash": "f4b140d5b253f5e2a1ff4e5506edbf8267724bde",
|
||||
"version": "10.2.1",
|
||||
"name": "fmt",
|
||||
"attr_paths": ["fmt"]
|
||||
})";
|
||||
|
||||
auto r = parse_devbox_resolve(input);
|
||||
REQUIRE(r.has_value());
|
||||
REQUIRE(r->name == "fmt");
|
||||
REQUIRE(r->version == "10.2.1");
|
||||
REQUIRE(r->commit_hash == "f4b140d5b253f5e2a1ff4e5506edbf8267724bde");
|
||||
REQUIRE(r->attr_paths == std::vector<std::string>{"fmt"});
|
||||
}
|
||||
|
||||
TEST_CASE("parse_devbox_resolve falls back to systems.<plat>.commit_hash",
|
||||
"[resolver][devbox]") {
|
||||
// Older / partial responses omit the top-level commit_hash but still
|
||||
// ship per-system entries.
|
||||
constexpr std::string_view input = R"({
|
||||
"name": "spdlog",
|
||||
"version": "1.13.0",
|
||||
"systems": {
|
||||
"x86_64-linux": {
|
||||
"commit_hash": "abc123def456",
|
||||
"attr_paths": ["spdlog"]
|
||||
}
|
||||
}
|
||||
})";
|
||||
|
||||
auto r = parse_devbox_resolve(input);
|
||||
REQUIRE(r.has_value());
|
||||
REQUIRE(r->commit_hash == "abc123def456");
|
||||
REQUIRE(r->attr_paths == std::vector<std::string>{"spdlog"});
|
||||
}
|
||||
|
||||
TEST_CASE("parse_devbox_resolve fails on missing commit_hash",
|
||||
"[resolver][devbox]") {
|
||||
constexpr std::string_view input = R"({
|
||||
"name": "fmt",
|
||||
"version": "10.2.1"
|
||||
})";
|
||||
auto r = parse_devbox_resolve(input);
|
||||
REQUIRE_FALSE(r.has_value());
|
||||
REQUIRE(r.error().code == ErrorCode::ResolutionVersionNotFound);
|
||||
}
|
||||
|
||||
TEST_CASE("parse_devbox_resolve fails on garbage input", "[resolver][devbox]") {
|
||||
auto r = parse_devbox_resolve("not-json");
|
||||
REQUIRE_FALSE(r.has_value());
|
||||
REQUIRE(r.error().code == ErrorCode::ResolutionNetworkError);
|
||||
}
|
||||
|
||||
TEST_CASE("parse_devbox_resolve fails on non-object root", "[resolver][devbox]") {
|
||||
auto r = parse_devbox_resolve("[]");
|
||||
REQUIRE_FALSE(r.has_value());
|
||||
REQUIRE(r.error().code == ErrorCode::ResolutionNetworkError);
|
||||
}
|
||||
|
||||
TEST_CASE("parse_devbox_resolve tolerates an empty attr_paths array",
|
||||
"[resolver][devbox]") {
|
||||
constexpr std::string_view input = R"({
|
||||
"name": "fmt",
|
||||
"version": "10.2.1",
|
||||
"commit_hash": "abc",
|
||||
"attr_paths": []
|
||||
})";
|
||||
auto r = parse_devbox_resolve(input);
|
||||
REQUIRE(r.has_value());
|
||||
REQUIRE(r->attr_paths.empty());
|
||||
REQUIRE(r->commit_hash == "abc");
|
||||
}
|
||||
Reference in New Issue
Block a user