11import os
22import pickle
33import re
4+ import tempfile
45import unittest
56import unittest .mock
6- import tempfile
77from test import support
88from test .support import import_helper
99from test .support import os_helper
5454"""
5555
5656
57+ def patch_screen ():
58+ """Patch turtle._Screen for testing without a display.
59+
60+ We must patch the _Screen class itself instead of the _Screen
61+ instance because instantiating it requires a display.
62+ """
63+ return unittest .mock .patch (
64+ "turtle._Screen.__new__" ,
65+ ** {
66+ "return_value.__class__" : turtle ._Screen ,
67+ "return_value.mode.return_value" : "standard" ,
68+ },
69+ )
70+
71+
5772class TurtleConfigTest (unittest .TestCase ):
5873
5974 def get_cfg_file (self , cfg_str ):
@@ -513,7 +528,7 @@ def test_save_overwrites_if_specified(self) -> None:
513528
514529 turtle .TurtleScreen .save (screen , file_path , overwrite = True )
515530 with open (file_path ) as f :
516- assert f .read () == "postscript"
531+ self . assertEqual ( f .read (), "postscript" )
517532
518533 def test_save (self ) -> None :
519534 screen = unittest .mock .Mock ()
@@ -524,7 +539,98 @@ def test_save(self) -> None:
524539
525540 turtle .TurtleScreen .save (screen , file_path )
526541 with open (file_path ) as f :
527- assert f .read () == "postscript"
542+ self .assertEqual (f .read (), "postscript" )
543+
544+ def test_no_animation_sets_tracer_0 (self ):
545+ s = turtle .TurtleScreen (cv = unittest .mock .MagicMock ())
546+
547+ with s .no_animation ():
548+ self .assertEqual (s .tracer (), 0 )
549+
550+ def test_no_animation_resets_tracer_to_old_value (self ):
551+ s = turtle .TurtleScreen (cv = unittest .mock .MagicMock ())
552+
553+ for tracer in [0 , 1 , 5 ]:
554+ s .tracer (tracer )
555+ with s .no_animation ():
556+ pass
557+ self .assertEqual (s .tracer (), tracer )
558+
559+ def test_no_animation_calls_update_at_exit (self ):
560+ s = turtle .TurtleScreen (cv = unittest .mock .MagicMock ())
561+ s .update = unittest .mock .MagicMock ()
562+
563+ with s .no_animation ():
564+ s .update .assert_not_called ()
565+ s .update .assert_called_once ()
566+
567+
568+ class TestTurtle (unittest .TestCase ):
569+ def setUp (self ):
570+ with patch_screen ():
571+ self .turtle = turtle .Turtle ()
572+
573+ def test_begin_end_fill (self ):
574+ self .assertFalse (self .turtle .filling ())
575+ self .turtle .begin_fill ()
576+ self .assertTrue (self .turtle .filling ())
577+ self .turtle .end_fill ()
578+ self .assertFalse (self .turtle .filling ())
579+
580+ def test_fill (self ):
581+ # The context manager behaves like begin_fill and end_fill.
582+ self .assertFalse (self .turtle .filling ())
583+ with self .turtle .fill ():
584+ self .assertTrue (self .turtle .filling ())
585+ self .assertFalse (self .turtle .filling ())
586+
587+ def test_fill_resets_after_exception (self ):
588+ # The context manager cleans up correctly after exceptions.
589+ try :
590+ with self .turtle .fill ():
591+ self .assertTrue (self .turtle .filling ())
592+ raise ValueError
593+ except ValueError :
594+ self .assertFalse (self .turtle .filling ())
595+
596+ def test_fill_context_when_filling (self ):
597+ # The context manager works even when the turtle is already filling.
598+ self .turtle .begin_fill ()
599+ self .assertTrue (self .turtle .filling ())
600+ with self .turtle .fill ():
601+ self .assertTrue (self .turtle .filling ())
602+ self .assertFalse (self .turtle .filling ())
603+
604+ def test_begin_end_poly (self ):
605+ self .assertFalse (self .turtle ._creatingPoly )
606+ self .turtle .begin_poly ()
607+ self .assertTrue (self .turtle ._creatingPoly )
608+ self .turtle .end_poly ()
609+ self .assertFalse (self .turtle ._creatingPoly )
610+
611+ def test_poly (self ):
612+ # The context manager behaves like begin_poly and end_poly.
613+ self .assertFalse (self .turtle ._creatingPoly )
614+ with self .turtle .poly ():
615+ self .assertTrue (self .turtle ._creatingPoly )
616+ self .assertFalse (self .turtle ._creatingPoly )
617+
618+ def test_poly_resets_after_exception (self ):
619+ # The context manager cleans up correctly after exceptions.
620+ try :
621+ with self .turtle .poly ():
622+ self .assertTrue (self .turtle ._creatingPoly )
623+ raise ValueError
624+ except ValueError :
625+ self .assertFalse (self .turtle ._creatingPoly )
626+
627+ def test_poly_context_when_creating_poly (self ):
628+ # The context manager works when the turtle is already creating poly.
629+ self .turtle .begin_poly ()
630+ self .assertTrue (self .turtle ._creatingPoly )
631+ with self .turtle .poly ():
632+ self .assertTrue (self .turtle ._creatingPoly )
633+ self .assertFalse (self .turtle ._creatingPoly )
528634
529635
530636class TestModuleLevel (unittest .TestCase ):
0 commit comments