import re
import sys
import traceback
from pathlib import Path
import pytest
import os
if hasattr(sys.stdout, 'reconfigure'):
try:
sys.stdout.reconfigure(encoding='utf-8')
except (AttributeError, OSError):
pass
os.environ['PYTHONIOENCODING'] = 'utf-8'
def extract_python_code_blocks(markdown_content):
pattern = r'```python\n(.*?)\n```'
matches = re.findall(pattern, markdown_content, re.DOTALL)
return matches
def run_code_blocks(code_blocks, context=None):
if context is None:
context = {}
results = []
for i, code in enumerate(code_blocks):
print(f"\n--- Running code block {i+1} ---")
print(code)
print("-" * 40)
try:
exec(code, context)
print("SUCCESS")
results.append(True)
except Exception as e:
print(f"ERROR: {e}")
traceback.print_exc()
results.append(False)
return results
def test_markdown_file():
docs_dir = Path(__file__).parent
file_path = docs_dir / "source" / "python_usage.md"
if not file_path.exists():
pytest.skip(f"Documentation file not found: {file_path}")
print(f"Testing Python code blocks in: {file_path}")
print("=" * 60)
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
code_blocks = extract_python_code_blocks(content)
if not code_blocks:
print("No Python code blocks found.")
return
print(f"Found {len(code_blocks)} Python code blocks.")
results = run_code_blocks(code_blocks)
print("\n" + "=" * 60)
print("Summary:")
successful = sum(results)
total = len(results)
print(f"PASSED: {successful}/{total} code blocks ran successfully")
if successful == total:
print("ALL TESTS PASSED!")
else:
print("SOME TESTS FAILED")
assert False, f"Only {successful}/{total} code blocks passed"
if __name__ == "__main__":
if len(sys.argv) == 2:
markdown_file = Path(sys.argv[1])
if not markdown_file.exists():
print(f"Error: File {markdown_file} does not exist")
sys.exit(1)
with open(markdown_file, 'r', encoding='utf-8') as f:
content = f.read()
code_blocks = extract_python_code_blocks(content)
if not code_blocks:
print("No Python code blocks found.")
sys.exit(0)
print(f"Found {len(code_blocks)} Python code blocks.")
results = run_code_blocks(code_blocks)
print("\n" + "=" * 60)
print("Summary:")
successful = sum(results)
total = len(results)
print(f"PASSED: {successful}/{total} code blocks ran successfully")
if successful == total:
print("ALL TESTS PASSED!")
sys.exit(0)
else:
print("SOME TESTS FAILED")
sys.exit(1)
else:
print("Usage: python test_docs_code.py <markdown_file>")
print("Or run with pytest to test the default documentation file.")
sys.exit(1)