PageRenderTime 30ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/modeltests/signals/tests.py

https://code.google.com/p/mango-py/
Python | 176 lines | 138 code | 26 blank | 12 comment | 0 complexity | 9183d7774e5fecc2e91d505eac9c9c9a MD5 | raw file
Possible License(s): BSD-3-Clause
  1. from django.db.models import signals
  2. from django.dispatch import receiver
  3. from django.test import TestCase
  4. from models import Person, Car
  5. # #8285: signals can be any callable
  6. class PostDeleteHandler(object):
  7. def __init__(self, data):
  8. self.data = data
  9. def __call__(self, signal, sender, instance, **kwargs):
  10. self.data.append(
  11. (instance, instance.id is None)
  12. )
  13. class MyReceiver(object):
  14. def __init__(self, param):
  15. self.param = param
  16. self._run = False
  17. def __call__(self, signal, sender, **kwargs):
  18. self._run = True
  19. signal.disconnect(receiver=self, sender=sender)
  20. class SignalTests(TestCase):
  21. def test_basic(self):
  22. # Save up the number of connected signals so that we can check at the
  23. # end that all the signals we register get properly unregistered (#9989)
  24. pre_signals = (
  25. len(signals.pre_save.receivers),
  26. len(signals.post_save.receivers),
  27. len(signals.pre_delete.receivers),
  28. len(signals.post_delete.receivers),
  29. )
  30. data = []
  31. def pre_save_test(signal, sender, instance, **kwargs):
  32. data.append(
  33. (instance, kwargs.get("raw", False))
  34. )
  35. signals.pre_save.connect(pre_save_test)
  36. def post_save_test(signal, sender, instance, **kwargs):
  37. data.append(
  38. (instance, kwargs.get("created"), kwargs.get("raw", False))
  39. )
  40. signals.post_save.connect(post_save_test)
  41. def pre_delete_test(signal, sender, instance, **kwargs):
  42. data.append(
  43. (instance, instance.id is None)
  44. )
  45. signals.pre_delete.connect(pre_delete_test)
  46. post_delete_test = PostDeleteHandler(data)
  47. signals.post_delete.connect(post_delete_test)
  48. # throw a decorator syntax receiver into the mix
  49. @receiver(signals.pre_save)
  50. def pre_save_decorator_test(signal, sender, instance, **kwargs):
  51. data.append(instance)
  52. @receiver(signals.pre_save, sender=Car)
  53. def pre_save_decorator_sender_test(signal, sender, instance, **kwargs):
  54. data.append(instance)
  55. p1 = Person(first_name="John", last_name="Smith")
  56. self.assertEqual(data, [])
  57. p1.save()
  58. self.assertEqual(data, [
  59. (p1, False),
  60. p1,
  61. (p1, True, False),
  62. ])
  63. data[:] = []
  64. p1.first_name = "Tom"
  65. p1.save()
  66. self.assertEqual(data, [
  67. (p1, False),
  68. p1,
  69. (p1, False, False),
  70. ])
  71. data[:] = []
  72. # Car signal (sender defined)
  73. c1 = Car(make="Volkswagon", model="Passat")
  74. c1.save()
  75. self.assertEqual(data, [
  76. (c1, False),
  77. c1,
  78. c1,
  79. (c1, True, False),
  80. ])
  81. data[:] = []
  82. # Calling an internal method purely so that we can trigger a "raw" save.
  83. p1.save_base(raw=True)
  84. self.assertEqual(data, [
  85. (p1, True),
  86. p1,
  87. (p1, False, True),
  88. ])
  89. data[:] = []
  90. p1.delete()
  91. self.assertEqual(data, [
  92. (p1, False),
  93. (p1, False),
  94. ])
  95. data[:] = []
  96. p2 = Person(first_name="James", last_name="Jones")
  97. p2.id = 99999
  98. p2.save()
  99. self.assertEqual(data, [
  100. (p2, False),
  101. p2,
  102. (p2, True, False),
  103. ])
  104. data[:] = []
  105. p2.id = 99998
  106. p2.save()
  107. self.assertEqual(data, [
  108. (p2, False),
  109. p2,
  110. (p2, True, False),
  111. ])
  112. data[:] = []
  113. p2.delete()
  114. self.assertEqual(data, [
  115. (p2, False),
  116. (p2, False)
  117. ])
  118. self.assertQuerysetEqual(
  119. Person.objects.all(), [
  120. "James Jones",
  121. ],
  122. unicode
  123. )
  124. signals.post_delete.disconnect(post_delete_test)
  125. signals.pre_delete.disconnect(pre_delete_test)
  126. signals.post_save.disconnect(post_save_test)
  127. signals.pre_save.disconnect(pre_save_test)
  128. signals.pre_save.disconnect(pre_save_decorator_test)
  129. signals.pre_save.disconnect(pre_save_decorator_sender_test, sender=Car)
  130. # Check that all our signals got disconnected properly.
  131. post_signals = (
  132. len(signals.pre_save.receivers),
  133. len(signals.post_save.receivers),
  134. len(signals.pre_delete.receivers),
  135. len(signals.post_delete.receivers),
  136. )
  137. self.assertEqual(pre_signals, post_signals)
  138. def test_disconnect_in_dispatch(self):
  139. """
  140. Test that signals that disconnect when being called don't mess future
  141. dispatching.
  142. """
  143. a, b = MyReceiver(1), MyReceiver(2)
  144. signals.post_save.connect(sender=Person, receiver=a)
  145. signals.post_save.connect(sender=Person, receiver=b)
  146. p = Person.objects.create(first_name='John', last_name='Smith')
  147. self.assertTrue(a._run)
  148. self.assertTrue(b._run)
  149. self.assertEqual(signals.post_save.receivers, [])