Files
ewoooc/tests/test_requirements_pinning.py
2026-05-13 11:18:35 +08:00

79 lines
2.7 KiB
Python

from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
def _strip_inline_comment(line: str) -> str:
return line.split("#", 1)[0].strip()
def _requirement_name(line: str) -> str:
line = _strip_inline_comment(line)
for operator in ("==", ">=", "<=", "~=", "!=", ">"):
if operator in line:
return line.split(operator, 1)[0].strip().lower()
return line.lower()
def _requirement_names() -> set[str]:
names = set()
for raw_line in (ROOT / "requirements.txt").read_text(encoding="utf-8").splitlines():
line = _strip_inline_comment(raw_line)
if not line or line.startswith(("-", "--")):
continue
names.add(_requirement_name(line))
return names
def test_requirements_have_version_specifiers():
unpinned = []
for raw_line in (ROOT / "requirements.txt").read_text(encoding="utf-8").splitlines():
line = _strip_inline_comment(raw_line)
if not line:
continue
if line.startswith(("-", "--")):
continue
if "@" in line:
continue
if not any(op in line for op in ("==", ">=", "<=", "~=", "!=", ">")):
unpinned.append(line)
assert unpinned == []
def test_audit_flagged_runtime_dependencies_have_import_evidence():
requirements = _requirement_names()
runtime_evidence = {
"beautifulsoup4": [
("services/cosme_crawler.py", "from bs4 import BeautifulSoup"),
("services/momo_crawler.py", "from bs4 import BeautifulSoup"),
("services/trend_crawler.py", "from bs4 import BeautifulSoup"),
],
"google-api-python-client": [
("services/google_drive_service.py", "from googleapiclient.discovery import build"),
],
"google-generativeai": [
("services/gemini_service.py", "import google.generativeai as genai"),
("services/openclaw_strategist_service.py", "import google.generativeai as genai"),
],
"python-pptx": [
("services/ppt_generator.py", "from pptx import Presentation"),
],
"matplotlib": [
("routes/openclaw_bot_routes.py", "import matplotlib"),
("services/chart_generator_service.py", "import matplotlib"),
("services/ppt_generator.py", "import matplotlib"),
],
}
missing_packages = sorted(set(runtime_evidence) - requirements)
assert missing_packages == []
missing_evidence = []
for package, locations in runtime_evidence.items():
if not any(pattern in (ROOT / path).read_text(encoding="utf-8") for path, pattern in locations):
missing_evidence.append(package)
assert missing_evidence == []