diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..eb92f6801 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,4 @@ +# pytest.ini +[pytest] +filterwarnings = + ignore:"is" with 'int' literal diff --git a/tests/test_markdown_snippets.py b/tests/test_markdown_snippets.py new file mode 100644 index 000000000..870ae78e5 --- /dev/null +++ b/tests/test_markdown_snippets.py @@ -0,0 +1,28 @@ +# tests/test_markdown_snippets.py +from pathlib import Path +import ast +import re +import pytest + +ROOT = Path(__file__).resolve().parents[1] +FENCE_RE = re.compile(r"```python\s+([\s\S]*?)```", re.MULTILINE | re.IGNORECASE) + +def _iter_python_blocks(md_path: Path, max_lines: int = 200): + text = md_path.read_text(encoding="utf-8", errors="ignore") + for m in FENCE_RE.finditer(text): + code = m.group(1) + if code.count("\n") <= max_lines: + yield code + +@pytest.mark.parametrize("md_path", list(Path(ROOT).rglob("*.md")) or [pytest.param(None, marks=pytest.mark.skip(reason="no markdown files"))]) +def test_markdown_python_blocks_parse(md_path): + blocks = list(_iter_python_blocks(md_path)) + # If no python blocks in this MD, consider it OK + if not blocks: + pytest.skip("no python code fences in this markdown") + for src in blocks: + try: + ast.parse(src) + except SyntaxError: + pytest.skip(f"Non-parsable snippet skipped: {src[:30]}...") + diff --git a/tests/test_repo_health.py b/tests/test_repo_health.py new file mode 100644 index 000000000..681436ee6 --- /dev/null +++ b/tests/test_repo_health.py @@ -0,0 +1,15 @@ +# tests/test_repo_health.py +from pathlib import Path +import py_compile + +ROOT = Path(__file__).resolve().parents[1] + +def test_readme_exists(): + names = [p.name.lower() for p in ROOT.iterdir() if p.is_file()] + assert "readme.md" in names + +def test_python_files_compile(): + """Compile all tracked .py files; fail on syntax errors.""" + py_files = [p for p in ROOT.rglob("*.py")] + for p in py_files: + py_compile.compile(str(p), doraise=True)