diff --git a/src/plugins/irc/irc-message.c b/src/plugins/irc/irc-message.c index afa999281..39327bfb9 100644 --- a/src/plugins/irc/irc-message.c +++ b/src/plugins/irc/irc-message.c @@ -336,7 +336,7 @@ struct t_hashtable * irc_message_parse_to_hashtable (struct t_irc_server *server, const char *message) { - char *tags,*message_without_tags, *nick, *host, *command, *channel; + char *tags, *message_without_tags, *nick, *host, *command, *channel; char *arguments, *text, str_pos[32]; char empty_str[1] = { '\0' }; int pos_command, pos_arguments, pos_channel, pos_text; diff --git a/tests/unit/plugins/irc/test-irc-message.cpp b/tests/unit/plugins/irc/test-irc-message.cpp index b06ab7ede..dda42b856 100644 --- a/tests/unit/plugins/irc/test-irc-message.cpp +++ b/tests/unit/plugins/irc/test-irc-message.cpp @@ -24,6 +24,7 @@ extern "C" { #include "tests/tests.h" +#include "src/core/wee-hashtable.h" #include "src/plugins/irc/irc-message.h" #include "src/plugins/irc/irc-server.h" } @@ -33,6 +34,114 @@ extern "C" "xxxxxx_128_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_256 test" +#define WEE_CHECK_PARSE(__tags, __message_without_tags, __nick, __host, \ + __command, __channel, __arguments, __text, \ + __pos_command, __pos_arguments, __pos_channel, \ + __pos_text, __server, __message) \ + tags = NULL; \ + message_without_tags = NULL; \ + nick = NULL; \ + host = NULL; \ + command = NULL; \ + channel = NULL; \ + arguments = NULL; \ + text = NULL; \ + pos_command = -1; \ + pos_channel = -1; \ + pos_text = -1; \ + \ + irc_message_parse (__server, __message, &tags, \ + &message_without_tags, \ + &nick, &host, &command, &channel, &arguments, \ + &text, &pos_command, &pos_arguments, \ + &pos_channel, &pos_text); \ + \ + if (__tags == NULL) \ + { \ + POINTERS_EQUAL(NULL, tags); \ + } \ + else \ + { \ + STRCMP_EQUAL(__tags, tags); \ + } \ + if (__message_without_tags == NULL) \ + { \ + POINTERS_EQUAL(NULL, message_without_tags); \ + } \ + else \ + { \ + STRCMP_EQUAL(__message_without_tags, message_without_tags); \ + } \ + if (__nick == NULL) \ + { \ + POINTERS_EQUAL(NULL, nick); \ + } \ + else \ + { \ + STRCMP_EQUAL(__nick, nick); \ + } \ + if (__host == NULL) \ + { \ + POINTERS_EQUAL(NULL, host); \ + } \ + else \ + { \ + STRCMP_EQUAL(__host, host); \ + } \ + if (__command == NULL) \ + { \ + POINTERS_EQUAL(NULL, command); \ + } \ + else \ + { \ + STRCMP_EQUAL(__command, command); \ + } \ + if (__channel == NULL) \ + { \ + POINTERS_EQUAL(NULL, channel); \ + } \ + else \ + { \ + STRCMP_EQUAL(__channel, channel); \ + } \ + if (__arguments == NULL) \ + { \ + POINTERS_EQUAL(NULL, arguments); \ + } \ + else \ + { \ + STRCMP_EQUAL(__arguments, arguments); \ + } \ + if (__text == NULL) \ + { \ + POINTERS_EQUAL(NULL, text); \ + } \ + else \ + { \ + STRCMP_EQUAL(__text, text); \ + } \ + LONGS_EQUAL(__pos_command, pos_command); \ + LONGS_EQUAL(__pos_arguments, pos_arguments); \ + LONGS_EQUAL(__pos_channel, pos_channel); \ + LONGS_EQUAL(__pos_text, pos_text); \ + \ + if (tags) \ + free (tags); \ + if (message_without_tags) \ + free (message_without_tags); \ + if (nick) \ + free (nick); \ + if (host) \ + free (host); \ + if (command) \ + free (command); \ + if (channel) \ + free (channel); \ + if (arguments) \ + free (arguments); \ + if (text) \ + free (text); + TEST_GROUP(IrcMessage) { }; @@ -40,12 +149,272 @@ TEST_GROUP(IrcMessage) /* * Tests functions: * irc_message_parse - * irc_message_parse_to_hashtable */ TEST(IrcMessage, Parse) { - /* TODO: write tests */ + char *tags, *message_without_tags, *nick, *host, *command, *channel; + char *arguments, *text; + int pos_command, pos_arguments, pos_channel, pos_text; + + WEE_CHECK_PARSE(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + -1, -1, -1, -1, + NULL, NULL); + + WEE_CHECK_PARSE(NULL, "", NULL, NULL, NULL, NULL, NULL, NULL, + -1, -1, -1, -1, + NULL, ""); + + WEE_CHECK_PARSE(NULL, ":nick!user@host", "nick", "nick!user@host", NULL, + NULL, NULL, NULL, + -1, -1, -1, -1, + NULL, ":nick!user@host"); + + /* AWAY */ + WEE_CHECK_PARSE(NULL, ":nick!user@host AWAY", "nick", "nick!user@host", + "AWAY", NULL, NULL, NULL, + 16, -1, -1, -1, + NULL, ":nick!user@host AWAY"); + WEE_CHECK_PARSE(NULL, ":nick!user@host AWAY :I am away", "nick", + "nick!user@host", "AWAY", NULL, ":I am away", "I am away", + 16, 21, -1, 22, + NULL, ":nick!user@host AWAY :I am away"); + + /* CAP */ + WEE_CHECK_PARSE(NULL, + ":irc.example.com CAP * LS :identify-msg multi-prefix sasl", + "irc.example.com", "irc.example.com", "CAP", "*", + "* LS :identify-msg multi-prefix sasl", + "LS :identify-msg multi-prefix sasl", + 17, 21, 21, 23, + NULL, + ":irc.example.com CAP * LS :identify-msg multi-prefix sasl"); + + /* JOIN */ + WEE_CHECK_PARSE(NULL, ":nick!user@host JOIN #channel", "nick", + "nick!user@host", "JOIN", "#channel", "#channel", NULL, + 16, 21, 21, -1, + NULL, ":nick!user@host JOIN #channel"); + + /* JOIN with colon */ + WEE_CHECK_PARSE(NULL, ":nick!user@host JOIN :#channel", "nick", + "nick!user@host", "JOIN", "#channel", ":#channel", NULL, + 16, 21, 22, -1, + NULL, ":nick!user@host JOIN :#channel"); + + /* JOIN with extended join capability */ + WEE_CHECK_PARSE(NULL, ":nick!user@host JOIN #channel account :real name", + "nick", "nick!user@host", "JOIN", "#channel", + "#channel account :real name", "account :real name", + 16, 21, 21, 30, + NULL, ":nick!user@host JOIN #channel account :real name"); + + /* KICK */ + WEE_CHECK_PARSE(NULL, ":nick1!user@host KICK #channel nick2 :kick reason", + "nick1", "nick1!user@host", "KICK", "#channel", + "#channel nick2 :kick reason", "nick2 :kick reason", + 17, 22, 22, 31, + NULL, ":nick1!user@host KICK #channel nick2 :kick reason"); + + /* MODE */ + WEE_CHECK_PARSE(NULL, ":nick!user@host MODE #channel +o nick", + "nick", "nick!user@host", "MODE", "#channel", + "#channel +o nick", "+o nick", + 16, 21, 21, 30, + NULL, ":nick!user@host MODE #channel +o nick"); + + /* MODE with colon */ + WEE_CHECK_PARSE(NULL, ":nick!user@host MODE #channel :+o nick", + "nick", "nick!user@host", "MODE", "#channel", + "#channel :+o nick", "+o nick", + 16, 21, 21, 31, + NULL, ":nick!user@host MODE #channel :+o nick"); + + /* NICK */ + WEE_CHECK_PARSE(NULL, ":oldnick!user@host NICK :newnick", + "oldnick", "oldnick!user@host", "NICK", NULL, + ":newnick", "newnick", + 19, 24, -1, 25, + NULL, ":oldnick!user@host NICK :newnick"); + + /* NOTICE */ + WEE_CHECK_PARSE(NULL, "NOTICE AUTH :*** Looking up your hostname...", + "AUTH", NULL, "NOTICE", "AUTH", + "AUTH :*** Looking up your hostname...", + "*** Looking up your hostname...", + 0, 7, 7, 13, + NULL, "NOTICE AUTH :*** Looking up your hostname..."); + + /* PING */ + WEE_CHECK_PARSE(NULL, "PING :arguments", NULL, NULL, "PING", NULL, + ":arguments", "arguments", + 0, 5, -1, 6, + NULL, "PING :arguments"); + + + /* PART */ + WEE_CHECK_PARSE(NULL, ":nick!user@host PART #channel", "nick", + "nick!user@host", "PART", "#channel", "#channel", NULL, + 16, 21, 21, -1, + NULL, ":nick!user@host PART #channel"); + + /* PART with colon */ + WEE_CHECK_PARSE(NULL, ":nick!user@host PART :#channel", "nick", + "nick!user@host", "PART", "#channel", ":#channel", NULL, + 16, 21, 22, -1, + NULL, ":nick!user@host PART :#channel"); + + /* INVITE */ + WEE_CHECK_PARSE(NULL, ":nick!user@host INVITE nick2 #channel", "nick", + "nick!user@host", "INVITE", "#channel", "nick2 #channel", + NULL, + 16, 23, 29, -1, + NULL, ":nick!user@host INVITE nick2 #channel"); + + /* PRIVMSG */ + WEE_CHECK_PARSE(NULL, ":nick PRIVMSG", "nick", "nick", + "PRIVMSG", NULL, NULL, NULL, + 6, -1, -1, -1, + NULL, ":nick PRIVMSG"); + WEE_CHECK_PARSE(NULL, ":nick@host PRIVMSG", "nick", "nick@host", + "PRIVMSG", NULL, NULL, NULL, + 11, -1, -1, -1, + NULL, ":nick@host PRIVMSG"); + WEE_CHECK_PARSE(NULL, ":nick!user@host PRIVMSG", "nick", "nick!user@host", + "PRIVMSG", NULL, NULL, NULL, + 16, -1, -1, -1, + NULL, ":nick!user@host PRIVMSG"); + WEE_CHECK_PARSE(NULL, ":nick!user@host PRIVMSG #channel", "nick", + "nick!user@host", "PRIVMSG", "#channel", "#channel", NULL, + 16, 24, 24, -1, + NULL, ":nick!user@host PRIVMSG #channel"); + WEE_CHECK_PARSE(NULL, ":nick!user@host PRIVMSG #channel :the message", + "nick", "nick!user@host", "PRIVMSG", "#channel", + "#channel :the message", "the message", + 16, 24, 24, 34, + NULL, ":nick!user@host PRIVMSG #channel :the message"); + + /* PRIVMSG with tags */ + WEE_CHECK_PARSE("time=2019-08-03T12:13:00.000Z", + ":nick!user@host PRIVMSG #channel :the message", + "nick", "nick!user@host", "PRIVMSG", "#channel", + "#channel :the message", "the message", + 47, 55, 55, 65, + NULL, + "@time=2019-08-03T12:13:00.000Z :nick!user@host PRIVMSG " + "#channel :the message"); + + /* PRIVMSG with tags and extra spaces*/ + WEE_CHECK_PARSE("time=2019-08-03T12:13:00.000Z", + ":nick!user@host PRIVMSG #channel :the message", + "nick", "nick!user@host", "PRIVMSG", "#channel", + "#channel :the message", "the message", + 49, 58, 58, 69, + NULL, + "@time=2019-08-03T12:13:00.000Z :nick!user@host " + "PRIVMSG #channel :the message"); + + /* PRIVMSG to a nick */ + WEE_CHECK_PARSE(NULL, ":nick!user@host PRIVMSG nick2 :the message", + "nick", "nick!user@host", "PRIVMSG", "nick2", + "nick2 :the message", "the message", + 16, 24, 24, 31, + NULL, ":nick!user@host PRIVMSG nick2 :the message"); + + /* 005 */ + WEE_CHECK_PARSE(NULL, + ":irc.example.com 005 mynick MODES=4 CHANLIMIT=#:20 " + "NICKLEN=16 USERLEN=10 HOSTLEN=63 TOPICLEN=450 " + "KICKLEN=450 CHANNELLEN=30 KEYLEN=23 CHANTYPES=# " + "PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB IRCD=dancer " + ":are available on this server", + "irc.example.com", "irc.example.com", "005", "mynick", + "mynick MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10 " + "HOSTLEN=63 TOPICLEN=450 KICKLEN=450 CHANNELLEN=30 " + "KEYLEN=23 CHANTYPES=# PREFIX=(ov)@+ CASEMAPPING=ascii " + "CAPAB IRCD=dancer :are available on this server", + "MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10 HOSTLEN=63 " + "TOPICLEN=450 KICKLEN=450 CHANNELLEN=30 KEYLEN=23 " + "CHANTYPES=# PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB " + "IRCD=dancer :are available on this server", + 17, 21, 21, 28, + NULL, + ":irc.example.com 005 mynick MODES=4 CHANLIMIT=#:20 " + "NICKLEN=16 USERLEN=10 HOSTLEN=63 TOPICLEN=450 " + "KICKLEN=450 CHANNELLEN=30 KEYLEN=23 CHANTYPES=# " + "PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB IRCD=dancer " + ":are available on this server"); + + /* 301 */ + WEE_CHECK_PARSE(NULL, + ":irc.example.com 301 mynick nick :away message for nick", + "irc.example.com", "irc.example.com", "301", "mynick", + "mynick nick :away message for nick", + "nick :away message for nick", + 17, 21, 21, 28, + NULL, + ":irc.example.com 301 mynick nick :away message for nick"); + + /* error */ + WEE_CHECK_PARSE(NULL, + "404 nick #channel :Cannot send to channel", + "nick", NULL, "404", "#channel", + "nick #channel :Cannot send to channel", + "Cannot send to channel", + 0, 4, 9, 19, + NULL, + "404 nick #channel :Cannot send to channel"); + WEE_CHECK_PARSE(NULL, + ":irc.example.com 404 nick #channel :Cannot send to channel", + "irc.example.com", "irc.example.com", "404", "#channel", + "nick #channel :Cannot send to channel", + "Cannot send to channel", + 17, 21, 26, 36, + NULL, + ":irc.example.com 404 nick #channel :Cannot send to channel"); +} + +/* + * Tests functions: + * irc_message_parse_to_hashtable + */ + +TEST(IrcMessage, ParseToHashtable) +{ + struct t_hashtable *hashtable; + + hashtable = irc_message_parse_to_hashtable ( + NULL, + "@time=2019-08-03T12:13:00.000Z :nick!user@host PRIVMSG #channel " + ":the message"); + CHECK(hashtable); + + STRCMP_EQUAL("time=2019-08-03T12:13:00.000Z", + (const char *)hashtable_get (hashtable, "tags")); + STRCMP_EQUAL(":nick!user@host PRIVMSG #channel :the message", + (const char *)hashtable_get (hashtable, "message_without_tags")); + STRCMP_EQUAL("nick", + (const char *)hashtable_get (hashtable, "nick")); + STRCMP_EQUAL("nick!user@host", + (const char *)hashtable_get (hashtable, "host")); + STRCMP_EQUAL("PRIVMSG", + (const char *)hashtable_get (hashtable, "command")); + STRCMP_EQUAL("#channel", + (const char *)hashtable_get (hashtable, "channel")); + STRCMP_EQUAL("#channel :the message", + (const char *)hashtable_get (hashtable, "arguments")); + STRCMP_EQUAL("the message", + (const char *)hashtable_get (hashtable, "text")); + STRCMP_EQUAL("47", + (const char *)hashtable_get (hashtable, "pos_command")); + STRCMP_EQUAL("55", + (const char *)hashtable_get (hashtable, "pos_arguments")); + STRCMP_EQUAL("55", + (const char *)hashtable_get (hashtable, "pos_channel")); + STRCMP_EQUAL("65", + (const char *)hashtable_get (hashtable, "pos_text")); + + hashtable_free (hashtable); } /*