| Commit message (Collapse) | Author | Age | Lines |
| |\ |
|
| | | |
|
| | |
| |
| |
| | |
Closes #604.
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
https://github.com/python-discord/bot/issues/628
https://github.com/python-discord/bot/issues/339
This commit introduces several changes to the output of the `!user`
command for moderation staff. The output for regular users has not
changed.
Changes:
- When issued in a moderation channel, the infraction count of the
user will now be broken down by type as described in #339. This
allows moderators to get a quicker overview of someone's history by
providing more information. The command will display the total
number of infractions per type, with the number of active
infractions in parentheses behind it if there are any.
This change also means that there no longer a need for the `hidden`
parameter: When issued in a moderation channel, hidden infractions
are included by default; when issued outside of a mod channel, the
command will be equal to what a regular user would get.
In addition to broken-down infraction info, the command now also
shows information about the nominations of a user when it's issued
inside of a moderation channel.
- The code has been refactored to smaller units that take care of a
single action to make unit testing easier. I have included tests
that cover the command and all of the new helper methods. Tests for
the other methods/commands in the cog will be added in the specific
issue calling for tests for this cog (#581)
This commit closes #628 and closes #339
|
| |
|
|
|
|
|
|
|
|
| |
I accidentally forgot to update the docstring of `CustomMockMixin`,
which changed quite dramatically in scope with the last commit. This
commit remedies that.
In addition, I inadvertently forgot to remove the `child_mock_type`
class attribute from `MockRole`. Since it uses the default value, it
is no longer necessary to specify it in the child class as well.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I have enhanced the custom mocks defined in `tests/helpers.py` in a
couple of important ways.
1. Automatically create AsyncMock attributes using `inspect`
Our previous approach, hard-coding AsynckMock attributes for all the
coroutine function methods defined for the class we are trying to
mock is prone to human error and not resilient against changes
introduced in updates of the library we are using.
Instead, I have now created a helper method in our `CustomMockMixin`
(formerly `GetChildMockMixin`) that automatically inspects the spec
instance we've passed for `coroutine functions` using the `inspect`
module. It then sets the according attributes with instances of the
AsyncMock class.
There is one caveat: `discord.py` very rarely defines regular methods
that return a coroutine object. Since the returned coroutine should
still be awaited, these regular methods should also be mocked with an
AsyncMock. However, since they are regular methods, `inspect` does
not detect them and they have to be added manually. (The only case of
this I've found so far is `Client.wait_for`.)
2. Properly set special attributes using `kwargs.get`
As we want attributes that point to other discord.py objects to use
our custom mocks (.e.g, `Message.author` should use `MockMember`),
the `__init__` method of our custom mocks make sure to correctly
instantiate these attributes.
However, the way we previously did that means we can't instantiate
the custom mock with a mock instance we provide, since this special
instantiation would overwrite the custom object we'd passed. I've
solved this by using `kwargs.get`, with a new mock as the default
value. This makes sure we only create a new mock if we didn't pass
a custom one:
```py
class MockMesseage:
def __init__(self, **kwargs):
self.author = kwargs.get('author', MockMember())
```
As you can see, we will only create a new MockMember if we did not
pass an `author` argument.
3. Factoring out duplicate lines
Since our `CustomMockMixin` is a parent to all of our custom mock
types, it makes sense to use it to factor out common code of all of
our custom mocks.
I've made the following changes:
- Set a default child mock type in the mixin.
- Create an `__init__` that takes care of the `inspect` of point 1
This means we won't have to repeat this in all of the child classes.
4. Three new Mock types: Emoji, PartialEmoji, and Reaction
I have added three more custom mocks:
- MockEmoji
- MockPartialEmoji
- MockReaction
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- https://docs.python.org/3/library/unittest.mock.html
We previously used an override of the `__new__` method to prevent our
custom mock types from instantiating their children with their own
type instead of a general mock type like `MagicMock` or `Mock`.
As it turns out, the Python documentation suggests another method of
doing this that does not involve overriding `__new__`. This commit
implements this new method to make sure we're using the idiomatic way
of handling this.
The suggested method is overriding the `_get_child_mock` method in
the subclass. To make our code DRY, I've created a mixin that should
come BEFORE the mock type we're subclassing in the MRO.
---
In addition, I have also added this new mixin to our `AsyncMock`
class to make sure that its `__call__` method returns a proper mock
object after it has been awaited. This makes sure that subsequent
attribute access on the returned object is mocked as expected.
|
| | |
|
| |\ |
|
| | |\
| | |
| | |
| | |
| | | |
Resolving merge conflicts from master in `.gitignore` and
`tests/helpers.py`.
|
| | | | |
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | | |
This commit replaces the standard MagicMocks by our specialized mocks
for discord.py objects. It also adds the missing `channel` attribute
to the `tests.helpers.MockMessage` mock and moves the file to the
correct folder.
|
| | | | |
|
| | | | |
|
| | |\ \
| | | |
| | | |
| | | | |
unittest-migration
|
| | | | |
| | | |
| | | |
| | | |
| | | | |
Migrates the `test_constants.py` file to unittest. As with the pytest
version, there is not yet support to test container types.
|
| | |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This commit introduces some new Mock-types to the already existing
Mock-types for discord.py objects. The total list is now:
- MockGuild
- MockRole
- MockMember
- MockBot
- MockContext
- MockTextChannel
- MockMessage
In addition, I've added all coroutines in the documentation for these
discord.py objects as `AsyncMock` attributes to ease testing. Tests
ensure that the attributes set for the Mocks exist for the actual
discord.py objects as well.
|
| | | | |
|
| | |\ \ |
|
| | | | | |
|
| | | | | |
|
| | | | | |
|
| | |\ \ \ |
|
| | | | | | |
|
| | | |/ / |
|
| | | | | |
|
| | |\ \ \ |
|
| | | | | | |
|
| | | |/ / |
|
| | |\ \ \ |
|
| | | | | | |
|
| | | |/ / |
|
| | |\ \ \ |
|
| | | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
I've added a `self.subTest` to the `name` loop so we still test and
get output for all names in the list if one of them fails the test.
In addition, I've moved it to the `tests/bot/resources` subdirectory.
|
| | | |/ / |
|
| | |/ / |
|
| | | | |
|
| | | |
| | |
| | |
| | |
| | | |
I've made some textual changes to the testing guidelines defined
in README.md.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
I have change the testrunner from `unittest` to `xmlrunner` in the
Azure pipeline to be able to publish our test results on Azure. This
is the same runner as `site` uses to generate XML reports.
In addition, I've cleaned up some small mistakes in docstrings and
`README.md`.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
I forgot to test some aspects of the `tests.base` module, including
some branches of the `self.assertNotLogs` method. I've corrected that
by including a couple of tests.
I also removed the test result publishing from the Azure pipeline,
since I've not configured an XML test runner yet. The coverage report
is still published, of course and test output will be available in
standard out, so information is readily available.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
After a discussion in the core developers channel, we have decided to
migrate from `pytest` to `unittest` as the testing framework. This
commit sets up the repository to use `unittest` and migrates the
first couple of tests files to the new framework.
What I have done to migrate to `unitest`:
- Removed all `pytest` test files, since they are incompatible.
- Removed `pytest`-related dependencies from the Pipfile.
- Added `coverage.py` to the Pipfile dev-packages and relocked.
- Added convenience scripts to Pipfile for running the test suite.
- Adjust to `azure-pipelines.yml` to use `coverage.py` and `unittest`.
- Migrated four test files from `pytest` to `unittest` format.
In addition, I've added five helper Mock subclasses in `helpers.py`
and created a `TestCase` subclass in `base.py` to add an assertion
that asserts that no log records were logged within the context of
the context manager. Obviously, these new utility functions and
classes are fully tested in their respective `test_` files.
Finally, I've started with an introductory guide for writing tests
for our bot in `README.md`.
|
| | |/
|/|
| |
| | |
- Update test cases for in_channel_check
|
| | | |
|
| |\| |
|
| | |\ |
|
| | | |\ |
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
As we have decided that the converter should return naive datetime
objects, we should explicitly test that datetime strings with a
timezone offset are still converted to a naive datetime object. I
have done this by adding a `tzinfo is None` assertion.
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The parser we use, `dateutil.parsers.isoparse` returns a timezone-
aware or timezone-unaware `datetime` object depending on whether or
not the datetime string included a timezone offset specification.
Since we can't compare tz-aware objects to tz-unaware objects it's
better to make sure our converter is consistent in the type it will
return.
For now, I've chosen to return tz-unaware datetime objects, since
`discord.py` also returns tz-unaware datetime objects when accessing
datetime-related attributes of objects. Since we're likely to compare
"our" datetime objects to discord.py-provided datetime objects, I
think that's the most parsimonious option for now.
Note: It's probably a good idea to open a larger discussion about
using timezone-aware datetime objects throughout the library to
avoid a UTC-time being interpreted as localtime. This will require
a broader discussion than this commit/PR allows, though.
|
| | | | |
| | | |
| | | | |
Co-Authored-By: Mark <[email protected]>
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Related to https://github.com/python-discord/bot/issues/458
This commit adds a converter that automatically parses ISO-formatted
datetime strings and returns a `datetime.datetime` object. It uses
`dateutil.parser.isoparse` to do the heavy lifting, so it supports
the same formats as this method.
In addition, I have added tests that ensure that it accepts certain
formats and added a description of these 'guaranteed' formats to the
`ISODate.convert` docstring.
This commit should make it easy to implement #485
|