summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJacob Kaplan-Moss <jacob@jacobian.org>2008-08-06 15:32:46 +0000
committerJacob Kaplan-Moss <jacob@jacobian.org>2008-08-06 15:32:46 +0000
commit34a3bd52255a2253696b74b2d76133aace839fd2 (patch)
tree73bc39cc2e0a93925b1e8796b18224192e19e4a3 /tests
parentd06b474251c979c512a966a7fb41cd8a06487c14 (diff)
Major refactoring of django.dispatch with an eye towards speed. The net result is that signals are up to 90% faster.
Though some attempts and backwards-compatibility were made, speed trumped compatibility. Thus, as usual, check BackwardsIncompatibleChanges for the complete list of backwards-incompatible changes. Thanks to Jeremy Dunck and Keith Busell for the bulk of the work; some ideas from Brian Herring's previous work (refs #4561) were incorporated. Documentation is, sigh, still forthcoming. Fixes #6814 and #3951 (with the new dispatch_uid argument to connect). git-svn-id: http://code.djangoproject.com/svn/django/trunk@8223 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
-rw-r--r--tests/modeltests/signals/models.py46
-rw-r--r--tests/regressiontests/dispatch/tests/__init__.py3
-rw-r--r--tests/regressiontests/dispatch/tests/test_dispatcher.py164
-rw-r--r--tests/regressiontests/dispatch/tests/test_robustapply.py34
4 files changed, 70 insertions, 177 deletions
diff --git a/tests/modeltests/signals/models.py b/tests/modeltests/signals/models.py
index fc58d90a14..23d1f2d87d 100644
--- a/tests/modeltests/signals/models.py
+++ b/tests/modeltests/signals/models.py
@@ -3,7 +3,6 @@ Testing signals before/after saving and deleting.
"""
from django.db import models
-from django.dispatch import dispatcher
class Person(models.Model):
first_name = models.CharField(max_length=20)
@@ -12,19 +11,12 @@ class Person(models.Model):
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
-
-def pre_save_nokwargs_test(sender, instance):
- print 'pre_save_nokwargs signal'
-
-def post_save_nokwargs_test(sender, instance):
- print 'post_save_nokwargs signal'
-
-def pre_save_test(sender, instance, **kwargs):
+def pre_save_test(signal, sender, instance, **kwargs):
print 'pre_save signal,', instance
if kwargs.get('raw'):
print 'Is raw'
-def post_save_test(sender, instance, **kwargs):
+def post_save_test(signal, sender, instance, **kwargs):
print 'post_save signal,', instance
if 'created' in kwargs:
if kwargs['created']:
@@ -34,44 +26,36 @@ def post_save_test(sender, instance, **kwargs):
if kwargs.get('raw'):
print 'Is raw'
-def pre_delete_test(sender, instance, **kwargs):
+def pre_delete_test(signal, sender, instance, **kwargs):
print 'pre_delete signal,', instance
print 'instance.id is not None: %s' % (instance.id != None)
-def post_delete_test(sender, instance, **kwargs):
+def post_delete_test(signal, sender, instance, **kwargs):
print 'post_delete signal,', instance
print 'instance.id is None: %s' % (instance.id == None)
__test__ = {'API_TESTS':"""
->>> dispatcher.connect(pre_save_nokwargs_test, signal=models.signals.pre_save)
->>> dispatcher.connect(post_save_nokwargs_test, signal=models.signals.post_save)
->>> dispatcher.connect(pre_save_test, signal=models.signals.pre_save)
->>> dispatcher.connect(post_save_test, signal=models.signals.post_save)
->>> dispatcher.connect(pre_delete_test, signal=models.signals.pre_delete)
->>> dispatcher.connect(post_delete_test, signal=models.signals.post_delete)
+>>> models.signals.pre_save.connect(pre_save_test)
+>>> models.signals.post_save.connect(post_save_test)
+>>> models.signals.pre_delete.connect(pre_delete_test)
+>>> models.signals.post_delete.connect(post_delete_test)
>>> p1 = Person(first_name='John', last_name='Smith')
>>> p1.save()
-pre_save_nokwargs signal
pre_save signal, John Smith
-post_save_nokwargs signal
post_save signal, John Smith
Is created
>>> p1.first_name = 'Tom'
>>> p1.save()
-pre_save_nokwargs signal
pre_save signal, Tom Smith
-post_save_nokwargs signal
post_save signal, Tom Smith
Is updated
# Calling an internal method purely so that we can trigger a "raw" save.
>>> p1.save_base(raw=True)
-pre_save_nokwargs signal
pre_save signal, Tom Smith
Is raw
-post_save_nokwargs signal
post_save signal, Tom Smith
Is updated
Is raw
@@ -85,17 +69,13 @@ instance.id is None: False
>>> p2 = Person(first_name='James', last_name='Jones')
>>> p2.id = 99999
>>> p2.save()
-pre_save_nokwargs signal
pre_save signal, James Jones
-post_save_nokwargs signal
post_save signal, James Jones
Is created
>>> p2.id = 99998
>>> p2.save()
-pre_save_nokwargs signal
pre_save signal, James Jones
-post_save_nokwargs signal
post_save signal, James Jones
Is created
@@ -108,10 +88,8 @@ instance.id is None: False
>>> Person.objects.all()
[<Person: James Jones>]
->>> dispatcher.disconnect(pre_save_nokwargs_test, signal=models.signals.pre_save)
->>> dispatcher.disconnect(post_save_nokwargs_test, signal=models.signals.post_save)
->>> dispatcher.disconnect(post_delete_test, signal=models.signals.post_delete)
->>> dispatcher.disconnect(pre_delete_test, signal=models.signals.pre_delete)
->>> dispatcher.disconnect(post_save_test, signal=models.signals.post_save)
->>> dispatcher.disconnect(pre_save_test, signal=models.signals.pre_save)
+>>> models.signals.post_delete.disconnect(post_delete_test)
+>>> models.signals.pre_delete.disconnect(pre_delete_test)
+>>> models.signals.post_save.disconnect(post_save_test)
+>>> models.signals.pre_save.disconnect(pre_save_test)
"""}
diff --git a/tests/regressiontests/dispatch/tests/__init__.py b/tests/regressiontests/dispatch/tests/__init__.py
index 0fdefe48a7..150bb01dc0 100644
--- a/tests/regressiontests/dispatch/tests/__init__.py
+++ b/tests/regressiontests/dispatch/tests/__init__.py
@@ -2,6 +2,5 @@
Unit-tests for the dispatch project
"""
-from test_dispatcher import *
-from test_robustapply import *
from test_saferef import *
+from test_dispatcher import *
diff --git a/tests/regressiontests/dispatch/tests/test_dispatcher.py b/tests/regressiontests/dispatch/tests/test_dispatcher.py
index f34173972d..baaae9cd95 100644
--- a/tests/regressiontests/dispatch/tests/test_dispatcher.py
+++ b/tests/regressiontests/dispatch/tests/test_dispatcher.py
@@ -1,5 +1,4 @@
-from django.dispatch.dispatcher import *
-from django.dispatch import dispatcher, robust
+from django.dispatch import Signal
import unittest
import copy
import sys
@@ -15,143 +14,94 @@ else:
def garbage_collect():
gc.collect()
-def x(a):
- return a
-
-class Dummy(object):
- pass
+def receiver_1_arg(val, **kwargs):
+ return val
class Callable(object):
- def __call__(self, a):
- return a
+ def __call__(self, val, **kwargs):
+ return val
- def a(self, a):
- return a
+ def a(self, val, **kwargs):
+ return val
+
+a_signal = Signal(providing_args=["val"])
class DispatcherTests(unittest.TestCase):
"""Test suite for dispatcher (barely started)"""
-
- def setUp(self):
- # track the initial state, since it's possible that others have bleed receivers in
- garbage_collect()
- self.sendersBack = copy.copy(dispatcher.sendersBack)
- self.connections = copy.copy(dispatcher.connections)
- self.senders = copy.copy(dispatcher.senders)
-
- def _testIsClean(self):
+
+ def _testIsClean(self, signal):
"""Assert that everything has been cleaned up automatically"""
- self.assertEqual(dispatcher.sendersBack, self.sendersBack)
- self.assertEqual(dispatcher.connections, self.connections)
- self.assertEqual(dispatcher.senders, self.senders)
+ self.assertEqual(signal.receivers, [])
+
+ # force cleanup just in case
+ signal.receivers = []
def testExact(self):
- a = Dummy()
- signal = 'this'
- connect(x, signal, a)
- expected = [(x,a)]
- result = send('this',a, a=a)
- self.assertEqual(result, expected)
- disconnect(x, signal, a)
- self.assertEqual(list(getAllReceivers(a,signal)), [])
- self._testIsClean()
-
- def testAnonymousSend(self):
- a = Dummy()
- signal = 'this'
- connect(x, signal)
- expected = [(x,a)]
- result = send(signal,None, a=a)
- self.assertEqual(result, expected)
- disconnect(x, signal)
- self.assertEqual(list(getAllReceivers(None,signal)), [])
- self._testIsClean()
-
- def testAnyRegistration(self):
- a = Dummy()
- signal = 'this'
- connect(x, signal, Any)
- expected = [(x,a)]
- result = send('this',object(), a=a)
- self.assertEqual(result, expected)
- disconnect(x, signal, Any)
- expected = []
- result = send('this',object(), a=a)
+ a_signal.connect(receiver_1_arg, sender=self)
+ expected = [(receiver_1_arg,"test")]
+ result = a_signal.send(sender=self, val="test")
self.assertEqual(result, expected)
- self.assertEqual(list(getAllReceivers(Any,signal)), [])
-
- self._testIsClean()
-
- def testAnyRegistration2(self):
- a = Dummy()
- signal = 'this'
- connect(x, Any, a)
- expected = [(x,a)]
- result = send('this',a, a=a)
+ a_signal.disconnect(receiver_1_arg, sender=self)
+ self._testIsClean(a_signal)
+
+ def testIgnoredSender(self):
+ a_signal.connect(receiver_1_arg)
+ expected = [(receiver_1_arg,"test")]
+ result = a_signal.send(sender=self, val="test")
self.assertEqual(result, expected)
- disconnect(x, Any, a)
- self.assertEqual(list(getAllReceivers(a,Any)), [])
- self._testIsClean()
+ a_signal.disconnect(receiver_1_arg)
+ self._testIsClean(a_signal)
def testGarbageCollected(self):
a = Callable()
- b = Dummy()
- signal = 'this'
- connect(a.a, signal, b)
- expected = []
- del a
- garbage_collect()
- result = send('this',b, a=b)
- self.assertEqual(result, expected)
- self.assertEqual(list(getAllReceivers(b,signal)), [])
- self._testIsClean()
-
- def testGarbageCollectedObj(self):
- class x:
- def __call__(self, a):
- return a
- a = Callable()
- b = Dummy()
- signal = 'this'
- connect(a, signal, b)
+ a_signal.connect(a.a, sender=self)
expected = []
del a
garbage_collect()
- result = send('this',b, a=b)
+ result = a_signal.send(sender=self, val="test")
self.assertEqual(result, expected)
- self.assertEqual(list(getAllReceivers(b,signal)), [])
- self._testIsClean()
-
+ self._testIsClean(a_signal)
def testMultipleRegistration(self):
a = Callable()
- b = Dummy()
- signal = 'this'
- connect(a, signal, b)
- connect(a, signal, b)
- connect(a, signal, b)
- connect(a, signal, b)
- connect(a, signal, b)
- connect(a, signal, b)
- result = send('this',b, a=b)
+ a_signal.connect(a)
+ a_signal.connect(a)
+ a_signal.connect(a)
+ a_signal.connect(a)
+ a_signal.connect(a)
+ a_signal.connect(a)
+ result = a_signal.send(sender=self, val="test")
self.assertEqual(len(result), 1)
- self.assertEqual(len(list(getAllReceivers(b,signal))), 1)
+ self.assertEqual(len(a_signal.receivers), 1)
del a
- del b
del result
garbage_collect()
- self._testIsClean()
+ self._testIsClean(a_signal)
+
+ def testUidRegistration(self):
+ def uid_based_receiver_1(**kwargs):
+ pass
+
+ def uid_based_receiver_2(**kwargs):
+ pass
+
+ a_signal.connect(uid_based_receiver_1, dispatch_uid = "uid")
+ a_signal.connect(uid_based_receiver_2, dispatch_uid = "uid")
+ self.assertEqual(len(a_signal.receivers), 1)
+ a_signal.disconnect(dispatch_uid = "uid")
+ self._testIsClean(a_signal)
def testRobust(self):
"""Test the sendRobust function"""
- def fails():
+ def fails(val, **kwargs):
raise ValueError('this')
- a = object()
- signal = 'this'
- connect(fails, Any, a)
- result = robust.sendRobust('this',a, a=a)
+ a_signal.connect(fails)
+ result = a_signal.send_robust(sender=self, val="test")
err = result[0][1]
self.assert_(isinstance(err, ValueError))
self.assertEqual(err.args, ('this',))
+ a_signal.disconnect(fails)
+ self._testIsClean(a_signal)
def getSuite():
return unittest.makeSuite(DispatcherTests,'test')
diff --git a/tests/regressiontests/dispatch/tests/test_robustapply.py b/tests/regressiontests/dispatch/tests/test_robustapply.py
deleted file mode 100644
index 499450eec4..0000000000
--- a/tests/regressiontests/dispatch/tests/test_robustapply.py
+++ /dev/null
@@ -1,34 +0,0 @@
-from django.dispatch.robustapply import *
-
-import unittest
-
-def noArgument():
- pass
-
-def oneArgument(blah):
- pass
-
-def twoArgument(blah, other):
- pass
-
-class TestCases(unittest.TestCase):
- def test01(self):
- robustApply(noArgument)
-
- def test02(self):
- self.assertRaises(TypeError, robustApply, noArgument, "this")
-
- def test03(self):
- self.assertRaises(TypeError, robustApply, oneArgument)
-
- def test04(self):
- """Raise error on duplication of a particular argument"""
- self.assertRaises(TypeError, robustApply, oneArgument, "this", blah = "that")
-
-def getSuite():
- return unittest.makeSuite(TestCases,'test')
-
-
-if __name__ == "__main__":
- unittest.main()
-