Add tests. Closes #5
parent
6834a0f481
commit
3ae568a38a
@ -0,0 +1,116 @@
|
|||||||
|
import pytest
|
||||||
|
import preserve
|
||||||
|
|
||||||
|
|
||||||
|
class PlainClass:
|
||||||
|
def __init__(self):
|
||||||
|
self.attr_int = 734
|
||||||
|
self.attr_string = "I'm a test string"
|
||||||
|
self.attr_float = 42.085
|
||||||
|
self.attr_dict = {"key1": 1, "key2": "val2"}
|
||||||
|
self.attr_list = ["item1", 2, 3, 4]
|
||||||
|
self.attr_bool = True
|
||||||
|
|
||||||
|
|
||||||
|
@preserve.preservable
|
||||||
|
class PreservableClass(PlainClass):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def primitive_data():
|
||||||
|
return {'key1': ["item1", {"d2k1": "val1", "d2k2": 2}, {"d3k1": "val1", "d3k2": True}, "test str"]}
|
||||||
|
|
||||||
|
|
||||||
|
def obj_attrs_and_type_equal(obj1, obj2):
|
||||||
|
# Checks that both the __dict__ on each object and the __class__ on each object
|
||||||
|
# are equal
|
||||||
|
return (vars(type(obj1)) == vars(type(obj2))) and (vars(obj1) == vars(obj2))
|
||||||
|
|
||||||
|
|
||||||
|
def test_primitive_data(primitive_data):
|
||||||
|
# preserve/restore shouldn't modify something that's already all primitives
|
||||||
|
preserved_data = preserve.preserve(primitive_data)
|
||||||
|
assert preserved_data == primitive_data
|
||||||
|
assert (preserve.restore(preserved_data)) == primitive_data
|
||||||
|
|
||||||
|
|
||||||
|
def test_data_with_preservable(primitive_data):
|
||||||
|
# Preservable class within a data structure
|
||||||
|
primitive_data["preservable"] = PreservableClass()
|
||||||
|
restored_data = preserve.restore(preserve.preserve(primitive_data))
|
||||||
|
assert restored_data['key1'] == primitive_data['key1']
|
||||||
|
assert restored_data["preservable"] != primitive_data["preservable"]
|
||||||
|
assert obj_attrs_and_type_equal(restored_data["preservable"], primitive_data["preservable"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_plain_class():
|
||||||
|
# plain class is not preservable
|
||||||
|
with pytest.raises(Exception, match="is not preservable"):
|
||||||
|
preserve.preserve(PlainClass())
|
||||||
|
|
||||||
|
|
||||||
|
def test_preservable_class():
|
||||||
|
# Preservable class should restore to a new instance with same content
|
||||||
|
obj = PreservableClass()
|
||||||
|
restored_obj = preserve.restore(preserve.preserve(obj))
|
||||||
|
assert restored_obj != obj
|
||||||
|
assert obj_attrs_and_type_equal(restored_obj, obj)
|
||||||
|
|
||||||
|
|
||||||
|
def test_attr_plain_class():
|
||||||
|
# Class with non-preservable class as an attribute should fail
|
||||||
|
obj = PreservableClass()
|
||||||
|
obj.attr_obj = PlainClass()
|
||||||
|
with pytest.raises(Exception, match="is not preservable"):
|
||||||
|
preserve.preserve(obj)
|
||||||
|
|
||||||
|
|
||||||
|
def test_class_key():
|
||||||
|
# Should be able to change the default class key before decorators
|
||||||
|
# and have preserve/restore work
|
||||||
|
old_class_key = preserve.class_key
|
||||||
|
preserve.class_key = "A different key"
|
||||||
|
|
||||||
|
@preserve.preservable
|
||||||
|
class TestClass(PlainClass):
|
||||||
|
pass
|
||||||
|
|
||||||
|
obj = TestClass()
|
||||||
|
restored_obj = preserve.restore(preserve.preserve(obj))
|
||||||
|
assert restored_obj != obj
|
||||||
|
assert obj_attrs_and_type_equal(restored_obj, obj)
|
||||||
|
|
||||||
|
preserve.class_key = old_class_key
|
||||||
|
|
||||||
|
|
||||||
|
def test_class_key_in_data():
|
||||||
|
# Can't use the class key as dict key being preserved
|
||||||
|
with pytest.raises(Exception, match="reserved for internal use"):
|
||||||
|
preserve.preserve({preserve.class_key: 1})
|
||||||
|
|
||||||
|
|
||||||
|
def test_unrestorable(primitive_data):
|
||||||
|
# Shouldn't be able to restore from data containing non-primitive types
|
||||||
|
preserved_data = preserve.preserve(primitive_data)
|
||||||
|
|
||||||
|
preserved_data["unrestorable"] = (1, 2, 3)
|
||||||
|
with pytest.raises(Exception, match="is not restorable"):
|
||||||
|
preserve.restore(preserved_data)
|
||||||
|
|
||||||
|
preserved_data["unrestorable"] = PlainClass()
|
||||||
|
with pytest.raises(Exception, match="is not restorable"):
|
||||||
|
preserve.restore(preserved_data)
|
||||||
|
|
||||||
|
|
||||||
|
def test_str_dict_keys(primitive_data):
|
||||||
|
# Non-string dict keys aren't restorable or preservable
|
||||||
|
preserved_data = preserve.preserve(primitive_data)
|
||||||
|
|
||||||
|
primitive_data[2] = "has a non-string key"
|
||||||
|
with pytest.raises(Exception, match="Non-string dictionary keys are not preservable"):
|
||||||
|
preserve.preserve(primitive_data)
|
||||||
|
|
||||||
|
preserved_data[2] = "has a non-string key"
|
||||||
|
with pytest.raises(Exception, match="Non-string dictionary keys are not restorable"):
|
||||||
|
preserve.restore(preserved_data)
|
||||||
Loading…
Reference in new issue