Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pythonlings/screens/track.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def on_mount(self) -> None:
self.current = self._initial_exercise()
self._render_state()
if self.current is None:
self.query_one(OutputPanel).show_final(
self.query_one(OutputPanel).show_topic_complete(
f"Topic '{self.topic}' complete."
)
return
Expand Down Expand Up @@ -198,7 +198,7 @@ def _apply_result(self, exercise: Exercise, result: RunResult) -> None:
celebration_message(len(all_exercises))
)
else:
self.query_one(OutputPanel).show_final(
self.query_one(OutputPanel).show_topic_complete(
f"Topic '{self.topic}' complete β€” press F4 for topics."
)
return
Expand Down
2 changes: 1 addition & 1 deletion pythonlings/screens/welcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def welcome_text() -> str:
return (
"You learn Python here by fixing small broken programs. The loop is:\n\n"
" 1. Edit the current exercise in the built-in editor.\n"
" 2. Save -- the check reruns automatically as you type.\n"
" 2. Checks rerun automatically as you type.\n"
" 3. Remove the `# I AM NOT DONE` marker to advance to the next one.\n\n"
"Handy keys: F1 hint - F3 exercise list - F4 topics - "
"F5 local docs - Ctrl+Q quit.\n\n"
Expand Down
11 changes: 9 additions & 2 deletions pythonlings/widgets/output_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,19 @@ def render_result(
)

def show_final(self, message: str) -> None:
"""Render the curriculum-complete screen."""
"""Render the whole-curriculum-complete screen."""
self._show_complete("All exercises complete", message)

def show_topic_complete(self, message: str) -> None:
"""Render a single-topic-complete screen (not the whole curriculum)."""
self._show_complete("Topic complete", message)

def _show_complete(self, header: str, message: str) -> None:
self.remove_class("failed", "pending")
self.add_class("passed")
self.query_one("#hint", Static).remove_class("visible")
self.query_one("#output-header", Static).update(
"[bold green]All exercises complete[/bold green]"
f"[bold green]{header}[/bold green]"
)
self.query_one("#goal", Static).update("")
self.query_one("#docs", Static).update("")
Expand Down
26 changes: 26 additions & 0 deletions tests/tui/test_output_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,29 @@ async def test_full_hint_toggles_on_f1(tmp_path: Path) -> None:
panel.toggle_hint("Full hint text.")
await pilot.pause()
assert "Full hint text." in str(panel.query_one("#hint", Static).content)


@pytest.mark.asyncio
async def test_show_topic_complete_uses_topic_header_not_global(tmp_path: Path) -> None:
app = _Harness()
async with app.run_test() as pilot:
await pilot.pause()
panel = app.query_one(OutputPanel)
panel.show_topic_complete("Topic 'variables' complete β€” press F4 for topics.")
await pilot.pause()
header = str(panel.query_one("#output-header", Static).content)
assert "Topic complete" in header
assert "All exercises complete" not in header
assert "Topic 'variables' complete" in panel.renderable_text()


@pytest.mark.asyncio
async def test_show_final_keeps_global_header(tmp_path: Path) -> None:
app = _Harness()
async with app.run_test() as pilot:
await pilot.pause()
panel = app.query_one(OutputPanel)
panel.show_final("πŸŽ‰ done")
await pilot.pause()
header = str(panel.query_one("#output-header", Static).content)
assert "All exercises complete" in header
2 changes: 2 additions & 0 deletions tests/tui/test_welcome_pilot.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import shutil
from pathlib import Path

Expand Down
5 changes: 4 additions & 1 deletion tests/unit/test_welcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ def test_welcome_text_explains_the_loop() -> None:
text = welcome_text()

assert "I AM NOT DONE" in text
assert "save" in text.lower()
# v0.4.0 reruns checks as you type in the built-in editor β€” no manual save,
# so the copy must not tell users to "save".
assert "as you type" in text.lower()
assert "save" not in text.lower()
assert "F1" in text
Loading