#include #include "base64.h" #include "irc_message.h" #include "reconnect_policy.h" using namespace roro; void setUp() {} void tearDown() {} void test_parse_full_message() { auto m = IrcMessage::parse(":alice!a@host PRIVMSG #roro :hello there"); TEST_ASSERT_EQUAL_STRING("alice!a@host", m.prefix.c_str()); TEST_ASSERT_EQUAL_STRING("alice", m.nick().c_str()); TEST_ASSERT_EQUAL_STRING("PRIVMSG", m.command.c_str()); TEST_ASSERT_EQUAL(2, m.params.size()); TEST_ASSERT_EQUAL_STRING("#roro", m.params[0].c_str()); TEST_ASSERT_EQUAL_STRING("hello there", m.params[1].c_str()); } void test_parse_without_prefix_and_with_tags() { auto m = IrcMessage::parse("@time=2026-10-02T12:00:00Z PING :abc"); TEST_ASSERT_EQUAL_STRING("", m.prefix.c_str()); TEST_ASSERT_EQUAL_STRING("PING", m.command.c_str()); TEST_ASSERT_EQUAL_STRING("abc", m.params[0].c_str()); } void test_parse_strips_line_endings_and_handles_empty_trailing() { auto m = IrcMessage::parse(":srv 332 me #roro :\r\n"); TEST_ASSERT_EQUAL(3, m.params.size()); TEST_ASSERT_EQUAL_STRING("", m.params[2].c_str()); } void test_parse_middle_params_only() { auto m = IrcMessage::parse(":srv MODE #roro +nt"); TEST_ASSERT_EQUAL(2, m.params.size()); TEST_ASSERT_EQUAL_STRING("+nt", m.params[1].c_str()); } void test_serialize_adds_colon_only_when_needed() { TEST_ASSERT_EQUAL_STRING("NICK roro", IrcMessage::serialize("NICK", {"roro"}).c_str()); TEST_ASSERT_EQUAL_STRING("PRIVMSG #roro :hello there", IrcMessage::serialize("PRIVMSG", {"#roro", "hello there"}).c_str()); TEST_ASSERT_EQUAL_STRING("PRIVMSG #roro ::)", IrcMessage::serialize("PRIVMSG", {"#roro", ":)"}).c_str()); TEST_ASSERT_EQUAL_STRING("TOPIC #roro :", IrcMessage::serialize("TOPIC", {"#roro", ""}).c_str()); } void test_base64() { TEST_ASSERT_EQUAL_STRING("", base64Encode("").c_str()); TEST_ASSERT_EQUAL_STRING("Zg==", base64Encode("f").c_str()); TEST_ASSERT_EQUAL_STRING("Zm8=", base64Encode("fo").c_str()); TEST_ASSERT_EQUAL_STRING("Zm9v", base64Encode("foo").c_str()); TEST_ASSERT_EQUAL_STRING("dXNlcgB1c2VyAHBhc3M=", base64Encode(std::string("user\0user\0pass", 14)).c_str()); } void test_reconnect_delays_grow_then_cap_and_reset() { ReconnectPolicy p; uint32_t expected[] = {5000, 10000, 30000, 60000, 120000, 300000, 300000}; for (uint32_t e : expected) TEST_ASSERT_EQUAL_UINT32(e, p.nextDelayMs()); p.reset(); TEST_ASSERT_EQUAL_UINT32(5000, p.nextDelayMs()); } int main() { UNITY_BEGIN(); RUN_TEST(test_parse_full_message); RUN_TEST(test_parse_without_prefix_and_with_tags); RUN_TEST(test_parse_strips_line_endings_and_handles_empty_trailing); RUN_TEST(test_parse_middle_params_only); RUN_TEST(test_serialize_adds_colon_only_when_needed); RUN_TEST(test_base64); RUN_TEST(test_reconnect_delays_grow_then_cap_and_reset); return UNITY_END(); }