]> ToastFreeware Gitweb - philipp/winterrodeln/wrpylib.git/commitdiff
Further work on order_json_keys.
authorPhilipp Spitzer <philipp@spitzer.priv.at>
Tue, 26 Oct 2021 21:48:06 +0000 (23:48 +0200)
committerPhilipp Spitzer <philipp@spitzer.priv.at>
Tue, 26 Oct 2021 21:48:06 +0000 (23:48 +0200)
tests/test_json_validate.py
wrpylib/json_tools.py

index 64afcf1ff62a0c8b817d851f5edf01a4b0626332..d8888abcac0442f8524ce0c014f4d81d8904158f 100644 (file)
@@ -52,7 +52,33 @@ schema_object = {
 
 
 class TestJsonValidate(unittest.TestCase):
-    def test_empty_object(self):
+    def test_string_empty(self):
+        actual = order_json_keys('', {"type": "string"})
+        self.assertEqual('', actual)
+
+    def test_string_valid(self):
+        actual = order_json_keys('äüß', {"type": "string"})
+        self.assertEqual('äüß', actual)
+
+    def test_string_wrong_types(self):
+        for value in [True, False, None, 0, 1, 0.5, [], ['abc'], {}, {'a': 'b'}]:
+            with self.subTest(f'Try invalid value {value}.', value=value):
+                with self.assertRaises(ValueError):
+                    order_json_keys(value, {"type": "string"})
+
+    def test_number_valid(self):
+        for value in [0, 1, -10, 8.8, 0.0, -1024.9]:
+            with self.subTest(f'Valid number {value}.', value=value):
+                actual = order_json_keys(value, {"type": "number"})
+                self.assertEqual(value, actual)
+
+    def test_number_wrong_types(self):
+        for value in [True, False, None, '', 'abc', [], [0], [1], {}, {'a': 1}]:
+            with self.subTest(f'Try invalid value {value}.', value=value):
+                with self.assertRaises(ValueError):
+                    order_json_keys(value, {"type": "number"})
+
+    def test_object_empty(self):
         schema = schema_object.copy()
         del schema['required']
         actual = order_json_keys({}, schema)
@@ -118,3 +144,28 @@ class TestJsonValidate(unittest.TestCase):
         schema['additionalProperties'] = False
         with self.assertRaises(ValueError):
             order_json_keys(value, schema)
+
+    def test_array(self):
+        raise NotImplementedError()
+
+    def test_boolean_valid(self):
+        for value in [False, True]:
+            with self.subTest(f'Valid boolean {value}.', value=value):
+                actual = order_json_keys(value, {"type": "boolean"})
+                self.assertEqual(value, actual)
+
+    def test_boolean_wrong_types(self):
+        for value in [0, 1, -3, 10, 5.5, None, '', 'True', [], [True], [False], {}, {'a': True}]:
+            with self.subTest(f'Try invalid value {value}.', value=value):
+                with self.assertRaises(ValueError):
+                    order_json_keys(value, {"type": "boolean"})
+
+    def test_null_valid(self):
+        actual = order_json_keys(None, {"type": "null"})
+        self.assertEqual(None, actual)
+
+    def test_null_wrong_types(self):
+        for value in [True, False, 0, 1, -3, 10, 5.5, '', 'abc', [], [0], [1], {}, {'a': 1}]:
+            with self.subTest(f'Try invalid value {value}.', value=value):
+                with self.assertRaises(ValueError):
+                    order_json_keys(value, {"type": "null"})
index 2adacb9ae79206fdd985a92e3591559052f746ec..e48730223fbe6542516a870af71116ed7da2af6b 100644 (file)
@@ -8,28 +8,67 @@ class ValidationError(ValueError):
     pass
 
 
-def _order_json_keys(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> JsonTypes:
-    if sub_schema['type'] == 'object':
-        if not isinstance(sub_value, dict):
-            raise ValidationError(f'Type of {"".join(path)} needs to be object (Python dict).')
-        v = sub_value.copy()
-        p = sub_schema['properties']
-        result = {}
-        for key in p:
-            if key in v:
-                result[key] = _order_json_keys(v.pop(key), p[key], path + [f"['{key}']"])
-            else:
-                if key in sub_schema.get('required', []):
-                    raise ValidationError(f'Required key "{key}" not present ({"".join(path)}).')
-        if len(v) > 0:
-            if sub_schema.get('additionalProperties', True):
-                # strictly speaking additionalProperties could be more complicated than boolean
-                result.update(v)
-            else:
-                raise ValidationError(f'Keys not allowed in {"".join(path)}: {", ".join(v)}')
-        return result
+def _order_json_keys_string(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> str:
+    if not isinstance(sub_value, str):
+        raise ValidationError(f'Type of {"".join(path)} needs to be string (Python str).')
+    return sub_value
+
+
+def _order_json_keys_number(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> Union[int, float]:
+    if not isinstance(sub_value, (int, float)) or isinstance(sub_value, bool):
+        raise ValidationError(f'Type of {"".join(path)} needs to be number (Python int or float).')
+    return sub_value
+
+
+def _order_json_keys_object(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> Dict:
+    if not isinstance(sub_value, dict):
+        raise ValidationError(f'Type of {"".join(path)} needs to be object (Python dict).')
+    v = sub_value.copy()
+    p = sub_schema['properties']
+    result = {}
+    for key in p:
+        if key in v:
+            result[key] = _order_json_keys(v.pop(key), p[key], path + [f"['{key}']"])
+        else:
+            if key in sub_schema.get('required', []):
+                raise ValidationError(f'Required key "{key}" not present ({"".join(path)}).')
+    if len(v) > 0:
+        if sub_schema.get('additionalProperties', True):
+            # strictly speaking additionalProperties could be more complicated than boolean
+            result.update(v)
+        else:
+            raise ValidationError(f'Keys not allowed in {"".join(path)}: {", ".join(v)}')
+    return result
+
+
+def _order_json_keys_array(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> List:
+    if not isinstance(sub_value, list):
+        raise ValidationError(f'Type of {"".join(path)} needs to be array (Python list).')
     return sub_value
 
 
+def _order_json_keys_boolean(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> bool:
+    if not isinstance(sub_value, bool):
+        raise ValidationError(f'Type of {"".join(path)} needs to be boolean (Python bool).')
+    return sub_value
+
+
+def _order_json_keys_null(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> None:
+    if sub_value is not None:
+        raise ValidationError(f'Type of {"".join(path)} needs to be null (Python None).')
+    return sub_value
+
+
+def _order_json_keys(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> JsonTypes:
+    return {
+        'string': _order_json_keys_string,
+        'number': _order_json_keys_number,
+        'object': _order_json_keys_object,
+        'array': _order_json_keys_array,
+        'boolean': _order_json_keys_boolean,
+        'null': _order_json_keys_null,
+    }[sub_schema['type']](sub_value, sub_schema, path)
+
+
 def order_json_keys(value: JsonTypes, schema: JsonTypes) -> JsonTypes:
     return _order_json_keys(value, schema, ['value'])