summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Morozov <jmv@emorozov.net>2021-08-24 23:29:55 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-08-30 07:06:22 +0200
commitd89f976bddb49fb168334960acc8979c3de991fa (patch)
tree0af9c6e51cb89a7a895566ff9c1ad74567f75f46
parent02bc7161ec477afd4a7b328936eb8adac078d7b9 (diff)
Fixed #33054 -- Made TestCase.captureOnCommitCallbacks() capture callbacks recursively.
-rw-r--r--django/test/testcases.py17
-rw-r--r--docs/releases/4.0.txt3
-rw-r--r--docs/topics/testing/tools.txt5
-rw-r--r--tests/test_utils/tests.py7
4 files changed, 27 insertions, 5 deletions
diff --git a/django/test/testcases.py b/django/test/testcases.py
index b947d70a45..41d01b89b4 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -1282,11 +1282,18 @@ class TestCase(TransactionTestCase):
try:
yield callbacks
finally:
- run_on_commit = connections[using].run_on_commit[start_count:]
- callbacks[:] = [func for sids, func in run_on_commit]
- if execute:
- for callback in callbacks:
- callback()
+ callback_count = len(connections[using].run_on_commit)
+ while True:
+ run_on_commit = connections[using].run_on_commit[start_count:]
+ callbacks[:] = [func for sids, func in run_on_commit]
+ if execute:
+ for callback in callbacks:
+ callback()
+
+ if callback_count == len(connections[using].run_on_commit):
+ break
+ start_count = callback_count - 1
+ callback_count = len(connections[using].run_on_commit)
class CheckCondition:
diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt
index 45743c4139..53b738c8ec 100644
--- a/docs/releases/4.0.txt
+++ b/docs/releases/4.0.txt
@@ -368,6 +368,9 @@ Tests
* The :option:`test --parallel` option now supports the value ``auto`` to run
one test process for each processor core.
+* :meth:`.TestCase.captureOnCommitCallbacks` now captures new callbacks added
+ while executing :func:`.transaction.on_commit` callbacks.
+
URLs
~~~~
diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt
index 8e4f077fad..846d428980 100644
--- a/docs/topics/testing/tools.txt
+++ b/docs/topics/testing/tools.txt
@@ -912,6 +912,11 @@ It also provides an additional method:
self.assertEqual(mail.outbox[0].subject, 'Contact Form')
self.assertEqual(mail.outbox[0].body, 'I like your site')
+ .. versionchanged:: 4.0
+
+ In older versions, new callbacks added while executing
+ :func:`.transaction.on_commit` callbacks were not captured.
+
.. _live-test-server:
``LiveServerTestCase``
diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
index 44301aaa1b..82ec36ab38 100644
--- a/tests/test_utils/tests.py
+++ b/tests/test_utils/tests.py
@@ -1502,6 +1502,13 @@ class CaptureOnCommitCallbacksTests(TestCase):
self.assertEqual(callbacks, [])
+ def test_execute_recursive(self):
+ with self.captureOnCommitCallbacks(execute=True) as callbacks:
+ transaction.on_commit(self.enqueue_callback)
+
+ self.assertEqual(len(callbacks), 2)
+ self.assertIs(self.callback_called, True)
+
class DisallowedDatabaseQueriesTests(SimpleTestCase):
def test_disallowed_database_connections(self):