# -*- 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 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) 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) # ── 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)