Files
voculinux/tests/test_rename_sweep.py
T

176 lines
6.7 KiB
Python

"""Ticket #18 + #24: offline naming-sweep — no old-name strings on surfaces.
The fork takes its own name everywhere a user can see it. Anything still
spelling the old name must be on the allowlist below:
- upstream provenance (``VocaHQ/vocalinux`` URLs),
- the retained internal Python module name (``src/vocalinux`` paths,
``vocalinux.*`` imports/attributes, ``-m vocalinux.main``),
- retained internal class names (``VocalinuxEngine*``, ``VocalinuxDBusService``),
- one-time-legacy import sources (old config/dictionary/bus literals),
- generated or historical files (``uv.lock``, ``requirements/*.txt``,
``CHANGELOG.md``),
- web upstream surfaces (ticket #24): upstream GitHub/raw/nix flake URLs,
nix flake API identifiers, and the nixos-page fork-status note that names
the upstream flake as installing Vocalinux rather than Voculinux.
"""
import os
import re
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
OLD_NAME = re.compile(r"vocalinux", re.IGNORECASE)
SKIP_DIRS = {".git", "__pycache__", ".venv", "venv", "node_modules", ".next", "build", "dist", "out"}
SKIP_SUFFIXES = (".egg-info",)
SKIP_FILES = {"uv.lock", "CHANGELOG.md"}
SKIP_PREFIXES = ("requirements/",)
BINARY_EXTS = (
".wav",
".mp3",
".ogg",
".png",
".svg",
".ico",
".icns",
".bin",
".onnx",
".pt",
".zip",
".tar",
".gz",
".whl",
".AppImage",
".zsync",
".pyc",
)
#: web/ was fully rebranded in ticket #24; only upstream-provenance lines
#: (matched in _allowed) may still spell the old name there.
WEB_OWNED = {"web/src/app/page.tsx", "web/package.json"}
def _allowed(path: str, line: str) -> bool:
"""Return True when an old-name match is an allowlisted surface."""
low = line.lower()
if "vocahq/" in low or "jatinkrmalik/vocalinux" in low:
return True
if "vocalinux" in low and "voculinux" in low:
# Migration-compat shims that name both installs at once.
return True
if "upstream" in low:
# Upstream-provenance mentions that explicitly label the old name
# as upstream (fork-status notes, provenance cards).
return True
if "/{name}/vocalinux" in line:
# Upstream repo-name template (retained provenance).
return True
if path == "snap/local/check_runtime.py" and '"vocalinux"' in line:
# Smoke imports resolve the retained import package.
return True
if re.search(r'vocalinux\.["a-z_]', line):
return True
if line.strip().rstrip(",").lstrip("/ ") == '"vocalinux"':
# Retained module-dir path segment element in tests and tooling
# (single-line and os.path.join element forms).
return True
if 'site / "vocalinux"' in line or '"platform/vocalinux"' in line:
# Fixture module trees named after the retained import package.
return True
if '"vocalinux/' in line:
# Fixture module file paths under the retained package name.
return True
if "/vocalinux/" in line or "src/vocalinux" in line:
return True
if "-m vocalinux" in line or "import vocalinux" in line:
return True
if "VocalinuxEngine" in line or "VocalinuxDBusService" in line:
return True
if "cmdline" in line:
return True
if " - vocalinux" in line:
# Log logger names keep the retained module path.
return True
if path in (
"src/vocalinux/legacy_import.py",
"tests/test_legacy_import.py",
):
return True
if "LEGACY" in line or "legacy" in line:
return True
if "~/.config/vocalinux" in line or '".config" / "vocalinux"' in line:
# Documented one-time-import source (ticket #18).
return True
if "from vocalinux" in line:
return True
if '"src"' in line and '"vocalinux"' in line:
# Retained module-dir path segments in tests and tooling.
return True
if path == "web/src/app/install/nixos/page.tsx":
# The Nix flake is upstream's: flake URL, input/output names, module
# paths, and programs.* options spell the retained upstream API.
# The page carries a fork-status note stating those snippets install
# Vocalinux (upstream), not Voculinux.
return True
if path == "tests/test_rename_sweep.py":
return True
if path == "pyproject.toml" and re.search(r'"vocalinux[."\'\]]', line):
return True
if path == "pyproject.toml" and "vocalinux.version" in line:
return True
if 'PKG_NAME="vocalinux"' in line:
# Installer probes the retained import package, not the distribution.
return True
if path == "packaging/void/srcpkgs/voculinux/template" and "vocalinux-${version}" in line:
# Pre-rename release asset root (ticket #27); dropped at the first
# post-rename release bump.
return True
if path == "tests/test_void_app_template.py" and '"vocalinux"' in line:
# The app-template policy test asserts the old name is gone.
return True
if '== "vocalinux"' in line or '.startswith("vocalinux' in line:
# Retained module identity comparisons in test isolation helpers.
return True
return False
def _iter_files():
for root, dirs, files in os.walk(REPO_ROOT):
dirs[:] = [d for d in sorted(dirs) if d not in SKIP_DIRS]
for name in sorted(files):
if name in SKIP_FILES or name.endswith(BINARY_EXTS):
continue
full = os.path.join(root, name)
rel = os.path.relpath(full, REPO_ROOT)
if rel.startswith(SKIP_PREFIXES):
continue
yield rel, full
def test_naming_sweep_no_old_name_outside_allowlist() -> None:
"""Every old-name hit must be an allowlisted retained surface."""
offenders: list[str] = []
for rel, full in _iter_files():
if any(part.endswith(SKIP_SUFFIXES) for part in rel.split("/")):
continue
try:
with open(full, encoding="utf-8") as handle:
text = handle.read()
except (UnicodeDecodeError, ValueError):
continue
for number, line in enumerate(text.splitlines(), 1):
if OLD_NAME.search(line) and not _allowed(rel, line):
offenders.append(f"{rel}:{number}:{line.strip()[:160]}")
assert (
offenders == []
), f"{len(offenders)} old-name string(s) outside the allowlist:\n" + "\n".join(offenders[:60])
def test_owned_web_files_carry_new_name() -> None:
"""The two web rename surfaces name the fork (URLs aside)."""
for rel in sorted(WEB_OWNED):
with open(os.path.join(REPO_ROOT, rel), encoding="utf-8") as handle:
text = handle.read()
assert "Voculinux" in text or "voculinux" in text, rel