From 32d269dffce303322b983592ded74dcd65c3b258 Mon Sep 17 00:00:00 2001 From: pajlada Date: Sat, 17 Feb 2024 13:26:54 +0100 Subject: [PATCH] feat: add the ability to unit test some aspects of SplitInput (#5179) --- CHANGELOG.md | 1 + mocks/include/mocks/TwitchIrcServer.hpp | 6 ++ src/providers/twitch/TwitchIrcServer.cpp | 5 ++ src/providers/twitch/TwitchIrcServer.hpp | 4 + src/widgets/splits/SplitInput.cpp | 13 ++- src/widgets/splits/SplitInput.hpp | 7 ++ tests/CMakeLists.txt | 1 + tests/src/SplitInput.cpp | 109 +++++++++++++++++++++++ 8 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 tests/src/SplitInput.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index e904f9aa7..182d67839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,7 @@ - Dev: Replace `boost::optional` with `std::optional`. (#4877) - Dev: Improve performance of selecting text. (#4889, #4911) - Dev: Removed direct dependency on Qt 5 compatibility module. (#4906) +- Dev: Added unit test capabilities to SplitInput. (#5179) - Dev: Refactor `Emoji`'s EmojiMap into a vector. (#4980) - Dev: Refactor `DebugCount` and add copy button to debug popup. (#4921) - Dev: Refactor `common/Credentials`. (#4979) diff --git a/mocks/include/mocks/TwitchIrcServer.hpp b/mocks/include/mocks/TwitchIrcServer.hpp index 2ef163db6..976d6f2ad 100644 --- a/mocks/include/mocks/TwitchIrcServer.hpp +++ b/mocks/include/mocks/TwitchIrcServer.hpp @@ -24,8 +24,14 @@ public: return this->watchingChannel; } + QString getLastUserThatWhisperedMe() const override + { + return this->lastUserThatWhisperedMe; + } + ChannelPtr watchingChannelInner; IndirectChannel watchingChannel; + QString lastUserThatWhisperedMe{"forsen"}; }; } // namespace chatterino::mock diff --git a/src/providers/twitch/TwitchIrcServer.cpp b/src/providers/twitch/TwitchIrcServer.cpp index acad48f86..d7fbdc4d0 100644 --- a/src/providers/twitch/TwitchIrcServer.cpp +++ b/src/providers/twitch/TwitchIrcServer.cpp @@ -525,6 +525,11 @@ const IndirectChannel &TwitchIrcServer::getWatchingChannel() const return this->watchingChannel; } +QString TwitchIrcServer::getLastUserThatWhisperedMe() const +{ + return this->lastUserThatWhisperedMe.get(); +} + void TwitchIrcServer::reloadBTTVGlobalEmotes() { getIApp()->getBttvEmotes()->loadEmotes(); diff --git a/src/providers/twitch/TwitchIrcServer.hpp b/src/providers/twitch/TwitchIrcServer.hpp index 6fe36c0a2..53db35964 100644 --- a/src/providers/twitch/TwitchIrcServer.hpp +++ b/src/providers/twitch/TwitchIrcServer.hpp @@ -29,6 +29,8 @@ public: virtual const IndirectChannel &getWatchingChannel() const = 0; + virtual QString getLastUserThatWhisperedMe() const = 0; + // Update this interface with TwitchIrcServer methods as needed }; @@ -81,6 +83,8 @@ public: const IndirectChannel &getWatchingChannel() const override; + QString getLastUserThatWhisperedMe() const override; + protected: void initializeConnection(IrcConnection *connection, ConnectionType type) override; diff --git a/src/widgets/splits/SplitInput.cpp b/src/widgets/splits/SplitInput.cpp index e39b9d082..81707a066 100644 --- a/src/widgets/splits/SplitInput.cpp +++ b/src/widgets/splits/SplitInput.cpp @@ -78,7 +78,7 @@ SplitInput::SplitInput(QWidget *parent, Split *_chatWidget, void SplitInput::initLayout() { - auto *app = getApp(); + auto *app = getIApp(); LayoutCreator layoutCreator(this); auto layout = @@ -202,7 +202,7 @@ void SplitInput::initLayout() void SplitInput::scaleChangedEvent(float scale) { - auto *app = getApp(); + auto *app = getIApp(); // update the icon size of the buttons this->updateEmoteButton(); this->updateCancelReplyButton(); @@ -919,9 +919,14 @@ bool SplitInput::isHidden() const return this->hidden; } +void SplitInput::setInputText(const QString &newInputText) +{ + this->ui_.textEdit->setPlainText(newInputText); +} + void SplitInput::editTextChanged() { - auto *app = getApp(); + auto *app = getIApp(); // set textLengthLabel value QString text = this->ui_.textEdit->toPlainText(); @@ -936,7 +941,7 @@ void SplitInput::editTextChanged() if (text.startsWith("/r ", Qt::CaseInsensitive) && this->split_->getChannel()->isTwitchChannel()) { - QString lastUser = app->twitch->lastUserThatWhisperedMe.get(); + auto lastUser = app->getTwitch()->getLastUserThatWhisperedMe(); if (!lastUser.isEmpty()) { this->ui_.textEdit->setPlainText("/w " + lastUser + text.mid(2)); diff --git a/src/widgets/splits/SplitInput.hpp b/src/widgets/splits/SplitInput.hpp index d1eb64007..f66d5d27f 100644 --- a/src/widgets/splits/SplitInput.hpp +++ b/src/widgets/splits/SplitInput.hpp @@ -66,6 +66,13 @@ public: **/ bool isHidden() const; + /** + * @brief Sets the text of this input + * + * This method should only be used in tests + */ + void setInputText(const QString &newInputText); + pajlada::Signals::Signal textChanged; pajlada::Signals::NoArgSignal selectionChanged; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3aadc2543..564d6ad47 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -37,6 +37,7 @@ set(test_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/XDGHelper.cpp ${CMAKE_CURRENT_LIST_DIR}/src/Selection.cpp ${CMAKE_CURRENT_LIST_DIR}/src/NotebookTab.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/SplitInput.cpp # Add your new file above this line! ) diff --git a/tests/src/SplitInput.cpp b/tests/src/SplitInput.cpp new file mode 100644 index 000000000..8f5667bde --- /dev/null +++ b/tests/src/SplitInput.cpp @@ -0,0 +1,109 @@ +#include "widgets/splits/SplitInput.hpp" + +#include "common/Literals.hpp" +#include "controllers/accounts/AccountController.hpp" +#include "controllers/commands/Command.hpp" +#include "controllers/commands/CommandController.hpp" +#include "controllers/hotkeys/HotkeyController.hpp" +#include "mocks/EmptyApplication.hpp" +#include "singletons/Emotes.hpp" +#include "singletons/Fonts.hpp" +#include "singletons/Paths.hpp" +#include "singletons/Theme.hpp" +#include "singletons/WindowManager.hpp" +#include "widgets/Notebook.hpp" +#include "widgets/splits/Split.hpp" + +#include +#include +#include +#include + +using namespace chatterino; +using ::testing::Exactly; + +namespace { + +class MockApplication : mock::EmptyApplication +{ +public: + MockApplication() + : windowManager(this->paths) + { + } + Theme *getThemes() override + { + return &this->theme; + } + + HotkeyController *getHotkeys() override + { + return &this->hotkeys; + } + + Fonts *getFonts() override + { + return &this->fonts; + } + + WindowManager *getWindows() override + { + return &this->windowManager; + } + + AccountController *getAccounts() override + { + return &this->accounts; + } + + CommandController *getCommands() override + { + return &this->commands; + } + + IEmotes *getEmotes() override + { + return &this->emotes; + } + + Theme theme; + HotkeyController hotkeys; + Fonts fonts; + Paths paths; + WindowManager windowManager; + AccountController accounts; + CommandController commands; + Emotes emotes; +}; + +class SplitInputFixture : public ::testing::Test +{ +protected: + SplitInputFixture() + : split(new Split(nullptr)) + , input(this->split) + { + } + + MockApplication mockApplication; + Split *split; + SplitInput input; +}; + +} // namespace + +TEST_F(SplitInputFixture, Reply) +{ + ASSERT_EQ("", this->input.getInputText()); + this->input.setInputText("forsen"); + ASSERT_EQ("forsen", this->input.getInputText()); + auto *message = new Message(); + message->displayName = "xd"; + auto reply = MessagePtr(message); + this->input.setReply(reply); + QString expected("@xd forsen "); + QString actual = this->input.getInputText(); + ASSERT_EQ(expected, actual) + << "Input text after setReply should be '" << qUtf8Printable(expected) + << "', but got '" << qUtf8Printable(actual) << "'"; +}