Files
derp/tests/test_irc.py
user bf45abcbad feat: initial implementation
Asyncio IRC bot with decorator-based plugin system.
Zero external dependencies, Python 3.11+.

- IRC protocol: message parsing, formatting, async TCP/TLS connection
- Plugin system: @command and @event decorators, file-based loading
- Bot orchestrator: connect, dispatch, reconnect, nick recovery
- CLI: argparse entry point with TOML config
- Built-in plugins: ping, help, version, echo
- 28 unit tests for parser and plugin system
2026-02-15 00:37:31 +01:00

101 lines
3.3 KiB
Python

"""Tests for IRC message parsing and formatting."""
from derp.irc import format_msg, parse
class TestParse:
"""IRC message parser tests."""
def test_privmsg(self):
msg = parse(":nick!user@host PRIVMSG #channel :hello world")
assert msg.prefix == "nick!user@host"
assert msg.nick == "nick"
assert msg.command == "PRIVMSG"
assert msg.params == ["#channel", "hello world"]
assert msg.target == "#channel"
assert msg.text == "hello world"
assert msg.is_channel is True
def test_privmsg_pm(self):
msg = parse(":nick!user@host PRIVMSG bot :hello")
assert msg.target == "bot"
assert msg.is_channel is False
def test_ping(self):
msg = parse("PING :server.example.com")
assert msg.prefix is None
assert msg.nick is None
assert msg.command == "PING"
assert msg.params == ["server.example.com"]
def test_join(self):
msg = parse(":nick!user@host JOIN #channel")
assert msg.command == "JOIN"
assert msg.nick == "nick"
assert msg.target == "#channel"
def test_numeric(self):
msg = parse(":server 001 bot :Welcome to the IRC Network")
assert msg.command == "001"
assert msg.prefix == "server"
assert msg.nick is None
assert msg.params == ["bot", "Welcome to the IRC Network"]
def test_nick_in_use(self):
msg = parse(":server 433 * derp :Nickname is already in use")
assert msg.command == "433"
assert msg.params[1] == "derp"
def test_empty_trailing(self):
msg = parse(":nick!user@host PRIVMSG #channel :")
assert msg.text == ""
def test_no_prefix(self):
msg = parse("NOTICE AUTH :*** Looking up your hostname")
assert msg.prefix is None
assert msg.command == "NOTICE"
assert msg.params == ["AUTH", "*** Looking up your hostname"]
def test_server_prefix_no_nick(self):
msg = parse(":irc.server.net 372 bot :- Message of the day")
assert msg.prefix == "irc.server.net"
assert msg.nick is None
def test_command_case(self):
msg = parse(":nick!u@h privmsg #ch :test")
assert msg.command == "PRIVMSG"
def test_multiple_colons_in_trailing(self):
msg = parse(":nick!u@h PRIVMSG #ch :url: https://example.com")
assert msg.text == "url: https://example.com"
def test_part_with_reason(self):
msg = parse(":nick!u@h PART #channel :leaving")
assert msg.command == "PART"
assert msg.target == "#channel"
assert msg.text == "leaving"
class TestFormat:
"""IRC message formatting tests."""
def test_simple_command(self):
assert format_msg("NICK", "derp") == "NICK :derp"
def test_command_with_trailing(self):
assert format_msg("PRIVMSG", "#channel", "hello world") == \
"PRIVMSG #channel :hello world"
def test_join(self):
assert format_msg("JOIN", "#channel") == "JOIN :#channel"
def test_no_params(self):
assert format_msg("QUIT") == "QUIT"
def test_user_registration(self):
result = format_msg("USER", "derp", "0", "*", "derp IRC bot")
assert result == "USER derp 0 * :derp IRC bot"
def test_pong(self):
assert format_msg("PONG", "server.example.com") == "PONG :server.example.com"