18574: Adds strict checking on conversion methods. Adds/updates tests.
authorLucas Di Pentima <lucas.dipentima@curii.com>
Mon, 28 Feb 2022 20:51:29 +0000 (17:51 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Mon, 28 Feb 2022 21:34:48 +0000 (18:34 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

sdk/python/arvados/vocabulary.py
sdk/python/tests/test_vocabulary.py

index b4148890aa31e547879d940f5aa1ce9ff46bb742..d51435f03355f7fedca88e58701fa7b015246f9d 100644 (file)
@@ -46,9 +46,11 @@ class Vocabulary(object):
                 try:
                     v_id = self[k][v].identifier
                 except KeyError:
-                    pass
+                    if self[k].strict:
+                        raise ValueError("value '%s' not found for key '%s'" % (v, k))
             except KeyError:
-                pass
+                if self.strict_keys:
+                    raise KeyError("key '%s' not found" % k)
             r[k_id] = v_id
         return r
 
@@ -65,9 +67,11 @@ class Vocabulary(object):
                 try:
                     v_lbl = self[k][v].preferred_label
                 except KeyError:
-                    pass
+                    if self[k].strict:
+                        raise ValueError("value '%s' not found for key '%s'" % (v, k))
             except KeyError:
-                pass
+                if self.strict_keys:
+                    raise KeyError("key '%s' not found" % k)
             r[k_lbl] = v_lbl
         return r
 
index 7cca66a1c668ea160124777d29037b750b473f58..a3b6391b0edd1f06b1e0342b44005b29537fc23b 100644 (file)
@@ -32,7 +32,7 @@ class VocabularyTest(unittest.TestCase):
                     },
                 },
             },
-            'IDTAGIMPORTANCE': {
+            'IDTAGIMPORTANCES': {
                 'strict': True,
                 'labels': [
                     {'label': 'Importance'},
@@ -72,7 +72,7 @@ class VocabularyTest(unittest.TestCase):
         self.assertEqual(
             self.voc.key_aliases.keys(),
             set(['idtaganimals', 'creature', 'animal',
-                'idtagimportance', 'importance', 'priority'])
+                'idtagimportances', 'importance', 'priority'])
         )
 
         vk = self.voc.key_aliases['creature']
@@ -113,22 +113,55 @@ class VocabularyTest(unittest.TestCase):
 
     def test_convert_to_identifiers(self):
         cases = [
-            {'IDTAGIMPORTANCE': 'IDVALIMPORTANCE1'},
-            {'IDTAGIMPORTANCE': 'High'},
+            {'IDTAGIMPORTANCES': 'IDVALIMPORTANCE1'},
+            {'IDTAGIMPORTANCES': 'High'},
             {'importance': 'IDVALIMPORTANCE1'},
             {'priority': 'high priority'},
         ]
         for case in cases:
             self.assertEqual(
                 self.voc.convert_to_identifiers(case),
-                {'IDTAGIMPORTANCE': 'IDVALIMPORTANCE1'},
+                {'IDTAGIMPORTANCES': 'IDVALIMPORTANCE1'},
                 "failing test case: {}".format(case)
             )
 
+    def test_convert_to_identifiers_multiple_pairs(self):
+        cases = [
+            {'IDTAGIMPORTANCES': 'IDVALIMPORTANCE1', 'IDTAGANIMALS': 'IDVALANIMAL1'},
+            {'IDTAGIMPORTANCES': 'High', 'IDTAGANIMALS': 'IDVALANIMAL1'},
+            {'importance': 'IDVALIMPORTANCE1', 'animal': 'IDVALANIMAL1'},
+            {'priority': 'high priority', 'animal': 'IDVALANIMAL1'},
+        ]
+        for case in cases:
+            self.assertEqual(
+                self.voc.convert_to_identifiers(case),
+                {'IDTAGIMPORTANCES': 'IDVALIMPORTANCE1', 'IDTAGANIMALS': 'IDVALANIMAL1'},
+                "failing test case: {}".format(case)
+            )
+
+    def test_convert_to_identifiers_unknown_key(self):
+        # Non-strict vocabulary
+        self.assertEqual(self.voc.strict_keys, False)
+        self.assertEqual(self.voc.convert_to_identifiers({'foo': 'bar'}), {'foo': 'bar'})
+        # Strict vocabulary
+        strict_voc = arvados.vocabulary.Vocabulary(self.EXAMPLE_VOC)
+        strict_voc.strict_keys = True
+        with self.assertRaises(KeyError):
+            strict_voc.convert_to_identifiers({'foo': 'bar'})
+
+    def test_convert_to_identifiers_unknown_value(self):
+        # Non-strict key
+        self.assertEqual(self.voc['animal'].strict, False)
+        self.assertEqual(self.voc.convert_to_identifiers({'Animal': 'foo'}), {'IDTAGANIMALS': 'foo'})
+        # Strict key
+        self.assertEqual(self.voc['priority'].strict, True)
+        with self.assertRaises(ValueError):
+            self.voc.convert_to_identifiers({'Priority': 'foo'})
+
     def test_convert_to_labels(self):
         cases = [
-            {'IDTAGIMPORTANCE': 'IDVALIMPORTANCE1'},
-            {'IDTAGIMPORTANCE': 'High'},
+            {'IDTAGIMPORTANCES': 'IDVALIMPORTANCE1'},
+            {'IDTAGIMPORTANCES': 'High'},
             {'importance': 'IDVALIMPORTANCE1'},
             {'priority': 'high priority'},
         ]
@@ -137,4 +170,37 @@ class VocabularyTest(unittest.TestCase):
                 self.voc.convert_to_labels(case),
                 {'Importance': 'High'},
                 "failing test case: {}".format(case)
-            )
\ No newline at end of file
+            )
+
+    def test_convert_to_labels_multiple_pairs(self):
+        cases = [
+            {'IDTAGIMPORTANCES': 'IDVALIMPORTANCE1', 'IDTAGANIMALS': 'IDVALANIMAL1'},
+            {'IDTAGIMPORTANCES': 'High', 'IDTAGANIMALS': 'IDVALANIMAL1'},
+            {'importance': 'IDVALIMPORTANCE1', 'animal': 'IDVALANIMAL1'},
+            {'priority': 'high priority', 'animal': 'IDVALANIMAL1'},
+        ]
+        for case in cases:
+            self.assertEqual(
+                self.voc.convert_to_labels(case),
+                {'Importance': 'High', 'Animal': 'Human'},
+                "failing test case: {}".format(case)
+            )
+
+    def test_convert_to_labels_unknown_key(self):
+        # Non-strict vocabulary
+        self.assertEqual(self.voc.strict_keys, False)
+        self.assertEqual(self.voc.convert_to_labels({'foo': 'bar'}), {'foo': 'bar'})
+        # Strict vocabulary
+        strict_voc = arvados.vocabulary.Vocabulary(self.EXAMPLE_VOC)
+        strict_voc.strict_keys = True
+        with self.assertRaises(KeyError):
+            strict_voc.convert_to_labels({'foo': 'bar'})
+
+    def test_convert_to_labels_unknown_value(self):
+        # Non-strict key
+        self.assertEqual(self.voc['animal'].strict, False)
+        self.assertEqual(self.voc.convert_to_labels({'IDTAGANIMALS': 'foo'}), {'Animal': 'foo'})
+        # Strict key
+        self.assertEqual(self.voc['priority'].strict, True)
+        with self.assertRaises(ValueError):
+            self.voc.convert_to_labels({'IDTAGIMPORTANCES': 'foo'})
\ No newline at end of file