testsAndMisc/python_pkg/code_tutor/tests/test_challenge_part3.py
Krzysztof kuhy Rudnicki e3214c813c
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Python tests / test (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Clear the seven over-cap code_tutor test modules
Partitioned at the section banners each file already used, into ten new
modules named for what they cover. python_pkg/code_tutor is now entirely
under the cap, from thirteen violations.

The splitter copies the whole original header into each new file and
lets ruff's F401 pass prune it - 59 imports removed correctly, versus a
hand-written import block failing on every earlier test split today.
That does not cover module-level helpers: _make_verifier sat between two
banners and was left behind by its callers, so it moved to conftest.py,
taking test_verifier.py's shadowing copy of _make_live_mock with it.

No patch string changed. Pass count is 217 before and after.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-16 18:06:38 +02:00

119 lines
3.7 KiB
Python

"""Tests for python_pkg.code_tutor._challenge -- part 3.
Covers the user-implementation runner and the two challenge flows plus the
public entry point: ``_run_user_impl``, ``_write_tests_first_flow``,
``_existing_tests_flow`` and ``run_coding_challenge``.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from unittest.mock import MagicMock, patch
from python_pkg.code_tutor._challenge import _run_user_impl
from python_pkg.code_tutor.tests.conftest import _item, _make_live_mock
if TYPE_CHECKING:
from pathlib import Path
# ---------------------------------------------------------------------------
# _run_user_impl
# ---------------------------------------------------------------------------
def test_run_user_impl_skip(tmp_path: Path) -> None:
source = "def fn():\n return 1\n"
(tmp_path / "mod.py").write_text(source, encoding="utf-8")
mock_console = MagicMock()
live_mock = _make_live_mock()
with (
patch("python_pkg.code_tutor._verdict.Live", return_value=live_mock),
patch("python_pkg.code_tutor._challenge.Syntax"),
):
result = _run_user_impl(
_item(file="mod.py"),
str(tmp_path),
"def test_fn(): pass",
"# import",
mock_console,
lambda _: "skip",
)
assert result == "skipped"
def test_run_user_impl_syntax_error(tmp_path: Path) -> None:
source = "def fn():\n return 1\n"
(tmp_path / "mod.py").write_text(source, encoding="utf-8")
mock_console = MagicMock()
inputs = iter(["def (broken):", ""])
with patch("python_pkg.code_tutor._challenge.Syntax"):
result = _run_user_impl(
_item(file="mod.py"),
str(tmp_path),
"def test_fn(): pass",
"# import",
mock_console,
lambda _: next(inputs, "END") if _ == "" else "END",
)
# Provide the END and the broken implementation
inputs2 = iter(["def (broken):", "END"])
with patch("python_pkg.code_tutor._challenge.Syntax"):
result = _run_user_impl(
_item(file="mod.py"),
str(tmp_path),
"def test_fn(): pass",
"# import",
mock_console,
lambda _: next(inputs2),
)
assert result == "failed"
def test_run_user_impl_passed(tmp_path: Path) -> None:
source = "def fn():\n return 1\n"
(tmp_path / "mod.py").write_text(source, encoding="utf-8")
mock_console = MagicMock()
inputs = iter(["def fn():", " return 42", "END"])
with (
patch("python_pkg.code_tutor._challenge.Syntax"),
patch("python_pkg.code_tutor._challenge._pytest_clean", return_value=True),
):
result = _run_user_impl(
_item(file="mod.py"),
str(tmp_path),
"def test_fn(): pass",
"# import",
mock_console,
lambda _: next(inputs),
)
assert result == "passed"
# File restored
assert (tmp_path / "mod.py").read_text(encoding="utf-8") == source
def test_run_user_impl_failed(tmp_path: Path) -> None:
source = "def fn():\n return 1\n"
(tmp_path / "mod.py").write_text(source, encoding="utf-8")
mock_console = MagicMock()
inputs = iter(["def fn():", " return 0", "END"])
with (
patch("python_pkg.code_tutor._challenge.Syntax"),
patch("python_pkg.code_tutor._challenge._pytest_clean", return_value=False),
):
result = _run_user_impl(
_item(file="mod.py"),
str(tmp_path),
"def test_fn(): pass",
"# import",
mock_console,
lambda _: next(inputs),
)
assert result == "failed"
assert (tmp_path / "mod.py").read_text(encoding="utf-8") == source