import std; import Crafter.Build; using namespace Crafter; namespace { int failures = 0; void Check(bool cond, std::string_view msg) { if (!cond) { std::println(std::cerr, "FAIL: {}", msg); ++failures; } } } // Pure-data tests for ApplyStandardArgs and ArgQuery — no build/run, just // confirms the documented arg parsing produces the documented mutations. int main() { // --debug + --target= + --march= + --mtune= { Configuration cfg; cfg.target = "ignored"; std::array raw = { "--debug", "--target=aarch64-linux-gnu", "--march=armv8-a", "--mtune=cortex-a72", }; ApplyStandardArgs(cfg, raw); Check(cfg.debug, "--debug should set cfg.debug"); Check(cfg.target == "aarch64-linux-gnu", "--target= should overwrite cfg.target"); Check(cfg.march == "armv8-a", "--march= should overwrite cfg.march"); Check(cfg.mtune == "cortex-a72", "--mtune= should overwrite cfg.mtune"); } // --lib promotes Executable -> LibraryStatic; --shared then promotes to Dynamic. { Configuration cfg; cfg.type = ConfigurationType::Executable; std::array raw = { "--lib" }; ApplyStandardArgs(cfg, raw); Check(cfg.type == ConfigurationType::LibraryStatic, "--lib promotes Exe -> Static"); } { Configuration cfg; cfg.type = ConfigurationType::Executable; // Order shouldn't matter — promotions chain in priority order. std::array raw = { "--shared", "--lib" }; ApplyStandardArgs(cfg, raw); Check(cfg.type == ConfigurationType::LibraryDynamic, "--lib + --shared lands on Dynamic regardless of order"); } { Configuration cfg; cfg.type = ConfigurationType::Executable; std::array raw = { "--shared" }; ApplyStandardArgs(cfg, raw); Check(cfg.type == ConfigurationType::Executable, "--shared alone on Executable is a no-op"); } // ArgQuery is returned over the same args span and exposes Has/Get. { Configuration cfg; std::array raw = { "--timing", "--prefix=/opt/x", "extra" }; ArgQuery q = ApplyStandardArgs(cfg, raw); Check(q.Has("--timing"), "ArgQuery::Has true for present flag"); Check(!q.Has("--missing"), "ArgQuery::Has false for absent flag"); auto prefix = q.Get("--prefix="); Check(prefix.has_value(), "ArgQuery::Get returns a value for known prefix"); Check(prefix.value_or("") == "/opt/x", "ArgQuery::Get returns the substring after ="); Check(!q.Get("--other=").has_value(), "ArgQuery::Get returns nullopt for absent prefix"); } if (failures > 0) { std::println(std::cerr, "{} assertions failed", failures); return 1; } return 0; }