#include #include #include #include #include #define REQUIRE(expr) do { if(!(expr)) { fprintf(stderr, "%s:%d: Assert failed: %s\n", __FILE__, __LINE__, #expr); exit(EXIT_FAILURE); } } while(0) static void requireEqualValues(int a, int b, const char *file, int line) { if(a != b) { fprintf(stderr, "%s:%d: Assert failed: %d == %d\n", file, line, a, b); exit(EXIT_FAILURE); } } #define REQUIRE_EQUAL(a, b) do { requireEqualValues((a), (b), __FILE__, __LINE__); } while(0) static void testIncomingMessage() { std::vector expect = { dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 0, 4 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::EMOJI, dchat::Range{ 12, 16 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 17, 21 } } }; std::vector expectText = { "abc ", "cool", " def" }; dchat::usize index = 0; const char *str = "abc [emoji](cool) def"; dchat::usize strSize = strlen(str); auto compareFunc = [&str, &index, &expect, &expectText](dchat::IncomingMessagePart incomingMessagePart) { REQUIRE(index < expect.size()); REQUIRE_EQUAL((int)incomingMessagePart.type, (int)expect[index].type); REQUIRE_EQUAL(incomingMessagePart.textRange.start, expect[index].textRange.start); REQUIRE_EQUAL(incomingMessagePart.textRange.end, expect[index].textRange.end); int length = incomingMessagePart.textRange.end - incomingMessagePart.textRange.start; if(length != expectText[index].size() || strncmp(str + incomingMessagePart.textRange.start, expectText[index].c_str(), length) != 0) { fprintf(stderr, "Assert failed: |%.*s| == |%.*s|\n", length, str + incomingMessagePart.textRange.start, expectText[index].size(), expectText[index].c_str()); exit(EXIT_FAILURE); } ++index; }; dchat::parseIncomingMessage(str, strSize, compareFunc); { expect = { dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 0, 4 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 4, 20 } } }; expectText = { "abc ", "[emoji](cool def" }; index = 0; str = "abc [emoji](cool def"; strSize = strlen(str); dchat::parseIncomingMessage(str, strSize, compareFunc); } { expect = { dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 0, 4 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 4, 11 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 11, 22 } } }; expectText = { "abc ", "[emoji]", " (cool def)" }; index = 0; str = "abc [emoji] (cool def)"; strSize = strlen(str); dchat::parseIncomingMessage(str, strSize, compareFunc); } { expect = { dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 0, 4 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 4, 20 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 20, 24 } } }; expectText = { "abc ", "[notemoji](cool)", " def" }; index = 0; str = "abc [notemoji](cool) def"; strSize = strlen(str); dchat::parseIncomingMessage(str, strSize, compareFunc); } { expect = { dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::TEXT, dchat::Range{ 0, 12 } }, dchat::IncomingMessagePart { dchat::IncomingMessagePart::Type::EMOJI, dchat::Range{ 20, 71 } } }; expectText = { "Hello world ", "https://discordemoji.com/assets/emoji/PeepoHide.png" }; index = 0; str = "Hello world [emoji](https://discordemoji.com/assets/emoji/PeepoHide.png)"; strSize = strlen(str); dchat::parseIncomingMessage(str, strSize, compareFunc); } } static void testOutgoingMessage() { const dchat::EmojiBindMap binds = { { "thinking", "https://thinking" }, { "sad", "https://sad" } }; std::vector expect; std::vector expectText; dchat::usize index = 0; const char *str = nullptr; dchat::usize size = 0; auto callbackFunc = [&expect, &expectText, &index, &str](dchat::OutgoingMessagePart outgoingMessagePart) { REQUIRE(index < expect.size()); REQUIRE_EQUAL((int)outgoingMessagePart.type, (int)expect[index].type); switch(outgoingMessagePart.type) { case dchat::OutgoingMessagePart::Type::TEXT: { REQUIRE_EQUAL(outgoingMessagePart.textRange.start, expect[index].textRange.start); REQUIRE_EQUAL(outgoingMessagePart.textRange.end, expect[index].textRange.end); int length = outgoingMessagePart.textRange.end - outgoingMessagePart.textRange.start; if(length != expectText[index].size() || strncmp(str + outgoingMessagePart.textRange.start, expectText[index].c_str(), length) != 0) { fprintf(stderr, "Assert failed: |%.*s| == |%.*s|\n", length, str + outgoingMessagePart.textRange.start, expectText[index].size(), expectText[index].c_str()); exit(EXIT_FAILURE); } break; } case dchat::OutgoingMessagePart::Type::EMOJI: { if(*outgoingMessagePart.emoji != expectText[index]) { fprintf(stderr, "Assert failed: |%s| == |%s|\n", outgoingMessagePart.emoji->c_str(), expectText[index].c_str()); exit(EXIT_FAILURE); } break; } } ++index; }; { expect = { dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::TEXT, dchat::Range{ 0, 4 } }, dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::EMOJI, nullptr }, dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::TEXT, dchat::Range{ 14, 18 } } }; expectText = { "aaa ", "https://thinking", " bbb" }; index = 0; str = "aaa :thinking: bbb"; size = strlen(str); dchat::parseOutgoingMessage(str, size, binds, callbackFunc); } { expect = { dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::EMOJI, nullptr }, dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::TEXT, dchat::Range{ 5, 9 } } }; expectText = { "https://sad", " bbb" }; index = 0; str = ":sad: bbb"; size = strlen(str); dchat::parseOutgoingMessage(str, size, binds, callbackFunc); } { expect = { dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::EMOJI, nullptr }, }; expectText = { "https://sad", }; index = 0; str = ":sad:"; size = strlen(str); dchat::parseOutgoingMessage(str, size, binds, callbackFunc); } { expect = { dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::TEXT, dchat::Range{ 0, 9 } } }; expectText = { ":nothing:", }; index = 0; str = ":nothing:"; size = strlen(str); dchat::parseOutgoingMessage(str, size, binds, callbackFunc); } { expect = { dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::TEXT, dchat::Range{ 0, 4 } }, dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::TEXT, dchat::Range{ 4, 13 } }, dchat::OutgoingMessagePart { dchat::OutgoingMessagePart::Type::TEXT, dchat::Range{ 13, 17 } } }; expectText = { "aaa ", ":nothing:", " bbb" }; index = 0; str = "aaa :nothing: bbb"; size = strlen(str); dchat::parseOutgoingMessage(str, size, binds, callbackFunc); } } int main(int argc, char **argv) { testIncomingMessage(); testOutgoingMessage(); return 0; }