[M1] add manifest::write
This commit is contained in:
@@ -9,3 +9,4 @@ endfunction()
|
||||
|
||||
cargoxx_add_test(util_error)
|
||||
cargoxx_add_test(manifest_parse)
|
||||
cargoxx_add_test(manifest_write)
|
||||
|
||||
132
tests/manifest_write.cpp
Normal file
132
tests/manifest_write.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
import cargoxx.manifest;
|
||||
import cargoxx.util;
|
||||
import std;
|
||||
|
||||
using cargoxx::manifest::BuildSettings;
|
||||
using cargoxx::manifest::Dependency;
|
||||
using cargoxx::manifest::Edition;
|
||||
using cargoxx::manifest::Manifest;
|
||||
using cargoxx::manifest::Package;
|
||||
using cargoxx::manifest::parse;
|
||||
using cargoxx::manifest::write;
|
||||
|
||||
namespace {
|
||||
|
||||
auto tmp_path() -> std::filesystem::path {
|
||||
auto dir = std::filesystem::temp_directory_path() /
|
||||
std::format("cargoxx-write-test-{}", std::random_device{}());
|
||||
std::filesystem::create_directories(dir);
|
||||
return dir / "Cargoxx.toml";
|
||||
}
|
||||
|
||||
auto pkg(std::string name, std::string version, Edition ed = Edition::Cpp23,
|
||||
std::vector<std::string> authors = {},
|
||||
std::optional<std::string> license = std::nullopt) -> Package {
|
||||
return Package{
|
||||
.name = std::move(name),
|
||||
.version = std::move(version),
|
||||
.edition = ed,
|
||||
.authors = std::move(authors),
|
||||
.license = std::move(license),
|
||||
};
|
||||
}
|
||||
|
||||
auto dep(std::string name, std::string version,
|
||||
std::vector<std::string> components = {}) -> Dependency {
|
||||
return Dependency{
|
||||
.name = std::move(name),
|
||||
.version_spec = std::move(version),
|
||||
.components = std::move(components),
|
||||
};
|
||||
}
|
||||
|
||||
auto round_trip(const Manifest& m) -> Manifest {
|
||||
auto path = tmp_path();
|
||||
REQUIRE(write(m, path).has_value());
|
||||
auto parsed = parse(path);
|
||||
REQUIRE(parsed.has_value());
|
||||
return *parsed;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("write round-trips a minimal manifest", "[manifest][write]") {
|
||||
Manifest m{pkg("foo", "0.1.0"), {}, {}};
|
||||
REQUIRE(round_trip(m) == m);
|
||||
}
|
||||
|
||||
TEST_CASE("write round-trips authors and license", "[manifest][write]") {
|
||||
Manifest m{pkg("foo", "0.1.0", Edition::Cpp20, {"Ada", "Grace"}, "MIT"), {}, {}};
|
||||
REQUIRE(round_trip(m) == m);
|
||||
}
|
||||
|
||||
TEST_CASE("write round-trips a string-form dependency", "[manifest][write]") {
|
||||
Manifest m{pkg("foo", "0.1.0"), {dep("fmt", "10.2")}, {}};
|
||||
REQUIRE(round_trip(m) == m);
|
||||
}
|
||||
|
||||
TEST_CASE("write round-trips a table-form dependency with components",
|
||||
"[manifest][write]") {
|
||||
Manifest m{pkg("foo", "0.1.0"), {dep("boost", "1.84", {"filesystem", "system"})}, {}};
|
||||
REQUIRE(round_trip(m) == m);
|
||||
}
|
||||
|
||||
TEST_CASE("write sorts dependencies alphabetically (matches Cargo)",
|
||||
"[manifest][write]") {
|
||||
Manifest m{
|
||||
pkg("foo", "0.1.0"),
|
||||
{
|
||||
dep("fmt", "10.2"),
|
||||
dep("spdlog", "1.13"),
|
||||
dep("boost", "1.84", {"filesystem"}),
|
||||
},
|
||||
{},
|
||||
};
|
||||
auto rt = round_trip(m);
|
||||
REQUIRE(rt.dependencies.size() == 3);
|
||||
REQUIRE(rt.dependencies[0].name == "boost");
|
||||
REQUIRE(rt.dependencies[1].name == "fmt");
|
||||
REQUIRE(rt.dependencies[2].name == "spdlog");
|
||||
}
|
||||
|
||||
TEST_CASE("write round-trips build settings", "[manifest][write]") {
|
||||
Manifest m{
|
||||
pkg("foo", "0.1.0"),
|
||||
{},
|
||||
BuildSettings{.warnings_as_errors = true,
|
||||
.sanitizers = {"address", "undefined"}},
|
||||
};
|
||||
REQUIRE(round_trip(m) == m);
|
||||
}
|
||||
|
||||
TEST_CASE("write omits empty optional sections", "[manifest][write]") {
|
||||
Manifest m{pkg("foo", "0.1.0"), {}, {}};
|
||||
auto path = tmp_path();
|
||||
REQUIRE(write(m, path).has_value());
|
||||
|
||||
std::ifstream in{path};
|
||||
std::string content{std::istreambuf_iterator<char>(in), {}};
|
||||
REQUIRE(content.find("[dependencies]") == std::string::npos);
|
||||
REQUIRE(content.find("[build]") == std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE("write overwrites an existing file", "[manifest][write]") {
|
||||
auto path = tmp_path();
|
||||
std::ofstream{path} << "# stale content\n[package]\nname = \"old\"\n";
|
||||
|
||||
Manifest m{pkg("new", "1.0.0"), {}, {}};
|
||||
REQUIRE(write(m, path).has_value());
|
||||
|
||||
auto parsed = parse(path);
|
||||
REQUIRE(parsed.has_value());
|
||||
REQUIRE(parsed->package.name == "new");
|
||||
}
|
||||
|
||||
TEST_CASE("write fails when the target directory does not exist",
|
||||
"[manifest][write]") {
|
||||
Manifest m{pkg("foo", "0.1.0"), {}, {}};
|
||||
auto r = write(m, "/nonexistent/dir/Cargoxx.toml");
|
||||
REQUIRE_FALSE(r.has_value());
|
||||
}
|
||||
Reference in New Issue
Block a user