Repository: hedyorg/hedy

Issue:
Give an error for incorrect forward argument
The `forward` command currently interprets any argument that is not a number or a variable name as a 50px forward move. This will be confusing if a variable name was misspelled. It should give an error instead.


Discussion:
Once we have https://github.com/Felienne/hedy/issues/832 fixed, we should have a method that determines similar var names that can be used here.

Resolving patch:
diff --git a/hedy.py b/hedy.py
--- a/hedy.py
+++ b/hedy.py
@@ -122,7 +122,7 @@ def closest_command(invalid_command, known_commands):
     if min_command == invalid_command:
         return None
     return style_closest_command(min_command)
- 
+
 
 def style_closest_command(command):
     return f'<span class="command-highlighted">{command}</span>'
@@ -643,11 +643,15 @@ def ask(self, args):
         return "answer = input('" + argument + "')"
 
     def forward(self,args):
-        # when a not-number is given, we simply use 50 as default
+        if len(args) == 0:
+            return self.make_forward(50)
+
         try:
             parameter = int(args[0])
         except:
-            parameter = 50
+            raise InvalidArgumentTypeException(command='forward', invalid_type='',
+                                                            allowed_types=['number'],
+                                                            invalid_argument=args[0])
         return self.make_forward(parameter)
 
     def make_forward(self, parameter):
@@ -664,8 +668,12 @@ def turn(self, args):
             return f"t.right({argument})"
         elif argument == 'left':
             return "t.left(90)"
+        elif argument == 'right':
+            return "t.right(90)"
         else:
-            return "t.right(90)" #something else also defaults to right turn
+            raise InvalidArgumentTypeException(command='turn', invalid_type='',
+                                                            allowed_types=['right', 'left', 'number'],
+                                                            invalid_argument=argument)
 
     def check_arg_types(self, args, command, level):
         allowed_types = self.get_allowed_types(command, level)
@@ -766,19 +774,20 @@ def print(self, args):
         return f"print(f'{argument_string}')"
 
     def forward(self, args):
-        # no args received? default to 50
-        parameter = 50
-
-        if len(args) > 0:
-            parameter = args[0]
+        if len(args) == 0:
+            return self.make_forward(50)
 
-        #if the parameter is a variable, print as is
-        # otherwise, see if we got a number. if not, simply use 50 as default
+        # if the parameter is a number, use it as is
+        # otherwise, see if we got a defined variable. if not, give an error
         try:
-            if not is_variable(parameter, self.lookup):
-                parameter = int(parameter)
+            parameter = int(args[0])
         except:
-            parameter = 50
+            if is_variable(args[0], self.lookup):
+                parameter = args[0]
+            else:
+                raise InvalidArgumentTypeException(command='forward', invalid_type='',
+                                                   allowed_types=['number'],
+                                                   invalid_argument=args[0])
         return self.make_forward(parameter)
 
     def ask(self, args):


Test patch:
diff --git a/tests/tests_level_01.py b/tests/tests_level_01.py
--- a/tests/tests_level_01.py
+++ b/tests/tests_level_01.py
@@ -208,11 +208,9 @@ def test_one_turn_right(self):
     self.assertEqual(expected, result.code)
     self.assertEqual(True, result.has_turtle)
   def test_one_turn_with_var(self):
-    result = hedy.transpile("turn koekoek", self.level)
-    expected = textwrap.dedent("""\
-    t.right(90)""")
-    self.assertEqual(expected, result.code)
-    self.assertEqual(True, result.has_turtle)
+    with self.assertRaises(hedy.InvalidArgumentTypeException) as context:
+      result = hedy.transpile("turn koekoek", self.level)
+    self.assertEqual('Invalid Argument Type', context.exception.error_code)
   def test_one_turn_left(self):
     result = hedy.transpile("turn left", self.level)
     expected = textwrap.dedent("""\
@@ -277,6 +275,22 @@ def test_lines_with_spaces_gives_invalid(self):
     with self.assertRaises(hedy.InvalidSpaceException) as context:
       result = hedy.transpile(" print Hallo welkom bij Hedy!\n print Hallo welkom bij Hedy!", self.level)
     self.assertEqual('Invalid Space', context.exception.error_code)
+  def test_forward_without_number_gives_type_error(self):
+    code = "forward lalalala"
+    self.multi_level_tester(
+      max_level=7,
+      code=code,
+      exception=hedy.InvalidArgumentTypeException,
+      test_name=self.name()
+    )
+  def test_turn_without_number_gives_type_error(self):
+    code = "forward lalalala"
+    self.multi_level_tester(
+      max_level=7,
+      code=code,
+      exception=hedy.InvalidArgumentTypeException,
+      test_name=self.name()
+    )
   def test_word_plus_period_gives_invalid(self):
     with self.assertRaises(hedy.InvalidCommandException) as context:
       result = hedy.transpile("word.", self.level)