"""Tests for IRC message parsing and formatting.""" from derp.irc import ( IRCConnection, _parse_tags, _unescape_tag_value, 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" def test_no_tags_default(self): msg = parse(":nick!u@h PRIVMSG #ch :hello") assert msg.tags == {} def test_tags_parsed(self): msg = parse("@time=2026-02-15T12:00:00Z;account=alice " ":nick!user@host PRIVMSG #chan :hello") assert msg.tags == {"time": "2026-02-15T12:00:00Z", "account": "alice"} assert msg.nick == "nick" assert msg.command == "PRIVMSG" assert msg.text == "hello" def test_tags_value_unescaping(self): msg = parse(r"@key=hello\sworld\:end :nick!u@h PRIVMSG #ch :test") assert msg.tags["key"] == "hello world;end" def test_tags_no_value(self): msg = parse("@draft/feature :nick!u@h PRIVMSG #ch :test") assert msg.tags == {"draft/feature": ""} def test_tags_backslash_escapes(self): assert _unescape_tag_value(r"a\\b\r\n") == "a\\b\r\n" def test_tags_mixed_keys(self): tags = _parse_tags("a=1;b;c=three") assert tags == {"a": "1", "b": "", "c": "three"} def test_tags_empty_string(self): assert _parse_tags("") == {} 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" def test_trailing_starts_with_colon(self): result = format_msg("PRIVMSG", "#ch", ":)") assert result == "PRIVMSG #ch ::)" def test_empty_trailing(self): # Empty string has no space and no leading colon, but head exists result = format_msg("PRIVMSG", "#ch", "") assert result == "PRIVMSG #ch " def test_multi_param_mode(self): # No space in tail, not starting with colon, head exists -> no colon result = format_msg("MODE", "#ch", "+o", "nick") assert result == "MODE #ch +o nick" class TestIRCConnectionProxy: """IRCConnection proxy flag tests.""" def test_proxy_default_false(self): conn = IRCConnection("irc.example.com", 6697) assert conn.proxy is False def test_proxy_enabled(self): conn = IRCConnection("irc.example.com", 6697, proxy=True) assert conn.proxy is True def test_proxy_disabled(self): conn = IRCConnection("irc.example.com", 6697, proxy=False) assert conn.proxy is False