From acf8a4aeb76ca107faa2e5c8c8202f525544e814 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 23 Sep 2013 19:57:52 +0100 Subject: [PATCH 1/4] Amend and extend the tests a bit. --- tests/test_ninja.py | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tests/test_ninja.py b/tests/test_ninja.py index f2f2396..bce017a 100644 --- a/tests/test_ninja.py +++ b/tests/test_ninja.py @@ -1,7 +1,7 @@ import unittest from ninjaturtle.ninja import NinjaTurtle -from ninjaturtle.common import DEFAULT_MAX_SPEED +from ninjaturtle.common import DEFAULT_MAX_SPEED, DEFAULT_MAX_TURN from ninjaturtle.engine import get_engine class NinjaTurtleTest(unittest.TestCase): @@ -15,12 +15,53 @@ def tearDown(self): def test_max_speed_getter(self): turtle = NinjaTurtle(get_engine()) self.assertAlmostEqual(turtle.max_speed(), DEFAULT_MAX_SPEED) + self.assertAlmostEqual(turtle._max_speed, DEFAULT_MAX_SPEED) def test_max_speed_setter(self): turtle = NinjaTurtle(get_engine()) testValue = 999.0 + self.assertAlmostEqual(turtle._max_speed, DEFAULT_MAX_SPEED) self.assertEqual(turtle.max_speed(testValue), None) self.assertAlmostEqual(turtle._max_speed, testValue) + def test_max_turn_getter(self): + turtle = NinjaTurtle(get_engine()) + self.assertAlmostEqual(turtle.max_turn(), DEFAULT_MAX_TURN) + self.assertAlmostEqual(turtle._max_turn, DEFAULT_MAX_TURN) + + def test_max_turn_setter(self): + turtle = NinjaTurtle(get_engine()) + testValue = 999.0 + self.assertAlmostEqual(turtle._max_turn, DEFAULT_MAX_TURN) + self.assertEqual(turtle.max_turn(testValue), None) + self.assertAlmostEqual(turtle._max_turn, testValue) + + def test__calculate_speeds(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle._calculate_speeds(), None) + self.assertAlmostEqual(turtle._throttle, 0.6) + self.assertAlmostEqual(turtle._throttled_move_speed, 120.0) + self.assertAlmostEqual(turtle._throttled_turn_speed, 216.0) + + def test_speed_getter(self): + turtle = NinjaTurtle(get_engine()) + speed = 6.0 + self.assertAlmostEquals(turtle.data[5], speed) + self.assertAlmostEquals(turtle.speed(), speed) + self.assertAlmostEquals(turtle.data[5], speed) + + def test_speed_setter(self): + turtle = NinjaTurtle(get_engine()) + oldSpeed = 6.0 + newSpeed = 7.0 + self.assertAlmostEquals(turtle.data[5], oldSpeed) + self.assertAlmostEquals(turtle.speed(newSpeed), None) + self.assertAlmostEquals(turtle.data[5], newSpeed) + + def test_throttle_exists_and_is_alias_for_speed(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.throttle, turtle.speed) + + if __name__ == '__main__': unittest.main() From aa081a5bbebec9e74ce42fc4011963a8cbfa0320 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Tue, 24 Sep 2013 18:40:14 +0100 Subject: [PATCH 2/4] Add a few more basic tests as a way of getting some in place to act as a basis for some real tests. --- tests/test_ninja.py | 91 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/tests/test_ninja.py b/tests/test_ninja.py index bce017a..f0c7840 100644 --- a/tests/test_ninja.py +++ b/tests/test_ninja.py @@ -4,6 +4,8 @@ from ninjaturtle.common import DEFAULT_MAX_SPEED, DEFAULT_MAX_TURN from ninjaturtle.engine import get_engine +# TODO: Add tests for invalid data types and invalid values of the right type. + class NinjaTurtleTest(unittest.TestCase): def setUp(self): @@ -50,18 +52,101 @@ def test_speed_getter(self): self.assertAlmostEquals(turtle.speed(), speed) self.assertAlmostEquals(turtle.data[5], speed) - def test_speed_setter(self): + def test_speed_setter_numeric(self): turtle = NinjaTurtle(get_engine()) - oldSpeed = 6.0 newSpeed = 7.0 - self.assertAlmostEquals(turtle.data[5], oldSpeed) + self.assertAlmostEquals(turtle.data[5], 6.0) self.assertAlmostEquals(turtle.speed(newSpeed), None) self.assertAlmostEquals(turtle.data[5], newSpeed) + def test_speed_setter_symbolic(self): + turtle = NinjaTurtle(get_engine()) + self.assertAlmostEquals(turtle.data[5], 6.0) + self.assertAlmostEquals(turtle.speed('fast'), None) + self.assertAlmostEquals(turtle.data[5], 10.0) + def test_throttle_exists_and_is_alias_for_speed(self): turtle = NinjaTurtle(get_engine()) self.assertEqual(turtle.throttle, turtle.speed) + def test_fd_exists_and_is_alias_for_forward(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.fd, turtle.forward) + + def test_bk_exists_and_is_alias_for_back(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.bk, turtle.back) + + def test_lt_exists_and_is_alias_for_left(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.lt, turtle.left) + + def test_rt_exists_and_is_alias_for_right(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.rt, turtle.right) + + def test_xcor_initial(self): + turtle = NinjaTurtle(get_engine()) + self.assertAlmostEqual(turtle.xcor(), 0.0) + + def test_setx(self): + turtle = NinjaTurtle(get_engine()) + x = 10.0 + turtle.setx(x) + self.assertAlmostEqual(turtle.xcor(), x) + + def test_ycor_initial(self): + turtle = NinjaTurtle(get_engine()) + self.assertAlmostEqual(turtle.ycor(), 0.0) + + def test_sety(self): + turtle = NinjaTurtle(get_engine()) + y = 10.0 + turtle.sety(y) + self.assertAlmostEqual(turtle.ycor(), y) + + def test_position_initial(self): + turtle = NinjaTurtle(get_engine()) + x, y = turtle.position() + self.assertAlmostEqual(x, 0.0) + self.assertAlmostEqual(y, 0.0) + + def test_position_altered(self): + turtle = NinjaTurtle(get_engine()) + x_ = 11.0 + y_ = 12.0 + turtle.setx(x_) + turtle.sety(y_) + x, y = turtle.position() + self.assertAlmostEqual(x, x_) + self.assertAlmostEqual(y, y_) + + def test_pos_exists_an_is_alias_for_position(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.pos, turtle.position) + + def test_heading_initial(self): + turtle = NinjaTurtle(get_engine()) + self.assertAlmostEqual(turtle.heading(), 0.0) + + def test_setheading(self): + turtle = NinjaTurtle(get_engine()) + turtle.setheading(20.0) + self.assertAlmostEqual(turtle.heading(), 0.0) + # NB the heading value only changes after the next tick. + + def test_turtlesize_exists_an_is_alias_for_shapesize(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.turtlesize, turtle.shapesize) + + def test_ht_exists_an_is_alias_for_hideturtle(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.ht, turtle.hideturtle) + + def test_st_exists_an_is_alias_for_showturtle(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.ht, turtle.hideturtle) + if __name__ == '__main__': unittest.main() From b1c4b0558513e4cf6bc667fc2331a9e9d11aa301 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Wed, 25 Sep 2013 13:50:07 +0100 Subject: [PATCH 3/4] Amend and augment back method, to fit with turtle API. --- ninjaturtle/ninja.py | 6 ++++-- tests/test_ninja.py | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ninjaturtle/ninja.py b/ninjaturtle/ninja.py index c242209..e8c39c6 100644 --- a/ninjaturtle/ninja.py +++ b/ninjaturtle/ninja.py @@ -97,13 +97,15 @@ def forward(self, distance=None): fd = forward - def back(self, distance=None): + def backward(self, distance=None): if distance is None: self.queue_action(MOVE, -self._throttled_move_speed) else: self.queue_action(MOVE, -self._throttled_move_speed, -distance) - bk = back + bk = backward + + back = backward def left(self, angle=None): if angle is None: diff --git a/tests/test_ninja.py b/tests/test_ninja.py index f0c7840..50d7729 100644 --- a/tests/test_ninja.py +++ b/tests/test_ninja.py @@ -73,9 +73,13 @@ def test_fd_exists_and_is_alias_for_forward(self): turtle = NinjaTurtle(get_engine()) self.assertEqual(turtle.fd, turtle.forward) - def test_bk_exists_and_is_alias_for_back(self): + def test_bk_exists_and_is_alias_for_backward(self): turtle = NinjaTurtle(get_engine()) - self.assertEqual(turtle.bk, turtle.back) + self.assertEqual(turtle.bk, turtle.backward) + + def test_back_exists_and_is_alias_for_backward(self): + turtle = NinjaTurtle(get_engine()) + self.assertEqual(turtle.back, turtle.backward) def test_lt_exists_and_is_alias_for_left(self): turtle = NinjaTurtle(get_engine()) From 5e4caa6cb02572f0bd4a1c29319ac866685b9555 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Wed, 25 Sep 2013 13:51:15 +0100 Subject: [PATCH 4/4] Add module to check consistency of NinjaTurtle API and turtle API. --- tests/test_turtleAPICheck.py | 152 +++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100755 tests/test_turtleAPICheck.py diff --git a/tests/test_turtleAPICheck.py b/tests/test_turtleAPICheck.py new file mode 100755 index 0000000..246bc81 --- /dev/null +++ b/tests/test_turtleAPICheck.py @@ -0,0 +1,152 @@ +#! /usr/bin/env python3 +# -*- coding:utf-8; -*- + +# Assume Python ≥ 2.6 + +from __future__ import division, absolute_import, with_statement, print_function, unicode_literals + +''' +This module, realized as a unittest.TestCase, is a check to see which methods from the turtle package +are implemented by instances of NinjaTurtle. + +The unittest.TestCase class here has no methods "test…" and so Nose will not run any tests due to this file. +Only when run explicitly will the "test…" methods be created. +''' + +import unittest + +import sys +from os.path import abspath, dirname, join, normpath +sys.path.insert(0, normpath(join(dirname(abspath(__file__)), '..'))) + +from ninjaturtle.ninja import NinjaTurtle +from ninjaturtle.engine import get_engine + +class TurtleAPICheck(unittest.TestCase): + def setUp(self): + super(TurtleAPICheck, self).setUp() + self.turtle = NinjaTurtle(get_engine()) + + def tearDown(self): + super(TurtleAPICheck, self).tearDown() + self.turtle = None + + @classmethod + def add_function_check(clazz, name): + def test_function(this): + assert hasattr(this.turtle, name) + setattr(clazz, 'test_function___{}'.format(name), test_function) + +if __name__ == '__main__': + # This is a lit of all the functions in the turtle module as per the Python 3 documentation. + # Ones explictly not implemented in NinjaTurtle are commented out. + for name in ( + 'forward', 'fd', + 'backward', 'bk', 'back', + 'right', 'rt', + 'left', 'lt', + 'goto', 'setpos', 'setposition', + 'setx', + 'sety', + 'setheading', 'seth', + 'home', + 'circle', + 'dot', + 'stamp', + 'clearstamp', + 'clearstamps', + 'undo', + 'speed', + + 'position', 'pos', + 'towards', + 'xcor', + 'ycor', + 'heading', + 'distance', + + 'degrees', + 'radians', + + 'pendown', 'pd', 'down', + 'penup', 'pu', 'up', + 'pensize', 'width', + 'pen', + 'isdown', + + 'color', + 'pencolor', + 'fillcolor', + + 'filling', + 'begin_fill', + 'end_fill', + + 'reset', + 'clear', + 'write', + + 'showturtle', 'st', + 'hideturtle', 'ht', + 'isvisible', + + 'shape', + 'resizemode', + 'shapesize', 'turtlesize', + 'shearfactor', + 'settiltangle', + 'tiltangle', + 'tilt', + 'shapetransform', + 'get_shapepoly', + + 'onclick', + 'onrelease', + 'ondrag', + + 'begin_poly', + 'end_poly', + 'get_poly', + 'clone', + 'getturtle', 'getpen', + 'getscreen', + 'setundobuffer', + 'undobufferentries', + + 'bgcolor', + 'bgpic', + 'clear', 'clearscreen', + 'reset', 'resetscreen', + 'screensize', + 'setworldcoordinates', + + 'delay', + 'tracer', + 'update', + + 'listen', + 'onkey', 'onkeyrelease', + 'onkeypress', + 'onclick', 'onscreenclick', + 'ontimer', + 'mainloop', 'done', + + 'mode', + 'colormode', + 'getcanvas', + 'getshapes', + 'register_shape', 'addshape', + 'turtles', + 'window_height', + 'window_width', + + 'textinput', + 'numinput', + + 'bye', + 'exitonclick', + 'setup', + 'title', + ): + TurtleAPICheck.add_function_check(name) + unittest.main()