Commits

Andy Mikhailenko committed 00cbabc

Added validation of types via default values.

  • Participants
  • Parent commits b55bf13

Comments (0)

Files changed (2)

File monk/validation.py

 
 def check_type(typespec, value, keys_tuple):
     if typespec is None:
+        # any value is allowed
         return
     if not isinstance(typespec, type):
-        key = '.'.join(keys_tuple)
-        raise StructureSpecificationError(
-            '{path}: expected dict, list, type or None (got {value!r})'
-                .format(path=key, value=value))
+        # default value is provided
+        typespec = type(typespec)
     if not isinstance(value, typespec):
         key = '.'.join(keys_tuple)
         raise TypeError('{key}: expected {typespec.__name__}, got '
             continue
         elif isinstance(typespec, list) and value:
             # nested list
+            if not typespec:
+                # empty by default
+                continue
             item_spec = typespec[0]
             for item in value:
                 if item_spec == dict or isinstance(item, dict):

File unittests/test_validation.py

         validate_structure({'a': bool}, {'a': True})
         validate_structure({'a': bool}, {'a': False})
 
+    def test_bool_instance(self):
+        validate_structure({'a': True}, {'a': None})
+        validate_structure({'a': True}, {'a': True})
+        validate_structure({'a': True}, {'a': False})
+
     def test_dict(self):
         validate_structure({'a': dict}, {'a': None})
         validate_structure({'a': dict}, {'a': {}})
         validate_structure({'a': dict}, {'a': {'b': 'c'}})
 
+    def test_dict_instance(self):
+        validate_structure({'a': {}}, {'a': None})
+        validate_structure({'a': {}}, {'a': {}})
+        validate_structure({'a': {}}, {'a': {'b': 123}})
+
     def test_float(self):
         validate_structure({'a': float}, {'a': None})
         validate_structure({'a': float}, {'a': .5})
 
+    def test_float_instance(self):
+        validate_structure({'a': .2}, {'a': None})
+        validate_structure({'a': .2}, {'a': .5})
+
     def test_int(self):
         validate_structure({'a': int}, {'a': None})
         validate_structure({'a': int}, {'a': 123})
 
+    def test_int_instance(self):
+        validate_structure({'a': 1}, {'a': None})
+        validate_structure({'a': 1}, {'a': 123})
+
     def test_list(self):
         validate_structure({'a': list}, {'a': None})
         validate_structure({'a': list}, {'a': []})
         validate_structure({'a': list}, {'a': ['b', 123]})
 
+    def test_list_instance(self):
+        validate_structure({'a': []}, {'a': None})
+        validate_structure({'a': []}, {'a': []})
+        validate_structure({'a': []}, {'a': ['b', 123]})
+
+        validate_structure({'a': [int]}, {'a': None})
+        validate_structure({'a': [int]}, {'a': []})
+        validate_structure({'a': [int]}, {'a': [123]})
+        validate_structure({'a': [int]}, {'a': [123, 456]})
+        with pytest.raises(TypeError):
+            validate_structure({'a': [int]}, {'a': ['b', 123]})
+
     def test_unicode(self):
         validate_structure({'a': unicode}, {'a': None})
         validate_structure({'a': unicode}, {'a': u'hello'})
         with pytest.raises(TypeError):
             validate_structure({'a': unicode}, {'a': 123})
 
+    def test_unicode_instance(self):
+        validate_structure({'a': u'foo'}, {'a': None})
+        validate_structure({'a': u'foo'}, {'a': u'hello'})
+        with pytest.raises(TypeError):
+            validate_structure({'a': u'foo'}, {'a': 123})
+
     def test_datetime(self):
         validate_structure({'a': datetime.datetime}, {'a': None})
         validate_structure({'a': datetime.datetime},
-                                {'a': datetime.datetime.utcnow()})
+                           {'a': datetime.datetime.utcnow()})
+        with pytest.raises(TypeError):
+            validate_structure({'a': datetime.datetime}, {'a': 123})
+
+    def test_datetime_instance(self):
+        validate_structure({'a': datetime.datetime(1900, 1, 1)}, {'a': None})
+        validate_structure({'a': datetime.datetime(1900, 1, 1)},
+                           {'a': datetime.datetime.utcnow()})
+        with pytest.raises(TypeError):
+            validate_structure({'a': datetime.datetime}, {'a': 123})
 
     def test_objectid(self):
         validate_structure({'a': pymongo.objectid.ObjectId}, {'a': None})