diff options
Diffstat (limited to 'tests/utils/simplelazyobject.py')
-rw-r--r-- | tests/utils/simplelazyobject.py | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/tests/utils/simplelazyobject.py b/tests/utils/simplelazyobject.py new file mode 100644 index 0000000000..3f81e8f608 --- /dev/null +++ b/tests/utils/simplelazyobject.py @@ -0,0 +1,123 @@ +from __future__ import unicode_literals + +import copy +import pickle + +from django.test.utils import str_prefix +from django.utils import six +from django.utils.unittest import TestCase +from django.utils.functional import SimpleLazyObject, empty + + +class _ComplexObject(object): + def __init__(self, name): + self.name = name + + def __eq__(self, other): + return self.name == other.name + + def __hash__(self): + return hash(self.name) + + if six.PY3: + def __bytes__(self): + return ("I am _ComplexObject(%r)" % self.name).encode("utf-8") + + def __str__(self): + return self.name + + else: + def __str__(self): + return b"I am _ComplexObject(%r)" % str(self.name) + + def __unicode__(self): + return self.name + + def __repr__(self): + return "_ComplexObject(%r)" % self.name + + +complex_object = lambda: _ComplexObject("joe") + + +class TestUtilsSimpleLazyObject(TestCase): + """ + Tests for SimpleLazyObject + """ + # Note that concrete use cases for SimpleLazyObject are also found in the + # auth context processor tests (unless the implementation of that function + # is changed). + + def test_equality(self): + self.assertEqual(complex_object(), SimpleLazyObject(complex_object)) + self.assertEqual(SimpleLazyObject(complex_object), complex_object()) + + def test_hash(self): + # hash() equality would not be true for many objects, but it should be + # for _ComplexObject + self.assertEqual(hash(complex_object()), + hash(SimpleLazyObject(complex_object))) + + def test_repr(self): + # For debugging, it will really confuse things if there is no clue that + # SimpleLazyObject is actually a proxy object. So we don't + # proxy __repr__ + self.assertTrue("SimpleLazyObject" in repr(SimpleLazyObject(complex_object))) + + def test_bytes(self): + self.assertEqual(b"I am _ComplexObject('joe')", + bytes(SimpleLazyObject(complex_object))) + + def test_text(self): + self.assertEqual("joe", six.text_type(SimpleLazyObject(complex_object))) + + def test_class(self): + # This is important for classes that use __class__ in things like + # equality tests. + self.assertEqual(_ComplexObject, SimpleLazyObject(complex_object).__class__) + + def test_deepcopy(self): + # Check that we *can* do deep copy, and that it returns the right + # objects. + + # First, for an unevaluated SimpleLazyObject + s = SimpleLazyObject(complex_object) + self.assertIs(s._wrapped, empty) + s2 = copy.deepcopy(s) + # something has gone wrong is s is evaluated + self.assertIs(s._wrapped, empty) + self.assertEqual(s2, complex_object()) + + # Second, for an evaluated SimpleLazyObject + name = s.name # evaluate + self.assertIsNot(s._wrapped, empty) + s3 = copy.deepcopy(s) + self.assertEqual(s3, complex_object()) + + + def test_none(self): + i = [0] + def f(): + i[0] += 1 + return None + + x = SimpleLazyObject(f) + self.assertEqual(str(x), "None") + self.assertEqual(i, [1]) + self.assertEqual(str(x), "None") + self.assertEqual(i, [1]) + + def test_bool(self): + x = SimpleLazyObject(lambda: 3) + self.assertTrue(x) + x = SimpleLazyObject(lambda: 0) + self.assertFalse(x) + + def test_pickle_complex(self): + # See ticket #16563 + x = SimpleLazyObject(complex_object) + pickled = pickle.dumps(x) + unpickled = pickle.loads(pickled) + self.assertEqual(unpickled, x) + self.assertEqual(six.text_type(unpickled), six.text_type(x)) + self.assertEqual(unpickled.name, x.name) |