# -*- coding: utf-8 -*- """Fixture tests for scripts/reuse_refs_check.py — one per row of its resolution table, plus the kill condition. Run: python3 scripts/test_reuse_refs_check.py THE ONE THAT MATTERS is test_absent_path_fails (Scenario E). The 2026-08-02 change taught the checker to resolve suffixes and sibling repos, which turned 13 findings green in one step. A checker made green by being made BLIND is a failure this project has shipped before, so the ability to still fail is pinned here, and the assertion is on the EXIT CODE — the effect — not on the summary text, which the checker can print without having decided anything. """ import importlib.util import io import os import shutil import sys import tempfile import unittest from unittest import mock SCRIPT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "reuse_refs_check.py") def load_checker(): """Fresh module per test — the checker keeps a global failure count and an index cache.""" spec = importlib.util.spec_from_file_location("reuse_refs_check_under_test", SCRIPT) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) return mod def write(path, text=""): d = os.path.dirname(path) if d and not os.path.isdir(d): os.makedirs(d) with io.open(path, "w", encoding="utf-8") as f: f.write(text) class ReuseRefsCheckTest(unittest.TestCase): def setUp(self): self.tmp = tempfile.mkdtemp(prefix="reuse-refs-") self.root = os.path.join(self.tmp, "myrepo") write(os.path.join(self.root, ".git"), "gitdir: elsewhere\n") def tearDown(self): shutil.rmtree(self.tmp, ignore_errors=True) # ── harness ────────────────────────────────────────────────────────────────── def run_check(self, *roots): """Returns (exit_code, stdout). Exit code is the assertion that counts.""" mod = load_checker() buf = io.StringIO() real = sys.stdout sys.stdout = buf try: rc = mod.main(list(roots) or [self.root]) finally: sys.stdout = real return rc, buf.getvalue() def reuse(self, body): write(os.path.join(self.root, "REUSE.md"), body) def sibling(self, name): p = os.path.join(self.tmp, name) write(os.path.join(p, ".git"), "gitdir: elsewhere\n") return p # ── row 1: exact ───────────────────────────────────────────────────────────── def test_exact_match_is_silent_and_passes(self): write(os.path.join(self.root, "a", "b.go"), "package a\n") self.reuse("see `a/b.go` for the thing\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) self.assertIn("exact 1", out) self.assertNotIn("note [", out) # an exact hit prints no note # ── row 2: suffix ──────────────────────────────────────────────────────────── def test_package_shorthand_resolves_by_suffix(self): write(os.path.join(self.root, "controller", "internal", "pkg", "x.go"), "package pkg\n") self.reuse("see `pkg/x.go`\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) self.assertIn("resolved by suffix", out) self.assertIn("controller/internal/pkg/x.go", out) self.assertIn("suffix 1", out) # ── row 3: ambiguous — real citation, imprecise shorthand; NOT a failure ───── def test_two_suffix_matches_are_ambiguous_not_fatal(self): write(os.path.join(self.root, "one", "pkg", "x.go"), "package pkg\n") write(os.path.join(self.root, "two", "pkg", "x.go"), "package pkg\n") self.reuse("see `pkg/x.go`\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) self.assertIn("AMBIGUOUS", out) self.assertIn("one/pkg/x.go", out) self.assertIn("two/pkg/x.go", out) self.assertIn("ambiguous 1", out) # ── row 4: cross-repo, by suffix in a sibling ──────────────────────────────── def test_sibling_repo_resolution(self): sib = self.sibling("otherrepo") write(os.path.join(sib, "hub", "internal", "wgsync", "reconciler.go"), "package wgsync\n") self.reuse("see `wgsync/reconciler.go`\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) self.assertIn("cross-repo", out) self.assertIn("otherrepo", out) self.assertIn("cross-repo 1", out) # ── row 4b: cross-repo where the token CARRIES the sibling's repo name ─────── def test_sibling_repo_name_prefixed_token(self): sib = self.sibling("felhom.eu") write(os.path.join(sib, "scripts", "site_gates.py"), "# gate\n") self.reuse("run `felhom.eu/scripts/site_gates.py`\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) self.assertIn("cross-repo", out) # ── R-1114: a worktree outside git/ searches the workspace, never its own main clone ── def test_worktree_searches_the_workspace_not_its_own_main_clone(self): ws = os.path.join(self.tmp, "git") main = os.path.join(ws, "mainrepo") os.makedirs(os.path.join(main, ".git", "worktrees", "b3")) write(os.path.join(main, "only", "in", "main.go"), "package in\n") shared = os.path.join(ws, "felhom.eu") os.makedirs(os.path.join(shared, ".git")) write(os.path.join(shared, "scripts", "x.py"), "# gate\n") wt = os.path.join(self.tmp, "wt", "b3") write(os.path.join(wt, ".git"), "gitdir: %s\n" % os.path.join(main, ".git", "worktrees", "b3")) write(os.path.join(wt, "REUSE.md"), "run `felhom.eu/scripts/x.py`\n") rc, out = self.run_check(wt) self.assertNotEqual(rc, 0, "without FELHOM_WORKSPACE the worktree's own parent holds no felhom.eu:\n" + out) with mock.patch.dict(os.environ, {"FELHOM_WORKSPACE": ws}): rc, out = self.run_check(wt) self.assertEqual(rc, 0, out) self.assertNotIn("mainrepo", out.split("siblings searched:")[-1]) # its own main clone is skipped # a path that exists only in the main clone (deleted in the worktree) must NOT resolve there write(os.path.join(wt, "REUSE.md"), "see `only/in/main.go`\n") rc, out = self.run_check(wt) self.assertNotEqual(rc, 0, out) def test_non_git_sibling_is_not_searched(self): plain = os.path.join(self.tmp, "notarepo") # no .git — not a repo, must not resolve write(os.path.join(plain, "pkg", "x.go"), "package pkg\n") self.reuse("see `pkg/x.go`\n") rc, out = self.run_check() self.assertNotEqual(rc, 0, out) # ── row 5: THE KILL CONDITION (Scenario E) ────────────────────────────────── def test_absent_path_fails(self): write(os.path.join(self.root, "internal", "present.go"), "package internal\n") self.reuse("line one\nsee `internal/definitely_absent_xyz.go`\n") rc, out = self.run_check() self.assertNotEqual(rc, 0, "a citation that exists NOWHERE must fail:\n" + out) self.assertIn("definitely_absent_xyz.go", out) self.assertIn("line 2", out) # names the line self.assertIn("FAILED 1", out) def test_failure_lists_every_resolution_attempted(self): """CLAUDE.md standing rule: a 'not found' claim must name what was tried.""" self.sibling("otherrepo") self.reuse("see `internal/definitely_absent_xyz.go`\n") rc, out = self.run_check() self.assertNotEqual(rc, 0, out) self.assertIn("tried: repo-relative myrepo/internal/definitely_absent_xyz.go", out) self.assertIn("tried: suffix search over", out) self.assertIn("tried: sibling otherrepo", out) # ── evidence trees are not the file ───────────────────────────────────────── def test_evidence_copy_does_not_satisfy_a_citation(self): write(os.path.join(self.root, "documentation", "audits", "pkg", "x.go"), "package pkg\n") write(os.path.join(self.root, "documentation", "tests", "pkg", "y.go"), "package pkg\n") self.reuse("see `pkg/x.go` and `pkg/y.go`\n") rc, out = self.run_check() self.assertNotEqual(rc, 0, "an audits/ or documentation/tests/ copy must NOT resolve:\n" + out) self.assertIn("FAILED 2", out) # ── R-422: document citations are checked ─────────────────────────────────── def test_absent_md_citation_fails(self): """The measured hole: a rotted .md citation passed because .md was not a checked extension.""" self.reuse("see `documentation/architecture/99-does-not-exist.md`\n") rc, out = self.run_check() self.assertNotEqual(rc, 0, "a .md citation that exists nowhere must fail:\n" + out) self.assertIn("99-does-not-exist.md", out) def test_md_citation_resolves_including_under_audits(self): """An audit DOCUMENT is the cited thing, not an evidence copy — it must resolve (the one false positive the 2026-10-05 walk found, in app-catalog's REUSE.md).""" write(os.path.join(self.root, "documentation", "architecture", "05-hub.md"), "# x\n") write(os.path.join(self.root, "documentation", "audits", "SPIKE-x.md"), "# y\n") self.reuse("see `documentation/architecture/05-hub.md` and `documentation/audits/SPIKE-x.md`\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) def test_audits_still_hide_code_copies_when_docs_are_indexed(self): """Indexing .md under audits/ must not let a .go evidence copy there resolve.""" write(os.path.join(self.root, "documentation", "audits", "pkg", "x.go"), "package pkg\n") write(os.path.join(self.root, "documentation", "audits", "pkg", "notes.md"), "# n\n") self.reuse("see `pkg/x.go`\n") rc, out = self.run_check() self.assertNotEqual(rc, 0, out) # ── a clone in isolation must still check itself ──────────────────────────── def test_no_siblings_is_not_a_failure(self): write(os.path.join(self.root, "a", "b.go"), "package a\n") self.reuse("see `a/b.go`\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) self.assertIn("siblings searched: none", out) def test_missing_reuse_md_fails(self): rc, out = self.run_check() self.assertNotEqual(rc, 0, out) self.assertIn("no REUSE.md", out) # ── globs stay conventions, not refs ──────────────────────────────────────── def test_glob_is_not_a_citation(self): self.reuse("the gates are `scripts/*.py`\n") rc, out = self.run_check() self.assertEqual(rc, 0, out) self.assertIn("0 cited paths", out) # ── no args → usage, exit 2 ───────────────────────────────────────────────── def test_no_args_is_usage_exit_2(self): mod = load_checker() buf, real = io.StringIO(), sys.stdout sys.stdout = buf try: rc = mod.main([]) finally: sys.stdout = real self.assertEqual(rc, 2) if __name__ == "__main__": unittest.main(verbosity=2)