aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorGravatar Chris Lovering <[email protected]>2023-04-09 21:15:18 +0100
committerGravatar Chris Lovering <[email protected]>2023-04-11 16:48:14 +0100
commit8dca42846d2956122d45795763095559a6a51b64 (patch)
tree480cd7d3c1a6d6bc87710e2d3c19f223a92f7c5d /tests
parentReplace CI flake8 config with ruff (diff)
Migrate code style to ruff
Co-authored-by: Boris Muratov <[email protected]> Co-authored-by: wookie184 <[email protected]>
Diffstat (limited to 'tests')
-rw-r--r--tests/_autospec.py2
-rw-r--r--tests/base.py3
-rw-r--r--tests/bot/exts/filtering/test_discord_token_filter.py4
-rw-r--r--tests/bot/exts/filtering/test_extension_filter.py2
-rw-r--r--tests/bot/exts/info/test_information.py44
-rw-r--r--tests/bot/exts/moderation/infraction/test_infractions.py5
-rw-r--r--tests/bot/exts/moderation/infraction/test_utils.py14
-rw-r--r--tests/bot/exts/moderation/test_incidents.py4
-rw-r--r--tests/bot/exts/moderation/test_silence.py83
-rw-r--r--tests/bot/exts/moderation/test_slowmode.py20
-rw-r--r--tests/bot/exts/recruitment/talentpool/test_review.py10
-rw-r--r--tests/bot/exts/test_cogs.py2
-rw-r--r--tests/bot/exts/utils/snekbox/test_io.py2
-rw-r--r--tests/bot/exts/utils/snekbox/test_snekbox.py170
-rw-r--r--tests/bot/resources/test_resources.py2
-rw-r--r--tests/bot/test_constants.py8
-rw-r--r--tests/bot/test_converters.py162
-rw-r--r--tests/bot/test_decorators.py8
-rw-r--r--tests/bot/test_pagination.py18
-rw-r--r--tests/bot/utils/test_message_cache.py5
-rw-r--r--tests/bot/utils/test_time.py81
-rw-r--r--tests/helpers.py187
-rw-r--r--tests/test_base.py21
-rw-r--r--tests/test_helpers.py29
24 files changed, 446 insertions, 440 deletions
diff --git a/tests/_autospec.py b/tests/_autospec.py
index ecff6bcbe..6f990a580 100644
--- a/tests/_autospec.py
+++ b/tests/_autospec.py
@@ -2,7 +2,7 @@ import contextlib
import functools
import pkgutil
import unittest.mock
-from typing import Callable
+from collections.abc import Callable
@functools.wraps(unittest.mock._patch.decoration_helper)
diff --git a/tests/base.py b/tests/base.py
index 4863a1821..cad187b6a 100644
--- a/tests/base.py
+++ b/tests/base.py
@@ -1,7 +1,6 @@
import logging
import unittest
from contextlib import contextmanager
-from typing import Dict
import discord
from async_rediscache import RedisSession
@@ -86,7 +85,7 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
async def assertHasPermissionsCheck( # noqa: N802
self,
cmd: commands.Command,
- permissions: Dict[str, bool],
+ permissions: dict[str, bool],
) -> None:
"""
Test that `cmd` raises a `MissingPermissions` exception if author lacks `permissions`.
diff --git a/tests/bot/exts/filtering/test_discord_token_filter.py b/tests/bot/exts/filtering/test_discord_token_filter.py
index a5cddf8d9..1cb9e16fa 100644
--- a/tests/bot/exts/filtering/test_discord_token_filter.py
+++ b/tests/bot/exts/filtering/test_discord_token_filter.py
@@ -222,8 +222,8 @@ class DiscordTokenFilterTests(unittest.IsolatedAsyncioTestCase):
def test_regex_matches_multiple_valid(self):
"""Should support multiple matches in the middle of a string."""
- token_1 = "NDY3MjIzMjMwNjUwNzc3NjQx.XsyWGg.uFNEQPCc4ePwGh7egG8UicQssz8"
- token_2 = "NDcyMjY1OTQzMDYyNDEzMzMy.XsyWMw.l8XPnDqb0lp-EiQ2g_0xVFT1pyc"
+ token_1 = "NDY3MjIzMjMwNjUwNzc3NjQx.XsyWGg.uFNEQPCc4ePwGh7egG8UicQssz8" # noqa: S105
+ token_2 = "NDcyMjY1OTQzMDYyNDEzMzMy.XsyWMw.l8XPnDqb0lp-EiQ2g_0xVFT1pyc" # noqa: S105
message = f"garbage {token_1} hello {token_2} world"
results = discord_token.TOKEN_RE.finditer(message)
diff --git a/tests/bot/exts/filtering/test_extension_filter.py b/tests/bot/exts/filtering/test_extension_filter.py
index 827d267d2..f71de1e1b 100644
--- a/tests/bot/exts/filtering/test_extension_filter.py
+++ b/tests/bot/exts/filtering/test_extension_filter.py
@@ -25,7 +25,7 @@ class ExtensionsListTests(unittest.IsolatedAsyncioTestCase):
for i, filter_content in enumerate(self.whitelist, start=1):
filters.append({
"id": i, "content": filter_content, "description": None, "settings": {},
- "additional_settings": {}, "created_at": now, "updated_at": now # noqa: P103
+ "additional_settings": {}, "created_at": now, "updated_at": now
})
self.filter_list.add_list({
"id": 1,
diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py
index 65595e959..e90291f62 100644
--- a/tests/bot/exts/info/test_information.py
+++ b/tests/bot/exts/info/test_information.py
@@ -1,7 +1,7 @@
import textwrap
import unittest
import unittest.mock
-from datetime import datetime
+from datetime import UTC, datetime
from textwrap import shorten
import discord
@@ -41,7 +41,7 @@ class InformationCogTests(unittest.IsolatedAsyncioTestCase):
self.ctx.send.assert_called_once()
_, kwargs = self.ctx.send.call_args
- embed = kwargs.pop('embed')
+ embed = kwargs.pop("embed")
self.assertEqual(embed.title, "Role information (Total 1 role)")
self.assertEqual(embed.colour, discord.Colour.og_blurple())
@@ -110,15 +110,15 @@ class UserInfractionHelperMethodTests(unittest.IsolatedAsyncioTestCase):
test_values = (
{
"helper_method": self.cog.basic_user_infraction_counts,
- "expected_args": ("bot/infractions", {'hidden': 'False', 'user__id': str(self.member.id)}),
+ "expected_args": ("bot/infractions", {"hidden": "False", "user__id": str(self.member.id)}),
},
{
"helper_method": self.cog.expanded_user_infraction_counts,
- "expected_args": ("bot/infractions", {'user__id': str(self.member.id)}),
+ "expected_args": ("bot/infractions", {"user__id": str(self.member.id)}),
},
{
"helper_method": self.cog.user_nomination_counts,
- "expected_args": ("bot/nominations", {'user__id': str(self.member.id)}),
+ "expected_args": ("bot/nominations", {"user__id": str(self.member.id)}),
},
)
@@ -241,19 +241,19 @@ class UserInfractionHelperMethodTests(unittest.IsolatedAsyncioTestCase):
"expected_lines": ["No nominations"],
},
{
- "api response": [{'active': True}],
+ "api response": [{"active": True}],
"expected_lines": ["This user is **currently** nominated", "(1 nomination in total)"],
},
{
- "api response": [{'active': True}, {'active': False}],
+ "api response": [{"active": True}, {"active": False}],
"expected_lines": ["This user is **currently** nominated", "(2 nominations in total)"],
},
{
- "api response": [{'active': False}],
+ "api response": [{"active": False}],
"expected_lines": ["This user has 1 historical nomination, but is currently not nominated."],
},
{
- "api response": [{'active': False}, {'active': False}],
+ "api response": [{"active": False}, {"active": False}],
"expected_lines": ["This user has 2 historical nominations, but is currently not nominated."],
},
@@ -290,7 +290,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
user.nick = None
user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock")
user.colour = 0
- user.created_at = user.joined_at = datetime.utcnow()
+ user.created_at = user.joined_at = datetime.now(UTC)
embed = await self.cog.create_user_embed(ctx, user, False)
@@ -312,7 +312,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
user.nick = "Cat lover"
user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock")
user.colour = 0
- user.created_at = user.joined_at = datetime.utcnow()
+ user.created_at = user.joined_at = datetime.now(UTC)
embed = await self.cog.create_user_embed(ctx, user, False)
@@ -329,11 +329,11 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
async def test_create_user_embed_ignores_everyone_role(self):
"""Created `!user` embeds should not contain mention of the @everyone-role."""
ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1))
- admins_role = helpers.MockRole(name='Admins')
+ admins_role = helpers.MockRole(name="Admins")
# A `MockMember` has the @Everyone role by default; we add the Admins to that.
user = helpers.MockMember(roles=[admins_role], colour=100)
- user.created_at = user.joined_at = datetime.utcnow()
+ user.created_at = user.joined_at = datetime.now(UTC)
embed = await self.cog.create_user_embed(ctx, user, False)
@@ -354,13 +354,13 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
"""The embed should contain expanded infractions and nomination info in mod channels."""
ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=50))
- moderators_role = helpers.MockRole(name='Moderators')
+ moderators_role = helpers.MockRole(name="Moderators")
infraction_counts.return_value = ("Infractions", "expanded infractions info")
nomination_counts.return_value = ("Nominations", "nomination info")
user = helpers.MockMember(id=314, roles=[moderators_role], colour=100)
- user.created_at = user.joined_at = datetime.utcfromtimestamp(1)
+ user.created_at = user.joined_at = datetime.fromtimestamp(1, tz=UTC)
embed = await self.cog.create_user_embed(ctx, user, False)
infraction_counts.assert_called_once_with(user)
@@ -394,13 +394,13 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
"""The embed should contain only basic infraction data outside of mod channels."""
ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=100))
- moderators_role = helpers.MockRole(name='Moderators')
+ moderators_role = helpers.MockRole(name="Moderators")
infraction_counts.return_value = ("Infractions", "basic infractions info")
user_messages.return_value = ("Messages", "user message counts")
user = helpers.MockMember(id=314, roles=[moderators_role], colour=100)
- user.created_at = user.joined_at = datetime.utcfromtimestamp(1)
+ user.created_at = user.joined_at = datetime.fromtimestamp(1, tz=UTC)
embed = await self.cog.create_user_embed(ctx, user, False)
infraction_counts.assert_called_once_with(user)
@@ -444,10 +444,10 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
"""The embed should be created with the colour of the top role, if a top role is available."""
ctx = helpers.MockContext()
- moderators_role = helpers.MockRole(name='Moderators')
+ moderators_role = helpers.MockRole(name="Moderators")
user = helpers.MockMember(id=314, roles=[moderators_role], colour=100)
- user.created_at = user.joined_at = datetime.utcnow()
+ user.created_at = user.joined_at = datetime.now(UTC)
embed = await self.cog.create_user_embed(ctx, user, False)
self.assertEqual(embed.colour, discord.Colour(100))
@@ -465,7 +465,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
ctx = helpers.MockContext()
user = helpers.MockMember(id=217, colour=discord.Colour.default())
- user.created_at = user.joined_at = datetime.utcnow()
+ user.created_at = user.joined_at = datetime.now(UTC)
embed = await self.cog.create_user_embed(ctx, user, False)
self.assertEqual(embed.colour, discord.Colour.og_blurple())
@@ -483,7 +483,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase):
ctx = helpers.MockContext()
user = helpers.MockMember(id=217, colour=0)
- user.created_at = user.joined_at = datetime.utcnow()
+ user.created_at = user.joined_at = datetime.now(UTC)
user.display_avatar.url = "avatar url"
embed = await self.cog.create_user_embed(ctx, user, False)
@@ -644,6 +644,6 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase):
for raw_user_input, expected_matched_rule_numbers in test_cases:
with self.subTest(identifier=raw_user_input):
final_rule_numbers = await self.cog.rules(self.cog, self.ctx, args=raw_user_input)
- embed = self.ctx.send.call_args.kwargs['embed']
+ embed = self.ctx.send.call_args.kwargs["embed"]
self.assertEqual(information.DEFAULT_RULES_DESCRIPTION, embed.description)
self.assertEqual(expected_matched_rule_numbers, final_rule_numbers)
diff --git a/tests/bot/exts/moderation/infraction/test_infractions.py b/tests/bot/exts/moderation/infraction/test_infractions.py
index b78328137..26ba770dc 100644
--- a/tests/bot/exts/moderation/infraction/test_infractions.py
+++ b/tests/bot/exts/moderation/infraction/test_infractions.py
@@ -270,10 +270,9 @@ class CleanBanTests(unittest.IsolatedAsyncioTestCase):
def inner(name):
if name == "ModManagement":
return self.management_cog if enable_manage else None
- elif name == "Clean":
+ if name == "Clean":
return self.clean_cog if enable_clean else None
- else:
- return DEFAULT
+ return DEFAULT
return inner
async def test_cleanban_falls_back_to_native_purge_without_clean_cog(self):
diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py
index 122935e37..25337673e 100644
--- a/tests/bot/exts/moderation/infraction/test_utils.py
+++ b/tests/bot/exts/moderation/infraction/test_utils.py
@@ -1,6 +1,6 @@
import unittest
from collections import namedtuple
-from datetime import datetime
+from datetime import UTC, datetime
from unittest.mock import AsyncMock, MagicMock, patch
from discord import Embed, Forbidden, HTTPException, NotFound
@@ -136,7 +136,10 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):
"""
test_cases = [
{
- "args": (dict(id=0, type="ban", reason=None, expires_at=datetime(2020, 2, 26, 9, 20)), self.user),
+ "args": (
+ dict(id=0, type="ban", reason=None, expires_at=datetime(2020, 2, 26, 9, 20, tzinfo=UTC)),
+ self.user,
+ ),
"expected_output": Embed(
title=utils.INFRACTION_TITLE,
description=utils.INFRACTION_DESCRIPTION_TEMPLATE.format(
@@ -192,7 +195,10 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase):
"send_result": False
},
{
- "args": (dict(id=0, type="mute", reason="Test", expires_at=datetime(2020, 2, 26, 9, 20)), self.user),
+ "args": (
+ dict(id=0, type="mute", reason="Test", expires_at=datetime(2020, 2, 26, 9, 20, tzinfo=UTC)),
+ self.user,
+ ),
"expected_output": Embed(
title=utils.INFRACTION_TITLE,
description=utils.INFRACTION_DESCRIPTION_TEMPLATE.format(
@@ -309,7 +315,7 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase):
async def test_normal_post_infraction(self):
"""Should return response from POST request if there are no errors."""
- now = datetime.utcnow()
+ now = datetime.now(UTC)
expected = {
"actor": self.ctx.author.id,
"hidden": True,
diff --git a/tests/bot/exts/moderation/test_incidents.py b/tests/bot/exts/moderation/test_incidents.py
index 53d98360c..1a02339d4 100644
--- a/tests/bot/exts/moderation/test_incidents.py
+++ b/tests/bot/exts/moderation/test_incidents.py
@@ -20,7 +20,7 @@ from tests.helpers import (
MockUser
)
-CURRENT_TIME = datetime.datetime(2022, 1, 1, tzinfo=datetime.timezone.utc)
+CURRENT_TIME = datetime.datetime(2022, 1, 1, tzinfo=datetime.UTC)
class MockAsyncIterable:
@@ -799,7 +799,7 @@ class TestMessageLinkEmbeds(TestIncidents):
"\n".join("Lets make a new line test".split()): "Lets\nmake\na...",
- 'Hello, World!' * 300: (
+ "Hello, World!" * 300: (
"Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!"
"Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!"
"Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!"
diff --git a/tests/bot/exts/moderation/test_silence.py b/tests/bot/exts/moderation/test_silence.py
index 2622f46a7..ec0b3bf43 100644
--- a/tests/bot/exts/moderation/test_silence.py
+++ b/tests/bot/exts/moderation/test_silence.py
@@ -1,7 +1,6 @@
import itertools
import unittest
-from datetime import datetime, timezone
-from typing import List, Tuple
+from datetime import UTC, datetime
from unittest import mock
from unittest.mock import AsyncMock, Mock
@@ -97,10 +96,12 @@ class SilenceNotifierTests(SilenceTest):
"""Alert is skipped on first loop or not an increment of 900."""
test_cases = (0, 15, 5000)
for current_loop in test_cases:
- with self.subTest(current_loop=current_loop):
- with mock.patch.object(self.notifier, "_current_loop", new=current_loop):
- await self.notifier._notifier()
- self.alert_channel.send.assert_not_called()
+ with (
+ self.subTest(current_loop=current_loop),
+ mock.patch.object(self.notifier, "_current_loop", new=current_loop),
+ ):
+ await self.notifier._notifier()
+ self.alert_channel.send.assert_not_called()
@autospec(silence.Silence, "previous_overwrites", "unsilence_timestamps", pass_mocks=False)
@@ -203,7 +204,7 @@ class SilenceCogTests(SilenceTest):
self.assertEqual((None,), member.move_to.call_args_list[0].args)
@staticmethod
- def create_erroneous_members() -> Tuple[List[MockMember], List[MockMember]]:
+ def create_erroneous_members() -> tuple[list[MockMember], list[MockMember]]:
"""
Helper method to generate a list of members that error out on move_to call.
@@ -363,7 +364,7 @@ class RescheduleTests(RedisTestCase):
channels = [MockTextChannel(id=123), MockTextChannel(id=456)]
self.bot.get_channel.side_effect = channels
self.cog.unsilence_timestamps.items.return_value = [(123, 2000), (456, 3000)]
- silence.datetime.now.return_value = datetime.fromtimestamp(1000, tz=timezone.utc)
+ silence.datetime.now.return_value = datetime.fromtimestamp(1000, tz=UTC)
self.cog._unsilence_wrapper = mock.MagicMock()
unsilence_return = self.cog._unsilence_wrapper.return_value
@@ -426,17 +427,19 @@ class SilenceTests(SilenceTest):
targets = (MockTextChannel(), MockVoiceChannel(), None)
for (duration, message, was_silenced), target in itertools.product(test_cases, targets):
- with mock.patch.object(self.cog, "_set_silence_overwrites", return_value=was_silenced):
- with self.subTest(was_silenced=was_silenced, target=target, message=message):
- with mock.patch.object(self.cog, "send_message") as send_message:
- ctx = MockContext()
- await self.cog.silence.callback(self.cog, ctx, target, duration)
- send_message.assert_called_once_with(
- message,
- ctx.channel,
- target or ctx.channel,
- alert_target=was_silenced
- )
+ with (
+ mock.patch.object(self.cog, "_set_silence_overwrites", return_value=was_silenced),
+ self.subTest(was_silenced=was_silenced, target=target, message=message),
+ mock.patch.object(self.cog, "send_message") as send_message
+ ):
+ ctx = MockContext()
+ await self.cog.silence.callback(self.cog, ctx, target, duration)
+ send_message.assert_called_once_with(
+ message,
+ ctx.channel,
+ target or ctx.channel,
+ alert_target=was_silenced
+ )
@voice_sync_helper
async def test_sync_called(self, ctx, sync, kick):
@@ -577,10 +580,10 @@ class SilenceTests(SilenceTest):
new_overwrite_dict = dict(self.voice_overwrite)
# Remove 'connect' & 'speak' keys because they were changed by the method.
- del prev_overwrite_dict['connect']
- del prev_overwrite_dict['speak']
- del new_overwrite_dict['connect']
- del new_overwrite_dict['speak']
+ del prev_overwrite_dict["connect"]
+ del prev_overwrite_dict["speak"]
+ del new_overwrite_dict["connect"]
+ del new_overwrite_dict["speak"]
self.assertDictEqual(prev_overwrite_dict, new_overwrite_dict)
@@ -617,13 +620,13 @@ class SilenceTests(SilenceTest):
now_timestamp = 100
duration = 15
timestamp = now_timestamp + duration * 60
- datetime_mock.now.return_value = datetime.fromtimestamp(now_timestamp, tz=timezone.utc)
+ datetime_mock.now.return_value = datetime.fromtimestamp(now_timestamp, tz=UTC)
ctx = MockContext(channel=self.text_channel)
await self.cog.silence.callback(self.cog, ctx, duration)
self.cog.unsilence_timestamps.set.assert_awaited_once_with(ctx.channel.id, timestamp)
- datetime_mock.now.assert_called_once_with(tz=timezone.utc) # Ensure it's using an aware dt.
+ datetime_mock.now.assert_called_once_with(tz=UTC) # Ensure it's using an aware dt.
async def test_cached_indefinite_time(self):
"""A value of -1 was cached for a permanent silence."""
@@ -697,13 +700,15 @@ class UnsilenceTests(SilenceTest):
if target:
target.overwrites_for.return_value = overwrite
- with mock.patch.object(self.cog, "_unsilence", return_value=was_unsilenced):
- with mock.patch.object(self.cog, "send_message") as send_message:
- with self.subTest(was_unsilenced=was_unsilenced, overwrite=overwrite, target=target):
- await self.cog.unsilence.callback(self.cog, ctx, channel=target)
+ with (
+ mock.patch.object(self.cog, "_unsilence", return_value=was_unsilenced),
+ mock.patch.object(self.cog, "send_message") as send_message,
+ self.subTest(was_unsilenced=was_unsilenced, overwrite=overwrite, target=target),
+ ):
+ await self.cog.unsilence.callback(self.cog, ctx, channel=target)
- call_args = (message, ctx.channel, target or ctx.channel)
- send_message.assert_awaited_once_with(*call_args, alert_target=was_unsilenced)
+ call_args = (message, ctx.channel, target or ctx.channel)
+ send_message.assert_awaited_once_with(*call_args, alert_target=was_unsilenced)
async def test_skipped_already_unsilenced(self):
"""Permissions were not set and `False` was returned for an already unsilenced channel."""
@@ -808,10 +813,10 @@ class UnsilenceTests(SilenceTest):
new_overwrite_dict = dict(self.text_overwrite)
# Remove these keys because they were modified by the unsilence.
- del prev_overwrite_dict['send_messages']
- del prev_overwrite_dict['add_reactions']
- del new_overwrite_dict['send_messages']
- del new_overwrite_dict['add_reactions']
+ del prev_overwrite_dict["send_messages"]
+ del prev_overwrite_dict["add_reactions"]
+ del new_overwrite_dict["send_messages"]
+ del new_overwrite_dict["add_reactions"]
self.assertDictEqual(prev_overwrite_dict, new_overwrite_dict)
@@ -826,10 +831,10 @@ class UnsilenceTests(SilenceTest):
new_overwrite_dict = dict(self.voice_overwrite)
# Remove these keys because they were modified by the unsilence.
- del prev_overwrite_dict['connect']
- del prev_overwrite_dict['speak']
- del new_overwrite_dict['connect']
- del new_overwrite_dict['speak']
+ del prev_overwrite_dict["connect"]
+ del prev_overwrite_dict["speak"]
+ del new_overwrite_dict["connect"]
+ del new_overwrite_dict["speak"]
self.assertDictEqual(prev_overwrite_dict, new_overwrite_dict)
diff --git a/tests/bot/exts/moderation/test_slowmode.py b/tests/bot/exts/moderation/test_slowmode.py
index 5483b7a64..cf5101e16 100644
--- a/tests/bot/exts/moderation/test_slowmode.py
+++ b/tests/bot/exts/moderation/test_slowmode.py
@@ -17,24 +17,24 @@ class SlowmodeTests(unittest.IsolatedAsyncioTestCase):
async def test_get_slowmode_no_channel(self) -> None:
"""Get slowmode without a given channel."""
- self.ctx.channel = MockTextChannel(name='python-general', slowmode_delay=5)
+ self.ctx.channel = MockTextChannel(name="python-general", slowmode_delay=5)
await self.cog.get_slowmode(self.cog, self.ctx, None)
self.ctx.send.assert_called_once_with("The slowmode delay for #python-general is 5 seconds.")
async def test_get_slowmode_with_channel(self) -> None:
"""Get slowmode with a given channel."""
- text_channel = MockTextChannel(name='python-language', slowmode_delay=2)
+ text_channel = MockTextChannel(name="python-language", slowmode_delay=2)
await self.cog.get_slowmode(self.cog, self.ctx, text_channel)
- self.ctx.send.assert_called_once_with('The slowmode delay for #python-language is 2 seconds.')
+ self.ctx.send.assert_called_once_with("The slowmode delay for #python-language is 2 seconds.")
async def test_set_slowmode_no_channel(self) -> None:
"""Set slowmode without a given channel."""
test_cases = (
- ('helpers', 23, True, f'{Emojis.check_mark} The slowmode delay for #helpers is now 23 seconds.'),
- ('mods', 76526, False, f'{Emojis.cross_mark} The slowmode delay must be between 0 and 6 hours.'),
- ('admins', 97, True, f'{Emojis.check_mark} The slowmode delay for #admins is now 1 minute and 37 seconds.')
+ ("helpers", 23, True, f"{Emojis.check_mark} The slowmode delay for #helpers is now 23 seconds."),
+ ("mods", 76526, False, f"{Emojis.cross_mark} The slowmode delay must be between 0 and 6 hours."),
+ ("admins", 97, True, f"{Emojis.check_mark} The slowmode delay for #admins is now 1 minute and 37 seconds.")
)
for channel_name, seconds, edited, result_msg in test_cases:
@@ -60,9 +60,9 @@ class SlowmodeTests(unittest.IsolatedAsyncioTestCase):
async def test_set_slowmode_with_channel(self) -> None:
"""Set slowmode with a given channel."""
test_cases = (
- ('bot-commands', 12, True, f'{Emojis.check_mark} The slowmode delay for #bot-commands is now 12 seconds.'),
- ('mod-spam', 21, True, f'{Emojis.check_mark} The slowmode delay for #mod-spam is now 21 seconds.'),
- ('admin-spam', 4323598, False, f'{Emojis.cross_mark} The slowmode delay must be between 0 and 6 hours.')
+ ("bot-commands", 12, True, f"{Emojis.check_mark} The slowmode delay for #bot-commands is now 12 seconds."),
+ ("mod-spam", 21, True, f"{Emojis.check_mark} The slowmode delay for #mod-spam is now 21 seconds."),
+ ("admin-spam", 4323598, False, f"{Emojis.cross_mark} The slowmode delay must be between 0 and 6 hours.")
)
for channel_name, seconds, edited, result_msg in test_cases:
@@ -87,7 +87,7 @@ class SlowmodeTests(unittest.IsolatedAsyncioTestCase):
async def test_reset_slowmode_sets_delay_to_zero(self) -> None:
"""Reset slowmode with a given channel."""
- text_channel = MockTextChannel(name='meta', slowmode_delay=1)
+ text_channel = MockTextChannel(name="meta", slowmode_delay=1)
self.cog.set_slowmode = mock.AsyncMock()
await self.cog.reset_slowmode(self.cog, self.ctx, text_channel)
diff --git a/tests/bot/exts/recruitment/talentpool/test_review.py b/tests/bot/exts/recruitment/talentpool/test_review.py
index f726fccc7..25622e91f 100644
--- a/tests/bot/exts/recruitment/talentpool/test_review.py
+++ b/tests/bot/exts/recruitment/talentpool/test_review.py
@@ -1,5 +1,5 @@
import unittest
-from datetime import datetime, timedelta, timezone
+from datetime import UTC, datetime, timedelta
from unittest.mock import AsyncMock, Mock, patch
from bot.exts.recruitment.talentpool import _review
@@ -61,8 +61,8 @@ class ReviewerTests(unittest.IsolatedAsyncioTestCase):
@patch("bot.exts.recruitment.talentpool._review.MIN_REVIEW_INTERVAL", timedelta(days=1))
async def test_is_ready_for_review(self):
"""Tests for the `is_ready_for_review` function."""
- too_recent = datetime.now(timezone.utc) - timedelta(hours=1)
- not_too_recent = datetime.now(timezone.utc) - timedelta(days=7)
+ too_recent = datetime.now(UTC) - timedelta(hours=1)
+ not_too_recent = datetime.now(UTC) - timedelta(days=7)
cases = (
# Only one review, and not too recent, so ready.
(
@@ -126,7 +126,7 @@ class ReviewerTests(unittest.IsolatedAsyncioTestCase):
@patch("bot.exts.recruitment.talentpool._review.MIN_NOMINATION_TIME", timedelta(days=7))
async def test_get_nomination_to_review(self):
"""Test get_nomination_to_review function."""
- now = datetime.now(timezone.utc)
+ now = datetime.now(UTC)
# Each case contains a list of nominations, followed by the index in that list
# of the one that should be selected, or None if None should be returned
@@ -184,7 +184,7 @@ class ReviewerTests(unittest.IsolatedAsyncioTestCase):
@patch("bot.exts.recruitment.talentpool._review.MIN_NOMINATION_TIME", timedelta(days=0))
async def test_get_nomination_to_review_order(self):
- now = datetime.now(timezone.utc)
+ now = datetime.now(UTC)
# Each case in cases is a list of nominations in the order they should be chosen from first to last
cases = [
diff --git a/tests/bot/exts/test_cogs.py b/tests/bot/exts/test_cogs.py
index f8e120262..99bc87120 100644
--- a/tests/bot/exts/test_cogs.py
+++ b/tests/bot/exts/test_cogs.py
@@ -50,7 +50,7 @@ class CommandNameTests(unittest.TestCase):
yield obj
@staticmethod
- def get_qualified_names(command: commands.Command) -> t.List[str]:
+ def get_qualified_names(command: commands.Command) -> list[str]:
"""Return a list of all qualified names, including aliases, for the `command`."""
names = [f"{command.full_parent_name} {alias}".strip() for alias in command.aliases]
names.append(command.qualified_name)
diff --git a/tests/bot/exts/utils/snekbox/test_io.py b/tests/bot/exts/utils/snekbox/test_io.py
index bcf1162b8..4f7f49a5e 100644
--- a/tests/bot/exts/utils/snekbox/test_io.py
+++ b/tests/bot/exts/utils/snekbox/test_io.py
@@ -19,7 +19,7 @@ class SnekboxIOTests(TestCase):
(r"A\0\tB", "A__B"),
# Any other disallowed chars -> underscore
(r"\\.txt", "_.txt"),
- (r"A!@#$%^&*B, C()[]{}+=D.txt", "A_B_C_D.txt"), # noqa: P103
+ (r"A!@#$%^&*B, C()[]{}+=D.txt", "A_B_C_D.txt"),
(" ", "_"),
# Normal file names should be unchanged
("legal_file-name.txt", "legal_file-name.txt"),
diff --git a/tests/bot/exts/utils/snekbox/test_snekbox.py b/tests/bot/exts/utils/snekbox/test_snekbox.py
index 79ac8ea2c..fa28aade8 100644
--- a/tests/bot/exts/utils/snekbox/test_snekbox.py
+++ b/tests/bot/exts/utils/snekbox/test_snekbox.py
@@ -43,7 +43,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
"files": [
{
"path": "main.py",
- "content": b64encode("import random".encode()).decode()
+ "content": b64encode(b"import random").decode()
}
]
}
@@ -72,45 +72,45 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
async def test_codeblock_converter(self):
ctx = MockContext()
cases = (
- ('print("Hello world!")', 'print("Hello world!")', 'non-formatted'),
- ('`print("Hello world!")`', 'print("Hello world!")', 'one line code block'),
- ('```\nprint("Hello world!")```', 'print("Hello world!")', 'multiline code block'),
- ('```py\nprint("Hello world!")```', 'print("Hello world!")', 'multiline python code block'),
- ('text```print("Hello world!")```text', 'print("Hello world!")', 'code block surrounded by text'),
+ ('print("Hello world!")', 'print("Hello world!")', "non-formatted"),
+ ('`print("Hello world!")`', 'print("Hello world!")', "one line code block"),
+ ('```\nprint("Hello world!")```', 'print("Hello world!")', "multiline code block"),
+ ('```py\nprint("Hello world!")```', 'print("Hello world!")', "multiline python code block"),
+ ('text```print("Hello world!")```text', 'print("Hello world!")', "code block surrounded by text"),
('```print("Hello world!")```\ntext\n```py\nprint("Hello world!")```',
- 'print("Hello world!")\nprint("Hello world!")', 'two code blocks with text in-between'),
+ 'print("Hello world!")\nprint("Hello world!")', "two code blocks with text in-between"),
('`print("Hello world!")`\ntext\n```print("How\'s it going?")```',
- 'print("How\'s it going?")', 'code block preceded by inline code'),
+ 'print("How\'s it going?")', "code block preceded by inline code"),
('`print("Hello world!")`\ntext\n`print("Hello world!")`',
- 'print("Hello world!")', 'one inline code block of two')
+ 'print("Hello world!")', "one inline code block of two")
)
for case, expected, testname in cases:
- with self.subTest(msg=f'Extract code from {testname}.'):
+ with self.subTest(msg=f"Extract code from {testname}."):
self.assertEqual(
- '\n'.join(await snekbox.CodeblockConverter.convert(ctx, case)), expected
+ "\n".join(await snekbox.CodeblockConverter.convert(ctx, case)), expected
)
def test_prepare_timeit_input(self):
"""Test the prepare_timeit_input codeblock detection."""
- base_args = ('-m', 'timeit', '-s')
+ base_args = ("-m", "timeit", "-s")
cases = (
- (['print("Hello World")'], '', 'single block of code'),
- (['x = 1', 'print(x)'], 'x = 1', 'two blocks of code'),
- (['x = 1', 'print(x)', 'print("Some other code.")'], 'x = 1', 'three blocks of code')
+ (['print("Hello World")'], "", "single block of code"),
+ (["x = 1", "print(x)"], "x = 1", "two blocks of code"),
+ (["x = 1", "print(x)", 'print("Some other code.")'], "x = 1", "three blocks of code")
)
for case, setup_code, test_name in cases:
setup = snekbox._cog.TIMEIT_SETUP_WRAPPER.format(setup=setup_code)
- expected = [*base_args, setup, '\n'.join(case[1:] if setup_code else case)]
- with self.subTest(msg=f'Test with {test_name} and expected return {expected}'):
+ expected = [*base_args, setup, "\n".join(case[1:] if setup_code else case)]
+ with self.subTest(msg=f"Test with {test_name} and expected return {expected}"):
self.assertEqual(self.cog.prepare_timeit_input(case), expected)
def test_eval_result_message(self):
"""EvalResult.get_message(), should return message."""
cases = (
- ('ERROR', None, ('Your 3.11 eval job has failed', 'ERROR', '')),
- ('', 128 + snekbox._eval.SIGKILL, ('Your 3.11 eval job timed out or ran out of memory', '', '')),
- ('', 255, ('Your 3.11 eval job has failed', 'A fatal NsJail error occurred', ''))
+ ("ERROR", None, ("Your 3.11 eval job has failed", "ERROR", "")),
+ ("", 128 + snekbox._eval.SIGKILL, ("Your 3.11 eval job timed out or ran out of memory", "", "")),
+ ("", 255, ("Your 3.11 eval job has failed", "A fatal NsJail error occurred", ""))
)
for stdout, returncode, expected in cases:
exp_msg, exp_err, exp_files_err = expected
@@ -167,7 +167,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
msg = result.get_failed_files_str(char_max=10)
self.assertEqual(msg, expected)
- @patch('bot.exts.utils.snekbox._eval.Signals', side_effect=ValueError)
+ @patch("bot.exts.utils.snekbox._eval.Signals", side_effect=ValueError)
def test_eval_result_message_invalid_signal(self, _mock_signals: Mock):
result = EvalResult(stdout="", returncode=127)
self.assertEqual(
@@ -177,7 +177,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(result.error_message, "")
self.assertEqual(result.files_error_message, "")
- @patch('bot.exts.utils.snekbox._eval.Signals')
+ @patch("bot.exts.utils.snekbox._eval.Signals")
def test_eval_result_message_valid_signal(self, mock_signals: Mock):
mock_signals.return_value.name = "SIGTEST"
result = EvalResult(stdout="", returncode=127)
@@ -189,9 +189,9 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
def test_eval_result_status_emoji(self):
"""Return emoji according to the eval result."""
cases = (
- (' ', -1, ':warning:'),
- ('Hello world!', 0, ':white_check_mark:'),
- ('Invalid beard size', -1, ':x:')
+ (" ", -1, ":warning:"),
+ ("Hello world!", 0, ":white_check_mark:"),
+ ("Invalid beard size", -1, ":x:")
)
for stdout, returncode, expected in cases:
with self.subTest(stdout=stdout, returncode=returncode, expected=expected):
@@ -200,48 +200,48 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
async def test_format_output(self):
"""Test output formatting."""
- self.cog.upload_output = AsyncMock(return_value='https://testificate.com/')
+ self.cog.upload_output = AsyncMock(return_value="https://testificate.com/")
too_many_lines = (
- '001 | v\n002 | e\n003 | r\n004 | y\n005 | l\n006 | o\n'
- '007 | n\n008 | g\n009 | b\n010 | e\n011 | a\n... (truncated - too many lines)'
+ "001 | v\n002 | e\n003 | r\n004 | y\n005 | l\n006 | o\n"
+ "007 | n\n008 | g\n009 | b\n010 | e\n011 | a\n... (truncated - too many lines)"
)
too_long_too_many_lines = (
"\n".join(
- f"{i:03d} | {line}" for i, line in enumerate(['verylongbeard' * 10] * 15, 1)
+ f"{i:03d} | {line}" for i, line in enumerate(["verylongbeard" * 10] * 15, 1)
)[:1000] + "\n... (truncated - too long, too many lines)"
)
cases = (
- ('', ('[No output]', None), 'No output'),
- ('My awesome output', ('My awesome output', None), 'One line output'),
- ('<@', ("<@\u200B", None), r'Convert <@ to <@\u200B'),
- ('<!@', ("<!@\u200B", None), r'Convert <!@ to <!@\u200B'),
+ ("", ("[No output]", None), "No output"),
+ ("My awesome output", ("My awesome output", None), "One line output"),
+ ("<@", ("<@\u200B", None), r"Convert <@ to <@\u200B"),
+ ("<!@", ("<!@\u200B", None), r"Convert <!@ to <!@\u200B"),
(
- '\u202E\u202E\u202E',
- ('Code block escape attempt detected; will not output result', 'https://testificate.com/'),
- 'Detect RIGHT-TO-LEFT OVERRIDE'
+ "\u202E\u202E\u202E",
+ ("Code block escape attempt detected; will not output result", "https://testificate.com/"),
+ "Detect RIGHT-TO-LEFT OVERRIDE"
),
(
- '\u200B\u200B\u200B',
- ('Code block escape attempt detected; will not output result', 'https://testificate.com/'),
- 'Detect ZERO WIDTH SPACE'
+ "\u200B\u200B\u200B",
+ ("Code block escape attempt detected; will not output result", "https://testificate.com/"),
+ "Detect ZERO WIDTH SPACE"
),
- ('long\nbeard', ('001 | long\n002 | beard', None), 'Two line output'),
+ ("long\nbeard", ("001 | long\n002 | beard", None), "Two line output"),
(
- 'v\ne\nr\ny\nl\no\nn\ng\nb\ne\na\nr\nd',
- (too_many_lines, 'https://testificate.com/'),
- '12 lines output'
+ "v\ne\nr\ny\nl\no\nn\ng\nb\ne\na\nr\nd",
+ (too_many_lines, "https://testificate.com/"),
+ "12 lines output"
),
(
- 'verylongbeard' * 100,
- ('verylongbeard' * 76 + 'verylongbear\n... (truncated - too long)', 'https://testificate.com/'),
- '1300 characters output'
+ "verylongbeard" * 100,
+ ("verylongbeard" * 76 + "verylongbear\n... (truncated - too long)", "https://testificate.com/"),
+ "1300 characters output"
),
(
- ('verylongbeard' * 10 + '\n') * 15,
- (too_long_too_many_lines, 'https://testificate.com/'),
- '15 lines, 1965 characters output'
+ ("verylongbeard" * 10 + "\n") * 15,
+ (too_long_too_many_lines, "https://testificate.com/"),
+ "15 lines, 1965 characters output"
),
)
for case, expected, testname in cases:
@@ -257,10 +257,10 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
self.cog.send_job = AsyncMock(return_value=response)
self.cog.continue_job = AsyncMock(return_value=None)
- await self.cog.eval_command(self.cog, ctx=ctx, python_version='3.11', code=['MyAwesomeCode'])
+ await self.cog.eval_command(self.cog, ctx=ctx, python_version="3.11", code=["MyAwesomeCode"])
job = EvalJob.from_code("MyAwesomeCode")
self.cog.send_job.assert_called_once_with(ctx, job)
- self.cog.continue_job.assert_called_once_with(ctx, response, 'eval')
+ self.cog.continue_job.assert_called_once_with(ctx, response, "eval")
async def test_eval_command_evaluate_twice(self):
"""Test the eval and re-eval command procedure."""
@@ -269,9 +269,9 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
ctx.command = MagicMock()
self.cog.send_job = AsyncMock(return_value=response)
self.cog.continue_job = AsyncMock()
- self.cog.continue_job.side_effect = (EvalJob.from_code('MyAwesomeFormattedCode'), None)
+ self.cog.continue_job.side_effect = (EvalJob.from_code("MyAwesomeFormattedCode"), None)
- await self.cog.eval_command(self.cog, ctx=ctx, python_version='3.11', code=['MyAwesomeCode'])
+ await self.cog.eval_command(self.cog, ctx=ctx, python_version="3.11", code=["MyAwesomeCode"])
expected_job = EvalJob.from_code("MyAwesomeFormattedCode")
self.cog.send_job.assert_called_with(ctx, expected_job)
@@ -285,7 +285,7 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
async def delay_with_side_effect(*args, **kwargs) -> dict:
"""Delay the post_job call to ensure the job runs long enough to conflict."""
await asyncio.sleep(1)
- return {'stdout': '', 'returncode': 0}
+ return {"stdout": "", "returncode": 0}
self.cog.post_job = AsyncMock(side_effect=delay_with_side_effect)
with self.assertRaises(LockedResourceError):
@@ -299,32 +299,32 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
ctx = MockContext()
ctx.message = MockMessage()
ctx.send = AsyncMock()
- ctx.author = MockUser(mention='@LemonLemonishBeard#0042')
+ ctx.author = MockUser(mention="@LemonLemonishBeard#0042")
eval_result = EvalResult("", 0)
self.cog.post_job = AsyncMock(return_value=eval_result)
- self.cog.format_output = AsyncMock(return_value=('[No output]', None))
+ self.cog.format_output = AsyncMock(return_value=("[No output]", None))
self.cog.upload_output = AsyncMock() # Should not be called
mocked_filter_cog = MagicMock()
mocked_filter_cog.filter_snekbox_output = AsyncMock(return_value=(False, []))
self.bot.get_cog.return_value = mocked_filter_cog
- job = EvalJob.from_code('MyAwesomeCode')
+ job = EvalJob.from_code("MyAwesomeCode")
await self.cog.send_job(ctx, job),
ctx.send.assert_called_once()
self.assertEqual(
ctx.send.call_args.args[0],
- '@LemonLemonishBeard#0042 :warning: Your 3.11 eval job has completed '
- 'with return code 0.\n\n```\n[No output]\n```'
+ "@LemonLemonishBeard#0042 :warning: Your 3.11 eval job has completed "
+ "with return code 0.\n\n```\n[No output]\n```"
)
- allowed_mentions = ctx.send.call_args.kwargs['allowed_mentions']
+ allowed_mentions = ctx.send.call_args.kwargs["allowed_mentions"]
expected_allowed_mentions = AllowedMentions(everyone=False, roles=False, users=[ctx.author])
self.assertEqual(allowed_mentions.to_dict(), expected_allowed_mentions.to_dict())
self.cog.post_job.assert_called_once_with(job)
- self.cog.format_output.assert_called_once_with('')
+ self.cog.format_output.assert_called_once_with("")
self.cog.upload_output.assert_not_called()
async def test_send_job_with_paste_link(self):
@@ -332,11 +332,11 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
ctx = MockContext()
ctx.message = MockMessage()
ctx.send = AsyncMock()
- ctx.author.mention = '@LemonLemonishBeard#0042'
+ ctx.author.mention = "@LemonLemonishBeard#0042"
eval_result = EvalResult("Way too long beard", 0)
self.cog.post_job = AsyncMock(return_value=eval_result)
- self.cog.format_output = AsyncMock(return_value=('Way too long beard', 'lookatmybeard.com'))
+ self.cog.format_output = AsyncMock(return_value=("Way too long beard", "lookatmybeard.com"))
mocked_filter_cog = MagicMock()
mocked_filter_cog.filter_snekbox_output = AsyncMock(return_value=(False, []))
@@ -348,20 +348,20 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
ctx.send.assert_called_once()
self.assertEqual(
ctx.send.call_args.args[0],
- '@LemonLemonishBeard#0042 :white_check_mark: Your 3.11 eval job '
- 'has completed with return code 0.'
- '\n\n```\nWay too long beard\n```\nFull output: lookatmybeard.com'
+ "@LemonLemonishBeard#0042 :white_check_mark: Your 3.11 eval job "
+ "has completed with return code 0."
+ "\n\n```\nWay too long beard\n```\nFull output: lookatmybeard.com"
)
self.cog.post_job.assert_called_once_with(job)
- self.cog.format_output.assert_called_once_with('Way too long beard')
+ self.cog.format_output.assert_called_once_with("Way too long beard")
async def test_send_job_with_non_zero_eval(self):
"""Test the send_job function with a code returning a non-zero code."""
ctx = MockContext()
ctx.message = MockMessage()
ctx.send = AsyncMock()
- ctx.author.mention = '@LemonLemonishBeard#0042'
+ ctx.author.mention = "@LemonLemonishBeard#0042"
eval_result = EvalResult("ERROR", 127)
self.cog.post_job = AsyncMock(return_value=eval_result)
@@ -377,8 +377,8 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
ctx.send.assert_called_once()
self.assertEqual(
ctx.send.call_args.args[0],
- '@LemonLemonishBeard#0042 :x: Your 3.11 eval job has completed with return code 127.'
- '\n\n```\nERROR\n```'
+ "@LemonLemonishBeard#0042 :x: Your 3.11 eval job has completed with return code 127."
+ "\n\n```\nERROR\n```"
)
self.cog.post_job.assert_called_once_with(job)
@@ -436,11 +436,11 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
self.bot.wait_for.assert_has_awaits(
(
call(
- 'message_edit',
+ "message_edit",
check=partial_mock(snekbox._cog.predicate_message_edit, ctx),
timeout=snekbox._cog.REDO_TIMEOUT,
),
- call('reaction_add', check=partial_mock(snekbox._cog.predicate_emoji_reaction, ctx), timeout=10)
+ call("reaction_add", check=partial_mock(snekbox._cog.predicate_emoji_reaction, ctx), timeout=10)
)
)
ctx.message.add_reaction.assert_called_once_with(snekbox._cog.REDO_EMOJI)
@@ -483,17 +483,17 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
def test_predicate_message_edit(self):
"""Test the predicate_message_edit function."""
- msg0 = MockMessage(id=1, content='abc')
- msg1 = MockMessage(id=2, content='abcdef')
- msg2 = MockMessage(id=1, content='abcdef')
+ msg0 = MockMessage(id=1, content="abc")
+ msg1 = MockMessage(id=2, content="abcdef")
+ msg2 = MockMessage(id=1, content="abcdef")
cases = (
- (msg0, msg0, False, 'same ID, same content'),
- (msg0, msg1, False, 'different ID, different content'),
- (msg0, msg2, True, 'same ID, different content')
+ (msg0, msg0, False, "same ID, same content"),
+ (msg0, msg1, False, "different ID, different content"),
+ (msg0, msg2, True, "same ID, different content")
)
for ctx_msg, new_msg, expected, testname in cases:
- with self.subTest(msg=f'Messages with {testname} return {expected}'):
+ with self.subTest(msg=f"Messages with {testname} return {expected}"):
ctx = MockContext(message=ctx_msg)
actual = snekbox._cog.predicate_message_edit(ctx, ctx_msg, new_msg)
self.assertEqual(actual, expected)
@@ -509,16 +509,16 @@ class SnekboxTests(unittest.IsolatedAsyncioTestCase):
invalid_reaction_id.__str__.return_value = snekbox._cog.REDO_EMOJI
invalid_user_id = MockUser(id=42)
invalid_reaction_str = MockReaction(message=MockMessage(id=1))
- invalid_reaction_str.__str__.return_value = ':longbeard:'
+ invalid_reaction_str.__str__.return_value = ":longbeard:"
cases = (
- (invalid_reaction_id, valid_user, False, 'invalid reaction ID'),
- (valid_reaction, invalid_user_id, False, 'invalid user ID'),
- (invalid_reaction_str, valid_user, False, 'invalid reaction __str__'),
- (valid_reaction, valid_user, True, 'matching attributes')
+ (invalid_reaction_id, valid_user, False, "invalid reaction ID"),
+ (valid_reaction, invalid_user_id, False, "invalid user ID"),
+ (invalid_reaction_str, valid_user, False, "invalid reaction __str__"),
+ (valid_reaction, valid_user, True, "matching attributes")
)
for reaction, user, expected, testname in cases:
- with self.subTest(msg=f'Test with {testname} and expected return {expected}'):
+ with self.subTest(msg=f"Test with {testname} and expected return {expected}"):
actual = snekbox._cog.predicate_emoji_reaction(valid_ctx, reaction, user)
self.assertEqual(actual, expected)
diff --git a/tests/bot/resources/test_resources.py b/tests/bot/resources/test_resources.py
index 73937cfa6..77f92f100 100644
--- a/tests/bot/resources/test_resources.py
+++ b/tests/bot/resources/test_resources.py
@@ -7,7 +7,7 @@ class ResourceValidationTests(unittest.TestCase):
"""Validates resources used by the bot."""
def test_stars_valid(self):
"""The resource `bot/resources/stars.json` should contain a list of strings."""
- path = Path('bot', 'resources', 'stars.json')
+ path = Path("bot", "resources", "stars.json")
content = path.read_text()
data = json.loads(content)
diff --git a/tests/bot/test_constants.py b/tests/bot/test_constants.py
index f10d6fbe8..3492021ce 100644
--- a/tests/bot/test_constants.py
+++ b/tests/bot/test_constants.py
@@ -23,11 +23,7 @@ def is_annotation_instance(value: typing.Any, annotation: typing.Any) -> bool:
def is_any_instance(value: typing.Any, types: typing.Collection) -> bool:
"""Return True if `value` is an instance of any type in `types`."""
- for type_ in types:
- if is_annotation_instance(value, type_):
- return True
-
- return False
+ return any(is_annotation_instance(value, type_) for type_ in types)
class ConstantsTests(unittest.TestCase):
@@ -39,7 +35,7 @@ class ConstantsTests(unittest.TestCase):
sections = (
cls
for (name, cls) in inspect.getmembers(constants)
- if hasattr(cls, 'section') and isinstance(cls, type)
+ if hasattr(cls, "section") and isinstance(cls, type)
)
for section in sections:
for name, annotation in section.__annotations__.items():
diff --git a/tests/bot/test_converters.py b/tests/bot/test_converters.py
index 1bb678db2..e5ccf27f7 100644
--- a/tests/bot/test_converters.py
+++ b/tests/bot/test_converters.py
@@ -1,6 +1,6 @@
import re
import unittest
-from datetime import MAXYEAR, datetime, timezone
+from datetime import MAXYEAR, UTC, datetime
from unittest.mock import MagicMock, patch
from dateutil.relativedelta import relativedelta
@@ -15,13 +15,13 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
@classmethod
def setUpClass(cls):
cls.context = MagicMock
- cls.context.author = 'bob'
+ cls.context.author = "bob"
- cls.fixed_utc_now = datetime.fromisoformat('2019-01-01T00:00:00+00:00')
+ cls.fixed_utc_now = datetime.fromisoformat("2019-01-01T00:00:00+00:00")
async def test_package_name_for_valid(self):
"""PackageName returns valid package names unchanged."""
- test_values = ('foo', 'le_mon', 'num83r')
+ test_values = ("foo", "le_mon", "num83r")
for name in test_values:
with self.subTest(identifier=name):
@@ -30,47 +30,46 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
async def test_package_name_for_invalid(self):
"""PackageName raises the proper exception for invalid package names."""
- test_values = ('text_with_a_dot.', 'UpperCaseName', 'dashed-name')
+ test_values = ("text_with_a_dot.", "UpperCaseName", "dashed-name")
for name in test_values:
- with self.subTest(identifier=name):
- with self.assertRaises(BadArgument):
- await PackageName.convert(self.context, name)
+ with self.subTest(identifier=name), self.assertRaises(BadArgument):
+ await PackageName.convert(self.context, name)
async def test_duration_converter_for_valid(self):
"""Duration returns the correct `datetime` for valid duration strings."""
test_values = (
# Simple duration strings
- ('1Y', {"years": 1}),
- ('1y', {"years": 1}),
- ('1year', {"years": 1}),
- ('1years', {"years": 1}),
- ('1m', {"months": 1}),
- ('1month', {"months": 1}),
- ('1months', {"months": 1}),
- ('1w', {"weeks": 1}),
- ('1W', {"weeks": 1}),
- ('1week', {"weeks": 1}),
- ('1weeks', {"weeks": 1}),
- ('1d', {"days": 1}),
- ('1D', {"days": 1}),
- ('1day', {"days": 1}),
- ('1days', {"days": 1}),
- ('1h', {"hours": 1}),
- ('1H', {"hours": 1}),
- ('1hour', {"hours": 1}),
- ('1hours', {"hours": 1}),
- ('1M', {"minutes": 1}),
- ('1minute', {"minutes": 1}),
- ('1minutes', {"minutes": 1}),
- ('1s', {"seconds": 1}),
- ('1S', {"seconds": 1}),
- ('1second', {"seconds": 1}),
- ('1seconds', {"seconds": 1}),
+ ("1Y", {"years": 1}),
+ ("1y", {"years": 1}),
+ ("1year", {"years": 1}),
+ ("1years", {"years": 1}),
+ ("1m", {"months": 1}),
+ ("1month", {"months": 1}),
+ ("1months", {"months": 1}),
+ ("1w", {"weeks": 1}),
+ ("1W", {"weeks": 1}),
+ ("1week", {"weeks": 1}),
+ ("1weeks", {"weeks": 1}),
+ ("1d", {"days": 1}),
+ ("1D", {"days": 1}),
+ ("1day", {"days": 1}),
+ ("1days", {"days": 1}),
+ ("1h", {"hours": 1}),
+ ("1H", {"hours": 1}),
+ ("1hour", {"hours": 1}),
+ ("1hours", {"hours": 1}),
+ ("1M", {"minutes": 1}),
+ ("1minute", {"minutes": 1}),
+ ("1minutes", {"minutes": 1}),
+ ("1s", {"seconds": 1}),
+ ("1S", {"seconds": 1}),
+ ("1second", {"seconds": 1}),
+ ("1seconds", {"seconds": 1}),
# Complex duration strings
(
- '1y1m1w1d1H1M1S',
+ "1y1m1w1d1H1M1S",
{
"years": 1,
"months": 1,
@@ -81,13 +80,13 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
"seconds": 1
}
),
- ('5y100S', {"years": 5, "seconds": 100}),
- ('2w28H', {"weeks": 2, "hours": 28}),
+ ("5y100S", {"years": 5, "seconds": 100}),
+ ("2w28H", {"weeks": 2, "hours": 28}),
# Duration strings with spaces
- ('1 year 2 months', {"years": 1, "months": 2}),
- ('1d 2H', {"days": 1, "hours": 2}),
- ('1 week2 days', {"weeks": 1, "days": 2}),
+ ("1 year 2 months", {"years": 1, "months": 2}),
+ ("1d 2H", {"days": 1, "hours": 2}),
+ ("1 week2 days", {"weeks": 1, "days": 2}),
)
converter = Duration()
@@ -95,7 +94,7 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
for duration, duration_dict in test_values:
expected_datetime = self.fixed_utc_now + relativedelta(**duration_dict)
- with patch('bot.converters.datetime') as mock_datetime:
+ with patch("bot.converters.datetime") as mock_datetime:
mock_datetime.now.return_value = self.fixed_utc_now
with self.subTest(duration=duration, duration_dict=duration_dict):
@@ -106,19 +105,19 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
"""Duration raises the right exception for invalid duration strings."""
test_values = (
# Units in wrong order
- '1d1w',
- '1s1y',
+ "1d1w",
+ "1s1y",
# Duplicated units
- '1 year 2 years',
- '1 M 10 minutes',
+ "1 year 2 years",
+ "1 M 10 minutes",
# Unknown substrings
- '1MVes',
- '1y3breads',
+ "1MVes",
+ "1y3breads",
# Missing amount
- 'ym',
+ "ym",
# Incorrect whitespace
" 1y",
@@ -126,15 +125,15 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
"1y 1m",
# Garbage
- 'Guido van Rossum',
- 'lemon lemon lemon lemon lemon lemon lemon',
+ "Guido van Rossum",
+ "lemon lemon lemon lemon lemon lemon lemon",
)
converter = Duration()
for invalid_duration in test_values:
with self.subTest(invalid_duration=invalid_duration):
- exception_message = f'`{invalid_duration}` is not a valid duration string.'
+ exception_message = f"`{invalid_duration}` is not a valid duration string."
with self.assertRaisesRegex(BadArgument, re.escape(exception_message)):
await converter.convert(self.context, invalid_duration)
@@ -151,44 +150,43 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
async def test_isodatetime_converter_for_valid(self):
"""ISODateTime converter returns correct datetime for valid datetime string."""
- utc = timezone.utc
test_values = (
# `YYYY-mm-ddTHH:MM:SSZ` | `YYYY-mm-dd HH:MM:SSZ`
- ('2019-09-02T02:03:05Z', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02 02:03:05Z', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
+ ("2019-09-02T02:03:05Z", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02 02:03:05Z", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
# `YYYY-mm-ddTHH:MM:SS±HH:MM` | `YYYY-mm-dd HH:MM:SS±HH:MM`
- ('2019-09-02T03:18:05+01:15', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02 03:18:05+01:15', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02T00:48:05-01:15', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02 00:48:05-01:15', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
+ ("2019-09-02T03:18:05+01:15", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02 03:18:05+01:15", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02T00:48:05-01:15", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02 00:48:05-01:15", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
# `YYYY-mm-ddTHH:MM:SS±HHMM` | `YYYY-mm-dd HH:MM:SS±HHMM`
- ('2019-09-02T03:18:05+0115', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02 03:18:05+0115', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02T00:48:05-0115', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02 00:48:05-0115', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
+ ("2019-09-02T03:18:05+0115", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02 03:18:05+0115", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02T00:48:05-0115", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02 00:48:05-0115", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
# `YYYY-mm-ddTHH:MM:SS±HH` | `YYYY-mm-dd HH:MM:SS±HH`
- ('2019-09-02 03:03:05+01', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02T01:03:05-01', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
+ ("2019-09-02 03:03:05+01", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02T01:03:05-01", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
# `YYYY-mm-ddTHH:MM:SS` | `YYYY-mm-dd HH:MM:SS`
- ('2019-09-02T02:03:05', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
- ('2019-09-02 02:03:05', datetime(2019, 9, 2, 2, 3, 5, tzinfo=utc)),
+ ("2019-09-02T02:03:05", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
+ ("2019-09-02 02:03:05", datetime(2019, 9, 2, 2, 3, 5, tzinfo=UTC)),
# `YYYY-mm-ddTHH:MM` | `YYYY-mm-dd HH:MM`
- ('2019-11-12T09:15', datetime(2019, 11, 12, 9, 15, tzinfo=utc)),
- ('2019-11-12 09:15', datetime(2019, 11, 12, 9, 15, tzinfo=utc)),
+ ("2019-11-12T09:15", datetime(2019, 11, 12, 9, 15, tzinfo=UTC)),
+ ("2019-11-12 09:15", datetime(2019, 11, 12, 9, 15, tzinfo=UTC)),
# `YYYY-mm-dd`
- ('2019-04-01', datetime(2019, 4, 1, tzinfo=utc)),
+ ("2019-04-01", datetime(2019, 4, 1, tzinfo=UTC)),
# `YYYY-mm`
- ('2019-02-01', datetime(2019, 2, 1, tzinfo=utc)),
+ ("2019-02-01", datetime(2019, 2, 1, tzinfo=UTC)),
# `YYYY`
- ('2025', datetime(2025, 1, 1, tzinfo=utc)),
+ ("2025", datetime(2025, 1, 1, tzinfo=UTC)),
)
converter = ISODateTime()
@@ -202,19 +200,19 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
"""ISODateTime converter raises the correct exception for invalid datetime strings."""
test_values = (
# Make sure it doesn't interfere with the Duration converter
- '1Y',
- '1d',
- '1H',
+ "1Y",
+ "1d",
+ "1H",
# Check if it fails when only providing the optional time part
- '10:10:10',
- '10:00',
+ "10:10:10",
+ "10:00",
# Invalid date format
- '19-01-01',
+ "19-01-01",
# Other non-valid strings
- 'fisk the tag master',
+ "fisk the tag master",
)
converter = ISODateTime()
@@ -249,6 +247,8 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase):
)
converter = HushDurationConverter()
for invalid_minutes_string, exception_message in test_values:
- with self.subTest(invalid_minutes_string=invalid_minutes_string, exception_message=exception_message):
- with self.assertRaisesRegex(BadArgument, re.escape(exception_message)):
- await converter.convert(self.context, invalid_minutes_string)
+ with (
+ self.subTest(invalid_minutes_string=invalid_minutes_string, exception_message=exception_message),
+ self.assertRaisesRegex(BadArgument, re.escape(exception_message)),
+ ):
+ await converter.convert(self.context, invalid_minutes_string)
diff --git a/tests/bot/test_decorators.py b/tests/bot/test_decorators.py
index 3d450caa0..6a04123a7 100644
--- a/tests/bot/test_decorators.py
+++ b/tests/bot/test_decorators.py
@@ -142,6 +142,8 @@ class InWhitelistTests(unittest.TestCase):
with unittest.mock.patch("bot.decorators.commands.check", new=lambda predicate: predicate):
predicate = in_whitelist(**test_case.kwargs)
- with self.subTest(test_description=test_case.description):
- with self.assertRaisesRegex(InWhitelistCheckFailure, exception_message):
- predicate(test_case.ctx)
+ with (
+ self.subTest(test_description=test_case.description),
+ self.assertRaisesRegex(InWhitelistCheckFailure, exception_message),
+ ):
+ predicate(test_case.ctx)
diff --git a/tests/bot/test_pagination.py b/tests/bot/test_pagination.py
index 630f2516d..cf23f1948 100644
--- a/tests/bot/test_pagination.py
+++ b/tests/bot/test_pagination.py
@@ -8,39 +8,39 @@ class LinePaginatorTests(TestCase):
def setUp(self):
"""Create a paginator for the test method."""
- self.paginator = pagination.LinePaginator(prefix='', suffix='', max_size=30,
+ self.paginator = pagination.LinePaginator(prefix="", suffix="", max_size=30,
scale_to_size=50)
def test_add_line_works_on_small_lines(self):
"""`add_line` should allow small lines to be added."""
- self.paginator.add_line('x' * (self.paginator.max_size - 3))
+ self.paginator.add_line("x" * (self.paginator.max_size - 3))
# Note that the page isn't added to _pages until it's full.
self.assertEqual(len(self.paginator._pages), 0)
def test_add_line_works_on_long_lines(self):
"""After additional lines after `max_size` is exceeded should go on the next page."""
- self.paginator.add_line('x' * self.paginator.max_size)
+ self.paginator.add_line("x" * self.paginator.max_size)
self.assertEqual(len(self.paginator._pages), 0)
# Any additional lines should start a new page after `max_size` is exceeded.
- self.paginator.add_line('x')
+ self.paginator.add_line("x")
self.assertEqual(len(self.paginator._pages), 1)
def test_add_line_continuation(self):
"""When `scale_to_size` is exceeded, remaining words should be split onto the next page."""
- self.paginator.add_line('zyz ' * (self.paginator.scale_to_size//4 + 1))
+ self.paginator.add_line("zyz " * (self.paginator.scale_to_size//4 + 1))
self.assertEqual(len(self.paginator._pages), 1)
def test_add_line_no_continuation(self):
"""If adding a new line to an existing page would exceed `max_size`, it should start a new
page rather than using continuation.
"""
- self.paginator.add_line('z' * (self.paginator.max_size - 3))
- self.paginator.add_line('z')
+ self.paginator.add_line("z" * (self.paginator.max_size - 3))
+ self.paginator.add_line("z")
self.assertEqual(len(self.paginator._pages), 1)
def test_add_line_truncates_very_long_words(self):
"""`add_line` should truncate if a single long word exceeds `scale_to_size`."""
- self.paginator.add_line('x' * (self.paginator.scale_to_size + 1))
+ self.paginator.add_line("x" * (self.paginator.scale_to_size + 1))
# Note: item at index 1 is the truncated line, index 0 is prefix
- self.assertEqual(self.paginator._current_page[1], 'x' * self.paginator.scale_to_size)
+ self.assertEqual(self.paginator._current_page[1], "x" * self.paginator.scale_to_size)
diff --git a/tests/bot/utils/test_message_cache.py b/tests/bot/utils/test_message_cache.py
index 04bfd28d1..ad3f4e8b6 100644
--- a/tests/bot/utils/test_message_cache.py
+++ b/tests/bot/utils/test_message_cache.py
@@ -157,9 +157,8 @@ class TestMessageCache(unittest.TestCase):
cache.append(msg)
for current_loop in test_cases:
- with self.subTest(current_loop=current_loop):
- with self.assertRaises(IndexError):
- cache[current_loop]
+ with self.subTest(current_loop=current_loop), self.assertRaises(IndexError):
+ cache[current_loop]
def test_slicing_with_unfilled_cache(self):
"""Test if slicing returns the correct messages if the cache is not yet fully filled."""
diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py
index 120d65176..6244a3548 100644
--- a/tests/bot/utils/test_time.py
+++ b/tests/bot/utils/test_time.py
@@ -1,5 +1,5 @@
import unittest
-from datetime import datetime, timezone
+from datetime import UTC, datetime
from dateutil.relativedelta import relativedelta
@@ -13,23 +13,23 @@ class TimeTests(unittest.TestCase):
"""humanize_delta should be able to handle unknown units, and will not abort."""
# Does not abort for unknown units, as the unit name is checked
# against the attribute of the relativedelta instance.
- actual = time.humanize_delta(relativedelta(days=2, hours=2), precision='elephants', max_units=2)
- self.assertEqual(actual, '2 days and 2 hours')
+ actual = time.humanize_delta(relativedelta(days=2, hours=2), precision="elephants", max_units=2)
+ self.assertEqual(actual, "2 days and 2 hours")
def test_humanize_delta_handle_high_units(self):
"""humanize_delta should be able to handle very high units."""
# Very high maximum units, but it only ever iterates over
# each value the relativedelta might have.
- actual = time.humanize_delta(relativedelta(days=2, hours=2), precision='hours', max_units=20)
- self.assertEqual(actual, '2 days and 2 hours')
+ actual = time.humanize_delta(relativedelta(days=2, hours=2), precision="hours", max_units=20)
+ self.assertEqual(actual, "2 days and 2 hours")
def test_humanize_delta_should_normal_usage(self):
"""Testing humanize delta."""
test_cases = (
- (relativedelta(days=2), 'seconds', 1, '2 days'),
- (relativedelta(days=2, hours=2), 'seconds', 2, '2 days and 2 hours'),
- (relativedelta(days=2, hours=2), 'seconds', 1, '2 days'),
- (relativedelta(days=2, hours=2), 'days', 2, '2 days'),
+ (relativedelta(days=2), "seconds", 1, "2 days"),
+ (relativedelta(days=2, hours=2), "seconds", 2, "2 days and 2 hours"),
+ (relativedelta(days=2, hours=2), "seconds", 1, "2 days"),
+ (relativedelta(days=2, hours=2), "days", 2, "2 days"),
)
for delta, precision, max_units, expected in test_cases:
@@ -43,8 +43,8 @@ class TimeTests(unittest.TestCase):
for max_units in test_cases:
with self.subTest(max_units=max_units), self.assertRaises(ValueError) as error:
- time.humanize_delta(relativedelta(days=2, hours=2), precision='hours', max_units=max_units)
- self.assertEqual(str(error.exception), 'max_units must be positive.')
+ time.humanize_delta(relativedelta(days=2, hours=2), precision="hours", max_units=max_units)
+ self.assertEqual(str(error.exception), "max_units must be positive.")
def test_format_with_duration_none_expiry(self):
"""format_with_duration should work for None expiry."""
@@ -52,9 +52,9 @@ class TimeTests(unittest.TestCase):
(None, None, None, None),
# To make sure that date_from and max_units are not touched
- (None, 'Why hello there!', None, None),
- (None, None, float('inf'), None),
- (None, 'Why hello there!', float('inf'), None),
+ (None, "Why hello there!", None, None),
+ (None, None, float("inf"), None),
+ (None, "Why hello there!", float("inf"), None),
)
for expiry, date_from, max_units, expected in test_cases:
@@ -64,10 +64,10 @@ class TimeTests(unittest.TestCase):
def test_format_with_duration_custom_units(self):
"""format_with_duration should work for custom max_units."""
test_cases = (
- ('3000-12-12T00:01:00Z', datetime(3000, 12, 11, 12, 5, 5, tzinfo=timezone.utc), 6,
- '<t:32533488060:f> (11 hours, 55 minutes and 55 seconds)'),
- ('3000-11-23T20:09:00Z', datetime(3000, 4, 25, 20, 15, tzinfo=timezone.utc), 20,
- '<t:32531918940:f> (6 months, 28 days, 23 hours and 54 minutes)')
+ ("3000-12-12T00:01:00Z", datetime(3000, 12, 11, 12, 5, 5, tzinfo=UTC), 6,
+ "<t:32533488060:f> (11 hours, 55 minutes and 55 seconds)"),
+ ("3000-11-23T20:09:00Z", datetime(3000, 4, 25, 20, 15, tzinfo=UTC), 20,
+ "<t:32531918940:f> (6 months, 28 days, 23 hours and 54 minutes)")
)
for expiry, date_from, max_units, expected in test_cases:
@@ -76,23 +76,22 @@ class TimeTests(unittest.TestCase):
def test_format_with_duration_normal_usage(self):
"""format_with_duration should work for normal usage, across various durations."""
- utc = timezone.utc
test_cases = (
- ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5, tzinfo=utc), 2,
- '<t:1576108860:f> (12 hours and 55 seconds)'),
- ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5, tzinfo=utc), 1, '<t:1576108860:f> (12 hours)'),
- ('2019-12-12T00:00:00Z', datetime(2019, 12, 11, 23, 59, tzinfo=utc), 2, '<t:1576108800:f> (1 minute)'),
- ('2019-11-23T20:09:00Z', datetime(2019, 11, 15, 20, 15, tzinfo=utc), 2,
- '<t:1574539740:f> (7 days and 23 hours)'),
- ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15, tzinfo=utc), 2,
- '<t:1574539740:f> (6 months and 28 days)'),
- ('2019-11-23T20:58:00Z', datetime(2019, 11, 23, 20, 53, tzinfo=utc), 2, '<t:1574542680:f> (5 minutes)'),
- ('2019-11-24T00:00:00Z', datetime(2019, 11, 23, 23, 59, 0, tzinfo=utc), 2, '<t:1574553600:f> (1 minute)'),
- ('2019-11-23T23:59:00Z', datetime(2017, 7, 21, 23, 0, tzinfo=utc), 2,
- '<t:1574553540:f> (2 years and 4 months)'),
- ('2019-11-23T23:59:00Z', datetime(2019, 11, 23, 23, 49, 5, tzinfo=utc), 2,
- '<t:1574553540:f> (9 minutes and 55 seconds)'),
- (None, datetime(2019, 11, 23, 23, 49, 5), 2, None),
+ ("2019-12-12T00:01:00Z", datetime(2019, 12, 11, 12, 0, 5, tzinfo=UTC), 2,
+ "<t:1576108860:f> (12 hours and 55 seconds)"),
+ ("2019-12-12T00:01:00Z", datetime(2019, 12, 11, 12, 0, 5, tzinfo=UTC), 1, "<t:1576108860:f> (12 hours)"),
+ ("2019-12-12T00:00:00Z", datetime(2019, 12, 11, 23, 59, tzinfo=UTC), 2, "<t:1576108800:f> (1 minute)"),
+ ("2019-11-23T20:09:00Z", datetime(2019, 11, 15, 20, 15, tzinfo=UTC), 2,
+ "<t:1574539740:f> (7 days and 23 hours)"),
+ ("2019-11-23T20:09:00Z", datetime(2019, 4, 25, 20, 15, tzinfo=UTC), 2,
+ "<t:1574539740:f> (6 months and 28 days)"),
+ ("2019-11-23T20:58:00Z", datetime(2019, 11, 23, 20, 53, tzinfo=UTC), 2, "<t:1574542680:f> (5 minutes)"),
+ ("2019-11-24T00:00:00Z", datetime(2019, 11, 23, 23, 59, 0, tzinfo=UTC), 2, "<t:1574553600:f> (1 minute)"),
+ ("2019-11-23T23:59:00Z", datetime(2017, 7, 21, 23, 0, tzinfo=UTC), 2,
+ "<t:1574553540:f> (2 years and 4 months)"),
+ ("2019-11-23T23:59:00Z", datetime(2019, 11, 23, 23, 49, 5, tzinfo=UTC), 2,
+ "<t:1574553540:f> (9 minutes and 55 seconds)"),
+ (None, datetime(2019, 11, 23, 23, 49, 5, tzinfo=UTC), 2, None),
)
for expiry, date_from, max_units, expected in test_cases:
@@ -106,8 +105,8 @@ class TimeTests(unittest.TestCase):
def test_until_expiration_with_duration_custom_units(self):
"""until_expiration should work for custom max_units."""
test_cases = (
- ('3000-12-12T00:01:00Z', '<t:32533488060:R>'),
- ('3000-11-23T20:09:00Z', '<t:32531918940:R>')
+ ("3000-12-12T00:01:00Z", "<t:32533488060:R>"),
+ ("3000-11-23T20:09:00Z", "<t:32531918940:R>")
)
for expiry, expected in test_cases:
@@ -117,11 +116,11 @@ class TimeTests(unittest.TestCase):
def test_until_expiration_normal_usage(self):
"""until_expiration should work for normal usage, across various durations."""
test_cases = (
- ('3000-12-12T00:01:00Z', '<t:32533488060:R>'),
- ('3000-12-12T00:01:00Z', '<t:32533488060:R>'),
- ('3000-12-12T00:00:00Z', '<t:32533488000:R>'),
- ('3000-11-23T20:09:00Z', '<t:32531918940:R>'),
- ('3000-11-23T20:09:00Z', '<t:32531918940:R>'),
+ ("3000-12-12T00:01:00Z", "<t:32533488060:R>"),
+ ("3000-12-12T00:01:00Z", "<t:32533488060:R>"),
+ ("3000-12-12T00:00:00Z", "<t:32533488000:R>"),
+ ("3000-11-23T20:09:00Z", "<t:32531918940:R>"),
+ ("3000-11-23T20:09:00Z", "<t:32531918940:R>"),
)
for expiry, expected in test_cases:
diff --git a/tests/helpers.py b/tests/helpers.py
index 020f1aee5..bb12c4977 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -5,7 +5,7 @@ import itertools
import logging
import unittest.mock
from asyncio import AbstractEventLoop
-from typing import Iterable, Optional
+from collections.abc import Iterable
import discord
from aiohttp import ClientSession
@@ -79,7 +79,7 @@ class CustomMockMixin:
additional_spec_asyncs = None
def __init__(self, **kwargs):
- name = kwargs.pop('name', None) # `name` has special meaning for Mock classes, so we need to set it manually.
+ name = kwargs.pop("name", None) # `name` has special meaning for Mock classes, so we need to set it manually.
super().__init__(spec_set=self.spec_set, **kwargs)
if self.additional_spec_asyncs:
@@ -101,7 +101,7 @@ class CustomMockMixin:
This override will look for an attribute called `child_mock_type` and use that as the type of the child mock.
"""
_new_name = kw.get("_new_name")
- if _new_name in self.__dict__['_spec_asyncs']:
+ if _new_name in self.__dict__["_spec_asyncs"]:
return unittest.mock.AsyncMock(**kw)
_type = type(self)
@@ -121,23 +121,23 @@ class CustomMockMixin:
# Create a guild instance to get a realistic Mock of `discord.Guild`
guild_data = {
- 'id': 1,
- 'name': 'guild',
- 'region': 'Europe',
- 'verification_level': 2,
- 'default_notications': 1,
- 'afk_timeout': 100,
- 'icon': "icon.png",
- 'banner': 'banner.png',
- 'mfa_level': 1,
- 'splash': 'splash.png',
- 'system_channel_id': 464033278631084042,
- 'description': 'mocking is fun',
- 'max_presences': 10_000,
- 'max_members': 100_000,
- 'preferred_locale': 'UTC',
- 'owner_id': 1,
- 'afk_channel_id': 464033278631084042,
+ "id": 1,
+ "name": "guild",
+ "region": "Europe",
+ "verification_level": 2,
+ "default_notications": 1,
+ "afk_timeout": 100,
+ "icon": "icon.png",
+ "banner": "banner.png",
+ "mfa_level": 1,
+ "splash": "splash.png",
+ "system_channel_id": 464033278631084042,
+ "description": "mocking is fun",
+ "max_presences": 10_000,
+ "max_members": 100_000,
+ "preferred_locale": "UTC",
+ "owner_id": 1,
+ "afk_channel_id": 464033278631084042,
}
guild_instance = discord.Guild(data=guild_data, state=unittest.mock.MagicMock())
@@ -170,8 +170,8 @@ class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin):
"""
spec_set = guild_instance
- def __init__(self, roles: Optional[Iterable[MockRole]] = None, **kwargs) -> None:
- default_kwargs = {'id': next(self.discord_id), 'members': [], "chunked": True}
+ def __init__(self, roles: Iterable[MockRole] | None = None, **kwargs) -> None:
+ default_kwargs = {"id": next(self.discord_id), "members": [], "chunked": True}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
self.roles = [MockRole(name="@everyone", position=1, id=0)]
@@ -180,7 +180,7 @@ class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin):
# Create a Role instance to get a realistic Mock of `discord.Role`
-role_data = {'name': 'role', 'id': 1}
+role_data = {"name": "role", "id": 1}
role_instance = discord.Role(guild=guild_instance, state=unittest.mock.MagicMock(), data=role_data)
@@ -195,11 +195,11 @@ class MockRole(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):
def __init__(self, **kwargs) -> None:
default_kwargs = {
- 'id': next(self.discord_id),
- 'name': 'role',
- 'position': 1,
- 'colour': discord.Colour(0xdeadbf),
- 'permissions': discord.Permissions(),
+ "id": next(self.discord_id),
+ "name": "role",
+ "position": 1,
+ "colour": discord.Colour(0xdeadbf),
+ "permissions": discord.Permissions(),
}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
@@ -209,8 +209,8 @@ class MockRole(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):
if isinstance(self.permissions, int):
self.permissions = discord.Permissions(self.permissions)
- if 'mention' not in kwargs:
- self.mention = f'&{self.name}'
+ if "mention" not in kwargs:
+ self.mention = f"&{self.name}"
def __lt__(self, other):
"""Simplified position-based comparisons similar to those of `discord.Role`."""
@@ -222,7 +222,7 @@ class MockRole(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):
# Create a Member instance to get a realistic Mock of `discord.Member`
-member_data = {'user': 'lemon', 'roles': [1], 'flags': 2}
+member_data = {"user": "lemon", "roles": [1], "flags": 2}
state_mock = unittest.mock.MagicMock()
member_instance = discord.Member(data=member_data, guild=guild_instance, state=state_mock)
@@ -236,8 +236,8 @@ class MockMember(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin
"""
spec_set = member_instance
- def __init__(self, roles: Optional[Iterable[MockRole]] = None, **kwargs) -> None:
- default_kwargs = {'name': 'member', 'id': next(self.discord_id), 'bot': False, "pending": False}
+ def __init__(self, roles: Iterable[MockRole] | None = None, **kwargs) -> None:
+ default_kwargs = {"name": "member", "id": next(self.discord_id), "bot": False, "pending": False}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
self.roles = [MockRole(name="@everyone", position=1, id=0)]
@@ -245,7 +245,7 @@ class MockMember(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin
self.roles.extend(roles)
self.top_role = max(self.roles)
- if 'mention' not in kwargs:
+ if "mention" not in kwargs:
self.mention = f"@{self.name}"
@@ -269,10 +269,10 @@ class MockUser(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):
spec_set = user_instance
def __init__(self, **kwargs) -> None:
- default_kwargs = {'name': 'user', 'id': next(self.discord_id), 'bot': False}
+ default_kwargs = {"name": "user", "id": next(self.discord_id), "bot": False}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
- if 'mention' not in kwargs:
+ if "mention" not in kwargs:
self.mention = f"@{self.name}"
@@ -331,16 +331,16 @@ class MockBot(CustomMockMixin, unittest.mock.MagicMock):
# Create a TextChannel instance to get a realistic MagicMock of `discord.TextChannel`
channel_data = {
- 'id': 1,
- 'type': 'TextChannel',
- 'name': 'channel',
- 'parent_id': 1234567890,
- 'topic': 'topic',
- 'position': 1,
- 'nsfw': False,
- 'last_message_id': 1,
- 'bitrate': 1337,
- 'user_limit': 25,
+ "id": 1,
+ "type": "TextChannel",
+ "name": "channel",
+ "parent_id": 1234567890,
+ "topic": "topic",
+ "position": 1,
+ "nsfw": False,
+ "last_message_id": 1,
+ "bitrate": 1337,
+ "user_limit": 25,
}
state = unittest.mock.MagicMock()
guild = unittest.mock.MagicMock()
@@ -360,10 +360,10 @@ class MockTextChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):
spec_set = text_channel_instance
def __init__(self, **kwargs) -> None:
- default_kwargs = {'id': next(self.discord_id), 'name': 'channel', 'guild': MockGuild()}
+ default_kwargs = {"id": next(self.discord_id), "name": "channel", "guild": MockGuild()}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
- if 'mention' not in kwargs:
+ if "mention" not in kwargs:
self.mention = f"#{self.name}"
@@ -377,10 +377,10 @@ class MockVoiceChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):
spec_set = voice_channel_instance
def __init__(self, **kwargs) -> None:
- default_kwargs = {'id': next(self.discord_id), 'name': 'channel', 'guild': MockGuild()}
+ default_kwargs = {"id": next(self.discord_id), "name": "channel", "guild": MockGuild()}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
- if 'mention' not in kwargs:
+ if "mention" not in kwargs:
self.mention = f"#{self.name}"
@@ -401,16 +401,16 @@ class MockDMChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):
spec_set = dm_channel_instance
def __init__(self, **kwargs) -> None:
- default_kwargs = {'id': next(self.discord_id), 'recipient': MockUser(), "me": MockUser(), 'guild': None}
+ default_kwargs = {"id": next(self.discord_id), "recipient": MockUser(), "me": MockUser(), "guild": None}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
# Create CategoryChannel instance to get a realistic MagicMock of `discord.CategoryChannel`
category_channel_data = {
- 'id': 1,
- 'type': discord.ChannelType.category,
- 'name': 'category',
- 'position': 1,
+ "id": 1,
+ "type": discord.ChannelType.category,
+ "name": "category",
+ "position": 1,
}
state = unittest.mock.MagicMock()
@@ -422,26 +422,26 @@ category_channel_instance = discord.CategoryChannel(
class MockCategoryChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):
def __init__(self, **kwargs) -> None:
- default_kwargs = {'id': next(self.discord_id)}
+ default_kwargs = {"id": next(self.discord_id)}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
# Create a Message instance to get a realistic MagicMock of `discord.Message`
message_data = {
- 'id': 1,
- 'webhook_id': 431341013479718912,
- 'attachments': [],
- 'embeds': [],
- 'application': {"id": 4, "description": "A Python Bot", "name": "Python Discord", "icon": None},
- 'activity': 'mocking',
- 'channel': unittest.mock.MagicMock(),
- 'edited_timestamp': '2019-10-14T15:33:48+00:00',
- 'type': 'message',
- 'pinned': False,
- 'mention_everyone': False,
- 'tts': None,
- 'content': 'content',
- 'nonce': None,
+ "id": 1,
+ "webhook_id": 431341013479718912,
+ "attachments": [],
+ "embeds": [],
+ "application": {"id": 4, "description": "A Python Bot", "name": "Python Discord", "icon": None},
+ "activity": "mocking",
+ "channel": unittest.mock.MagicMock(),
+ "edited_timestamp": "2019-10-14T15:33:48+00:00",
+ "type": "message",
+ "pinned": False,
+ "mention_everyone": False,
+ "tts": None,
+ "content": "content",
+ "nonce": None,
}
state = unittest.mock.MagicMock()
channel = unittest.mock.MagicMock()
@@ -470,13 +470,13 @@ class MockContext(CustomMockMixin, unittest.mock.MagicMock):
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
- self.me = kwargs.get('me', MockMember())
- self.bot = kwargs.get('bot', MockBot())
- self.guild = kwargs.get('guild', MockGuild())
- self.author = kwargs.get('author', MockMember())
- self.channel = kwargs.get('channel', MockTextChannel())
- self.message = kwargs.get('message', MockMessage())
- self.invoked_from_error_handler = kwargs.get('invoked_from_error_handler', False)
+ self.me = kwargs.get("me", MockMember())
+ self.bot = kwargs.get("bot", MockBot())
+ self.guild = kwargs.get("guild", MockGuild())
+ self.author = kwargs.get("author", MockMember())
+ self.channel = kwargs.get("channel", MockTextChannel())
+ self.message = kwargs.get("message", MockMessage())
+ self.invoked_from_error_handler = kwargs.get("invoked_from_error_handler", False)
class MockInteraction(CustomMockMixin, unittest.mock.MagicMock):
@@ -489,13 +489,13 @@ class MockInteraction(CustomMockMixin, unittest.mock.MagicMock):
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
- self.me = kwargs.get('me', MockMember())
- self.client = kwargs.get('client', MockBot())
- self.guild = kwargs.get('guild', MockGuild())
- self.user = kwargs.get('user', MockMember())
- self.channel = kwargs.get('channel', MockTextChannel())
- self.message = kwargs.get('message', MockMessage())
- self.invoked_from_error_handler = kwargs.get('invoked_from_error_handler', False)
+ self.me = kwargs.get("me", MockMember())
+ self.client = kwargs.get("client", MockBot())
+ self.guild = kwargs.get("guild", MockGuild())
+ self.user = kwargs.get("user", MockMember())
+ self.channel = kwargs.get("channel", MockTextChannel())
+ self.message = kwargs.get("message", MockMessage())
+ self.invoked_from_error_handler = kwargs.get("invoked_from_error_handler", False)
attachment_instance = discord.Attachment(data=unittest.mock.MagicMock(id=1), state=unittest.mock.MagicMock())
@@ -543,10 +543,10 @@ class MockMessage(CustomMockMixin, unittest.mock.MagicMock):
spec_set = message_instance
def __init__(self, **kwargs) -> None:
- default_kwargs = {'attachments': []}
+ default_kwargs = {"attachments": []}
super().__init__(**collections.ChainMap(kwargs, default_kwargs))
- self.author = kwargs.get('author', MockMember())
- self.channel = kwargs.get('channel', MockTextChannel())
+ self.author = kwargs.get("author", MockMember())
+ self.channel = kwargs.get("channel", MockTextChannel())
class MockInteractionMessage(MockMessage):
@@ -556,10 +556,9 @@ class MockInteractionMessage(MockMessage):
Instances of this class will follow the specifications of `discord.InteractionMessage` instances. For more
information, see the `MockGuild` docstring.
"""
- pass
-emoji_data = {'require_colons': True, 'managed': True, 'id': 1, 'name': 'hyperlemon'}
+emoji_data = {"require_colons": True, "managed": True, "id": 1, "name": "hyperlemon"}
emoji_instance = discord.Emoji(guild=MockGuild(), state=unittest.mock.MagicMock(), data=emoji_data)
@@ -574,10 +573,10 @@ class MockEmoji(CustomMockMixin, unittest.mock.MagicMock):
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
- self.guild = kwargs.get('guild', MockGuild())
+ self.guild = kwargs.get("guild", MockGuild())
-partial_emoji_instance = discord.PartialEmoji(animated=False, name='guido')
+partial_emoji_instance = discord.PartialEmoji(animated=False, name="guido")
class MockPartialEmoji(CustomMockMixin, unittest.mock.MagicMock):
@@ -590,7 +589,7 @@ class MockPartialEmoji(CustomMockMixin, unittest.mock.MagicMock):
spec_set = partial_emoji_instance
-reaction_instance = discord.Reaction(message=MockMessage(), data={'me': True}, emoji=MockEmoji())
+reaction_instance = discord.Reaction(message=MockMessage(), data={"me": True}, emoji=MockEmoji())
class MockReaction(CustomMockMixin, unittest.mock.MagicMock):
@@ -605,8 +604,8 @@ class MockReaction(CustomMockMixin, unittest.mock.MagicMock):
def __init__(self, **kwargs) -> None:
_users = kwargs.pop("users", [])
super().__init__(**kwargs)
- self.emoji = kwargs.get('emoji', MockEmoji())
- self.message = kwargs.get('message', MockMessage())
+ self.emoji = kwargs.get("emoji", MockEmoji())
+ self.message = kwargs.get("message", MockMessage())
user_iterator = unittest.mock.AsyncMock()
user_iterator.__aiter__.return_value = _users
diff --git a/tests/test_base.py b/tests/test_base.py
index 365805a71..f1fb1a514 100644
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -30,15 +30,19 @@ class LoggingTestCaseTests(unittest.TestCase):
r"1 logs of DEBUG or higher were triggered on root:\n"
r'<LogRecord: tests\.test_base, [\d]+, .+[/\\]tests[/\\]test_base\.py, [\d]+, "Log!">'
)
- with self.assertRaisesRegex(AssertionError, msg_regex):
- with LoggingTestCase.assertNotLogs(self, level=logging.DEBUG):
- self.log.debug("Log!")
+ with (
+ self.assertRaisesRegex(AssertionError, msg_regex),
+ LoggingTestCase.assertNotLogs(self, level=logging.DEBUG),
+ ):
+ self.log.debug("Log!")
def test_assert_not_logs_reraises_unexpected_exception_in_managed_context(self):
"""Test if LoggingTestCase.assertNotLogs reraises an unexpected exception."""
- with self.assertRaises(ValueError, msg="test exception"):
- with LoggingTestCase.assertNotLogs(self, level=logging.DEBUG):
- raise ValueError("test exception")
+ with (
+ self.assertRaises(ValueError, msg="test exception"),
+ LoggingTestCase.assertNotLogs(self, level=logging.DEBUG),
+ ):
+ raise ValueError("test exception")
def test_assert_not_logs_restores_old_logging_settings(self):
"""Test if LoggingTestCase.assertNotLogs reraises an unexpected exception."""
@@ -56,9 +60,8 @@ class LoggingTestCaseTests(unittest.TestCase):
def test_logging_test_case_works_with_logger_instance(self):
"""Test if the LoggingTestCase captures logging for provided logger."""
log = get_logger("new_logger")
- with self.assertRaises(AssertionError):
- with LoggingTestCase.assertNotLogs(self, logger=log):
- log.info("Hello, this should raise an AssertionError")
+ with self.assertRaises(AssertionError), LoggingTestCase.assertNotLogs(self, logger=log):
+ log.info("Hello, this should raise an AssertionError")
def test_logging_test_case_respects_alternative_logger(self):
"""Test if LoggingTestCase only checks the provided logger."""
diff --git a/tests/test_helpers.py b/tests/test_helpers.py
index b2686b1d0..fa7d0eb44 100644
--- a/tests/test_helpers.py
+++ b/tests/test_helpers.py
@@ -144,13 +144,13 @@ class DiscordMocksTests(unittest.TestCase):
def test_mocks_allows_access_to_attributes_part_of_spec(self):
"""Accessing attributes that are valid for the objects they mock should succeed."""
mocks = (
- (helpers.MockGuild(), 'name'),
- (helpers.MockRole(), 'hoist'),
- (helpers.MockMember(), 'display_name'),
- (helpers.MockBot(), 'user'),
- (helpers.MockContext(), 'invoked_with'),
- (helpers.MockTextChannel(), 'last_message'),
- (helpers.MockMessage(), 'mention_everyone'),
+ (helpers.MockGuild(), "name"),
+ (helpers.MockRole(), "hoist"),
+ (helpers.MockMember(), "display_name"),
+ (helpers.MockBot(), "user"),
+ (helpers.MockContext(), "invoked_with"),
+ (helpers.MockTextChannel(), "last_message"),
+ (helpers.MockMessage(), "mention_everyone"),
)
for mock, valid_attribute in mocks:
@@ -161,8 +161,8 @@ class DiscordMocksTests(unittest.TestCase):
msg = f"accessing valid attribute `{valid_attribute}` raised an AttributeError"
self.fail(msg)
- @unittest.mock.patch(f'{__name__}.DiscordMocksTests.subTest')
- @unittest.mock.patch(f'{__name__}.getattr')
+ @unittest.mock.patch(f"{__name__}.DiscordMocksTests.subTest")
+ @unittest.mock.patch(f"{__name__}.getattr")
def test_mock_allows_access_to_attributes_test(self, mock_getattr, mock_subtest):
"""The valid attribute test should raise an AssertionError after an AttributeError."""
mock_getattr.side_effect = AttributeError
@@ -184,9 +184,8 @@ class DiscordMocksTests(unittest.TestCase):
)
for mock in mocks:
- with self.subTest(mock=mock):
- with self.assertRaises(AttributeError):
- mock.the_cake_is_a_lie
+ with self.subTest(mock=mock), self.assertRaises(AttributeError):
+ mock.the_cake_is_a_lie # noqa: B018
def test_mocks_use_mention_when_provided_as_kwarg(self):
"""The mock should use the passed `mention` instead of the default one if present."""
@@ -333,9 +332,9 @@ class MockObjectTests(unittest.TestCase):
(helpers.MockBot, "owner_id"),
(helpers.MockContext, "command_failed"),
(helpers.MockMessage, "mention_everyone"),
- (helpers.MockEmoji, 'managed'),
- (helpers.MockPartialEmoji, 'url'),
- (helpers.MockReaction, 'me'),
+ (helpers.MockEmoji, "managed"),
+ (helpers.MockPartialEmoji, "url"),
+ (helpers.MockReaction, "me"),
)
for mock_type, valid_attribute in test_values: