"""Tests for the plugin system.""" import textwrap from pathlib import Path from derp.plugin import PluginRegistry, command, event class TestDecorators: """Test that decorators mark functions correctly.""" def test_command_decorator(self): @command("test", help="a test command") async def handler(bot, msg): pass assert handler._derp_command == "test" assert handler._derp_help == "a test command" def test_event_decorator(self): @event("join") async def handler(bot, msg): pass assert handler._derp_event == "JOIN" def test_event_decorator_case(self): @event("PRIVMSG") async def handler(bot, msg): pass assert handler._derp_event == "PRIVMSG" class TestRegistry: """Test the plugin registry.""" def test_register_command(self): registry = PluginRegistry() async def handler(bot, msg): pass registry.register_command("test", handler, help="test help") assert "test" in registry.commands assert registry.commands["test"].help == "test help" def test_register_event(self): registry = PluginRegistry() async def handler(bot, msg): pass registry.register_event("PRIVMSG", handler) assert "PRIVMSG" in registry.events assert len(registry.events["PRIVMSG"]) == 1 def test_multiple_event_handlers(self): registry = PluginRegistry() async def handler_a(bot, msg): pass async def handler_b(bot, msg): pass registry.register_event("JOIN", handler_a) registry.register_event("JOIN", handler_b) assert len(registry.events["JOIN"]) == 2 def test_load_plugin_file(self, tmp_path: Path): plugin_code = textwrap.dedent("""\ from derp.plugin import command, event @command("greet", help="Say hello") async def cmd_greet(bot, msg): pass @event("JOIN") async def on_join(bot, msg): pass """) plugin_file = tmp_path / "greet.py" plugin_file.write_text(plugin_code) registry = PluginRegistry() registry.load_plugin(plugin_file) assert "greet" in registry.commands assert "JOIN" in registry.events def test_load_directory(self, tmp_path: Path): for name in ("a.py", "b.py"): (tmp_path / name).write_text(textwrap.dedent(f"""\ from derp.plugin import command @command("{name[0]}", help="{name}") async def cmd(bot, msg): pass """)) registry = PluginRegistry() registry.load_directory(tmp_path) assert "a" in registry.commands assert "b" in registry.commands def test_skip_underscore_files(self, tmp_path: Path): (tmp_path / "__init__.py").write_text("") (tmp_path / "_private.py").write_text("x = 1\n") (tmp_path / "valid.py").write_text(textwrap.dedent("""\ from derp.plugin import command @command("valid") async def cmd(bot, msg): pass """)) registry = PluginRegistry() registry.load_directory(tmp_path) assert "valid" in registry.commands assert len(registry.commands) == 1 def test_load_missing_directory(self, tmp_path: Path): registry = PluginRegistry() registry.load_directory(tmp_path / "nonexistent") assert len(registry.commands) == 0