diff --git a/cogs/info.py b/cogs/info.py index 79ad3d2..40a15b0 100644 --- a/cogs/info.py +++ b/cogs/info.py @@ -1,8 +1,10 @@ import os + import disnake import psutil - +from disnake import ApplicationCommandInteraction from disnake.ext import commands + from __init__ import version_info as ver from lib.Comands import determine_prefix from lib.Logger import logger @@ -18,7 +20,7 @@ class BotInfo(commands.Cog, name='Bot Info'): @commands.slash_command(name="info_bot", description='Shows general info about bot') # this is for making a command - async def info_bot(self, inter: disnake.ApplicationCommandInteraction): + async def info_bot(self, inter: ApplicationCommandInteraction): _pid = os.getpid() _process = psutil.Process(_pid) emb = disnake.Embed( diff --git a/lib/CogsPrep.py b/lib/CogsPrep.py index 9b6ef9c..05283f6 100644 --- a/lib/CogsPrep.py +++ b/lib/CogsPrep.py @@ -7,14 +7,11 @@ work_with_cogs: loads, reloads and unloads cogs files """ from os import listdir, rename -from typing import List - -from disnake.ext import commands from .Logger import logger -async def cog_list(fold: str = './cogs') -> List[str]: +async def cog_list(fold: str = './cogs') -> list: cogs_list = [] for _filename in listdir(fold): if _filename.endswith('.py'): @@ -22,11 +19,11 @@ async def cog_list(fold: str = './cogs') -> List[str]: return cogs_list -async def work_with_cogs(what_do, bot: commands.Bot, cog): +async def work_with_cogs(what_do, bot, cog): if isinstance(cog, str): cog = cog.split() for _filename in cog: - if what_do == "load": + if what_do == "lad": bot.load_extension(f'cogs.{_filename}') logger.info(f'Loaded cog {_filename}') elif what_do == 'unload': @@ -37,7 +34,6 @@ async def work_with_cogs(what_do, bot: commands.Bot, cog): logger.info(f'Cog {_filename} reloaded') elif what_do == 'disable': bot.unload_extension(f'cogs.{_filename}') - rename(f'cogs/{_filename}.py', f'cogs/disabled/{_filename}.py') logger.info(f'Cog {_filename} stopped and disabled') elif what_do == 'enable': rename(f'cogs/disabled/{_filename}.py', f'cogs/{_filename}.py') diff --git a/lib/Comands.py b/lib/Comands.py index 8a66794..c4eac96 100644 --- a/lib/Comands.py +++ b/lib/Comands.py @@ -2,6 +2,8 @@ lib.Commands ~~~~~~~~~~~~~~ Some prepare for commands + + """ from json import load, decoder, dump, JSONDecodeError from os import getenv diff --git a/requirements.txt b/requirements.txt index 330d6fb..1a0fe09 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,5 @@ disnake[audio] psutil python-dotenv yandex-music +pytest +pytest-asyncio \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_bot.py b/tests/test_bot.py new file mode 100644 index 0000000..2059b15 --- /dev/null +++ b/tests/test_bot.py @@ -0,0 +1,45 @@ +import tracemalloc + +from disnake import Intents +from disnake.ext import commands + +tracemalloc.start() + +intents = Intents(messages=True, + message_content=True, + ) + + +class Cog(commands.Cog): + @commands.command() + async def my_cmd(self, ctx): + pass + + +class CogTwo(commands.Cog): + async def bot_check(self, ctx) -> bool: + pass + + +class CogThree(commands.Cog): + async def bot_check_once(self, ctx) -> bool: + pass + + +class CogFour(commands.Cog): + async def bot_slash_command_check(self, ctx) -> bool: + pass + + +class CogFive(commands.Cog): + async def can_run(self, ctx) -> bool: + pass + + +def test_bot(): + bot = commands.Bot(command_prefix='$', intents=intents) + bot.add_cog(Cog()) + bot.add_cog(CogTwo()) + bot.add_cog(CogThree()) + bot.add_cog(CogFour()) + bot.add_cog(CogFive()) diff --git a/tests/test_lib_Cog.py b/tests/test_lib_Cog.py new file mode 100644 index 0000000..46e23d5 --- /dev/null +++ b/tests/test_lib_Cog.py @@ -0,0 +1,70 @@ +import asyncio +import inspect +import os +import tracemalloc +from unittest.mock import AsyncMock, patch + +import pytest +from disnake.ext import commands + +from ..lib.Logger import logger + +tracemalloc.start() + +pytest_plugins = ('pytest_asyncio',) + + +def asyncio_run(async_func): + def wrapper(*args, **kwargs): + return asyncio.run(async_func(*args, **kwargs)) + + wrapper.__signature__ = inspect.signature(async_func) # without this, fixtures are not injected + + return wrapper + + +absolute_path = os.path.dirname(__file__) +relative_path = "../cogs" +full_path = os.path.join(absolute_path, relative_path) +return_value = ['cog1', 'cog2'] + +bot = commands.InteractionBot() +logger = logger + + +@pytest.fixture(params=['cog1', 'cog2']) +def mock_cog_list(mocker): + async_mock = AsyncMock() + mocker.patch('discord_bot.lib.CogsPrep.cog_list', return_value=async_mock) + return async_mock + + +@pytest.fixture(params=['load', + 'unload', + 'reload', + 'enable', + 'disable']) +def mock_work_with_cogs(mocker, mock_cog_list): + mock_cog_list.return_value = return_value + result = asyncio.run(mock_cog_list(full_path)) + + async_mock = AsyncMock() + mocker.patch('discord_bot.lib.CogsPrep.work_with_cogs', params=async_mock) + return async_mock + + +@pytest.mark.asyncio +async def test_cog_list(mock_cog_list): + # Assuming there are two .py files in the folder + mock_cog_list.return_value = return_value + result = await mock_cog_list(full_path) + assert result == return_value + + +@patch('discord_bot.lib.CogsPrep.work_with_cogs', return_value=return_value) +@pytest.mark.asyncio +async def test_work_with_cogs(mock_work_with_cogs): + var = mock_work_with_cogs + result = await mock_work_with_cogs() + # Check if the logger was called once with a message indicating that cog1 has been loaded + assert result