Add draw_square and draw_dashed_line with tests

Challenge 1 draws four sides and turns right 90 degrees after each. Challenge 2 puts
the pen down for a dash and up for a gap and leaves it down at the end. Lengths and
counts come from constants.py; invalid values raise ValueError.

Task: MIL-002#3
Task: MIL-002#4
Task: MIL-002#5
This commit is contained in:
2026-10-07 23:58:52 +08:00
parent e2249de46e
commit a34bf6bbc2
6 changed files with 217 additions and 1 deletions
+76
View File
@@ -0,0 +1,76 @@
import pytest
from tests.fakes import FakePen
from turtle_challenges.constants import DASH_COUNT, DASH_LENGTH, GAP_LENGTH
from turtle_challenges.dashed_line import draw_dashed_line
def test_draw_dashed_line_alternates_dash_and_gap() -> None:
pen = FakePen()
draw_dashed_line(pen, dash_count=2)
assert (
pen.calls[:-1]
== [
("pendown", ()),
("forward", (DASH_LENGTH,)),
("penup", ()),
("forward", (GAP_LENGTH,)),
]
* 2
)
def test_draw_dashed_line_draws_the_default_number_of_dashes() -> None:
pen = FakePen()
draw_dashed_line(pen)
assert pen.names().count("pendown") == DASH_COUNT + 1
assert pen.names().count("forward") == 2 * DASH_COUNT
def test_draw_dashed_line_leaves_the_pen_down() -> None:
pen = FakePen()
draw_dashed_line(pen, dash_count=3)
assert pen.calls[-1] == ("pendown", ())
def test_draw_dashed_line_uses_the_given_lengths() -> None:
pen = FakePen()
draw_dashed_line(pen, dash_count=1, dash_length=4, gap_length=7)
assert pen.args_of("forward") == [(4,), (7,)]
def test_draw_dashed_line_with_no_dashes_only_puts_the_pen_down() -> None:
pen = FakePen()
draw_dashed_line(pen, dash_count=0)
assert pen.names() == ["pendown"]
def test_draw_dashed_line_rejects_a_negative_count() -> None:
pen = FakePen()
with pytest.raises(ValueError, match="dash_count"):
draw_dashed_line(pen, dash_count=-1)
assert pen.calls == []
@pytest.mark.parametrize(("dash_length", "gap_length"), [(0, 10), (10, 0), (-1, 10)])
def test_draw_dashed_line_rejects_a_length_that_is_not_positive(
dash_length: float, gap_length: float
) -> None:
pen = FakePen()
with pytest.raises(ValueError, match="lengths"):
draw_dashed_line(pen, dash_length=dash_length, gap_length=gap_length)
assert pen.calls == []
+46
View File
@@ -0,0 +1,46 @@
import pytest
from tests.fakes import FakePen
from turtle_challenges.constants import RIGHT_ANGLE_DEGREES, SQUARE_SIDE_LENGTH
from turtle_challenges.square import draw_square
def test_draw_square_moves_forward_and_turns_right_four_times() -> None:
pen = FakePen()
draw_square(pen)
assert (
pen.calls
== [
("forward", (SQUARE_SIDE_LENGTH,)),
("right", (RIGHT_ANGLE_DEGREES,)),
]
* 4
)
def test_draw_square_uses_the_given_side_length() -> None:
pen = FakePen()
draw_square(pen, side_length=40)
assert pen.args_of("forward") == [(40,)] * 4
def test_draw_square_returns_the_turtle_to_its_start_heading() -> None:
pen = FakePen()
draw_square(pen)
assert pen.heading() == 0
@pytest.mark.parametrize("side_length", [0, -5])
def test_draw_square_rejects_a_side_that_is_not_positive(side_length: float) -> None:
pen = FakePen()
with pytest.raises(ValueError, match="side_length"):
draw_square(pen, side_length=side_length)
assert pen.calls == []