def test_set_type_instance(): """Set can take an instance of a Type as well as a Type subclass""" type_instance = String() instance_set = Set(type_instance) assert instance_set.inner_typedef is type_instance type_subclass = String subclass_set = Set(type_subclass) assert isinstance(subclass_set.inner_typedef, type_subclass)
def test_sets(engine, set_type, loaded, dumped): typedef = Set(set_type) assert typedef.dynamo_load(dumped, context={"engine": engine}) == loaded # Can't use a simple set because the values are unhashable dicts like {"S": "value"} actual_dumped = typedef.dynamo_dump(loaded, context={"engine": engine}) assert len(actual_dumped) == len(dumped) for item in actual_dumped: assert item in dumped
def test_repr(): typedef = Type() assert repr(typedef) == "<Type[None:None]>" # Not all python types will be classes typedef.backing_type = "foo" typedef.python_type = 3 assert repr(typedef) == "<Type[foo:3]>" set_typedef = Set(Integer) assert repr(set_typedef) == "<Set[NS:Set]>"
def test_set_registered(): """set registers its typedef so loading/dumping happens properly""" type_engine = declare.TypeEngine.unique() string_type = String() string_set_type = Set(string_type) type_engine.bind() assert string_type not in type_engine.bound_types type_engine.register(string_set_type) type_engine.bind() assert string_type in type_engine.bound_types
def test_set_illegal_backing_type(): """The backing type for a set MUST be one of S/N/B, not BOOL""" for typedef in [Boolean, Set(Integer)]: with pytest.raises(TypeError): Set(typedef)
@pytest.mark.parametrize( "typedef", [String, UUID, DateTime, Number, Integer, Binary, Boolean]) def test_none_scalar_types(typedef): """single-value types without an explicit 'lack of value' sentinel should return None when given None""" type = typedef() context = {} assert type._load(None, context=context) is None assert type._load({typedef.backing_type: None}, context=context) is None assert type.dynamo_load(None, context=context) is None assert type._dump(None, context=context) is None assert type.dynamo_dump(None, context=context) is None @pytest.mark.parametrize("typedef, default", [(Set(String), set()), (Set(Integer), set()), (Set(Binary), set()), (List(DateTime), list()), (DocumentType, { "Rating": None, "Stock": None, "Description": { "Heading": None, "Body": None, "Specifications": None }, "Id": None, "Updated": None })]) def test_load_none_vector_types(engine, typedef, default):
typedef = MyType() with pytest.raises(NotImplementedError): typedef._load({"S": "value"}, context={}) with pytest.raises(NotImplementedError): typedef._dump("value", context={}) @pytest.mark.parametrize("type", [ Type(), String(), Binary(), Number(), Boolean(), Set(String), Set(Binary), Set(Number), ]) def test_type_paths_raise(type): """List, Map, DynamicList, and DynamicMap are the only types that support paths""" with pytest.raises(RuntimeError): _ = type["string-key"] # noqa: F841 with pytest.raises(RuntimeError): _ = type[3] # noqa: F841 def test_load_dump_best_effort(engine): """python_type is an informational field, and doesn't check types on load/dump""" class MyType(String): backing_type = "FOO"
assert condition.values == [3] condition = c.is_not(3) assert condition.operation == "!=" assert condition.column is c assert condition.values == [3] @pytest.mark.parametrize( "op, typedefs, args", [("begins_with", [ Integer(), List(String), Map(s=String), Boolean(), Set(Integer), Set(Binary), Set(String) ], ("one-arg", )), ("contains", [Integer(), Boolean(), Map(s=String)], ("one-arg", )), ("between", [ Set(String), Set(Binary), Set(String), List(String), Map(s=String), Boolean() ], ("first-arg", "second-arg"))]) def test_unsupported_mixin_function_conditions(op, typedefs, args): class Model(BaseModel): id = Column(Integer, hash_key=True)