104 lines
3.7 KiB
Python
104 lines
3.7 KiB
Python
"""Tests for the discovery-to-context mapping document."""
|
|
|
|
from pathlib import Path
|
|
|
|
# Path to the mapping document (relative to project root)
|
|
MAPPING_FILE = "context/discovery-context-mapping.md"
|
|
|
|
|
|
def _get_project_root() -> Path:
|
|
"""Return the project root directory.
|
|
|
|
Walk up from this file's location to find the repo root.
|
|
"""
|
|
# Start from tests/ and walk up
|
|
current = Path(__file__).resolve().parent.parent
|
|
# Look for pyproject.toml or .git as markers
|
|
while current != current.parent:
|
|
if (current / "pyproject.toml").exists() or (current / ".git").exists():
|
|
return current
|
|
current = current.parent
|
|
return Path.cwd()
|
|
|
|
|
|
def test_mapping_file_exists() -> None:
|
|
"""The discovery-to-context mapping file must exist."""
|
|
root = _get_project_root()
|
|
mapping_path = root / MAPPING_FILE
|
|
assert mapping_path.exists(), f"Mapping file missing: {mapping_path}"
|
|
|
|
|
|
def test_mapping_contains_all_10_questions() -> None:
|
|
"""Every core discovery question must appear in the mapping."""
|
|
from rdb_discovery.templates import CORE_QUESTIONS
|
|
|
|
root = _get_project_root()
|
|
mapping_path = root / MAPPING_FILE
|
|
content = mapping_path.read_text(encoding="utf-8")
|
|
|
|
for question in CORE_QUESTIONS:
|
|
assert question in content, f"Question not mapped: {question}"
|
|
|
|
|
|
def test_mapping_documentation_contains_table_format() -> None:
|
|
"""The mapping must be documented in a table format (machine-readable)."""
|
|
root = _get_project_root()
|
|
mapping_path = root / MAPPING_FILE
|
|
content = mapping_path.read_text(encoding="utf-8")
|
|
|
|
# Accept both the exact header and any variant that contains the key phrase
|
|
has_section = ("Mapping: Question" in content or "Question → Context" in content)
|
|
assert has_section, (
|
|
"Missing 'Mapping: Question -> Context Files + Sections' section header"
|
|
)
|
|
|
|
|
|
def test_mapping_contains_summary_matrix() -> None:
|
|
"""A summary question-to-file matrix table must exist."""
|
|
root = _get_project_root()
|
|
mapping_path = root / MAPPING_FILE
|
|
content = mapping_path.read_text(encoding="utf-8")
|
|
|
|
assert "Question-to-File Matrix" in content, (
|
|
"Missing 'Question-to-File Matrix' summary section"
|
|
)
|
|
|
|
|
|
def test_mapping_contains_future_implementation_notes() -> None:
|
|
"""The mapping must define future implementation guidance."""
|
|
root = _get_project_root()
|
|
mapping_path = root / MAPPING_FILE
|
|
content = mapping_path.read_text(encoding="utf-8")
|
|
|
|
assert "## Implementation Notes" in content or "## What future implementation should do" in content, (
|
|
"Missing 'Implementation Notes' section"
|
|
)
|
|
# Verify it clearly states no code has been implemented yet
|
|
assert "No code generation has been implemented" in content, (
|
|
"Must clarify that mapping is a planning artifact with no code yet"
|
|
)
|
|
|
|
|
|
def test_mapping_covers_all_context_files() -> None:
|
|
"""Every context file listed in templates.py must appear in the mapping."""
|
|
from rdb_discovery.templates import CONTEXT_FILES
|
|
|
|
# Filter out control files (TASKS.md, PROJECT_STATE.md, etc.) and keep context files
|
|
context_paths = {p for p in CONTEXT_FILES if p.startswith("context/")}
|
|
|
|
root = _get_project_root()
|
|
mapping_path = root / MAPPING_FILE
|
|
content = mapping_path.read_text(encoding="utf-8")
|
|
|
|
# Extract file paths from the mapping's Reference section
|
|
found_files = set()
|
|
for line in content.splitlines():
|
|
for cp in context_paths:
|
|
if f"`{cp}`" in line or cp in line:
|
|
found_files.add(cp)
|
|
|
|
for cp in context_paths:
|
|
assert any(cp in fp for fp in found_files), (
|
|
f"Context file not referenced in mapping: {cp}"
|
|
)
|