#include 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{"fmt"}); } TEST_CASE("parse_devbox_resolve falls back to systems..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{"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"); }