ยปCore Development>Code coverage>Lib/test/test_turtle.py

Python code coverage for Lib/test/test_turtle.py

#countcontent
1n/aimport pickle
2n/aimport unittest
3n/afrom test import support
4n/a
5n/aturtle = support.import_module('turtle')
6n/aVec2D = turtle.Vec2D
7n/a
8n/atest_config = """\
9n/awidth = 0.75
10n/aheight = 0.8
11n/acanvwidth = 500
12n/acanvheight = 200
13n/aleftright = 100
14n/atopbottom = 100
15n/amode = world
16n/acolormode = 255
17n/adelay = 100
18n/aundobuffersize = 10000
19n/ashape = circle
20n/apencolor = red
21n/afillcolor = blue
22n/aresizemode = auto
23n/avisible = None
24n/alanguage = english
25n/aexampleturtle = turtle
26n/aexamplescreen = screen
27n/atitle = Python Turtle Graphics
28n/ausing_IDLE = ''
29n/a"""
30n/a
31n/atest_config_two = """\
32n/a# Comments!
33n/a# Testing comments!
34n/apencolor = red
35n/afillcolor = blue
36n/avisible = False
37n/alanguage = english
38n/a# Some more
39n/a# comments
40n/ausing_IDLE = False
41n/a"""
42n/a
43n/ainvalid_test_config = """
44n/apencolor = red
45n/afillcolor: blue
46n/avisible = False
47n/a"""
48n/a
49n/a
50n/aclass TurtleConfigTest(unittest.TestCase):
51n/a
52n/a def get_cfg_file(self, cfg_str):
53n/a self.addCleanup(support.unlink, support.TESTFN)
54n/a with open(support.TESTFN, 'w') as f:
55n/a f.write(cfg_str)
56n/a return support.TESTFN
57n/a
58n/a def test_config_dict(self):
59n/a
60n/a cfg_name = self.get_cfg_file(test_config)
61n/a parsed_cfg = turtle.config_dict(cfg_name)
62n/a
63n/a expected = {
64n/a 'width' : 0.75,
65n/a 'height' : 0.8,
66n/a 'canvwidth' : 500,
67n/a 'canvheight': 200,
68n/a 'leftright': 100,
69n/a 'topbottom': 100,
70n/a 'mode': 'world',
71n/a 'colormode': 255,
72n/a 'delay': 100,
73n/a 'undobuffersize': 10000,
74n/a 'shape': 'circle',
75n/a 'pencolor' : 'red',
76n/a 'fillcolor' : 'blue',
77n/a 'resizemode' : 'auto',
78n/a 'visible' : None,
79n/a 'language': 'english',
80n/a 'exampleturtle': 'turtle',
81n/a 'examplescreen': 'screen',
82n/a 'title': 'Python Turtle Graphics',
83n/a 'using_IDLE': '',
84n/a }
85n/a
86n/a self.assertEqual(parsed_cfg, expected)
87n/a
88n/a def test_partial_config_dict_with_commments(self):
89n/a
90n/a cfg_name = self.get_cfg_file(test_config_two)
91n/a parsed_cfg = turtle.config_dict(cfg_name)
92n/a
93n/a expected = {
94n/a 'pencolor': 'red',
95n/a 'fillcolor': 'blue',
96n/a 'visible': False,
97n/a 'language': 'english',
98n/a 'using_IDLE': False,
99n/a }
100n/a
101n/a self.assertEqual(parsed_cfg, expected)
102n/a
103n/a def test_config_dict_invalid(self):
104n/a
105n/a cfg_name = self.get_cfg_file(invalid_test_config)
106n/a
107n/a with support.captured_stdout() as stdout:
108n/a parsed_cfg = turtle.config_dict(cfg_name)
109n/a
110n/a err_msg = stdout.getvalue()
111n/a
112n/a self.assertIn('Bad line in config-file ', err_msg)
113n/a self.assertIn('fillcolor: blue', err_msg)
114n/a
115n/a self.assertEqual(parsed_cfg, {
116n/a 'pencolor': 'red',
117n/a 'visible': False,
118n/a })
119n/a
120n/a
121n/aclass VectorComparisonMixin:
122n/a
123n/a def assertVectorsAlmostEqual(self, vec1, vec2):
124n/a if len(vec1) != len(vec2):
125n/a self.fail("Tuples are not of equal size")
126n/a for idx, (i, j) in enumerate(zip(vec1, vec2)):
127n/a self.assertAlmostEqual(
128n/a i, j, msg='values at index {} do not match'.format(idx))
129n/a
130n/a
131n/aclass TestVec2D(VectorComparisonMixin, unittest.TestCase):
132n/a
133n/a def test_constructor(self):
134n/a vec = Vec2D(0.5, 2)
135n/a self.assertEqual(vec[0], 0.5)
136n/a self.assertEqual(vec[1], 2)
137n/a self.assertIsInstance(vec, Vec2D)
138n/a
139n/a self.assertRaises(TypeError, Vec2D)
140n/a self.assertRaises(TypeError, Vec2D, 0)
141n/a self.assertRaises(TypeError, Vec2D, (0, 1))
142n/a self.assertRaises(TypeError, Vec2D, vec)
143n/a self.assertRaises(TypeError, Vec2D, 0, 1, 2)
144n/a
145n/a def test_repr(self):
146n/a vec = Vec2D(0.567, 1.234)
147n/a self.assertEqual(repr(vec), '(0.57,1.23)')
148n/a
149n/a def test_equality(self):
150n/a vec1 = Vec2D(0, 1)
151n/a vec2 = Vec2D(0.0, 1)
152n/a vec3 = Vec2D(42, 1)
153n/a self.assertEqual(vec1, vec2)
154n/a self.assertEqual(vec1, tuple(vec1))
155n/a self.assertEqual(tuple(vec1), vec1)
156n/a self.assertNotEqual(vec1, vec3)
157n/a self.assertNotEqual(vec2, vec3)
158n/a
159n/a def test_pickling(self):
160n/a vec = Vec2D(0.5, 2)
161n/a for proto in range(pickle.HIGHEST_PROTOCOL + 1):
162n/a with self.subTest(proto=proto):
163n/a pickled = pickle.dumps(vec, protocol=proto)
164n/a unpickled = pickle.loads(pickled)
165n/a self.assertEqual(unpickled, vec)
166n/a self.assertIsInstance(unpickled, Vec2D)
167n/a
168n/a def _assert_arithmetic_cases(self, test_cases, lambda_operator):
169n/a for test_case in test_cases:
170n/a with self.subTest(case=test_case):
171n/a
172n/a ((first, second), expected) = test_case
173n/a
174n/a op1 = Vec2D(*first)
175n/a op2 = Vec2D(*second)
176n/a
177n/a result = lambda_operator(op1, op2)
178n/a
179n/a expected = Vec2D(*expected)
180n/a
181n/a self.assertVectorsAlmostEqual(result, expected)
182n/a
183n/a def test_vector_addition(self):
184n/a
185n/a test_cases = [
186n/a (((0, 0), (1, 1)), (1.0, 1.0)),
187n/a (((-1, 0), (2, 2)), (1, 2)),
188n/a (((1.5, 0), (1, 1)), (2.5, 1)),
189n/a ]
190n/a
191n/a self._assert_arithmetic_cases(test_cases, lambda x, y: x + y)
192n/a
193n/a def test_vector_subtraction(self):
194n/a
195n/a test_cases = [
196n/a (((0, 0), (1, 1)), (-1, -1)),
197n/a (((10.625, 0.125), (10, 0)), (0.625, 0.125)),
198n/a ]
199n/a
200n/a self._assert_arithmetic_cases(test_cases, lambda x, y: x - y)
201n/a
202n/a def test_vector_multiply(self):
203n/a
204n/a vec1 = Vec2D(10, 10)
205n/a vec2 = Vec2D(0.5, 3)
206n/a answer = vec1 * vec2
207n/a expected = 35
208n/a self.assertAlmostEqual(answer, expected)
209n/a
210n/a vec = Vec2D(0.5, 3)
211n/a answer = vec * 10
212n/a expected = Vec2D(5, 30)
213n/a self.assertVectorsAlmostEqual(answer, expected)
214n/a
215n/a def test_vector_negative(self):
216n/a vec = Vec2D(10, -10)
217n/a expected = (-10, 10)
218n/a self.assertVectorsAlmostEqual(-vec, expected)
219n/a
220n/a def test_distance(self):
221n/a vec = Vec2D(6, 8)
222n/a expected = 10
223n/a self.assertEqual(abs(vec), expected)
224n/a
225n/a vec = Vec2D(0, 0)
226n/a expected = 0
227n/a self.assertEqual(abs(vec), expected)
228n/a
229n/a vec = Vec2D(2.5, 6)
230n/a expected = 6.5
231n/a self.assertEqual(abs(vec), expected)
232n/a
233n/a def test_rotate(self):
234n/a
235n/a cases = [
236n/a (((0, 0), 0), (0, 0)),
237n/a (((0, 1), 90), (-1, 0)),
238n/a (((0, 1), -90), (1, 0)),
239n/a (((1, 0), 180), (-1, 0)),
240n/a (((1, 0), 360), (1, 0)),
241n/a ]
242n/a
243n/a for case in cases:
244n/a with self.subTest(case=case):
245n/a (vec, rot), expected = case
246n/a vec = Vec2D(*vec)
247n/a got = vec.rotate(rot)
248n/a self.assertVectorsAlmostEqual(got, expected)
249n/a
250n/a
251n/aclass TestTNavigator(VectorComparisonMixin, unittest.TestCase):
252n/a
253n/a def setUp(self):
254n/a self.nav = turtle.TNavigator()
255n/a
256n/a def test_goto(self):
257n/a self.nav.goto(100, -100)
258n/a self.assertAlmostEqual(self.nav.xcor(), 100)
259n/a self.assertAlmostEqual(self.nav.ycor(), -100)
260n/a
261n/a def test_pos(self):
262n/a self.assertEqual(self.nav.pos(), self.nav._position)
263n/a self.nav.goto(100, -100)
264n/a self.assertEqual(self.nav.pos(), self.nav._position)
265n/a
266n/a def test_left(self):
267n/a self.assertEqual(self.nav._orient, (1.0, 0))
268n/a self.nav.left(90)
269n/a self.assertVectorsAlmostEqual(self.nav._orient, (0.0, 1.0))
270n/a
271n/a def test_right(self):
272n/a self.assertEqual(self.nav._orient, (1.0, 0))
273n/a self.nav.right(90)
274n/a self.assertVectorsAlmostEqual(self.nav._orient, (0, -1.0))
275n/a
276n/a def test_reset(self):
277n/a self.nav.goto(100, -100)
278n/a self.assertAlmostEqual(self.nav.xcor(), 100)
279n/a self.assertAlmostEqual(self.nav.ycor(), -100)
280n/a self.nav.reset()
281n/a self.assertAlmostEqual(self.nav.xcor(), 0)
282n/a self.assertAlmostEqual(self.nav.ycor(), 0)
283n/a
284n/a def test_forward(self):
285n/a self.nav.forward(150)
286n/a expected = Vec2D(150, 0)
287n/a self.assertVectorsAlmostEqual(self.nav.position(), expected)
288n/a
289n/a self.nav.reset()
290n/a self.nav.left(90)
291n/a self.nav.forward(150)
292n/a expected = Vec2D(0, 150)
293n/a self.assertVectorsAlmostEqual(self.nav.position(), expected)
294n/a
295n/a self.assertRaises(TypeError, self.nav.forward, 'skldjfldsk')
296n/a
297n/a def test_backwards(self):
298n/a self.nav.back(200)
299n/a expected = Vec2D(-200, 0)
300n/a self.assertVectorsAlmostEqual(self.nav.position(), expected)
301n/a
302n/a self.nav.reset()
303n/a self.nav.right(90)
304n/a self.nav.back(200)
305n/a expected = Vec2D(0, 200)
306n/a self.assertVectorsAlmostEqual(self.nav.position(), expected)
307n/a
308n/a def test_distance(self):
309n/a self.nav.forward(100)
310n/a expected = 100
311n/a self.assertAlmostEqual(self.nav.distance(Vec2D(0,0)), expected)
312n/a
313n/a def test_radians_and_degrees(self):
314n/a self.nav.left(90)
315n/a self.assertAlmostEqual(self.nav.heading(), 90)
316n/a self.nav.radians()
317n/a self.assertAlmostEqual(self.nav.heading(), 1.57079633)
318n/a self.nav.degrees()
319n/a self.assertAlmostEqual(self.nav.heading(), 90)
320n/a
321n/a def test_towards(self):
322n/a
323n/a coordinates = [
324n/a # coordinates, expected
325n/a ((100, 0), 0.0),
326n/a ((100, 100), 45.0),
327n/a ((0, 100), 90.0),
328n/a ((-100, 100), 135.0),
329n/a ((-100, 0), 180.0),
330n/a ((-100, -100), 225.0),
331n/a ((0, -100), 270.0),
332n/a ((100, -100), 315.0),
333n/a ]
334n/a
335n/a for (x, y), expected in coordinates:
336n/a self.assertEqual(self.nav.towards(x, y), expected)
337n/a self.assertEqual(self.nav.towards((x, y)), expected)
338n/a self.assertEqual(self.nav.towards(Vec2D(x, y)), expected)
339n/a
340n/a def test_heading(self):
341n/a
342n/a self.nav.left(90)
343n/a self.assertAlmostEqual(self.nav.heading(), 90)
344n/a self.nav.left(45)
345n/a self.assertAlmostEqual(self.nav.heading(), 135)
346n/a self.nav.right(1.6)
347n/a self.assertAlmostEqual(self.nav.heading(), 133.4)
348n/a self.assertRaises(TypeError, self.nav.right, 'sdkfjdsf')
349n/a self.nav.reset()
350n/a
351n/a rotations = [10, 20, 170, 300]
352n/a result = sum(rotations) % 360
353n/a for num in rotations:
354n/a self.nav.left(num)
355n/a self.assertEqual(self.nav.heading(), result)
356n/a self.nav.reset()
357n/a
358n/a result = (360-sum(rotations)) % 360
359n/a for num in rotations:
360n/a self.nav.right(num)
361n/a self.assertEqual(self.nav.heading(), result)
362n/a self.nav.reset()
363n/a
364n/a rotations = [10, 20, -170, 300, -210, 34.3, -50.2, -10, -29.98, 500]
365n/a sum_so_far = 0
366n/a for num in rotations:
367n/a if num < 0:
368n/a self.nav.right(abs(num))
369n/a else:
370n/a self.nav.left(num)
371n/a sum_so_far += num
372n/a self.assertAlmostEqual(self.nav.heading(), sum_so_far % 360)
373n/a
374n/a def test_setheading(self):
375n/a self.nav.setheading(102.32)
376n/a self.assertAlmostEqual(self.nav.heading(), 102.32)
377n/a self.nav.setheading(-123.23)
378n/a self.assertAlmostEqual(self.nav.heading(), (-123.23) % 360)
379n/a self.nav.setheading(-1000.34)
380n/a self.assertAlmostEqual(self.nav.heading(), (-1000.34) % 360)
381n/a self.nav.setheading(300000)
382n/a self.assertAlmostEqual(self.nav.heading(), 300000%360)
383n/a
384n/a def test_positions(self):
385n/a self.nav.forward(100)
386n/a self.nav.left(90)
387n/a self.nav.forward(-200)
388n/a self.assertVectorsAlmostEqual(self.nav.pos(), (100.0, -200.0))
389n/a
390n/a def test_setx_and_sety(self):
391n/a self.nav.setx(-1023.2334)
392n/a self.nav.sety(193323.234)
393n/a self.assertVectorsAlmostEqual(self.nav.pos(), (-1023.2334, 193323.234))
394n/a
395n/a def test_home(self):
396n/a self.nav.left(30)
397n/a self.nav.forward(-100000)
398n/a self.nav.home()
399n/a self.assertVectorsAlmostEqual(self.nav.pos(), (0,0))
400n/a self.assertAlmostEqual(self.nav.heading(), 0)
401n/a
402n/a def test_distance_method(self):
403n/a self.assertAlmostEqual(self.nav.distance(30, 40), 50)
404n/a vec = Vec2D(0.22, .001)
405n/a self.assertAlmostEqual(self.nav.distance(vec), 0.22000227271553355)
406n/a another_turtle = turtle.TNavigator()
407n/a another_turtle.left(90)
408n/a another_turtle.forward(10000)
409n/a self.assertAlmostEqual(self.nav.distance(another_turtle), 10000)
410n/a
411n/a
412n/aclass TestTPen(unittest.TestCase):
413n/a
414n/a def test_pendown_and_penup(self):
415n/a
416n/a tpen = turtle.TPen()
417n/a
418n/a self.assertTrue(tpen.isdown())
419n/a tpen.penup()
420n/a self.assertFalse(tpen.isdown())
421n/a tpen.pendown()
422n/a self.assertTrue(tpen.isdown())
423n/a
424n/a def test_showturtle_hideturtle_and_isvisible(self):
425n/a
426n/a tpen = turtle.TPen()
427n/a
428n/a self.assertTrue(tpen.isvisible())
429n/a tpen.hideturtle()
430n/a self.assertFalse(tpen.isvisible())
431n/a tpen.showturtle()
432n/a self.assertTrue(tpen.isvisible())
433n/a
434n/a
435n/aif __name__ == '__main__':
436n/a unittest.main()