~ubuntu-branches/debian/sid/python-django/sid

« back to all changes in this revision

Viewing changes to tests/signals/tests.py

  • Committer: Package Import Robot
  • Author(s): Luke Faraone
  • Date: 2013-11-07 15:33:49 UTC
  • mfrom: (1.3.12)
  • Revision ID: package-import@ubuntu.com-20131107153349-e31sc149l2szs3jb
Tags: 1.6-1
* New upstream version. Closes: #557474, #724637.
* python-django now also suggests the installation of ipython,
  bpython, python-django-doc, and libgdal1.
  Closes: #636511, #686333, #704203
* Set package maintainer to Debian Python Modules Team.
* Bump standards version to 3.9.5, no changes needed.

Show diffs side-by-side

added added

removed removed

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