def test_implicit_schema_copy(self): from cocktail.schema import Schema, Adapter user_schema = get_user_schema() adapter = Adapter() self.assertTrue(adapter.implicit_copy) # Exporting schemas form_schema = Schema() adapter.export_schema(user_schema, form_schema) self.assertEqual( len(list(user_schema.members().keys())), len(list(form_schema.members().keys())) ) self.assertEqual( set(user_schema.members().keys()), set(form_schema.members().keys()) ) # Importing schemas user_schema_2 = Schema() adapter.import_schema(form_schema, user_schema_2) self.assertEqual( list(form_schema.members().keys()), list(user_schema_2.members().keys()) )
def test_simple_schema_copy(self): from cocktail.schema import Adapter, Schema, Copy adapter = Adapter() adapter.implicit_copy = False adapter.copy("id") adapter.copy("name") user_schema = get_user_schema() form_schema = Schema() adapter.export_schema(user_schema, form_schema) self.assertEqual(len(form_schema.members()), 2) self.assertEqual( set(form_schema.members().keys()), set(["id", "name"]) )
def test_exclude_undefined_member(self): from cocktail.schema import Adapter, Schema adapter = Adapter() adapter.exclude("fictitious_member") user_schema = get_user_schema() form_schema = Schema() adapter.export_schema(user_schema, form_schema) self.assertFalse("fictitious_member" in form_schema.members())
def test_disabled_implicit_schema_copy(self): from cocktail.schema import Schema, Adapter user_schema = get_user_schema() form_schema = Schema() adapter = Adapter() adapter.implicit_copy = False adapter.export_schema(user_schema, form_schema) self.assertFalse(form_schema.members())
class SchemaCoercionTestCase(TestCase): def setUp(self): from cocktail.schema import Schema, Integer, String self.schema = Schema(members=[ Integer("num", required=True, min=5, default=50), String("text", min=5, default="cornucopia") ]) def test_can_ignore_errors(self): from itertools import product from cocktail.schema import Coercion for obj in [{ "num": 3, "text": None }, { "num": 20, "text": "hum" }, { "num": 3, "text": "hum" }, { "num": 15, "text": "spam!" }]: original = obj.copy() result = self.schema.coerce(obj, Coercion.NONE) assert result is obj assert result == original def test_can_replace_invalid_values_with_none(self): from cocktail.schema import Coercion # num invalid, text valid obj = {"num": 3, "text": None} result = self.schema.coerce(obj, Coercion.SET_NONE) assert obj is result assert result == {"num": None, "text": None} # num valid, text invalid obj = {"num": 20, "text": "hum"} result = self.schema.coerce(obj, Coercion.SET_NONE) assert obj is result assert result == {"num": 20, "text": None} # both invalid obj = {"num": 3, "text": "hum"} result = self.schema.coerce(obj, Coercion.SET_NONE) assert obj is result assert result == {"num": None, "text": None} # both valid obj = {"num": 15, "text": "spam!"} result = self.schema.coerce(obj, Coercion.SET_NONE) assert obj is result assert result == {"num": 15, "text": "spam!"} def test_can_replace_invalid_values_with_default(self): from cocktail.schema import Coercion default_num = self.schema["num"].default default_text = self.schema["text"].default # num invalid, text valid obj = {"num": 3, "text": None} result = self.schema.coerce(obj, Coercion.SET_DEFAULT) assert obj is result assert result == {"num": default_num, "text": None} # num valid, text invalid obj = {"num": 20, "text": "hum"} result = self.schema.coerce(obj, Coercion.SET_DEFAULT) assert obj is result assert result == {"num": 20, "text": default_text} # both invalid obj = {"num": 3, "text": "hum"} result = self.schema.coerce(obj, Coercion.SET_DEFAULT) assert obj is result assert result == {"num": default_num, "text": default_text} # both valid obj = {"num": 15, "text": "spam!"} result = self.schema.coerce(obj, Coercion.SET_DEFAULT) assert obj is result assert result == {"num": 15, "text": "spam!"} def test_can_raise_errors_immediately(self): from cocktail.schema import Coercion from cocktail.schema.exceptions import (InputError, MinValueError, MinLengthError) FI = Coercion.FAIL_IMMEDIATELY # num invalid, text valid obj = {"num": 3, "text": None} try: self.schema.coerce(obj, FI) except InputError as e: assert e.member is self.schema assert len(e.errors) == 1 error = e.errors[0] assert isinstance(error, MinValueError) assert error.member is self.schema["num"] else: raise AssertionError( f"Coercing {obj} should raise an input error on 'num'") # num valid, text invalid obj = {"num": 20, "text": "hum"} try: self.schema.coerce(obj, FI) except InputError as e: assert e.member is self.schema assert len(e.errors) == 1 error = e.errors[0] assert isinstance(error, MinLengthError) assert error.member is self.schema["text"] else: raise AssertionError( f"Coercing {obj} should raise a validation error on 'text'") # both invalid obj = {"num": 3, "text": "hum"} try: self.schema.coerce(obj, FI) except InputError as e: assert e.member is self.schema assert len(e.errors) == 1 assert e.errors[0].member in list(self.schema.members().values()) else: raise AssertionError( f"Coercing {obj} should raise a validation error") # both valid obj = {"num": 15, "text": "spam!"} original = obj.copy() result = self.schema.coerce(obj, FI) assert obj is result assert result == original def test_can_aggregate_errors(self): from cocktail.schema import Coercion from cocktail.schema.exceptions import InputError def bad_keys(e): keys = set() for error in e.errors: keys.update(member.name for member in error.invalid_members) return keys # num invalid, text valid obj = {"num": 3, "text": None} try: self.schema.coerce(obj, Coercion.FAIL) except InputError as e: assert bad_keys(e) == {"num"} else: raise AssertionError( f"Coercing {obj} should raise a validation error on 'num'") # num valid, text invalid obj = {"num": 20, "text": "hum"} try: self.schema.coerce(obj, Coercion.FAIL) except InputError as e: assert bad_keys(e) == {"text"} else: raise AssertionError( f"Coercing {obj} should raise a validation error on 'text'") # both invalid obj = {"num": 3, "text": "hum"} try: self.schema.coerce(obj, Coercion.FAIL) except InputError as e: assert bad_keys(e) == {"num", "text"} else: raise AssertionError( f"Coercing {obj} should raise a validation error") # both valid obj = {"num": 15, "text": "spam!"} original = obj.copy() result = self.schema.coerce(obj, Coercion.FAIL) assert obj is result assert result == original