def test_nested_error(): schema = {'nested': S.Dict(schema={'num': S.Integer()})} with pytest.raises(E.BadType) as ei: normalize_dict(schema, {'nested': {'num': 'three!'}}) assert ei.value.value == 'three!' assert ei.value.type_ == 'integer' assert ei.value.stack == ('nested', 'num')
def test_nullable_with_anyof(): """This is the second reason that sureberus exists.""" anyof = { 'nullable': True, 'anyof': [S.Integer(), S.String()], } assert normalize_schema(anyof, None) == None
def test_list_schema(): schema = S.List(schema=S.Integer()) val = [1, 2, 3] assert normalize_schema(schema, val) == val with pytest.raises(E.BadType) as ei: normalize_schema(schema, [1, 'two', object()]) assert ei.value.value == 'two' assert ei.value.stack == (1, )
def test_default_setter(): old_dict = {'foo': 0} schema = S.Dict( schema={ 'foo': S.Integer(), 'foo-incremented': { 'default_setter': lambda doc: doc['foo'] + 1 } }) new_dict = normalize_schema(schema, old_dict) assert old_dict == {'foo': 0} assert new_dict == {'foo': 0, 'foo-incremented': 1} assert normalize_schema(schema, { 'foo': 0, 'foo-incremented': 5 }) == { 'foo': 0, 'foo-incremented': 5 }
def test_anyof_with_normalization(): """THIS IS THE WHOLE REASON FOR SUREBERUS TO EXIST""" # We want to support # ANY OF: # - {'image': str, 'opacity': {'type': 'integer', 'default': 100}} # - {'gradient': ...} # And when you normalize this, you actually get the `default` applied in the # result, if that rule matches! anyof = S.Dict(anyof=[ S.SubSchema(gradient=S.String()), S.SubSchema(image=S.String(), opacity=S.Integer(default=100)) ]) gfoo = {'gradient': 'foo'} assert normalize_schema(anyof, gfoo) == gfoo ifoo_with_opacity = {'image': 'foo', 'opacity': 99} assert normalize_schema(anyof, ifoo_with_opacity) == ifoo_with_opacity ifoo_with_default = {'image': 'foo'} assert normalize_schema(anyof, ifoo_with_default) == { 'image': 'foo', 'opacity': 100 }
def test_not_required(): assert normalize_dict({'id': S.Integer(required=False)}, {}) == {}
def test_field_not_found(): with pytest.raises(E.DictFieldNotFound) as ei: normalize_dict({'id': S.Integer(required=True)}, {}) assert ei.value.key == 'id' assert ei.value.value == {} assert ei.value.stack == ()
def test_oneof(): oneof = {'oneof': [S.Integer(), S.String()]} assert normalize_schema(oneof, 3) == 3 assert normalize_schema(oneof, 'three') == 'three' with pytest.raises(E.NoneMatched) as ei: normalize_schema(oneof, object())
def test_nullable(): assert normalize_schema({'nullable': True}, None) == None assert normalize_schema(S.Integer(nullable=True), None) == None with pytest.raises(E.BadType): normalize_schema(S.Integer(nullable=False), None)
def test_normalize_schema(): assert normalize_schema(S.Integer(), 3)
def test_default(): old_dict = {} schema = {'num': S.Integer(default=0)} new_dict = normalize_dict(schema, old_dict) assert old_dict == {} assert new_dict == {'num': 0}
import pytest from sureberus import normalize_dict, normalize_schema from sureberus import schema as S from sureberus import errors as E id_int = {'id': S.Integer()} def test_dict_of_int(): sample = {'id': 3} assert normalize_dict(id_int, sample) == sample def test_bad_type(): sample = {'id': '3'} with pytest.raises(E.BadType) as ei: normalize_dict(id_int, sample) assert ei.value.value == '3' assert ei.value.type_ == 'integer' assert ei.value.stack == ('id', ) def test_field_not_found(): with pytest.raises(E.DictFieldNotFound) as ei: normalize_dict({'id': S.Integer(required=True)}, {}) assert ei.value.key == 'id' assert ei.value.value == {} assert ei.value.stack == ()
from copy import copy from datetime import date, datetime from dateutil.relativedelta import relativedelta import dateparser import inspect from sqlalchemy.ext.declarative import DeclarativeMeta from sqlalchemy.sql.base import ImmutableColumnCollection from sureberus import schema as S from recipe.exceptions import InvalidColumnError SCALAR_TYPES = [S.Integer(), S.String(), S.Float(), S.Boolean()] def _chain(*args): """Chain several coercers together""" def fn(value): for arg in args: value = arg(value) return value return fn def _make_sqlalchemy_datatype_lookup(): """ Build a dictionary of the allowed sqlalchemy casts """ from sqlalchemy.sql import sqltypes d = {} for name in dir(sqltypes): sqltype = getattr(sqltypes, name) if name.lower() not in d and name[0] != "_" and name != "NULLTYPE":