Repository: hedyorg/hedy

Issue:
[Tests idea] Make Multilanguage tester
**Language idea incl level**
Right now the tests for the Hedy translator are hardcoded in each language. So, for example, if we want to test a feature there we'd call the test something like: `test_is_spanish_english` and it would include Spanish keywords.

I see 2 problems with this approach: only people who can speak the language can write the tests or understand it at first glance (I can understand Dutch tests, but I have to go to the grammar and see each definition),  and also, more importantly, we can only test one language at a time. 

Maybe we can do something like the Multilevel test, but for languages? We'd build each test so it take a generic placeholder like `lang['nl']['is]` and iterate through a language dictionary that contains all keywords for each language. Or perhaps this is not needed? Since the keywords for each language shouldn't affect the grammar and a test in a single language is all that is needed.

I'd love to read your input!



Discussion:
Hi! 

I think this is a good idea that is not all too hard to implement. We could indeed make a dictionary of keywords and then use a parametrized test (like we do here, for example):

https://github.com/Felienne/hedy/blob/bede1281e6983d8ddc19b3f4a35763058f3a5326/tests/test_z_adventures.py#L60

You are right that, in principle, we should not have to tests all keywords for all languages, but I would say adding more tests is never bad, we don't know what weird interactions might occur when add more languages.

If you want to pick this up, please feel free to do so, if not, someone in the core team can do it too.
Hi! Thank you for your input. And yes, I can take this one, but can't probably work on this until next week, if that's ok for you.
> Hi! Thank you for your input. And yes, I can take this one, but can't probably work on this until next week, if that's ok for you.

Yeah no rush, we do have a few Dutch and Spanish tests now so we should be good for a while.

Resolving patch:
diff --git a/hedy_translation.py b/hedy_translation.py
--- a/hedy_translation.py
+++ b/hedy_translation.py
@@ -8,6 +8,8 @@
 
 TRANSLATOR_LOOKUP = {}
 
+KEYWORD_LANGUAGES = ['en', 'nl', 'es']
+
 def keywords_to_dict(to_lang="nl"):
     """"Return a dictionary of keywords from language of choice. Key is english value is lang of choice"""
     base = path.abspath(path.dirname(__file__))
@@ -20,6 +22,14 @@ def keywords_to_dict(to_lang="nl"):
 
     return command_combinations
 
+def all_keywords_to_dict():
+    """Return a dictionary where each key is a list of the translations of that keyword. Used for testing"""    
+    keyword_list = []
+    for lang in KEYWORD_LANGUAGES:
+        commands = keywords_to_dict(lang)
+        keyword_list.append(commands)
+    all_translations = {k: [d[k] for d in keyword_list] for k in keyword_list[0]}
+    return all_translations
 
 def translate_keywords(input_string, from_lang="en", to_lang="nl", level=1):
     """"Return code with keywords translated to language of choice in level of choice"""


Test patch:
diff --git a/tests/Tester.py b/tests/Tester.py
--- a/tests/Tester.py
+++ b/tests/Tester.py
@@ -63,6 +63,17 @@ def is_turtle(self):
   def result_in(self, list):
     return (lambda result: HedyTester.run_code(result) in list)
 
+  @staticmethod
+  def as_list_of_tuples(*args):
+    # used to conver a variable number of paralel list
+    # into a list of tuples to be used by the parametrized tester
+    # All of the lists need to have the same size
+    res = []
+    for i in range(len(args[0])):
+      t = tuple((item[i] for item in args))
+      res.append(t)
+    return res
+    
   def multi_level_tester(self, code, max_level=hedy.HEDY_MAX_LEVEL, expected=None, exception=None, extra_check_function=None, expected_commands=None):
     # used to test the same code snippet over multiple levels
     # Use exception to check for an exception
diff --git a/tests/test_translation_level_02.py b/tests/test_translation_level_02.py
--- a/tests/test_translation_level_02.py
+++ b/tests/test_translation_level_02.py
@@ -1,3 +1,5 @@
+import textwrap
+from parameterized import parameterized
 from test_level_01 import HedyTester
 import hedy_translation
 
@@ -11,6 +13,7 @@
 
 class TestsTranslationLevel2(HedyTester):
     level = 2
+    all_keywords = hedy_translation.all_keywords_to_dict()
 
     def test_print(self):
         code = "print Hallo welkom bij Hedy!"
@@ -111,6 +114,22 @@ def test_echo(self):
 
         self.assertEqual(expected, result)
 
+    @parameterized.expand(HedyTester.as_list_of_tuples(all_keywords["ask"], all_keywords["is"] ,all_keywords["print"], hedy_translation.KEYWORD_LANGUAGES))
+    def test_ask_print_all_lang(self,ask_keyword, is_keyword, print_keyword, lang):
+        code = textwrap.dedent(f"""\
+        {print_keyword} Hello, tell us your name please
+        name {is_keyword} {ask_keyword} Whats your name?
+        {print_keyword} name is your name!""")
+    
+        result = hedy_translation.translate_keywords(code, from_lang=lang, to_lang="en", level=self.level)
+        
+        expected = textwrap.dedent(f"""\
+        print Hello, tell us your name please
+        name is ask Whats your name?
+        print name is your name!""")
+
+        self.assertEqual(expected, result)
+    
     def no_argument_ask_english(self):
         code = "ask"
 
diff --git a/tests/test_translation_level_05.py b/tests/test_translation_level_05.py
--- a/tests/test_translation_level_05.py
+++ b/tests/test_translation_level_05.py
@@ -1,6 +1,7 @@
 import hedy
 from test_level_01 import HedyTester
 import hedy_translation
+from parameterized import parameterized
 
     # tests should be ordered as follows:
     # * Translation from English to Dutch
@@ -13,7 +14,8 @@ class TestsTranslationLevel5(HedyTester):
     level = 5
     keywords_from = hedy_translation.keywords_to_dict('en')
     keywords_to = hedy_translation.keywords_to_dict('nl')
-
+    all_keywords = hedy_translation.all_keywords_to_dict()
+    
     def test_print_english_dutch(self):
         code = "print 'Hallo welkom bij Hedy!'"
 
@@ -94,4 +96,13 @@ def test_in_list_dutch_english(self):
         result = hedy_translation.translate_keywords(code, from_lang="nl", to_lang="en", level=self.level)
         expected = "if hond in dieren print 'Cute!'"
 
+        self.assertEqual(expected, result)
+
+    @parameterized.expand(HedyTester.as_list_of_tuples(all_keywords["if"], all_keywords["print"], all_keywords["is"], all_keywords["else"],hedy_translation.KEYWORD_LANGUAGES))
+    def test_print_if_is_else_all_lang(self, if_keyword, print_keyword, is_kwrd, else_kwrd, lang):
+        code = f"{if_keyword} name {is_kwrd} Hedy {print_keyword} 'Great!' {else_kwrd} {print_keyword} 'Oh no'"
+
+        result = hedy_translation.translate_keywords(code, from_lang=lang, to_lang="en", level=self.level)
+        expected = "if name is Hedy print 'Great!' else print 'Oh no'"
+
         self.assertEqual(expected, result)
\ No newline at end of file
diff --git a/tests/test_translation_level_11.py b/tests/test_translation_level_11.py
--- a/tests/test_translation_level_11.py
+++ b/tests/test_translation_level_11.py
@@ -2,7 +2,7 @@
 from test_level_01 import HedyTester
 import hedy_translation
 import textwrap
-
+from parameterized import parameterized
 
 # tests should be ordered as follows:
 # * Translation from English to Dutch
@@ -15,7 +15,8 @@ class TestsTranslationLevel11(HedyTester):
     level = 11
     keywords_from = hedy_translation.keywords_to_dict('en')
     keywords_to = hedy_translation.keywords_to_dict('nl')
-
+    all_keywords = hedy_translation.all_keywords_to_dict()
+    
     def test_for_in_english_dutch(self):
         code = textwrap.dedent("""\
         for counter in range 1 to 5
@@ -28,14 +29,15 @@ def test_for_in_english_dutch(self):
 
         self.assertEqual(expected, result)
 
-    def test_for_in_dutch_english(self):
-        code = textwrap.dedent("""\
-        nummer = vraag 'hoe oud ben je'
-        voor counter in bereik 1 tot 5
-            voor count in bereik nummer tot 0
-                print 'hoi' counter""")
+    @parameterized.expand(HedyTester.as_list_of_tuples(all_keywords["ask"], all_keywords["for"], all_keywords["in"], all_keywords["range"], all_keywords["to"], all_keywords["print"],hedy_translation.KEYWORD_LANGUAGES))
+    def test_for_in_all_lang(self, ask_keyword, for_keyword, in_keyword, range_keyword, to_keyword, print_keyword, lang):
+        code = textwrap.dedent(f"""\
+        nummer = {ask_keyword} 'hoe oud ben je'
+        {for_keyword} counter {in_keyword} {range_keyword} 1 {to_keyword} 5
+            {for_keyword} count {in_keyword} {range_keyword} nummer {to_keyword} 0
+                {print_keyword} 'hoi' counter""")
 
-        result = hedy_translation.translate_keywords(code, from_lang="nl", to_lang="en", level=self.level)
+        result = hedy_translation.translate_keywords(code, from_lang=lang, to_lang="en", level=self.level)
         expected = textwrap.dedent("""\
         nummer = ask 'hoe oud ben je'
         for counter in range 1 to 5
diff --git a/tests/test_translation_level_14.py b/tests/test_translation_level_14.py
--- a/tests/test_translation_level_14.py
+++ b/tests/test_translation_level_14.py
@@ -1,3 +1,4 @@
+from parameterized import parameterized
 import hedy
 from test_level_01 import HedyTester
 import hedy_translation
@@ -12,7 +13,8 @@
 
 
 class TestsTranslationLevel14(HedyTester):
-    level = 14
+    level = 14    
+    all_keywords_dict = hedy_translation.all_keywords_to_dict()
 
     def test_bigger(self):
         code = textwrap.dedent("""\
@@ -96,4 +98,19 @@ def test_double_equals(self):
         als hedy == 6
             print 'hedy'""")
 
-        self.assertEqual(expected, result)
\ No newline at end of file
+        self.assertEqual(expected, result)
+
+    @parameterized.expand(HedyTester.as_list_of_tuples(all_keywords_dict["if"], all_keywords_dict["print"], hedy_translation.KEYWORD_LANGUAGES))   
+    def test_double_equals_all_lang(self, if_keyword, print_keyword, lang):
+        code = textwrap.dedent(f"""\
+        hedy = 5
+        {if_keyword} hedy == 6
+            {print_keyword} 'hedy'""")
+
+        result = hedy_translation.translate_keywords(code, from_lang=lang, to_lang="nl", level=self.level)
+        expected = textwrap.dedent("""\
+        hedy = 5
+        als hedy == 6
+            print 'hedy'""")
+
+        self.assertEqual(expected, result)   
\ No newline at end of file