|
1 | 1 | import pickle |
2 | 2 | import unittest |
| 3 | +import unittest.mock |
3 | 4 | from test import support |
4 | 5 | from test.support import import_helper |
5 | 6 | from test.support import os_helper |
|
50 | 51 | """ |
51 | 52 |
|
52 | 53 |
|
| 54 | +def patch_screen(): |
| 55 | + """Patch turtle._Screen for testing without a display. |
| 56 | +
|
| 57 | + We must patch the _Screen class itself instead of the _Screen |
| 58 | + instance because instantiating it requires a display. |
| 59 | + """ |
| 60 | + # Create a mock screen that delegates color validation to the real TurtleScreen methods |
| 61 | + mock_screen = unittest.mock.MagicMock() |
| 62 | + mock_screen.__class__ = turtle._Screen |
| 63 | + mock_screen.mode.return_value = "standard" |
| 64 | + mock_screen._colormode = 1.0 |
| 65 | + |
| 66 | + def mock_iscolorstring(color): |
| 67 | + valid_colors = {'red', 'green', 'blue', 'black', 'white', 'yellow', |
| 68 | + 'orange', 'purple', 'pink', 'brown', 'gray', 'grey', |
| 69 | + 'cyan', 'magenta'} |
| 70 | + |
| 71 | + return color in valid_colors or (isinstance(color, str) and color.startswith('#')) |
| 72 | + |
| 73 | + mock_screen._iscolorstring = mock_iscolorstring |
| 74 | + mock_screen._colorstr = turtle._Screen._colorstr.__get__(mock_screen) |
| 75 | + |
| 76 | + return unittest.mock.patch( |
| 77 | + "turtle._Screen.__new__", |
| 78 | + return_value=mock_screen |
| 79 | + ) |
| 80 | + |
| 81 | + |
53 | 82 | class TurtleConfigTest(unittest.TestCase): |
54 | 83 |
|
55 | 84 | def get_cfg_file(self, cfg_str): |
@@ -461,6 +490,38 @@ def test_teleport(self): |
461 | 490 | self.assertTrue(tpen.isdown()) |
462 | 491 |
|
463 | 492 |
|
| 493 | +class TestTurtle(unittest.TestCase): |
| 494 | + def setUp(self): |
| 495 | + with patch_screen(): |
| 496 | + self.turtle = turtle.Turtle() |
| 497 | + |
| 498 | + # Reset the Screen singleton to avoid reference leaks |
| 499 | + self.addCleanup(setattr, turtle.Turtle, '_screen', None) |
| 500 | + |
| 501 | + def test_dot_signature(self): |
| 502 | + self.turtle.dot() |
| 503 | + self.turtle.dot(10) |
| 504 | + self.turtle.dot(size=10) |
| 505 | + self.turtle.dot((0, 0, 0)) |
| 506 | + self.turtle.dot(size=(0, 0, 0)) |
| 507 | + self.turtle.dot("blue") |
| 508 | + self.turtle.dot("") |
| 509 | + self.turtle.dot(size="blue") |
| 510 | + self.turtle.dot(20, "blue") |
| 511 | + self.turtle.dot(20, "blue") |
| 512 | + self.turtle.dot(20, (0, 0, 0)) |
| 513 | + self.turtle.dot(20, 0, 0, 0) |
| 514 | + with self.assertRaises(TypeError): |
| 515 | + self.turtle.dot(color="blue") |
| 516 | + self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, "_not_a_color_") |
| 517 | + self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, (0, 0, 0, 0)) |
| 518 | + self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, 0, 0, 0, 0) |
| 519 | + self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, (-1, 0, 0)) |
| 520 | + self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, -1, 0, 0) |
| 521 | + self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, (0, 257, 0)) |
| 522 | + self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, 0, 257, 0) |
| 523 | + |
| 524 | + |
464 | 525 | class TestModuleLevel(unittest.TestCase): |
465 | 526 | def test_all_signatures(self): |
466 | 527 | import inspect |
|
0 commit comments