From 0487bccf07c6b11f5f3e3c298decb57bbe2e7834 Mon Sep 17 00:00:00 2001 From: Simon Roy <49426163+PenguinBoi12@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:38:48 -0400 Subject: [PATCH 1/2] exclude tests from config's extensions --- bot/config.py | 6 ++++ tests/test_config.py | 68 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/bot/config.py b/bot/config.py index cdcd568..6eaf715 100644 --- a/bot/config.py +++ b/bot/config.py @@ -30,6 +30,12 @@ def extensions(self) -> Iterator[Extension]: from bot import extensions for name in find_all_importable(extensions): + if any(part.startswith("test") for part in name.split(".")): + continue + + if not name.endswith("_extension"): + continue + imported: ModuleType = import_module(name) if not name.endswith("_extension"): diff --git a/tests/test_config.py b/tests/test_config.py index c2f9d5b..10d1070 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,5 +1,7 @@ +import sys import pytest from pathlib import Path +from unittest.mock import MagicMock, patch from bot.config import BotConfig, DEFAULT_LOG_LEVEL, DEFAULT_ENVIRONMENT @@ -21,6 +23,13 @@ def bot_config(config_file: Path) -> BotConfig: return BotConfig(str(config_file)) +@pytest.fixture +def extension_module() -> MagicMock: + module = MagicMock() + module.extension = MagicMock() + return module + + def test_config_loads_username(bot_config: BotConfig) -> None: assert bot_config.username == "@ada:matrix.org" @@ -68,3 +77,62 @@ def test_config_overrides_environment(tmp_path: Path) -> None: ) config = BotConfig(str(config_file)) assert config.environment == "production" + + +def test_extensions_yields_valid_extension( + bot_config: BotConfig, extension_module: MagicMock +) -> None: + with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ + patch("bot.config.find_all_importable", return_value={"bot.extensions.foo_extension"}), \ + patch("bot.config.import_module", return_value=extension_module): + result = list(bot_config.extensions) + + assert result == [extension_module.extension] + + +def test_extensions_skips_tests_folder( + bot_config: BotConfig, extension_module: MagicMock +) -> None: + with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ + patch("bot.config.find_all_importable", return_value={"bot.extensions.tests.foo_extension"}), \ + patch("bot.config.import_module") as mock_import: + result = list(bot_config.extensions) + + assert result == [] + mock_import.assert_not_called() + + +def test_extensions_skips_test_modules( + bot_config: BotConfig, extension_module: MagicMock +) -> None: + with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ + patch("bot.config.find_all_importable", return_value={"bot.extensions.test_foo_extension"}), \ + patch("bot.config.import_module") as mock_import: + result = list(bot_config.extensions) + + assert result == [] + mock_import.assert_not_called() + + +def test_extensions_skips_non_extension_modules( + bot_config: BotConfig, extension_module: MagicMock +) -> None: + with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ + patch("bot.config.find_all_importable", return_value={"bot.extensions.helpers"}), \ + patch("bot.config.import_module") as mock_import: + result = list(bot_config.extensions) + + assert result == [] + mock_import.assert_not_called() + + +def test_extensions_raises_if_missing_extension_attribute( + bot_config: BotConfig, +) -> None: + module = MagicMock(spec=[]) + + with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ + patch("bot.config.find_all_importable", return_value={"bot.extensions.foo_extension"}), \ + patch("bot.config.import_module", return_value=module): + with pytest.raises(RuntimeError, match="does not define an extension"): + list(bot_config.extensions) \ No newline at end of file From 35d8637b6031bc9d769f0c25f9806191e2dcb055 Mon Sep 17 00:00:00 2001 From: Simon Roy <49426163+PenguinBoi12@users.noreply.github.com> Date: Tue, 23 Jun 2026 12:09:51 -0400 Subject: [PATCH 2/2] fix format --- bot/config.py | 2 +- tests/test_config.py | 56 +++++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/bot/config.py b/bot/config.py index 6eaf715..314fa5d 100644 --- a/bot/config.py +++ b/bot/config.py @@ -32,7 +32,7 @@ def extensions(self) -> Iterator[Extension]: for name in find_all_importable(extensions): if any(part.startswith("test") for part in name.split(".")): continue - + if not name.endswith("_extension"): continue diff --git a/tests/test_config.py b/tests/test_config.py index 10d1070..f81bf60 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -82,9 +82,14 @@ def test_config_overrides_environment(tmp_path: Path) -> None: def test_extensions_yields_valid_extension( bot_config: BotConfig, extension_module: MagicMock ) -> None: - with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ - patch("bot.config.find_all_importable", return_value={"bot.extensions.foo_extension"}), \ - patch("bot.config.import_module", return_value=extension_module): + with ( + patch.dict(sys.modules, {"bot.extensions": MagicMock()}), + patch( + "bot.config.find_all_importable", + return_value={"bot.extensions.foo_extension"}, + ), + patch("bot.config.import_module", return_value=extension_module), + ): result = list(bot_config.extensions) assert result == [extension_module.extension] @@ -93,9 +98,14 @@ def test_extensions_yields_valid_extension( def test_extensions_skips_tests_folder( bot_config: BotConfig, extension_module: MagicMock ) -> None: - with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ - patch("bot.config.find_all_importable", return_value={"bot.extensions.tests.foo_extension"}), \ - patch("bot.config.import_module") as mock_import: + with ( + patch.dict(sys.modules, {"bot.extensions": MagicMock()}), + patch( + "bot.config.find_all_importable", + return_value={"bot.extensions.tests.foo_extension"}, + ), + patch("bot.config.import_module") as mock_import, + ): result = list(bot_config.extensions) assert result == [] @@ -105,9 +115,14 @@ def test_extensions_skips_tests_folder( def test_extensions_skips_test_modules( bot_config: BotConfig, extension_module: MagicMock ) -> None: - with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ - patch("bot.config.find_all_importable", return_value={"bot.extensions.test_foo_extension"}), \ - patch("bot.config.import_module") as mock_import: + with ( + patch.dict(sys.modules, {"bot.extensions": MagicMock()}), + patch( + "bot.config.find_all_importable", + return_value={"bot.extensions.test_foo_extension"}, + ), + patch("bot.config.import_module") as mock_import, + ): result = list(bot_config.extensions) assert result == [] @@ -117,9 +132,13 @@ def test_extensions_skips_test_modules( def test_extensions_skips_non_extension_modules( bot_config: BotConfig, extension_module: MagicMock ) -> None: - with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ - patch("bot.config.find_all_importable", return_value={"bot.extensions.helpers"}), \ - patch("bot.config.import_module") as mock_import: + with ( + patch.dict(sys.modules, {"bot.extensions": MagicMock()}), + patch( + "bot.config.find_all_importable", return_value={"bot.extensions.helpers"} + ), + patch("bot.config.import_module") as mock_import, + ): result = list(bot_config.extensions) assert result == [] @@ -131,8 +150,13 @@ def test_extensions_raises_if_missing_extension_attribute( ) -> None: module = MagicMock(spec=[]) - with patch.dict(sys.modules, {"bot.extensions": MagicMock()}), \ - patch("bot.config.find_all_importable", return_value={"bot.extensions.foo_extension"}), \ - patch("bot.config.import_module", return_value=module): + with ( + patch.dict(sys.modules, {"bot.extensions": MagicMock()}), + patch( + "bot.config.find_all_importable", + return_value={"bot.extensions.foo_extension"}, + ), + patch("bot.config.import_module", return_value=module), + ): with pytest.raises(RuntimeError, match="does not define an extension"): - list(bot_config.extensions) \ No newline at end of file + list(bot_config.extensions)