diff options
author | Jon Janzen <jon@jonjanzen.com> | 2020-11-07 13:19:20 +0300 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-03-07 08:39:25 +0100 |
commit | e83a88566a71a2353cebc35992c110be0f8628af (patch) | |
tree | 466c863fc3bfe6fc9946b5a3f7163c62e58ecbb9 /tests/signals | |
parent | 9a07999aef7958c9b5441e368cd90646d0edc5c9 (diff) | |
download | django-e83a88566a71a2353cebc35992c110be0f8628af.tar.gz |
Fixed #32172 -- Adapted signals to allow async handlers.
co-authored-by: kozzztik <kozzztik@mail.ru>
co-authored-by: Carlton Gibson <carlton.gibson@noumenal.es>
Diffstat (limited to 'tests/signals')
-rw-r--r-- | tests/signals/tests.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/tests/signals/tests.py b/tests/signals/tests.py index 0385033b07..0f161eeeb1 100644 --- a/tests/signals/tests.py +++ b/tests/signals/tests.py @@ -1,5 +1,7 @@ +import asyncio from unittest import mock +from django import dispatch from django.apps.registry import Apps from django.db import models from django.db.models import signals @@ -530,3 +532,94 @@ class LazyModelRefTests(BaseSignalSetup, SimpleTestCase): apps2 = Apps() signals.post_init.connect(self.receiver, sender=Book, apps=apps2) self.assertEqual(list(apps2._pending_operations), []) + + +class SyncHandler: + param = 0 + + def __call__(self, **kwargs): + self.param += 1 + return self.param + + +class AsyncHandler: + _is_coroutine = asyncio.coroutines._is_coroutine + param = 0 + + async def __call__(self, **kwargs): + self.param += 1 + return self.param + + +class AsyncReceiversTests(SimpleTestCase): + async def test_asend(self): + sync_handler = SyncHandler() + async_handler = AsyncHandler() + signal = dispatch.Signal() + signal.connect(sync_handler) + signal.connect(async_handler) + result = await signal.asend(self.__class__) + self.assertEqual(result, [(sync_handler, 1), (async_handler, 1)]) + + def test_send(self): + sync_handler = SyncHandler() + async_handler = AsyncHandler() + signal = dispatch.Signal() + signal.connect(sync_handler) + signal.connect(async_handler) + result = signal.send(self.__class__) + self.assertEqual(result, [(sync_handler, 1), (async_handler, 1)]) + + def test_send_robust(self): + class ReceiverException(Exception): + pass + + receiver_exception = ReceiverException() + + async def failing_async_handler(**kwargs): + raise receiver_exception + + sync_handler = SyncHandler() + async_handler = AsyncHandler() + signal = dispatch.Signal() + signal.connect(failing_async_handler) + signal.connect(async_handler) + signal.connect(sync_handler) + result = signal.send_robust(self.__class__) + # The ordering here is different than the order that signals were + # connected in. + self.assertEqual( + result, + [ + (sync_handler, 1), + (failing_async_handler, receiver_exception), + (async_handler, 1), + ], + ) + + async def test_asend_robust(self): + class ReceiverException(Exception): + pass + + receiver_exception = ReceiverException() + + async def failing_async_handler(**kwargs): + raise receiver_exception + + sync_handler = SyncHandler() + async_handler = AsyncHandler() + signal = dispatch.Signal() + signal.connect(failing_async_handler) + signal.connect(async_handler) + signal.connect(sync_handler) + result = await signal.asend_robust(self.__class__) + # The ordering here is different than the order that signals were + # connected in. + self.assertEqual( + result, + [ + (sync_handler, 1), + (failing_async_handler, receiver_exception), + (async_handler, 1), + ], + ) |