2011-03-28 10:11:19 +08:00
|
|
|
import copy
|
2010-09-28 16:18:12 +08:00
|
|
|
import unittest
|
2010-09-27 23:15:04 +08:00
|
|
|
|
2011-06-01 23:30:06 +08:00
|
|
|
from django.utils.functional import SimpleLazyObject, empty
|
|
|
|
|
2010-09-27 23:15:04 +08:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return "I am _ComplexObject(%r)" % self.name
|
|
|
|
|
|
|
|
def __unicode__(self):
|
|
|
|
return unicode(self.name)
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return "_ComplexObject(%r)" % self.name
|
|
|
|
|
|
|
|
complex_object = lambda: _ComplexObject("joe")
|
|
|
|
|
2010-09-28 16:18:12 +08:00
|
|
|
class TestUtilsSimpleLazyObject(unittest.TestCase):
|
2010-09-27 23:15:04 +08:00
|
|
|
"""
|
|
|
|
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__
|
2011-03-03 23:04:39 +08:00
|
|
|
self.assertTrue("SimpleLazyObject" in repr(SimpleLazyObject(complex_object)))
|
2010-09-27 23:15:04 +08:00
|
|
|
|
|
|
|
def test_str(self):
|
|
|
|
self.assertEqual("I am _ComplexObject('joe')", str(SimpleLazyObject(complex_object)))
|
|
|
|
|
|
|
|
def test_unicode(self):
|
|
|
|
self.assertEqual(u"joe", unicode(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)
|
2011-06-01 23:30:06 +08:00
|
|
|
self.assertIs(s._wrapped, empty)
|
2010-09-27 23:15:04 +08:00
|
|
|
s2 = copy.deepcopy(s)
|
2011-06-01 23:30:06 +08:00
|
|
|
# something has gone wrong is s is evaluated
|
|
|
|
self.assertIs(s._wrapped, empty)
|
2010-09-27 23:15:04 +08:00
|
|
|
self.assertEqual(s2, complex_object())
|
|
|
|
|
|
|
|
# Second, for an evaluated SimpleLazyObject
|
|
|
|
name = s.name # evaluate
|
2011-06-01 23:30:06 +08:00
|
|
|
self.assertIsNot(s._wrapped, empty)
|
2010-09-27 23:15:04 +08:00
|
|
|
s3 = copy.deepcopy(s)
|
|
|
|
self.assertEqual(s3, complex_object())
|
2011-06-01 23:30:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
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)
|