// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® // Dispositions: in force, carried, lapsed, and the prompt block. import std; import Crafter.Review; namespace fs = std::filesystem; using namespace Crafter::Review; namespace { std::int32_t Failures = 0; void Check(std::string_view name, bool cond, std::string_view detail = {}) { std::println("{}{}{}", cond ? " ok " : " FAIL ", name, !cond && !detail.empty() ? std::format(" ({})", detail) : std::string()); if (!cond) ++Failures; } } int main() { std::println("dispositions: in-force / carried / lapsed, the prompt block"); const fs::path td = fs::temp_directory_path() / std::format("crafter-review-dispositions-{}", Platform::PublishedPid()); fs::create_directories(td); std::ofstream(td / "0001-a.patch", std::ios::binary) << "x\nANCHOR TEXT\ny\nANCHOR TEXT\n"; const std::vector e = { {{"id", "a"}, {"hash", "H1"}}, {{"id", "b"}, {"hash", "H0"}, {"carry", true}, {"anchors", {{{"file", "0001-a.patch"}, {"text", "ANCHOR TEXT"}, {"count", 2}}}}}, {{"id", "c"}, {"hash", "H0"}, {"carry", true}, {"anchors", {{{"file", "0001-a.patch"}, {"text", "ANCHOR TEXT"}, {"count", 1}}}}}, {{"id", "d"}, {"hash", "H0"}}, }; std::map rows; for (const Json& row : Dispositions::Classify(e, "H1", td)) rows[row.at("id").get()] = row.at("status").get(); const std::map expected = {{"a", "in-force"}, {"b", "carried"}, {"c", "lapsed"}, {"d", "lapsed"}}; Check("hash match in-force, count match carried, count mismatch lapsed, no carry lapsed", rows == expected); const std::vector inf = Dispositions::InForce(e, Dispositions::Classify(e, "H1", td)); Check("in_force = in-force + carried", inf.size() == 2 && inf[0].at("id") == "a" && inf[1].at("id") == "b"); const std::string blk = Dispositions::Block(inf, Dispositions::Classify(e, "H1", td), "repo-bug-prover.md", "H1"); Check("block text names the carried entry, nothing outside the register discharges, Gate 4 named", blk.contains("CARRIED to this hash") && blk.contains("- a [") && blk.contains("Nothing outside this list") && blk.contains("Gate 4") && !blk.contains("ledger")); const std::vector e2 = {{{"id", "r"}, {"hash", "H1"}, {"kind", "refuted"}, {"lenses", {"repo-functional.md"}}}}; const std::vector rowsR = {{{"id", "r"}, {"status", "in-force"}}}; Check("refuted entry hidden from other lenses, shown to its own", Dispositions::Block(e2, rowsR, "repo-bug-prover.md", "H1").contains("(none)") && Dispositions::Block(e2, rowsR, Plan::FunctionalLens, "H1").contains("- r [")); fs::remove_all(td); return Failures ? 1 : 0; }