test(pipeline): the checks of the pure pipeline

Stream, Normalize, Merge, Dispositions, Config, CodeKeys and the pure half
of CommitsMode, each a test of its own (131 checks). The fixture rewrites
are checked in (code-keys/<name>/, commits3/), so the suite reads fixtures
and edits nothing. The allowlist, command-line and MCP checks of
CommitsMode come with the pool they test.

Among them: this binary's `<exe> sql` spelling counts as a SQL call, and a
result line with a raw U+2028 in a JSON string is still the result line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-31 06:56:09 +01:00
commit 71dba5690f
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
12 changed files with 3778 additions and 1 deletions

76
tests/Merge/main.cpp Normal file
View file

@ -0,0 +1,76 @@
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
// Merging a lens's parts: the dedupe, the cross-unit rule, the strongest
// verdict, missing units; the matrix with units nobody reviews.
import std;
import Crafter.Review;
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;
}
// {item: verdict} of a merged result.
std::map<std::string, std::string> Verdicts(const Json& merged) {
std::map<std::string, std::string> out;
for (const Json& c : merged.at("coverage")) out[c.at("item").get<std::string>()] = c.at("verdict").get<std::string>();
return out;
}
Json With(Json value, const Json& changes) {
value.update(changes);
return value;
}
}
int main() {
std::println("merge_parts: dedupe, cross-unit rule, strongest verdict, missing units; the matrix with not-reviewed units");
const std::string lens = "repo-bug-prover.md";
const Json note = {{"kind", "info"}, {"items", {"A", "B"}}, {"note", "shared"}};
const Json found = {{"finding", "x"}, {"items", {"A", "B"}}, {"discharged", true}, {"dischargedBy", "w1"}};
const std::vector<Json> parts = {
{{"partLabel", "a"}, {"expectedIds", {"A"}}, {"findings", {found}}, {"notes", {note, note}}, {"coverage", {{{"item", "A"}, {"verdict", "clear"}}}}},
{{"partLabel", "b"}, {"expectedIds", {"B"}}, {"findings", {found}}, {"notes", {note}}, {"coverage", {{{"item", "B"}, {"verdict", "clear"}}}}},
};
Json m = Normalize::MergeParts("L", lens, parts, {});
Check("one note and one finding after the merge, verdict unchanged", m.at("notes").size() == 1 && m.at("findings").size() == 1 && m.at("verdict") == "SEND-READY");
const Json pa = {{"partLabel", "L:block:A"}, {"partKind", "block"}, {"partUnit", "A"}, {"verdict", "FIX FIRST"},
{"findings", {{{"finding", "B contradicts A"}, {"evidence", "e"}, {"proposedAction", "p"}, {"items", {"A", "B"}}, {"discharged", false}}}},
{"notes", Json::array()}, {"coverage", {{{"item", "A"}, {"verdict", "defect"}, {"basis", "b"}}}}, {"coverageMissing", Json::array()}, {"undischarged", 1}};
const Json pb = {{"partLabel", "L:block:B"}, {"partKind", "block"}, {"partUnit", "B"}, {"verdict", "SEND-READY"}, {"findings", Json::array()}, {"notes", Json::array()},
{"coverage", {{{"item", "B"}, {"verdict", "clear"}, {"basis", "checked"}}}}, {"coverageMissing", Json::array()}};
m = Normalize::MergeParts("L", lens, std::vector<Json>{pa, pb}, {});
Json basisOfB;
for (const Json& c : m.at("coverage")) {
if (c.at("item") == "B") basisOfB = c;
}
const bool raised = std::ranges::any_of(m.at("normalizeLogs"), [](const Json& l) { return l.get<std::string>().contains("raised to defect"); });
Check("B raised to defect by the finding citing it; lens FIX FIRST", basisOfB.at("verdict") == "defect" && basisOfB.at("basis").get<std::string>().starts_with("cited by finding")
&& m.at("verdict") == "FIX FIRST" && raised);
Json dischargedFinding = pa.at("findings").at(0);
dischargedFinding["discharged"] = true;
dischargedFinding["dischargedBy"] = "w1";
const Json pc = With(pa, {{"findings", {dischargedFinding}}, {"coverage", {{{"item", "A"}, {"verdict", "clear"}, {"basis", "discharged"}}}}, {"verdict", "SEND-READY"}, {"undischarged", 0}});
Check("a discharged finding does not raise B", Verdicts(Normalize::MergeParts("L", lens, std::vector<Json>{pc, pb}, {}))["B"] == "clear");
const std::vector<std::string> missingA = {"A"};
const Json m3 = Normalize::MergeParts("L", lens, std::vector<Json>{pb}, missingA);
Check("missing unit -> coverageMissing + contract violation + verdict NOT RETURNED", m3.at("coverageMissing") == Json::array({"A"}) && !m3.at("contractViolations").empty()
&& m3.at("verdict") == "NOT RETURNED");
const Json pd = With(pb, {{"coverage", {{{"item", "B"}, {"verdict", "immaterial"}, {"basis", "w"}}}}});
Check("strongest verdict per unit wins (immaterial > clear)", Verdicts(Normalize::MergeParts("L", lens, std::vector<Json>{pb, pd}, {}))["B"] == "immaterial");
const Json result = Normalize::MergeParts("L", lens, std::vector<Json>{pa, pb}, {});
const std::vector<std::string> notReviewed = {"p1:msg"};
const Json mx = Normalize::Matrix(Json::array({{{"id", "A"}}, {{"id", "B"}}, {{"id", "C"}}, {{"id", "p1:msg"}}}), std::vector<Json>{result}, notReviewed);
std::set<std::string> defects;
for (auto it = mx.at("defects").begin(); it != mx.at("defects").end(); ++it) defects.insert(it.key());
Check("matrix: a unit without an entry is MISSING and a hole; a not-reviewed unit is listed, never a hole; defects per unit",
mx.at("matrix").at("C").at("L").at("verdict") == "MISSING" && mx.at("holes") == Json::array({"C"}) && mx.at("notReviewed") == Json::array({"p1:msg"})
&& defects == std::set<std::string>{"A", "B"}, DumpCompactSorted(mx.at("holes")));
return Failures ? 1 : 0;
}