Skip to content

Commit 7f8ce74

Browse files
committed
gh-131178: add unittest for turtledemo
1 parent d4e5802 commit 7f8ce74

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

Lib/test/test_turtledemo.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import unittest
2+
import os
3+
import importlib.util
4+
5+
6+
class TurtledemoCommandLineTest(unittest.TestCase):
7+
"""Test command line interface for turtledemo module."""
8+
9+
def setUp(self):
10+
"""Set up test fixtures."""
11+
self.demo_dir = os.path.join(os.path.dirname(__file__), '..', 'turtledemo')
12+
self.main_file = os.path.join(self.demo_dir, '__main__.py')
13+
14+
def test_turtledemo_directory_exists(self):
15+
"""Test that turtledemo directory exists."""
16+
self.assertTrue(os.path.exists(self.demo_dir), "turtledemo directory exists")
17+
self.assertTrue(os.path.isdir(self.demo_dir), "turtledemo is a directory")
18+
19+
def test_main_file_exists(self):
20+
"""Test that __main__.py exists."""
21+
self.assertTrue(os.path.exists(self.main_file), "__main__.py exists")
22+
23+
def test_demo_files_exist(self):
24+
"""Test that demo files exist."""
25+
if os.path.exists(self.demo_dir):
26+
demo_files = [f for f in os.listdir(self.demo_dir)
27+
if f.endswith('.py') and not f.startswith('_')]
28+
self.assertGreater(len(demo_files), 0, f"found {len(demo_files)} demo files")
29+
30+
# Check for known demo files
31+
expected_demos = ['bytedesign.py', 'chaos.py', 'clock.py', 'colormixer.py', 'forest.py']
32+
for demo in expected_demos:
33+
self.assertIn(demo, demo_files, f"demo file {demo} exists")
34+
35+
def test_module_import(self):
36+
"""Test that turtledemo module can be imported."""
37+
try:
38+
spec = importlib.util.spec_from_file_location("turtledemo",
39+
os.path.join(self.demo_dir, '__init__.py'))
40+
if spec and spec.loader:
41+
turtledemo = importlib.util.module_from_spec(spec)
42+
spec.loader.exec_module(turtledemo)
43+
self.assertTrue(True, "turtledemo module imported successfully")
44+
else:
45+
self.fail("could not create spec for turtledemo")
46+
except Exception as e:
47+
self.fail(f"turtledemo import failed: {e}")
48+
49+
def test_main_module_structure(self):
50+
"""Test __main__ module structure."""
51+
try:
52+
with open(self.main_file, 'r') as f:
53+
content = f.read()
54+
55+
# Check for key functions and classes
56+
self.assertIn('def main():', content, "main function defined")
57+
self.assertIn('class DemoWindow', content, "DemoWindow class defined")
58+
self.assertIn('def getExampleEntries():', content, "getExampleEntries function defined")
59+
self.assertIn('if __name__ == \'__main__\':', content, "__main__ guard present")
60+
61+
# Check for imports
62+
self.assertIn('import sys', content, "sys import present")
63+
self.assertIn('import os', content, "os import present")
64+
self.assertIn('from tkinter import', content, "tkinter import present")
65+
66+
except Exception as e:
67+
self.fail(f"failed to read __main__.py: {e}")
68+
69+
def test_individual_demo_files_structure(self):
70+
"""Test individual demo files structure."""
71+
demo_files_to_check = ['bytedesign.py', 'chaos.py', 'clock.py']
72+
for demo_file in demo_files_to_check:
73+
with self.subTest(demo_file=demo_file):
74+
demo_path = os.path.join(self.demo_dir, demo_file)
75+
if os.path.exists(demo_path):
76+
try:
77+
with open(demo_path, 'r') as f:
78+
content = f.read()
79+
self.assertIn('def main():', content, f"{demo_file} has main function")
80+
has_main_guard = ('if __name__ == \'__main__\':' in content or
81+
'if __name__ == "__main__":' in content)
82+
self.assertTrue(has_main_guard, f"{demo_file} has __main__ guard")
83+
except Exception as e:
84+
self.fail(f"failed to read {demo_file}: {e}")
85+
86+
def test_configuration_files(self):
87+
"""Test configuration files exist."""
88+
config_file = os.path.join(self.demo_dir, 'turtle.cfg')
89+
self.assertTrue(os.path.exists(config_file), "turtle.cfg exists")
90+
91+
def test_main_file_syntax(self):
92+
"""Test that __main__.py is valid Python code."""
93+
try:
94+
with open(self.main_file, 'r') as f:
95+
content = f.read()
96+
97+
# Try to compile it
98+
compile(content, self.main_file, 'exec')
99+
# If we get here, compilation succeeded
100+
self.assertTrue(True, "__main__.py is valid Python code")
101+
102+
except SyntaxError as e:
103+
self.fail(f"__main__.py has syntax error: {e}")
104+
except Exception as e:
105+
self.fail(f"failed to validate __main__.py: {e}")
106+
107+
def test_documentation_strings(self):
108+
"""Test for documentation strings."""
109+
try:
110+
with open(self.main_file, 'r') as f:
111+
content = f.read()
112+
113+
# Check for module docstring
114+
has_docstring = (content.startswith('"""') or content.startswith("'''"))
115+
self.assertTrue(has_docstring, "__main__.py has module docstring")
116+
117+
# Check for function docstrings
118+
self.assertIn('"""', content, "contains docstrings")
119+
120+
except Exception as e:
121+
self.fail(f"failed to check docstrings: {e}")
122+
123+
def test_cli_entry_point(self):
124+
"""Test CLI entry point."""
125+
try:
126+
with open(self.main_file, 'r') as f:
127+
content = f.read()
128+
129+
# Check that main() is called when run as script
130+
self.assertIn('main()', content, "main() is called in __main__")
131+
132+
except Exception as e:
133+
self.fail(f"failed to check CLI entry point: {e}")
134+
135+
136+
if __name__ == '__main__':
137+
unittest.main()

0 commit comments

Comments
 (0)