Crafter.Review/tests/CodeKeys/main.cpp

180 lines
13 KiB
C++
Raw Normal View History

// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
// Code keys: a static code pass is keyed on its code, a functional pass on
// its code AND the range. Every rewrite of the commits fixture is checked in
// under tests/Goldens/fixture/code-keys/<rewrite>/.
import std;
import Crafter.Review;
namespace fs = std::filesystem;
using namespace Crafter::Review;
namespace {
std::int32_t Failures = 0;
const std::string Fn(Plan::FunctionalLens);
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;
}
using Keys = std::map<std::string, std::string>;
Keys CodeKeys(const fs::path& d, const std::string& lens = "repo-bug-prover.md", std::string_view env = {}) {
const Inventory::Built built = Inventory::Build("commits", d.string());
const Plan::CommitCode cc = Plan::CommitCodeOf(Artifact::PatchTexts(d));
Keys out;
for (const Json& u : built.out.at("units")) {
const std::string id = u.at("id").get<std::string>();
if (Plan::KindFor(lens, u) != "code") continue;
if (lens == Fn && (id.ends_with(":outside") || id.ends_with(":absent") || id.ends_with("#hdr"))) continue;
const Json job = {{"kind", "block"}, {"unit", id}, {"unitKind", "code"}};
out[id] = Plan::BlockReuseKey(job, lens, Plan::UnitText(built.lines, u), cc, {}, "c", 1, env).value_or("");
}
return out;
}
std::optional<std::string> WholeKey(const fs::path& d, const std::string& lens = "repo-better-solution.md", std::string_view env = {}) {
return Plan::WholeCodeKey({{"kind", "whole"}, {"unit", nullptr}}, lens, Plan::CommitCodeOf(Artifact::PatchTexts(d)), {}, "c", 1, env);
}
std::set<std::string> Changed(const Keys& now, const Keys& before) {
std::set<std::string> out;
for (const auto& [id, key] : before) {
if (now.at(id) != key) out.insert(id);
}
return out;
}
bool AllChanged(const Keys& now, const Keys& before) {
return Changed(now, before).size() == before.size();
}
std::string Show(const std::set<std::string>& ids) {
Json out = Json::array();
for (const std::string& id : ids) out.push_back(id);
return Dyn::ReprValue(out);
}
}
int main() {
std::println("reuse keys: a static code pass is keyed on its code; a functional pass on its code AND the range (fixtures/commits and rewrites of it)");
const fs::path fixture = fs::current_path() / "tests" / "Goldens" / "fixture";
const fs::path src = fixture / "commits";
auto rewrite = [&](std::string_view name) { return fixture / "code-keys" / name; };
const Keys base = CodeKeys(src);
const Keys fbase = CodeKeys(src, Fn);
const Keys sbase = CodeKeys(src, "repo-security.md");
std::set<std::string> baseValues;
std::set<std::string> sbaseValues;
for (const auto& [id, key] : base) baseValues.insert(key);
for (const auto& [id, key] : sbase) sbaseValues.insert(key);
const bool keysDiffer = std::ranges::all_of(base, [&](const auto& entry) { return sbase.contains(entry.first) && sbase.at(entry.first) != entry.second; });
Check("the security lens keys the same code units as the bug-prover, every key its own (the lens file is in the key): a verdict of one is never evidence for the other",
std::ranges::equal(std::views::keys(sbase), std::views::keys(base)) && keysDiffer && sbaseValues.size() == baseValues.size());
std::set<std::string> slots;
for (const auto& [id, key] : base) {
if (id.ends_with(":outside") || id.ends_with(":absent")) slots.insert(id);
}
std::set<std::string> fbaseValues;
for (const auto& [id, key] : fbase) fbaseValues.insert(key);
const std::set<std::string> functionalUnits = {"p1:hello.py#1", "p2:hello.py#1", "p2:hello.py#2"};
std::set<std::string> shared;
std::ranges::set_intersection(baseValues, fbaseValues, std::inserter(shared, shared.begin()));
Check("fixture: every static code unit has a key (4 slots, hunks, headers), the functional units are the hunks alone, no doc unit, no shared key",
std::ranges::all_of(base, [](const auto& entry) { return !entry.second.empty(); }) && slots.size() == 4 && base.contains("p2:hello.py#hdr")
&& std::set<std::string>(std::views::keys(fbase).begin(), std::views::keys(fbase).end()) == functionalUnits
&& std::ranges::none_of(base, [](const auto& entry) { return entry.first.contains(".md#"); }) && shared.empty());
const fs::path rw = rewrite("rewrite");
Check("a rewrite that leaves the code alone (ids, counter, blobs, line numbers, git version, a reworded message) -> every key the same, static and functional",
CodeKeys(rw) == base && CodeKeys(rw, Fn) == fbase && WholeKey(rw) == WholeKey(src) && WholeKey(rw, Fn) == WholeKey(src, Fn)
&& Artifact::ArtifactHash("commits", rw) != Artifact::ArtifactHash("commits", src));
const fs::path code = rewrite("code");
std::set<std::string> diff = Changed(CodeKeys(code), base);
std::set<std::string> expected = slots;
expected.insert("p2:hello.py#1");
Check("one changed line in p2:hello.py#1 -> static: that hunk and the four slots, nothing else", diff == expected, Show(diff));
Check("...functional: EVERY unit is asked again (the range is in its key)", AllChanged(CodeKeys(code, Fn), fbase));
Check("...and both whole passes", WholeKey(code) != WholeKey(src) && WholeKey(code, Fn) != WholeKey(src, Fn));
const Keys ctx = CodeKeys(rewrite("context"));
Check("a changed context line re-keys its hunk", ctx.at("p2:hello.py#1") != base.at("p2:hello.py#1") && ctx.at("p2:hello.py#2") == base.at("p2:hello.py#2"));
const fs::path nobody = rewrite("nobody");
Check("p2 loses its body -> p2:absent alone (static); nothing functional", Changed(CodeKeys(nobody), base) == std::set<std::string>{"p2:absent"} && CodeKeys(nobody, Fn) == fbase);
const fs::path bse = rewrite("base");
Check("another base -> every key changes, static, functional and both wholes", AllChanged(CodeKeys(bse), base) && AllChanged(CodeKeys(bse, Fn), fbase) && WholeKey(bse) != WholeKey(src));
const fs::path mode = rewrite("mode");
expected = slots;
expected.insert("p2:hello.py#hdr");
Check("a mode change re-keys the file header (and the slots), not the hunks; the functional hunks follow the range", Changed(CodeKeys(mode), base) == expected
&& AllChanged(CodeKeys(mode, Fn), fbase));
const fs::path docs = rewrite("docs");
Check("a reworded README sentence -> no key changes anywhere (documentation is nobody's code)", CodeKeys(docs) == base && CodeKeys(docs, Fn) == fbase && WholeKey(docs) == WholeKey(src));
const fs::path nodoc = rewrite("nodoc");
Check("p2 drops its README hunk -> p2's two slots and the whole passes are asked again, no hunk", Changed(CodeKeys(nodoc), base) == std::set<std::string>{"p2:absent", "p2:outside"}
&& WholeKey(nodoc) != WholeKey(src) && CodeKeys(nodoc, Fn) == fbase);
// The environment in the keys (plan.ENVIRONMENTS item 1).
const Keys sb = CodeKeys(src, "repo-bug-prover.md", "supabase");
const Keys fb = CodeKeys(src, Fn, "browser+supabase");
Check("environment: a lens in its default environment keeps the key every stored verdict was built with (none for the static lenses, browser for the functional lens)",
CodeKeys(src, "repo-bug-prover.md", "none") == base && CodeKeys(src, Fn, "browser") == fbase && WholeKey(src, "repo-better-solution.md", "none") == WholeKey(src)
&& WholeKey(src, Fn, "browser") == WholeKey(src, Fn) && Plan::EnvDeps("repo-bug-prover.md").empty() && Plan::EnvDeps(Fn, "browser").empty()
&& Plan::EnvDeps(Fn, "browser+supabase") == std::vector<std::string>{"env=browser+supabase"});
std::set<std::string> everyKey;
for (const Plan::Environment& environment : Plan::Environments) {
for (const auto& [id, key] : CodeKeys(src, "repo-bug-prover.md", environment.name)) everyKey.insert(key);
}
Check("environment: any other environment re-keys every unit, block and whole, static and functional - each environment its own keys, none shared",
AllChanged(sb, base) && AllChanged(fb, fbase) && WholeKey(src, "repo-better-solution.md", "supabase") != WholeKey(src)
&& WholeKey(src, Fn, "browser+supabase") != WholeKey(src, Fn) && everyKey.size() == Plan::Environments.size() * base.size());
expected = slots;
expected.insert("p2:hello.py#1");
Check("environment: the code rules hold inside an environment - a rewrite that leaves the code alone keeps every supabase key, a changed line re-keys that hunk and the slots alone",
CodeKeys(rw, "repo-bug-prover.md", "supabase") == sb && CodeKeys(rw, Fn, "browser+supabase") == fb
&& WholeKey(rw, "repo-better-solution.md", "supabase") == WholeKey(src, "repo-better-solution.md", "supabase")
&& Changed(CodeKeys(code, "repo-bug-prover.md", "supabase"), sb) == expected);
const Plan::CommitCode cc = Plan::CommitCodeOf(Artifact::PatchTexts(src));
Check("whole key: both wholes have keys and differ; a block never; the bug-prover has none", WholeKey(src) && WholeKey(src, Fn) && WholeKey(src) != WholeKey(src, Fn)
&& !WholeKey(src, "repo-bug-prover.md") && !Plan::WholeCodeKey({{"kind", "block"}, {"unit", "x"}}, "repo-better-solution.md", cc, {}, "c", 1));
const Json job = {{"kind", "whole"}, {"unit", nullptr}};
const std::vector<std::string> w1 = {"w1"};
Json withModel = job;
withModel["model"] = "m";
const std::set<std::optional<std::string>> wholes = {
WholeKey(src), Plan::WholeCodeKey(job, "repo-better-solution.md", cc, w1, "c", 1), Plan::WholeCodeKey(job, "repo-better-solution.md", cc, {}, "c2", 1),
Plan::WholeCodeKey(job, "repo-better-solution.md", cc, {}, "c", 2), Plan::WholeCodeKey(withModel, "repo-better-solution.md", cc, {}, "c", 1),
};
Check("whole key: dispositions, the charter, the prompt version and the model are in it", wholes.size() == 5);
Plan::CommitCode two;
two.base = "b";
two.range = "r";
two.code = {{3, Plan::Sha("")}, {4, Plan::Sha("")}};
two.body = {{3, true}, {4, true}};
two.docs = {{3, {"h"}}, {4, {"h"}}};
two.upto = {{3, "u"}, {4, "u"}};
Plan::CommitCode renamed = two;
renamed.docs = {{3, {"h2"}}, {4, {"h"}}};
Check("slot keys: two documentation-only commits do not share a slot key (the position is in it); a renamed doc file re-asks the slots of its commit",
Plan::CodeKeyParts("p3:absent", two) != Plan::CodeKeyParts("p4:absent", two)
&& Plan::CodeKeyParts("p3:outside", two) != Plan::CodeKeyParts("p3:outside", renamed) && Plan::CodeKeyParts("p3:absent", two) != Plan::CodeKeyParts("p3:absent", renamed));
Check("a hunk is keyed on its file and text, not on its number or its commit; the functional ident is its own", Plan::CodeKeyParts("p2:hello.py#2", cc) == Plan::CodeKeyParts("p7:hello.py#5", cc)
&& Plan::CodeKeyParts("p2:hello.py#2", cc).first != Plan::CodeKeyParts("p2:other.py#2", cc).first
&& Plan::CodeKeyParts("p2:hello.py#hdr", cc).first != Plan::CodeKeyParts("p2:hello.py#1", cc).first);
const std::vector<std::string> parts = {"repo-bug-prover.md", "U", Plan::Sha("T"), Plan::Sha("d"), "w1", "cs", "1", "", "max"};
Check("reuse key: the pre-2026-10-02 formula with the effort slot frozen at max", Plan::ReuseKey({{"kind", "block"}, {"unit", "U"}}, "repo-bug-prover.md", "T", {"d"}, {"w1"}, "cs", 1)
== Plan::Sha(Dyn::Join(parts, "|")).substr(0, 16) && Plan::ReuseKeyEffortSlot == "max");
Check("code_norm leaves a hunk body alone", Plan::CodeNorm("@@ -1,2 +1,2 @@ f\n-- \n+index 1..2\n+@@ -1 +1 @@") == "@@ f\n-- \n+index 1..2\n+@@ -1 +1 @@");
const Json e = {{"unit", "p2:hello.py#2"}, {"coverage", {{"item", "p2:hello.py#2"}, {"verdict", "clear"}, {"basis", "b"}}}, {"findings", Json::array()},
{"notes", {{{"note", "n"}, {"items", {"p2:hello.py#2", "p2:hello.py#1"}}}}}};
const Json r = Plan::Rebind(e, "p2:hello.py#3");
Json v = {{"verdict", "SEND-READY"}, {"findings", r.at("findings")}, {"notes", r.at("notes")}, {"coverage", {r.at("coverage")}}};
const std::vector<std::string> ids = {"p2:hello.py#3"};
const Json n = Normalize::NormalizeOutput(v, {}, "repo-bug-prover.md", "H", Json::array({{{"id", "p2:hello.py#3"}}}), ids);
Check("rebind: the stored result under the unit's id of today, and it covers the renumbered unit", r.at("unit") == "p2:hello.py#3"
&& r.at("notes").at(0).at("items") == Json::array({"p2:hello.py#3"}) && e.at("coverage").at("item") == "p2:hello.py#2" && n.at("verdict") == "SEND-READY"
&& n.at("coverageMissing").empty());
return Failures ? 1 : 0;
}