testsAndMisc/python_pkg/code_tutor/tests/conftest.py
Krzysztof kuhy Rudnicki 2d0d69b461 Add code_tutor: interactive codebase-learning CLI
New python_pkg/code_tutor package that turns an unfamiliar codebase into
an interactive lesson: analyse code into items (_analyzer), order them
dependency-first (_plan_builder), pose reimplement challenges
(_challenge + _challenge_support), verify user implementations with tests
and coverage (_verifier), track progress (_progress/_session), and offer
local-LLM hints (_llm), driven by a Typer/Rich CLI (cli).

- meta/pyproject.toml + .pre-commit-config.yaml + meta/requirements.txt:
  add anthropic/rich/typer deps, a cli.py per-file-ignore (Typer B008 etc),
  and code_tutor-specific ruff/pylint/mypy tuning.
- _challenge.py and its tests are split across _challenge_support.py and
  test_challenge_part2/part3.py to stay under the 500-line file cap.

Verification: pytest 631 passed at 100% line+branch coverage; every file
<=500 lines; pre-commit (ruff ALL, mypy strict, pylint 10/10, bandit,
evidence + multi-file contract) green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RRCdR4D8SaVrN2xraMQxM
2026-07-11 00:15:46 +02:00

57 lines
1.6 KiB
Python

"""Shared factory helpers for the ``_challenge`` / ``_challenge_support`` tests.
Kept in ``conftest.py`` (a single, import-safe location) so the split test
modules (``test_challenge``, ``test_challenge_part2``, ``test_challenge_part3``)
reuse one definition instead of duplicating the factories, which would trip
pylint's ``duplicate-code`` check.
"""
from __future__ import annotations
from unittest.mock import MagicMock
from python_pkg.code_tutor._analyzer import CodeItem
def _item(
file: str = "mod.py",
name: str = "fn",
start: int = 1,
end: int = 3,
class_name: str = "",
) -> CodeItem:
"""Build a ``CodeItem`` with sensible defaults for tests.
Args:
file: Relative source-file path for the item.
name: Function name.
start: 1-based start line of the item.
end: 1-based end line of the item.
class_name: Owning class name, or empty for module-level functions.
Returns:
A populated ``CodeItem`` instance.
"""
return CodeItem(
id=f"{file}.{name}",
file=file,
type="function",
name=name,
start_line=start,
end_line=end,
class_name=class_name,
)
def _make_live_mock() -> MagicMock:
"""Return a ``MagicMock`` that behaves like a ``rich.live.Live`` context.
Returns:
A mock whose ``__enter__`` yields itself and whose ``__exit__``
returns ``False`` so exceptions propagate normally.
"""
live = MagicMock()
live.__enter__ = MagicMock(return_value=live)
live.__exit__ = MagicMock(return_value=False)
return live