Skip to content

Commit

Permalink
And more testing
Browse files Browse the repository at this point in the history
  • Loading branch information
davfsa committed Oct 7, 2020
1 parent a611278 commit eaaca65
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 26 deletions.
5 changes: 3 additions & 2 deletions hikari/internal/aio.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@ async def all_of(
await f
except asyncio.CancelledError:
pass

gatherer.cancel()
try:
gatherer.cancel()
await gatherer
await gatherer # pragma: no cover - I tried everything to make this work with coverage, but no luck :(
except asyncio.CancelledError:
pass
28 changes: 14 additions & 14 deletions hikari/internal/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,20 @@ def iso8601_datetime_string_to_datetime(datetime_str: str) -> datetime.datetime:
return datetime.datetime.fromisoformat(datetime_str)


# MyPy complains if this is not present, so only do this if MyPy isn't running!
if not typing.TYPE_CHECKING:
try:
# CISO8601 is around 600x faster than modules like dateutil, which is
# going to be noticable on big bots where you are parsing hundreds of
# thousands of "joined_at" fields on users on startup.
import ciso8601

# Discord appears to actually use RFC-3339, which isn't a true ISO-8601 implementation,
# but somewhat of a subset with some edge cases.
# See https://tools.ietf.org/html/rfc3339#section-5.6
iso8601_datetime_string_to_datetime = ciso8601.parse_rfc3339 # noqa: F811 redefined function
except ImportError:
pass
try: # pragma: no cover
# CISO8601 is around 600x faster than modules like dateutil, which is
# going to be noticable on big bots where you are parsing hundreds of
# thousands of "joined_at" fields on users on startup.
#
# ciso8601 doesn't have typing available, so ignore it.
import ciso8601 # type: ignore[import]

# Discord appears to actually use RFC-3339, which isn't a true ISO-8601 implementation,
# but somewhat of a subset with some edge cases.
# See https://tools.ietf.org/html/rfc3339#section-5.6
iso8601_datetime_string_to_datetime = ciso8601.parse_rfc3339 # noqa: F811 - Redefined function
except ImportError:
pass


def discord_epoch_to_datetime(epoch: int, /) -> datetime.datetime:
Expand Down
3 changes: 1 addition & 2 deletions pipelines/pytest.nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Py.test integration."""
import os
"""Pytest integration."""
import shutil

from pipelines import config
Expand Down
3 changes: 3 additions & 0 deletions tests/hikari/events/test_message_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ def test_guild_property(self, event):
assert result is event.app.cache.get_guild.return_value
event.app.cache.get_guild.assert_called_once_with(342123123)

def test_author_property(self, event):
assert event.author is event.message.member


class TestGuildMessageUpdateEvent:
@pytest.fixture()
Expand Down
15 changes: 8 additions & 7 deletions tests/hikari/impl/test_entity_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -1442,13 +1442,13 @@ def test_deserialize_member_when_guild_id_already_in_role_array(
# While this isn't a legitimate case based on the current behaviour of the API, we still want to cover this
# to ensure no duplication occurs.
member_payload = {**member_payload, "guild_id": "76543325"}
member_payload["role_ids"] = [11111, 22222, 76543325, 33333, 44444]
member_payload["roles"] = [11111, 22222, 76543325, 33333, 44444]
member = entity_factory_impl.deserialize_member(member_payload)
assert member.app is mock_app
assert member.guild_id == 76543325
assert member.user == entity_factory_impl.deserialize_user(user_payload)
assert member.nickname == "foobarbaz"
assert member.role_ids == [11111, 22222, 33333, 44444, 76543325]
assert member.role_ids == [11111, 22222, 76543325, 33333, 44444]
assert member.joined_at == datetime.datetime(2015, 4, 26, 6, 26, 56, 936000, tzinfo=datetime.timezone.utc)
assert member.premium_since == datetime.datetime(2019, 5, 17, 6, 26, 56, 936000, tzinfo=datetime.timezone.utc)
assert member.is_deaf is False
Expand Down Expand Up @@ -2459,18 +2459,19 @@ def test_deserialize_partial_message(

def test_deserialize_partial_message_with_partial_fields(self, entity_factory_impl, message_payload):
message_payload["edited_timestamp"] = None
message_payload["member"] = None
partial_message = entity_factory_impl.deserialize_partial_message(message_payload)
assert partial_message.edited_timestamp is None
assert partial_message.guild_id is not None
assert partial_message.member is None

def test_deserialize_partial_message_with_unset_fields(self, entity_factory_impl, mock_app, user_payload):
partial_message = entity_factory_impl.deserialize_partial_message(
{"id": 123, "channel_id": 456, "author": user_payload}
)
def test_deserialize_partial_message_with_unset_fields(self, entity_factory_impl, mock_app):
partial_message = entity_factory_impl.deserialize_partial_message({"id": 123, "channel_id": 456})
assert partial_message.app is mock_app
assert partial_message.id == 123
assert partial_message.channel_id == 456
assert partial_message.guild_id is None
assert partial_message.author is not None
assert partial_message.author is None
assert partial_message.member is None
assert partial_message.content is undefined.UNDEFINED
assert partial_message.timestamp is undefined.UNDEFINED
Expand Down
11 changes: 11 additions & 0 deletions tests/hikari/internal/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,16 @@ def test_add_all_inserts_items(self, start_with, add_items, expect):
# then
assert sfs._ids.tolist() == expect

def test_add_all_when_empty_collection_passed(self):
started = [0, 122]
# given
sfs = collections.SnowflakeSet()
sfs._ids.extend(started)
# when
sfs.add_all([])
# then
assert sfs._ids.tolist() == started

def test_clear_empties_buffer(self):
# given
sfs = collections.SnowflakeSet(123, 121, 999991, 121, 121, 124, 120)
Expand Down Expand Up @@ -409,6 +419,7 @@ def test_discard(self, start_with, discard, expect):
([9, 18, 27, 36, 45, 54, 63], 63, True),
([9, 18, 27, 36, 45, 54, 63], 64, False),
([9, 18, 27, 36, 45, 54, 63], 72, False),
([12], "12", False),
],
)
def test_contains(self, start_with, look_for, expect):
Expand Down
10 changes: 10 additions & 0 deletions tests/hikari/internal/test_ux.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,16 @@ def test_when_CLICOLOR_and_is_a_tty(self):
assert getenv.call_count == 2
getenv.assert_has_calls([mock.call("CLICOLOR_FORCE", "0"), mock.call("CLICOLOR", "0")])

@pytest.mark.parametrize("colorterm", ["truecolor", "24bit", "TRUECOLOR", "24BIT"])
def test_when_COLORTERM_has_correct_value(self, colorterm):
with mock.patch.object(os, "getenv", side_effect=["0", "0", colorterm]) as getenv:
assert ux.supports_color(True, False) is True

assert getenv.call_count == 3
getenv.assert_has_calls(
[mock.call("CLICOLOR_FORCE", "0"), mock.call("CLICOLOR", "0"), mock.call("COLORTERM", "")]
)

def test_when_plat_is_Pocket_PC(self):
stack = contextlib.ExitStack()
getenv = stack.enter_context(mock.patch.object(os, "getenv", return_value="0"))
Expand Down
3 changes: 3 additions & 0 deletions tests/hikari/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@
# Mixing ints and floats
("1.0, 1.0, 3", r'Expected exactly 1 decimal point "\." in blue channel'),
("1.0 2 3", r'Expected exactly 1 decimal point "\." in green channel'),
# Weird decimals out of range
("0.1 2. 0.5", r"Expected green channel to be a decimal in the inclusive range of 0.0 and 1.0"),
# Too many int digits
("0 25600 200", r"Expected 1 to 3 digits for green channel, got 5"),
# Ints out of range
Expand Down Expand Up @@ -271,6 +273,7 @@ def test_Color_to_bytes(self):
@pytest.mark.parametrize(
("input", "expected_result"),
[
(colors.Color(0xFF051A), colors.Color(0xFF051A)),
(0xFF051A, colors.Color(0xFF051A)),
((1, 0.5, 0), colors.Color(0xFF7F00)),
([0xFF, 0x5, 0x1A], colors.Color(0xFF051A)),
Expand Down
6 changes: 6 additions & 0 deletions tests/hikari/test_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
from hikari import intents


class TestShardCloseCode:
@pytest.mark.parametrize(("code", "expected"), [(1000, True), (1001, True), (4000, False), (4014, False)])
def test_is_standard_property(self, code, expected):
assert errors.ShardCloseCode(code).is_standard is expected


class TestGatewayError:
@pytest.fixture()
def error(self):
Expand Down
16 changes: 15 additions & 1 deletion tests/hikari/test_event_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@
from tests.hikari import hikari_test_helpers


@pytest.mark.asyncio
async def test__generate_weak_listener_when_method_is_None():
def test():
return None

call_weak_method = event_stream._generate_weak_listener(test)

with pytest.raises(
TypeError,
match=r"dead weak referenced subscriber method cannot be executed, try actually closing your event streamers",
):
await call_weak_method(None)


class TestStreamer:
@pytest.fixture(scope="module")
def stub_streamer(self):
Expand Down Expand Up @@ -190,7 +204,7 @@ def test___del___for_active_stream(self):
streamer._event_type = events.Event
streamer._active = True

with mock.patch.object(asyncio, "ensure_future", return_value=mock_coroutine):
with mock.patch.object(asyncio, "ensure_future", side_effect=RuntimeError):
with unittest.TestCase().assertLogs("hikari", level=logging.WARNING) as logging_watcher:
del streamer

Expand Down
15 changes: 15 additions & 0 deletions tests/hikari/test_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ def test_str_operator(self):
assert str(premium_type) == "NITRO_CLASSIC"


class TestPartialUser:
@pytest.fixture()
def obj(self):
# ABC, so must be stubbed.
return hikari_test_helpers.mock_class_namespace(users.User, slots_=False)()

@pytest.mark.asyncio
async def test_fetch_self(self, obj):
obj.id = 123
obj.app = mock.AsyncMock()

assert await obj.fetch_self() is obj.app.rest.fetch_user.return_value
obj.app.rest.fetch_user.assert_awaited_once_with(user=123)


class TestUser:
@pytest.fixture()
def obj(self):
Expand Down

0 comments on commit eaaca65

Please sign in to comment.