diff --git a/.github/workflows/tests.inactive b/.github/workflows/test.yml similarity index 70% rename from .github/workflows/tests.inactive rename to .github/workflows/test.yml index 2d81893..1bc6a28 100644 --- a/.github/workflows/tests.inactive +++ b/.github/workflows/test.yml @@ -11,8 +11,6 @@ on: env: POSTGRES_URI: postgresql://postgres:postgres@localhost:5432/postgres - TARGET_REVISION: rev5 - jobs: Test: @@ -21,7 +19,7 @@ jobs: services: postgres: - image: no767/akari-pg:edge + image: postgres:16 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres @@ -43,11 +41,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - # - name: Setup Codecov Uploader - # run: | - # curl -Os https://uploader.codecov.io/latest/linux/codecov - # chmod +x codecov - # ./codecov + - name: Install pg_trgm + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends postgresql-client + psql $POSTGRES_URI -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;' - name: Set up Python id: setup-python @@ -63,11 +61,4 @@ jobs: run: | RAW_PYTHON_VERSION=${{ matrix.version }} PYTHON_VERSION=$(echo $RAW_PYTHON_VERSION | sed 's/\.//') - tox -e $PYTHON_VERSION - - # - name: Upload coverage to Codecov - # uses: codecov/codecov-action@v3 - # with: - # files: ./coverage.xml - # env: - # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file + tox -e $PYTHON_VERSION \ No newline at end of file diff --git a/bot/migrations.py b/bot/migrations.py index 5897309..44ce7db 100644 --- a/bot/migrations.py +++ b/bot/migrations.py @@ -1,4 +1,5 @@ import asyncio +import os import re import traceback from functools import wraps @@ -12,13 +13,18 @@ from libs.utils.config import CatherineConfig from typing_extensions import Self -path = Path(__file__).parent / "config.yml" -config = CatherineConfig(path) +# If we can't load the configuration, then let's look for the environment variable +try: + path = Path(__file__).parent / "config.yml" + config = CatherineConfig(path) + POSTGRES_URI = config["postgres"]["uri"] +except KeyError: + POSTGRES_URI = os.environ["POSTGRES_URI"] + BE = TypeVar("BE", bound=BaseException) REVISION_FILE = re.compile(r"(?PV)(?P\d+)__(?P.+).sql") -POSTGRES_URI = config["postgres"]["uri"] CREATE_MIGRATIONS_TABLE = """ CREATE TABLE IF NOT EXISTS migrations ( diff --git a/bot/tests/conftest.py b/bot/tests/conftest.py new file mode 100644 index 0000000..2d5f4a0 --- /dev/null +++ b/bot/tests/conftest.py @@ -0,0 +1,75 @@ +import glob +import os +from pathlib import Path + +import aiohttp +import asyncpg +import discord +import discord.ext.commands as commands +import discord.ext.test as dpytest +import pytest_asyncio +from libs.utils.config import CatherineConfig + +TESTING_EXTENSIONS = [ + "cogs.dictionary", + "cogs.hrt", + "cogs.pride_profiles", + "cogs.pronouns", +] + +CONFIG_PATH = Path(__file__).parents[1] / "config.yml" + + +def load_postgres_uri() -> str: + try: + config = CatherineConfig(CONFIG_PATH) + ideal_conf = config["postgres"]["uri"] + return ideal_conf + except KeyError: + return os.environ["POSTGRES_URI"] + + +class TestBot(commands.Bot): + pool: asyncpg.Pool + session: aiohttp.ClientSession + + def __init__(self, intents: discord.Intents): + super().__init__(command_prefix="!", intents=intents) + + async def close(self) -> None: + await self.session.close() + await self.pool.close() + + async def setup_hook(self) -> None: + self.pool = await asyncpg.create_pool(dsn=load_postgres_uri()) # type: ignore + self.session = aiohttp.ClientSession() + + for extension in TESTING_EXTENSIONS: + await self.load_extension(extension, package="..cogs") + + +@pytest_asyncio.fixture +async def bot(): + intents = discord.Intents.default() + intents.members = True + intents.message_content = True + b = TestBot(intents=intents) + await b._async_setup_hook() + await b.setup_hook() + dpytest.configure(b) + + yield b + + await b.close() + await dpytest.empty_queue() + + +def pytest_sessionfinish(session, exitstatus): + """Code to execute after all tests.""" + + file_list = glob.glob("./dpytest_*.dat") + for file_path in file_list: + try: + os.remove(file_path) + except Exception: + print("Error while deleting file : ", file_path) diff --git a/bot/tests/test_hrt.py b/bot/tests/test_hrt.py new file mode 100644 index 0000000..668c5cf --- /dev/null +++ b/bot/tests/test_hrt.py @@ -0,0 +1,13 @@ +import pytest +from cogs.hrt import HRTConversion + + +@pytest.fixture +def cog(bot) -> HRTConversion: + return HRTConversion(bot) + + +def test_calc_e(cog: HRTConversion): + # In order not to return an exit code 5 from pytest + # we just make an mock test + pass diff --git a/docs/source/guides/dev/contributing.rst b/docs/source/guides/dev/contributing.rst index 77e8bf8..51b9b26 100644 --- a/docs/source/guides/dev/contributing.rst +++ b/docs/source/guides/dev/contributing.rst @@ -103,6 +103,13 @@ Python Version Support Catherine-Chan generally follows `NEP-29 `_. Catherine-Chan is tested against versions supported by NEP-29. +Unit Tests +---------- + +Since `PR #189 `_, unit tests are now used to ensure software +quality. Each feature PR should include unit tests on methods that are relevant to the cog, and features that +can tested if possible. Please see ``bot/tests`` for examples of how to write these tests. + GitHub Contributing Guidelines ----------------------------------- diff --git a/docs/source/guides/dev/setup.rst b/docs/source/guides/dev/setup.rst index a8b7f29..d144383 100644 --- a/docs/source/guides/dev/setup.rst +++ b/docs/source/guides/dev/setup.rst @@ -60,7 +60,7 @@ Local Setup python3 bot/migrations.py Special Configuration Variables ---------------------- +------------------------------- Development Features ^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ Development Features Catherine-Chan includes an development mode allowing for continuous reloading of extensions and library code. Once the file is saved, the module is reloaded and changes can be reflected. This can be enabled -through the ``dev_mode`` key in the configuration file. In addition, +through the ``bot.dev_mode`` key in the configuration file. In addition, Jishaku is bundled with the bot, allowing for easy debugging and faster development. @@ -81,7 +81,7 @@ Prometheus Metrics ^^^^^^^^^^^^^^^^^^ Catherine-Chan also includes an Prometheus endpoint for metrics. -This can enabled through the ``prometheus.enabled`` key. If +This can enabled through the ``bot.prometheus.enabled`` key. If you don't need this feature, feel free to entirely disable it. Disabling this feature does not affect the bot, as the cog responsible for this feature is an extension that can be diff --git a/tests/bot/cogs/__init__.py b/old_tests/bot/cogs/__init__.py similarity index 100% rename from tests/bot/cogs/__init__.py rename to old_tests/bot/cogs/__init__.py diff --git a/tests/bot/cogs/embeds.py b/old_tests/bot/cogs/embeds.py similarity index 100% rename from tests/bot/cogs/embeds.py rename to old_tests/bot/cogs/embeds.py diff --git a/tests/bot/conftest.py b/old_tests/bot/conftest.py similarity index 100% rename from tests/bot/conftest.py rename to old_tests/bot/conftest.py diff --git a/tests/cog_utils/test_commons.py b/old_tests/cog_utils/test_commons.py similarity index 100% rename from tests/cog_utils/test_commons.py rename to old_tests/cog_utils/test_commons.py diff --git a/tests/cog_utils/test_dictionary.py b/old_tests/cog_utils/test_dictionary.py similarity index 100% rename from tests/cog_utils/test_dictionary.py rename to old_tests/cog_utils/test_dictionary.py diff --git a/tests/cog_utils/test_hrt.py b/old_tests/cog_utils/test_hrt.py similarity index 100% rename from tests/cog_utils/test_hrt.py rename to old_tests/cog_utils/test_hrt.py diff --git a/tests/cog_utils/test_profiles.py b/old_tests/cog_utils/test_profiles.py similarity index 100% rename from tests/cog_utils/test_profiles.py rename to old_tests/cog_utils/test_profiles.py diff --git a/tests/cog_utils/test_pronouns.py b/old_tests/cog_utils/test_pronouns.py similarity index 100% rename from tests/cog_utils/test_pronouns.py rename to old_tests/cog_utils/test_pronouns.py diff --git a/tests/cog_utils/test_tonetags.py b/old_tests/cog_utils/test_tonetags.py similarity index 100% rename from tests/cog_utils/test_tonetags.py rename to old_tests/cog_utils/test_tonetags.py diff --git a/tests/utils/test_blacklist.py b/old_tests/utils/test_blacklist.py similarity index 100% rename from tests/utils/test_blacklist.py rename to old_tests/utils/test_blacklist.py diff --git a/tests/utils/test_embeds.py b/old_tests/utils/test_embeds.py similarity index 100% rename from tests/utils/test_embeds.py rename to old_tests/utils/test_embeds.py diff --git a/tests/utils/test_utils.py b/old_tests/utils/test_utils.py similarity index 100% rename from tests/utils/test_utils.py rename to old_tests/utils/test_utils.py diff --git a/pyproject.toml b/pyproject.toml index 470e2a1..b6a31ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,8 @@ exclude = [ "**/.mypy_cache", "**/.dmpypy.json", "docs", - "docker" + "docker", + "bot/tests/**" ] reportMissingImports = true typeCheckingMode = "basic" @@ -33,9 +34,9 @@ ignore = ["E501", "N999", "E402", "S101"] select = ["E", "F", "N", "ASYNC", "S", "ERA"] [tool.pytest.ini_options] -minversion = "6.0" +minversion = "8.0" addopts = "-ra" testpaths = [ - "tests" + "bot/tests" ] pythonpath = ["bot"] diff --git a/requirements-dev.txt b/requirements-dev.txt index 0a951ee..6214ea8 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -15,4 +15,5 @@ dpytest>=0.7.0,<1 sphinx>=7.3.7,<8 furo>=2024.5.6,<2025 sphinx-copybutton>=0.5.2,<1 -sphinx-autobuild>=2024.4.16,<2025 \ No newline at end of file +sphinx-autobuild>=2024.4.16,<2025 +sphinxext-opengraph>=0.8.2,<1 \ No newline at end of file diff --git a/tox.ini b/tox.ini index d62fae6..81383bb 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,7 @@ no_package=true [testenv] description = run unit tests +passenv = POSTGRES_URI deps = pytest>=8.2.1,<9 pytest-asyncio>=0.23.7,<1