Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cogs] Cog model restructure #608

Open
7 of 16 tasks
quachtridat opened this issue Jan 21, 2023 · 0 comments
Open
7 of 16 tasks

[Cogs] Cog model restructure #608

quachtridat opened this issue Jan 21, 2023 · 0 comments
Assignees
Labels
refactor Umbrella label for refactoring efforts

Comments

@quachtridat
Copy link
Member

quachtridat commented Jan 21, 2023

Cog model restructure

Summary

File structure is important for separation of code logic. By splitting logics into separate chunks of code in different code files based on the logic and functionality of the code, we can make our code base easier to understand, follow, and allow for better development and testing experience. A cog is a Python class inheriting redbot.core.commands.Cog, and typically has its core business logics, event handlers, command handlers and instance variables. Instead of having all logics inside the cog class, we can write classes in separate files and let the cog class inherit them.

Event handlers and command handlers are cog instance methods that take specific Python decorators to be hooked to the Ren bot when the cog is loaded. This makes it hard for us to unit test because these methods are transformed into different Python callables, and we cannot invoke them directly. However, by separating cog logic (see details below), we can unit test these methods without worrying so much about decorators.

As we are encouraging and moving towards automated testing for Ren, and as discussed sideband in several Rengineer sessions, this change is necessary and shall be done for all cogs created and maintained by Rengineers. This document proposes a file structure, Python class structure, and a diagram of class inheritance chains that all of our cogs shall follow. The new model should be easy for us to adopt for our existing code.

To-do list

Many of our Ren cogs at the moment are written with all logics staying inside one cog class, making the files long and hard to be unit-tested. Below are our cogs sorted in order of importance (from the most important to the least importance). We should adopt the new structure accordingly, and preferably modify the less important cogs first, and the more important cogs later, to minimize potential disruptions.

Details for the file structure, class structure and inheritance chains to follow are documented here. While this may seem strict and concrete, I believe it’s better to take this as the best approach for the general scheme of file and class structures, and flexibility is still there. If one is unsure where to put a certain class/function/method, most likely discussions need to happen. Then, anything that is worth noting related to this new model can be additionally documented in this document.

@quachtridat quachtridat added the refactor Umbrella label for refactoring efforts label Jan 21, 2023
@quachtridat quachtridat self-assigned this Jan 21, 2023
@quachtridat quachtridat pinned this issue Jan 21, 2023
quachtridat added a commit to quachtridat/Ren that referenced this issue Jan 22, 2023
- Restructure `SlashSync` according to SFUAnime#608. No functional
  changes.
- Remove module docstring for `slashsync.py` as it is already included
  in `__init__.py`.
quachtridat added a commit to quachtridat/Ren that referenced this issue Jan 22, 2023
- Restructure `SlashSync` according to SFUAnime#608. No functional
  changes.
- Remove module docstring for `slashsync.py` as it is already included
  in `__init__.py`.
quachtridat added a commit that referenced this issue Jan 26, 2023
* [SlashSync] Cog model restructure

- Restructure `SlashSync` according to #608. No functional
  changes.
- Remove module docstring for `slashsync.py` as it is already included
  in `__init__.py`.

* [SlashSync] Shorten class names

As per sideband discussions (updated in
https://u.sfuani.me/rencogmodel), the presence of the cog name in
classes other than the cog class is considered redundant.
quachtridat added a commit to Injabie3/lui-cogs-v3 that referenced this issue Jan 26, 2023
- Restructure `SlashSync` according to SFUAnime/Ren#608. No functional
  changes.
- Remove module docstring for `slashsync.py` as it is already included
  in `__init__.py`.
quachtridat added a commit to quachtridat/Ren that referenced this issue Jan 26, 2023
- Restructure `SlashSync` according to SFUAnime#608. No
functional changes.
- Remove redundant imports.
- Remove redundant constant `AVATAR_URL`.
- Sort imports in this order: standard library imports, third-party
  imports, upstream (`redbot`) imports, and lastly, our code.
- Rework enum `Modes` by making it an `Enum`-derived class.
quachtridat added a commit to quachtridat/Ren that referenced this issue Jan 26, 2023
- Restructure `Triggered` according to SFUAnime#608. No functional
  changes.
- Remove redundant imports.
- Remove redundant constant `AVATAR_URL`.
- Sort imports in this order: standard library imports, third-party
  imports, upstream (`redbot`) imports, and lastly, our code.
- Rework enum `Modes` by making it an `Enum`-derived class.
quachtridat added a commit that referenced this issue Jan 29, 2023
* [Triggered] Cog model restructure

- Restructure `Triggered` according to #608. No functional
  changes.
- Remove redundant imports.
- Remove redundant constant `AVATAR_URL`.
- Sort imports in this order: standard library imports, third-party
  imports, upstream (`redbot`) imports, and lastly, our code.
- Rework enum `Modes` by making it an `Enum`-derived class.

* [Triggered] Add type hint in `__init__.py`

Add type hint for kwarg `bot` in `setup()` in `__init__.py`.

* [Triggered] Use `discord.User` type for `user`

Since none of the commands requires the user to be a member, let the
type hint for `user` kwarg in command handlers and commands core be
`discord.User` instead of `discord.Member`.
quachtridat added a commit to Injabie3/lui-cogs-v3 that referenced this issue Jan 29, 2023
- Restructure `Triggered` according to SFUAnime/Ren#608. No functional
  changes.
- Remove redundant imports.
- Remove redundant constant `AVATAR_URL`.
- Sort imports in this order: standard library imports, third-party
  imports, upstream (`redbot`) imports, and lastly, our code.
- Rework enum `Modes` by making it an `Enum`-derived class.
quachtridat added a commit to quachtridat/Ren that referenced this issue Jan 30, 2023
- Restructure `Triggered` according to SFUAnime#608.
  No functional changes.
- Move constants to `constants.py`.
- Remove redundant type hints (e.g., those fully inferrable from the
  return types of called functions).
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 4, 2023
- Restructure `QRChecker` according to SFUAnime#608.
  No functional changes.
- Move constants to `constants.py`.
- Remove redundant type hints (e.g., those fully inferrable from the
  return types of called functions).
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 4, 2023
- Restructure `QRChecker` according to SFUAnime#608.
  No functional changes.
- Move constants to `constants.py`.
- Remove redundant type hints (e.g., those fully inferable from the
  return types of called functions).
quachtridat added a commit that referenced this issue Feb 5, 2023
- Restructure `QRChecker` according to #608.
  No functional changes.
- Move constants to `constants.py`.
- Remove redundant type hints (e.g., those fully inferable from the
  return types of called functions).
quachtridat added a commit to Injabie3/lui-cogs-v3 that referenced this issue Feb 5, 2023
- Restructure `QRChecker` according to SFUAnime/Ren#608.
  No functional changes.
- Move constants to `constants.py`.
- Remove redundant type hints (e.g., those fully inferable from the
  return types of called functions).
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 5, 2023
Restructure cog `ServerManage` according to SFUAnime#608 by:
- Moving all methods from class `ServerManage` to `Core`
- Decoupling core command handling method calls from Red's command
  handler decorators by splitting `commands.py` into `commandsCore.py`
  and `commandHandlers.py`.
- Dropping `ServerManageMeta` metaclass.

No function changes are made in this commit.
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 5, 2023
Restructure cog `ServerManage` according to SFUAnime#608 by:
- Moving all methods from class `ServerManage` to `Core`
- Decoupling core command handling method calls from Red's command
  handler decorators by splitting `commands.py` into `commandsCore.py`
  and `commandHandlers.py`
- Dropping `ServerManageMeta` metaclass

No function changes are made in this commit.
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 9, 2023
Restructure cog `ServerManage` according to SFUAnime#608 by:
- Moving all methods from class `ServerManage` to `Core`
- Decoupling core command handling method calls from Red's command
  handler decorators by splitting `commands.py` into `commandsCore.py`
  and `commandHandlers.py`
- Dropping `ServerManageMeta` metaclass

No function changes are made in this commit.
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 9, 2023
Restructure cog `Respects` according to SFUAnime#608. No functional
changes.
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 9, 2023
Restructure cog `Respects` according to SFUAnime#608. No functional
changes.
quachtridat added a commit that referenced this issue Feb 13, 2023
* [ServerManage] Cog model restructure

Restructure cog `ServerManage` according to #608 by:
- Moving all methods from class `ServerManage` to `Core`
- Decoupling core command handling method calls from Red's command
  handler decorators by splitting `commands.py` into `commandsCore.py`
  and `commandHandlers.py`
- Dropping `ServerManageMeta` metaclass

No function changes are made in this commit.

* [ServerManage] Make logger use YYYY-MM-DD date fmt

Address review comment
#620 (comment)
quachtridat added a commit to Injabie3/lui-cogs-v3 that referenced this issue Feb 13, 2023
Restructure cog `ServerManage` according to SFUAnime/Ren#608 by:
- Moving all methods from class `ServerManage` to `Core`
- Decoupling core command handling method calls from Red's command
  handler decorators by splitting `commands.py` into `commandsCore.py`
  and `commandHandlers.py`
- Dropping `ServerManageMeta` metaclass

No function changes are made in this commit.
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 18, 2023
Restructure cog `YOURLSClient` according to SFUAnime#608. No
functional changes. Constants are moved to `constants.py`.
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 19, 2023
Restructure cog `YOURLSClient` according to SFUAnime#608. No
functional changes. Constants are moved to `constants.py`.
quachtridat added a commit that referenced this issue Feb 26, 2023
* [YOURLSClient] Cog model restructure

Restructure cog `YOURLSClient` according to #608. No
functional changes. Constants are moved to `constants.py`.

* [YOURLSClient] Use logging date format YYYY-MM-DD

Use logging date format YYYY-MM-DD instead of DD-MM-YYYY.

* [YOURLSClient] Add docstring to `YOURLS` class

Instead of doing `pass`, a docstring is attached to `YOURLS` class.
It is used in the help string of the cog name if we run the `[p]help
yourls` command.
quachtridat added a commit to Injabie3/lui-cogs-v3 that referenced this issue Feb 26, 2023
Restructure cog `YOURLSClient` according to SFUAnime/Ren#608. No
functional changes. Constants are moved to `constants.py`.
quachtridat added a commit to quachtridat/Ren that referenced this issue Feb 26, 2023
Restructure cog `Heartbeat` according to SFUAnime#608. No functional
changes.

Constants are moved to `constants.py`.
quachtridat added a commit that referenced this issue Mar 7, 2023
* [Respects] Cog model restructure

Restructure cog `Respects` according to #608. No functional
changes.

* [Respects] Fix `black`-reformatted split strings

* [Respects] Use YYYY-MM-DD date format for logging
quachtridat added a commit to Injabie3/lui-cogs-v3 that referenced this issue Mar 7, 2023
Restructure cog `Respects` according to SFUAnime/Ren#608. No functional
changes.
quachtridat added a commit to quachtridat/Ren that referenced this issue Mar 13, 2023
Restructure cog `Heartbeat` according to SFUAnime#608. No functional
changes.

Constants are moved to `constants.py`.
quachtridat added a commit that referenced this issue Apr 2, 2023
* [Heartbeat] Cog model restructure

Restructure cog `Heartbeat` according to #608. No functional
changes.

Constants are moved to `constants.py`.

* [Heartbeat] Add unit tests for `CommandsCore`

This commit adds unit tests for all methods in `CommandsCore`.

* [Heartbeat] Add unit tests for `Core`

This commit adds unit tests for the main loop (i.e., method `_loop`) in
class `Core`.

* [Heartbeat] Add pytest fixtures

Add relevant pytest fixtures to be used for refactoring
`testCommandsCore` and `testCore`.

* [Heartbeat] Refactor `testCommandsCore.py`

- Use avaliable pytest fixtures.
- Add function `contentFromMockContextSend` to contain the logic
  obtaining `content of mock `Context.send`.

* [Heartbeat] Refactor `testCore.py`

- Use available pytest fixtures `event_loop` and `cogHeartbeat`.
- Remove `red.remove_cog()` call because it is not a part of `_loop`
  test.

* [Heartbeat] Mock out `asyncio.sleep` in `testCore`

Since we do not care about whether the real time sleep duration is as
expected, but rather the fact that the loop has retried a certain number
of times as expected, and that the loop fails after receiving bad
respones, thus, `asyncio.sleep` can be mock-patched so that we do not
have to wait in real time for the test to complete.

* [Heartbeat] Use `maxFailedPings` var in `testCore`

Instead of asserting with the number literal equal to `maxFailedPings`,
use the variable `maxFailedPings` itself. Minor test fix.

* [Heartbeat] Fix a docstring in `testCommandsCore`

Fix the docstring of `contentFromMockContextSend` just so the mentioned
argument name matches the actual name of the argument of the said
function.

* [Heartbeat] Mock out background loop in fixture

Mock out `Core._loop` in `cogHeartbeat` fixture to avoid the background
loop being run. This allows us to say that the background loop does not
run upon cog instantiation via the fixture, rather than cancelling the
background task knowing that the background loop might have run for a
bit. The latter poses uncertainty and is not preferable.
quachtridat added a commit to Injabie3/lui-cogs-v3 that referenced this issue Apr 2, 2023
Restructure cog `Heartbeat` according to SFUAnime/Ren#608. No functional
changes.

Constants are moved to `constants.py`.
quachtridat added a commit to quachtridat/Ren that referenced this issue Dec 11, 2023
Restructure cog `Birthday` according to SFUAnime#608. No
functional changes expected.

Command handlers that utilize the `MonthDayConverter` now perform a
"typing cast" to inform static type checkers that the birthday being
passed to the command handlers as `MonthDayConverter` will be
subsequently passed to the corresponding methods in `CommandsCore` as
type `datetime.datetime` instead of `MonthDayConverter`. Note that
Python typing cast does not change or restrict any functionalities
because it is only information to static type checkers.

`MonthDayConverter` now exposes the `InputType` and `OutputType` as type
aliases so that code utilizes the converted can be type-hinted better.

The birth year constant 2020 is moved to `constants.py` as
`DEFAULT_YEAR`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor Umbrella label for refactoring efforts
Projects
None yet
Development

No branches or pull requests

1 participant