text: 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)
  
      def __str__(self):
          return "I am _ComplexObject(%r)" % self.name
  
      def __unicode__(self):
          return six.text_type(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_str(self):
          self.assertEqual(str_prefix("I am _ComplexObject(%(_)s'joe')"),
              str(SimpleLazyObject(complex_object)))
  
      def test_unicode(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)
  