def test_reference_relation_constraints(self): from cocktail.schema import Reference, Integer, exceptions, get foreign_field = Integer("foo") ref = Reference(relation_constraints=[ foreign_field.not_equal(None), foreign_field.greater(3), foreign_field.lower(8), lambda owner, related: get(related, "foo", None) is None or get( related, "foo", None) % 5 != 0 ]) self._test_validation(ref, [None, {"foo": 4}, {"foo": 6}, {"foo": 7}]) self._test_validation( ref, None, [{}, { "foo": None }], exceptions.RelationConstraintError, error_count=2 # Note that x > None is always True ) self._test_validation(ref, None, [{ "foo": -6 }, { "foo": 1 }, { "foo": 3 }], exceptions.RelationConstraintError, {"constraint": ref.relation_constraints[1]}) self._test_validation(ref, None, [{ "foo": 8 }, { "foo": 12 }, { "foo": 134 }], exceptions.RelationConstraintError, {"constraint": ref.relation_constraints[2]}) self._test_validation(ref, None, [{ "foo": 5 }], exceptions.RelationConstraintError, {"constraint": ref.relation_constraints[3]})
def test_items(self): from cocktail.schema import Collection, Integer, exceptions self._test_validation( Collection(items=Integer(), required=False), [None, [], [1], [1, 2], set([1, 2, 3]), tuple(range(10))], [["a", "b", "c"], [3.5, 2.7, 1.4]], exceptions.TypeCheckError, error_count=3)
def test_scalar(self): from cocktail.schema import Schema, Integer, exceptions class Validable(object): def __init__(self, foo): self.foo = foo def __repr__(self): return "Validable(%r)" % self.foo self._test_validation( Schema(members={"foo": Integer()}), [Validable(None), Validable(1), Validable(15)], [Validable(""), Validable("hello, world!"), Validable(3.15)], exceptions.TypeCheckError)
def get_user_schema(): import re from cocktail.schema import Schema, Integer, String, Boolean return Schema(members = { "id": Integer( required = True, unique = True, min = 1 ), "name": String( required = True, min = 4, max = 20, format = re.compile("^[a-zA-Z][a-zA-Z_0-9]*$") ), "enabled": Boolean( required = True, default = True ) })
def test_max(self): from cocktail.schema import Integer, exceptions self._test_validation(Integer(max=5), [None, 5, 4, 0, -6, -78], [6, 7, 15, 100, 300], exceptions.MaxValueError)
def test_min(self): from cocktail.schema import Integer, exceptions self._test_validation(Integer(min=5), [None, 5, 6, 15, 300], [4, 3, 0, -2, -100], exceptions.MinValueError)
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") ])
class ScalarFieldCoercionTestCase(TestCase): invalid_values = [None, "", "Foobar", 3] valid_values = [10, 333] def setUp(self): from cocktail.schema import Integer self.member = Integer(required=True, min=5, default=50) def test_can_ignore_errors(self): from cocktail.schema import Coercion for value in self.invalid_values: assert self.member.coerce(value, Coercion.NONE) == value for value in self.valid_values: assert self.member.coerce(value, Coercion.NONE) == value def test_can_replace_invalid_values_with_none(self): from cocktail.schema import Coercion for value in self.invalid_values: assert self.member.coerce(value, Coercion.SET_NONE) is None for value in self.valid_values: assert self.member.coerce(value, Coercion.SET_NONE) == value def test_can_replace_invalid_values_with_default(self): from cocktail.schema import Coercion for value in self.invalid_values: assert self.member.coerce(value, Coercion.SET_DEFAULT) \ == self.member.default for value in self.valid_values: assert self.member.coerce(value, Coercion.SET_DEFAULT) == value def test_can_raise_errors_immediately(self): from cocktail.schema import Coercion from cocktail.schema.exceptions import InputError for value in self.invalid_values: try: self.member.coerce(value, Coercion.FAIL_IMMEDIATELY) except InputError: pass else: raise AssertionError( f"Coercing {value} should raise an input error") for value in self.valid_values: assert self.member.coerce(value, Coercion.FAIL_IMMEDIATELY) \ == value def test_can_aggregate_errors(self): from cocktail.schema import Coercion from cocktail.schema.exceptions import InputError for value in self.invalid_values: try: self.member.coerce(value, Coercion.FAIL) except InputError as e: assert e.member is self.member assert e.errors else: raise AssertionError( f"Coercing {value} should raise a coercion error") for value in self.valid_values: assert self.member.coerce(value, Coercion.FAIL) == value
def setUp(self): from cocktail.schema import Integer self.member = Integer(required=True, min=5, default=50)