diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 56f442fb..ce23735f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -197,12 +197,15 @@ set(SOURCE_FILES controllers/highlights/HighlightBadge.hpp controllers/highlights/HighlightBlacklistModel.cpp controllers/highlights/HighlightBlacklistModel.hpp + controllers/highlights/HighlightCheck.hpp controllers/highlights/HighlightController.cpp controllers/highlights/HighlightController.hpp controllers/highlights/HighlightModel.cpp controllers/highlights/HighlightModel.hpp controllers/highlights/HighlightPhrase.cpp controllers/highlights/HighlightPhrase.hpp + controllers/highlights/HighlightResult.cpp + controllers/highlights/HighlightResult.hpp controllers/highlights/UserHighlightModel.cpp controllers/highlights/UserHighlightModel.hpp diff --git a/src/controllers/highlights/HighlightCheck.hpp b/src/controllers/highlights/HighlightCheck.hpp new file mode 100644 index 00000000..84997376 --- /dev/null +++ b/src/controllers/highlights/HighlightCheck.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "common/FlagsEnum.hpp" + +#include +#include +#include +#include + +class QString; + +namespace chatterino { + +struct HighlightResult; +struct MessageParseArgs; +class Badge; + +enum class MessageFlag : std::int64_t; +using MessageFlags = FlagsEnum; + +struct HighlightCheck { + using Checker = std::function( + const MessageParseArgs &args, const std::vector &badges, + const QString &senderName, const QString &originalMessage, + const MessageFlags &messageFlags, bool self)>; + Checker cb; +}; + +} // namespace chatterino diff --git a/src/controllers/highlights/HighlightController.cpp b/src/controllers/highlights/HighlightController.cpp index 78d072a3..7275559b 100644 --- a/src/controllers/highlights/HighlightController.cpp +++ b/src/controllers/highlights/HighlightController.cpp @@ -4,13 +4,14 @@ #include "common/QLogging.hpp" #include "controllers/accounts/AccountController.hpp" #include "controllers/highlights/HighlightBadge.hpp" +#include "controllers/highlights/HighlightCheck.hpp" #include "controllers/highlights/HighlightPhrase.hpp" +#include "controllers/highlights/HighlightResult.hpp" #include "messages/Message.hpp" #include "messages/MessageBuilder.hpp" #include "providers/colors/ColorProvider.hpp" -#include "providers/twitch/TwitchAccount.hpp" +#include "providers/twitch/TwitchAccount.hpp" // IWYU pragma: keep #include "providers/twitch/TwitchBadge.hpp" -#include "singletons/Paths.hpp" #include "singletons/Settings.hpp" namespace { @@ -359,89 +360,6 @@ void rebuildBadgeHighlights(Settings &settings, namespace chatterino { -HighlightResult::HighlightResult(bool _alert, bool _playSound, - std::optional _customSoundUrl, - std::shared_ptr _color, - bool _showInMentions) - : alert(_alert) - , playSound(_playSound) - , customSoundUrl(std::move(_customSoundUrl)) - , color(std::move(_color)) - , showInMentions(_showInMentions) -{ -} - -HighlightResult HighlightResult::emptyResult() -{ - return { - false, false, std::nullopt, nullptr, false, - }; -} - -bool HighlightResult::operator==(const HighlightResult &other) const -{ - if (this->alert != other.alert) - { - return false; - } - if (this->playSound != other.playSound) - { - return false; - } - if (this->customSoundUrl != other.customSoundUrl) - { - return false; - } - - if (this->color && other.color) - { - if (*this->color != *other.color) - { - return false; - } - } - - if (this->showInMentions != other.showInMentions) - { - return false; - } - - return true; -} - -bool HighlightResult::operator!=(const HighlightResult &other) const -{ - return !(*this == other); -} - -bool HighlightResult::empty() const -{ - return !this->alert && !this->playSound && - !this->customSoundUrl.has_value() && !this->color && - !this->showInMentions; -} - -bool HighlightResult::full() const -{ - return this->alert && this->playSound && this->customSoundUrl.has_value() && - this->color && this->showInMentions; -} - -std::ostream &operator<<(std::ostream &os, const HighlightResult &result) -{ - os << "Alert: " << (result.alert ? "Yes" : "No") << ", " - << "Play sound: " << (result.playSound ? "Yes" : "No") << " (" - << (result.customSoundUrl - ? result.customSoundUrl->toString().toStdString() - : "") - << ")" - << ", " - << "Color: " << (result.color ? result.color->name().toStdString() : "") - << ", " - << "Show in mentions: " << (result.showInMentions ? "Yes" : "No"); - return os; -} - HighlightController::HighlightController(Settings &settings, AccountController *accounts) { diff --git a/src/controllers/highlights/HighlightController.hpp b/src/controllers/highlights/HighlightController.hpp index 488f628f..23536cef 100644 --- a/src/controllers/highlights/HighlightController.hpp +++ b/src/controllers/highlights/HighlightController.hpp @@ -1,7 +1,8 @@ #pragma once +#include "common/FlagsEnum.hpp" #include "common/UniqueAccess.hpp" -#include "messages/MessageFlag.hpp" +#include "controllers/highlights/HighlightCheck.hpp" #include "singletons/Settings.hpp" #include @@ -10,6 +11,7 @@ #include #include +#include #include #include #include @@ -20,68 +22,8 @@ namespace chatterino { class Badge; struct MessageParseArgs; class AccountController; - -struct HighlightResult { - HighlightResult(bool _alert, bool _playSound, - std::optional _customSoundUrl, - std::shared_ptr _color, bool _showInMentions); - - /** - * @brief Construct an empty HighlightResult with all side-effects disabled - **/ - static HighlightResult emptyResult(); - - /** - * @brief true if highlight should trigger the taskbar to flash - **/ - bool alert{false}; - - /** - * @brief true if highlight should play a notification sound - **/ - bool playSound{false}; - - /** - * @brief Can be set to a different sound that should play when this highlight is activated - * - * May only be set if playSound is true - **/ - std::optional customSoundUrl{}; - - /** - * @brief set if highlight should set a background color - **/ - std::shared_ptr color{}; - - /** - * @brief true if highlight should show message in the /mentions split - **/ - bool showInMentions{false}; - - bool operator==(const HighlightResult &other) const; - bool operator!=(const HighlightResult &other) const; - - /** - * @brief Returns true if no side-effect has been enabled - **/ - [[nodiscard]] bool empty() const; - - /** - * @brief Returns true if all side-effects have been enabled - **/ - [[nodiscard]] bool full() const; - - friend std::ostream &operator<<(std::ostream &os, - const HighlightResult &result); -}; - -struct HighlightCheck { - using Checker = std::function( - const MessageParseArgs &args, const std::vector &badges, - const QString &senderName, const QString &originalMessage, - const MessageFlags &messageFlags, bool self)>; - Checker cb; -}; +enum class MessageFlag : std::int64_t; +using MessageFlags = FlagsEnum; class HighlightController final { diff --git a/src/controllers/highlights/HighlightResult.cpp b/src/controllers/highlights/HighlightResult.cpp new file mode 100644 index 00000000..af219e5f --- /dev/null +++ b/src/controllers/highlights/HighlightResult.cpp @@ -0,0 +1,88 @@ +#include "controllers/highlights/HighlightResult.hpp" + +namespace chatterino { + +HighlightResult::HighlightResult(bool _alert, bool _playSound, + std::optional _customSoundUrl, + std::shared_ptr _color, + bool _showInMentions) + : alert(_alert) + , playSound(_playSound) + , customSoundUrl(std::move(_customSoundUrl)) + , color(std::move(_color)) + , showInMentions(_showInMentions) +{ +} + +HighlightResult HighlightResult::emptyResult() +{ + return { + false, false, std::nullopt, nullptr, false, + }; +} + +bool HighlightResult::operator==(const HighlightResult &other) const +{ + if (this->alert != other.alert) + { + return false; + } + if (this->playSound != other.playSound) + { + return false; + } + if (this->customSoundUrl != other.customSoundUrl) + { + return false; + } + + if (this->color && other.color) + { + if (*this->color != *other.color) + { + return false; + } + } + + if (this->showInMentions != other.showInMentions) + { + return false; + } + + return true; +} + +bool HighlightResult::operator!=(const HighlightResult &other) const +{ + return !(*this == other); +} + +bool HighlightResult::empty() const +{ + return !this->alert && !this->playSound && + !this->customSoundUrl.has_value() && !this->color && + !this->showInMentions; +} + +bool HighlightResult::full() const +{ + return this->alert && this->playSound && this->customSoundUrl.has_value() && + this->color && this->showInMentions; +} + +std::ostream &operator<<(std::ostream &os, const HighlightResult &result) +{ + os << "Alert: " << (result.alert ? "Yes" : "No") << ", " + << "Play sound: " << (result.playSound ? "Yes" : "No") << " (" + << (result.customSoundUrl + ? result.customSoundUrl->toString().toStdString() + : "") + << ")" + << ", " + << "Color: " << (result.color ? result.color->name().toStdString() : "") + << ", " + << "Show in mentions: " << (result.showInMentions ? "Yes" : "No"); + return os; +} + +} // namespace chatterino diff --git a/src/controllers/highlights/HighlightResult.hpp b/src/controllers/highlights/HighlightResult.hpp new file mode 100644 index 00000000..eb6a32d6 --- /dev/null +++ b/src/controllers/highlights/HighlightResult.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace chatterino { + +struct HighlightResult { + HighlightResult(bool _alert, bool _playSound, + std::optional _customSoundUrl, + std::shared_ptr _color, bool _showInMentions); + + /** + * @brief Construct an empty HighlightResult with all side-effects disabled + **/ + static HighlightResult emptyResult(); + + /** + * @brief true if highlight should trigger the taskbar to flash + **/ + bool alert{false}; + + /** + * @brief true if highlight should play a notification sound + **/ + bool playSound{false}; + + /** + * @brief Can be set to a different sound that should play when this highlight is activated + * + * May only be set if playSound is true + **/ + std::optional customSoundUrl{}; + + /** + * @brief set if highlight should set a background color + **/ + std::shared_ptr color{}; + + /** + * @brief true if highlight should show message in the /mentions split + **/ + bool showInMentions{false}; + + bool operator==(const HighlightResult &other) const; + bool operator!=(const HighlightResult &other) const; + + /** + * @brief Returns true if no side-effect has been enabled + **/ + [[nodiscard]] bool empty() const; + + /** + * @brief Returns true if all side-effects have been enabled + **/ + [[nodiscard]] bool full() const; + + friend std::ostream &operator<<(std::ostream &os, + const HighlightResult &result); +}; + +} // namespace chatterino diff --git a/src/messages/MessageBuilder.cpp b/src/messages/MessageBuilder.cpp index 594d883b..8077c098 100644 --- a/src/messages/MessageBuilder.cpp +++ b/src/messages/MessageBuilder.cpp @@ -7,6 +7,7 @@ #include "controllers/accounts/AccountController.hpp" #include "controllers/emotes/EmoteController.hpp" #include "controllers/highlights/HighlightController.hpp" +#include "controllers/highlights/HighlightResult.hpp" #include "controllers/ignores/IgnoreController.hpp" #include "controllers/ignores/IgnorePhrase.hpp" #include "controllers/userdata/UserDataController.hpp" diff --git a/src/providers/twitch/eventsub/Connection.cpp b/src/providers/twitch/eventsub/Connection.cpp index f5474eb9..ab76cb4b 100644 --- a/src/providers/twitch/eventsub/Connection.cpp +++ b/src/providers/twitch/eventsub/Connection.cpp @@ -4,6 +4,7 @@ #include "common/QLogging.hpp" #include "controllers/accounts/AccountController.hpp" #include "controllers/highlights/HighlightController.hpp" +#include "controllers/highlights/HighlightResult.hpp" #include "messages/Message.hpp" #include "messages/MessageBuilder.hpp" #include "providers/twitch/eventsub/Controller.hpp" diff --git a/tests/README.md b/tests/README.md index f3c62c51..bbb93ae2 100644 --- a/tests/README.md +++ b/tests/README.md @@ -12,6 +12,8 @@ After you've built Chatterino, you can now run the tests with `ctest` or by manu We expect this to be listening to port 9050, you can launch it like this: `twitch-pubsub-server-test 127.0.0.1:9050` +Alternatively, you can run the docker-compose defined in this file: `docker compose up` before you run the tests. + # Modifying message building If you make a change that has to do with message building, there's a big chance that some of the snapshot tests will fail. diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml new file mode 100644 index 00000000..a61cd5f0 --- /dev/null +++ b/tests/docker-compose.yml @@ -0,0 +1,14 @@ +services: + http-server: + restart: always + image: ghcr.io/kevinastone/httpbox:master + command: "--port 9051" + ports: + - "9051:9051" + pubsub-server: + restart: always + image: ghcr.io/chatterino/twitch-pubsub-server-test:latest + command: "./server 0.0.0.0:9050 0.0.0.0:9052" + ports: + - "9050:9050" + - "9052:9052" diff --git a/tests/src/HighlightController.cpp b/tests/src/HighlightController.cpp index d36713a9..4f9aee45 100644 --- a/tests/src/HighlightController.cpp +++ b/tests/src/HighlightController.cpp @@ -2,6 +2,7 @@ #include "controllers/accounts/AccountController.hpp" #include "controllers/highlights/HighlightPhrase.hpp" +#include "controllers/highlights/HighlightResult.hpp" #include "messages/MessageBuilder.hpp" // for MessageParseArgs #include "mocks/BaseApplication.hpp" #include "mocks/Helix.hpp"