aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Sebastiaan Zeeff <[email protected]>2020-02-23 13:05:10 +0100
committerGravatar Sebastiaan Zeeff <[email protected]>2020-02-23 21:00:48 +0100
commit135d6daa4804574935cd788c5baec656765f484b (patch)
treec5e6b73dcce43f893b7bc4955d1fecc42933ba20
parentUse mixin-composition not inheritance for LoggingTestCase (diff)
Use IsolatedAsyncioTestCase instead of async_test
Since we upgraded to Python 3.8, we can now use the new IsolatedAsyncioTestCase test class to use coroutine-based test methods instead of our own, custom async_test decorator. I have changed the base class for all of our test classes that use coroutine-based test methods and removed the now obsolete decorator from our helpers.
-rw-r--r--tests/bot/cogs/test_duck_pond.py11
-rw-r--r--tests/bot/rules/__init__.py2
-rw-r--r--tests/bot/rules/test_attachments.py4
-rw-r--r--tests/bot/rules/test_burst.py4
-rw-r--r--tests/bot/rules/test_burst_shared.py4
-rw-r--r--tests/bot/rules/test_chars.py4
-rw-r--r--tests/bot/rules/test_discord_emojis.py4
-rw-r--r--tests/bot/rules/test_duplicates.py4
-rw-r--r--tests/bot/rules/test_links.py4
-rw-r--r--tests/bot/rules/test_mentions.py4
-rw-r--r--tests/bot/rules/test_newlines.py5
-rw-r--r--tests/bot/rules/test_role_mentions.py4
-rw-r--r--tests/bot/test_api.py4
-rw-r--r--tests/helpers.py17
-rw-r--r--tests/test_helpers.py8
15 files changed, 13 insertions, 70 deletions
diff --git a/tests/bot/cogs/test_duck_pond.py b/tests/bot/cogs/test_duck_pond.py
index 320cbd5c5..6406f0737 100644
--- a/tests/bot/cogs/test_duck_pond.py
+++ b/tests/bot/cogs/test_duck_pond.py
@@ -14,7 +14,7 @@ from tests import helpers
MODULE_PATH = "bot.cogs.duck_pond"
-class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
+class DuckPondTests(base.LoggingTestsMixin, unittest.IsolatedAsyncioTestCase):
"""Tests for DuckPond functionality."""
@classmethod
@@ -88,7 +88,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
with self.subTest(user_type=user.name, expected_return=expected_return, actual_return=actual_return):
self.assertEqual(expected_return, actual_return)
- @helpers.async_test
async def test_has_green_checkmark_correctly_detects_presence_of_green_checkmark_emoji(self):
"""The `has_green_checkmark` method should only return `True` if one is present."""
test_cases = (
@@ -172,7 +171,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
nonstaffers = [helpers.MockMember() for _ in range(nonstaff)]
return helpers.MockReaction(emoji=emoji, users=staffers + nonstaffers)
- @helpers.async_test
async def test_count_ducks_correctly_counts_the_number_of_eligible_duck_emojis(self):
"""The `count_ducks` method should return the number of unique staffers who gave a duck."""
test_cases = (
@@ -280,7 +278,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
with self.subTest(test_case=description, expected_count=expected_count, actual_count=actual_count):
self.assertEqual(expected_count, actual_count)
- @helpers.async_test
async def test_relay_message_correctly_relays_content_and_attachments(self):
"""The `relay_message` method should correctly relay message content and attachments."""
send_webhook_path = f"{MODULE_PATH}.DuckPond.send_webhook"
@@ -307,7 +304,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
message.add_reaction.assert_called_once_with(self.checkmark_emoji)
@patch(f"{MODULE_PATH}.send_attachments", new_callable=helpers.AsyncMock)
- @helpers.async_test
async def test_relay_message_handles_irretrievable_attachment_exceptions(self, send_attachments):
"""The `relay_message` method should handle irretrievable attachments."""
message = helpers.MockMessage(clean_content="message", attachments=["attachment"])
@@ -327,7 +323,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
@patch(f"{MODULE_PATH}.DuckPond.send_webhook", new_callable=helpers.AsyncMock)
@patch(f"{MODULE_PATH}.send_attachments", new_callable=helpers.AsyncMock)
- @helpers.async_test
async def test_relay_message_handles_attachment_http_error(self, send_attachments, send_webhook):
"""The `relay_message` method should handle irretrievable attachments."""
message = helpers.MockMessage(clean_content="message", attachments=["attachment"])
@@ -360,7 +355,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
payload.emoji.name = emoji_name
return payload
- @helpers.async_test
async def test_payload_has_duckpond_emoji_correctly_detects_relevant_emojis(self):
"""The `on_raw_reaction_add` event handler should ignore irrelevant emojis."""
test_values = (
@@ -434,7 +428,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
return channel, message, member, payload
- @helpers.async_test
async def test_on_raw_reaction_add_returns_for_bot_and_non_staff_members(self):
"""The `on_raw_reaction_add` event handler should return for bot users or non-staff members."""
channel_id = 1234
@@ -485,7 +478,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
# Assert that we've made it past `self.is_staff`
is_staff.assert_called_once()
- @helpers.async_test
async def test_on_raw_reaction_add_does_not_relay_below_duck_threshold(self):
"""The `on_raw_reaction_add` listener should not relay messages or attachments below the duck threshold."""
test_cases = (
@@ -515,7 +507,6 @@ class DuckPondTests(base.LoggingTestsMixin, unittest.TestCase):
if should_relay:
relay_message.assert_called_once_with(message)
- @helpers.async_test
async def test_on_raw_reaction_remove_prevents_removal_of_green_checkmark_depending_on_the_duck_count(self):
"""The `on_raw_reaction_remove` listener prevents removal of the check mark on messages with enough ducks."""
checkmark = helpers.MockPartialEmoji(name=self.checkmark_emoji)
diff --git a/tests/bot/rules/__init__.py b/tests/bot/rules/__init__.py
index 36c986fe1..0233e7939 100644
--- a/tests/bot/rules/__init__.py
+++ b/tests/bot/rules/__init__.py
@@ -12,7 +12,7 @@ class DisallowedCase(NamedTuple):
n_violations: int
-class RuleTest(unittest.TestCase, metaclass=ABCMeta):
+class RuleTest(unittest.IsolatedAsyncioTestCase, metaclass=ABCMeta):
"""
Abstract class for antispam rule test cases.
diff --git a/tests/bot/rules/test_attachments.py b/tests/bot/rules/test_attachments.py
index e54b4b5b8..d7e779221 100644
--- a/tests/bot/rules/test_attachments.py
+++ b/tests/bot/rules/test_attachments.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import attachments
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str, total_attachments: int) -> MockMessage:
@@ -17,7 +17,6 @@ class AttachmentRuleTests(RuleTest):
self.apply = attachments.apply
self.config = {"max": 5, "interval": 10}
- @async_test
async def test_allows_messages_without_too_many_attachments(self):
"""Messages without too many attachments are allowed as-is."""
cases = (
@@ -28,7 +27,6 @@ class AttachmentRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_with_too_many_attachments(self):
"""Messages with too many attachments trigger the rule."""
cases = (
diff --git a/tests/bot/rules/test_burst.py b/tests/bot/rules/test_burst.py
index 72f0be0c7..03682966b 100644
--- a/tests/bot/rules/test_burst.py
+++ b/tests/bot/rules/test_burst.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import burst
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str) -> MockMessage:
@@ -21,7 +21,6 @@ class BurstRuleTests(RuleTest):
self.apply = burst.apply
self.config = {"max": 2, "interval": 10}
- @async_test
async def test_allows_messages_within_limit(self):
"""Cases which do not violate the rule."""
cases = (
@@ -31,7 +30,6 @@ class BurstRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_beyond_limit(self):
"""Cases where the amount of messages exceeds the limit, triggering the rule."""
cases = (
diff --git a/tests/bot/rules/test_burst_shared.py b/tests/bot/rules/test_burst_shared.py
index 47367a5f8..3275143d5 100644
--- a/tests/bot/rules/test_burst_shared.py
+++ b/tests/bot/rules/test_burst_shared.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import burst_shared
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str) -> MockMessage:
@@ -21,7 +21,6 @@ class BurstSharedRuleTests(RuleTest):
self.apply = burst_shared.apply
self.config = {"max": 2, "interval": 10}
- @async_test
async def test_allows_messages_within_limit(self):
"""
Cases that do not violate the rule.
@@ -34,7 +33,6 @@ class BurstSharedRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_beyond_limit(self):
"""Cases where the amount of messages exceeds the limit, triggering the rule."""
cases = (
diff --git a/tests/bot/rules/test_chars.py b/tests/bot/rules/test_chars.py
index 7cc36f49e..f1e3c76a7 100644
--- a/tests/bot/rules/test_chars.py
+++ b/tests/bot/rules/test_chars.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import chars
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str, n_chars: int) -> MockMessage:
@@ -20,7 +20,6 @@ class CharsRuleTests(RuleTest):
"interval": 10,
}
- @async_test
async def test_allows_messages_within_limit(self):
"""Cases with a total amount of chars within limit."""
cases = (
@@ -31,7 +30,6 @@ class CharsRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_beyond_limit(self):
"""Cases where the total amount of chars exceeds the limit, triggering the rule."""
cases = (
diff --git a/tests/bot/rules/test_discord_emojis.py b/tests/bot/rules/test_discord_emojis.py
index 0239b0b00..9a72723e2 100644
--- a/tests/bot/rules/test_discord_emojis.py
+++ b/tests/bot/rules/test_discord_emojis.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import discord_emojis
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
discord_emoji = "<:abcd:1234>" # Discord emojis follow the format <:name:id>
@@ -19,7 +19,6 @@ class DiscordEmojisRuleTests(RuleTest):
self.apply = discord_emojis.apply
self.config = {"max": 2, "interval": 10}
- @async_test
async def test_allows_messages_within_limit(self):
"""Cases with a total amount of discord emojis within limit."""
cases = (
@@ -29,7 +28,6 @@ class DiscordEmojisRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_beyond_limit(self):
"""Cases with more than the allowed amount of discord emojis."""
cases = (
diff --git a/tests/bot/rules/test_duplicates.py b/tests/bot/rules/test_duplicates.py
index 59e0fb6ef..9bd886a77 100644
--- a/tests/bot/rules/test_duplicates.py
+++ b/tests/bot/rules/test_duplicates.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import duplicates
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str, content: str) -> MockMessage:
@@ -17,7 +17,6 @@ class DuplicatesRuleTests(RuleTest):
self.apply = duplicates.apply
self.config = {"max": 2, "interval": 10}
- @async_test
async def test_allows_messages_within_limit(self):
"""Cases which do not violate the rule."""
cases = (
@@ -28,7 +27,6 @@ class DuplicatesRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_beyond_limit(self):
"""Cases with too many duplicate messages from the same author."""
cases = (
diff --git a/tests/bot/rules/test_links.py b/tests/bot/rules/test_links.py
index 3c3f90e5f..b091bd9d7 100644
--- a/tests/bot/rules/test_links.py
+++ b/tests/bot/rules/test_links.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import links
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str, total_links: int) -> MockMessage:
@@ -21,7 +21,6 @@ class LinksTests(RuleTest):
"interval": 10
}
- @async_test
async def test_links_within_limit(self):
"""Messages with an allowed amount of links."""
cases = (
@@ -34,7 +33,6 @@ class LinksTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_links_exceeding_limit(self):
"""Messages with a a higher than allowed amount of links."""
cases = (
diff --git a/tests/bot/rules/test_mentions.py b/tests/bot/rules/test_mentions.py
index ebcdabac6..6444532f2 100644
--- a/tests/bot/rules/test_mentions.py
+++ b/tests/bot/rules/test_mentions.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import mentions
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str, total_mentions: int) -> MockMessage:
@@ -20,7 +20,6 @@ class TestMentions(RuleTest):
"interval": 10,
}
- @async_test
async def test_mentions_within_limit(self):
"""Messages with an allowed amount of mentions."""
cases = (
@@ -32,7 +31,6 @@ class TestMentions(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_mentions_exceeding_limit(self):
"""Messages with a higher than allowed amount of mentions."""
cases = (
diff --git a/tests/bot/rules/test_newlines.py b/tests/bot/rules/test_newlines.py
index d61c4609d..e35377773 100644
--- a/tests/bot/rules/test_newlines.py
+++ b/tests/bot/rules/test_newlines.py
@@ -2,7 +2,7 @@ from typing import Iterable, List
from bot.rules import newlines
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str, newline_groups: List[int]) -> MockMessage:
@@ -29,7 +29,6 @@ class TotalNewlinesRuleTests(RuleTest):
"interval": 10,
}
- @async_test
async def test_allows_messages_within_limit(self):
"""Cases which do not violate the rule."""
cases = (
@@ -41,7 +40,6 @@ class TotalNewlinesRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_total(self):
"""Cases which violate the rule by having too many newlines in total."""
cases = (
@@ -79,7 +77,6 @@ class GroupNewlinesRuleTests(RuleTest):
self.apply = newlines.apply
self.config = {"max": 5, "max_consecutive": 3, "interval": 10}
- @async_test
async def test_disallows_messages_consecutive(self):
"""Cases which violate the rule due to having too many consecutive newlines."""
cases = (
diff --git a/tests/bot/rules/test_role_mentions.py b/tests/bot/rules/test_role_mentions.py
index b339cccf7..26c05d527 100644
--- a/tests/bot/rules/test_role_mentions.py
+++ b/tests/bot/rules/test_role_mentions.py
@@ -2,7 +2,7 @@ from typing import Iterable
from bot.rules import role_mentions
from tests.bot.rules import DisallowedCase, RuleTest
-from tests.helpers import MockMessage, async_test
+from tests.helpers import MockMessage
def make_msg(author: str, n_mentions: int) -> MockMessage:
@@ -17,7 +17,6 @@ class RoleMentionsRuleTests(RuleTest):
self.apply = role_mentions.apply
self.config = {"max": 2, "interval": 10}
- @async_test
async def test_allows_messages_within_limit(self):
"""Cases with a total amount of role mentions within limit."""
cases = (
@@ -27,7 +26,6 @@ class RoleMentionsRuleTests(RuleTest):
await self.run_allowed(cases)
- @async_test
async def test_disallows_messages_beyond_limit(self):
"""Cases with more than the allowed amount of role mentions."""
cases = (
diff --git a/tests/bot/test_api.py b/tests/bot/test_api.py
index bdfcc73e4..99e942813 100644
--- a/tests/bot/test_api.py
+++ b/tests/bot/test_api.py
@@ -2,10 +2,9 @@ import unittest
from unittest.mock import MagicMock
from bot import api
-from tests.helpers import async_test
-class APIClientTests(unittest.TestCase):
+class APIClientTests(unittest.IsolatedAsyncioTestCase):
"""Tests for the bot's API client."""
@classmethod
@@ -18,7 +17,6 @@ class APIClientTests(unittest.TestCase):
"""The event loop should not be running by default."""
self.assertFalse(api.loop_is_running())
- @async_test
async def test_loop_is_running_in_async_context(self):
"""The event loop should be running in an async context."""
self.assertTrue(api.loop_is_running())
diff --git a/tests/helpers.py b/tests/helpers.py
index 5df796c23..01752a791 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -1,8 +1,6 @@
from __future__ import annotations
-import asyncio
import collections
-import functools
import inspect
import itertools
import logging
@@ -25,21 +23,6 @@ for logger in logging.Logger.manager.loggerDict.values():
logger.setLevel(logging.CRITICAL)
-def async_test(wrapped):
- """
- Run a test case via asyncio.
- Example:
- >>> @async_test
- ... async def lemon_wins():
- ... assert True
- """
-
- @functools.wraps(wrapped)
- def wrapper(*args, **kwargs):
- return asyncio.run(wrapped(*args, **kwargs))
- return wrapper
-
-
class HashableMixin(discord.mixins.EqualityComparable):
"""
Mixin that provides similar hashing and equality functionality as discord.py's `Hashable` mixin.
diff --git a/tests/test_helpers.py b/tests/test_helpers.py
index 7894e104a..fe39df308 100644
--- a/tests/test_helpers.py
+++ b/tests/test_helpers.py
@@ -395,11 +395,3 @@ class MockObjectTests(unittest.TestCase):
coroutine = async_mock()
self.assertTrue(inspect.iscoroutine(coroutine))
self.assertIsNotNone(asyncio.run(coroutine))
-
- def test_async_test_decorator_allows_synchronous_call_to_async_def(self):
- """Test if the `async_test` decorator allows an `async def` to be called synchronously."""
- @helpers.async_test
- async def kosayoda():
- return "return value"
-
- self.assertEqual(kosayoda(), "return value")