Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add input completion test suite #4644

Merged
merged 21 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Dev: Added command to set Qt's logging filter/rules at runtime (`/c2-set-logging-rules`). (#4637)
- Dev: Added the ability to see & load custom themes from the Themes directory. No stable promises are made of this feature, changes might be made that breaks custom themes without notice. (#4570)
- Dev: Added test cases for emote and tab completion. (#4644)

## 2.4.4

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ int main(int argc, char **argv)
::benchmark::Initialize(&argc, argv);

// Ensure settings are initialized before any tests are run
chatterino::Settings settings("/tmp/c2-empty-test");
chatterino::Settings settings("/tmp/c2-empty-mock");

QtConcurrent::run([&app] {
::benchmark::RunSpecifiedBenchmarks();
Expand Down
2 changes: 1 addition & 1 deletion mocks/include/mocks/EmptyApplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class EmptyApplication : public IApplication
return nullptr;
}

TwitchIrcServer *getTwitch() override
ITwitchIrcServer *getTwitch() override
{
return nullptr;
}
Expand Down
5 changes: 5 additions & 0 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ IUserDataController *Application::getUserData()
return this->userData;
}

ITwitchIrcServer *Application::getTwitch()
{
return this->twitch;
}

void Application::save()
{
for (auto &singleton : this->singletons_)
Expand Down
8 changes: 3 additions & 5 deletions src/Application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace chatterino {

class TwitchIrcServer;
class ITwitchIrcServer;
class PubSub;

class CommandController;
Expand Down Expand Up @@ -55,7 +56,7 @@ class IApplication
virtual CommandController *getCommands() = 0;
virtual HighlightController *getHighlights() = 0;
virtual NotificationController *getNotifications() = 0;
virtual TwitchIrcServer *getTwitch() = 0;
virtual ITwitchIrcServer *getTwitch() = 0;
virtual ChatterinoBadges *getChatterinoBadges() = 0;
virtual FfzBadges *getFfzBadges() = 0;
virtual IUserDataController *getUserData() = 0;
Expand Down Expand Up @@ -141,10 +142,7 @@ class Application : public IApplication
{
return this->highlights;
}
TwitchIrcServer *getTwitch() override
{
return this->twitch;
}
ITwitchIrcServer *getTwitch() override;
ChatterinoBadges *getChatterinoBadges() override
{
return this->chatterinoBadges;
Expand Down
31 changes: 23 additions & 8 deletions src/common/CompletionModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ void CompletionModel::refresh(const QString &prefix, bool isFirstWord)
return;
}

auto *app = getIApp();
// Twitch channel
auto *tc = dynamic_cast<TwitchChannel *>(&this->channel_);

Expand Down Expand Up @@ -130,7 +131,7 @@ void CompletionModel::refresh(const QString &prefix, bool isFirstWord)
}
};

if (auto account = getApp()->accounts->twitch.getCurrent())
if (auto account = app->getAccounts()->twitch.getCurrent())
{
// Twitch Emotes available globally
for (const auto &emote : account->accessEmotes()->emotes)
Expand All @@ -153,26 +154,27 @@ void CompletionModel::refresh(const QString &prefix, bool isFirstWord)

// 7TV Global
for (const auto &emote :
*getApp()->twitch->getSeventvEmotes().globalEmotes())
*app->getTwitch()->getSeventvEmotes().globalEmotes())
{
addString(emote.first.string, TaggedString::Type::SeventvGlobalEmote);
}
// Bttv Global
for (const auto &emote : *getApp()->twitch->getBttvEmotes().emotes())
for (const auto &emote : *app->getTwitch()->getBttvEmotes().emotes())
{
addString(emote.first.string, TaggedString::Type::BTTVChannelEmote);
}

// Ffz Global
for (const auto &emote : *getApp()->twitch->getFfzEmotes().emotes())
for (const auto &emote : *app->getTwitch()->getFfzEmotes().emotes())
{
addString(emote.first.string, TaggedString::Type::FFZChannelEmote);
}

// Emojis
if (prefix.startsWith(":"))
{
const auto &emojiShortCodes = getApp()->emotes->emojis.shortCodes;
const auto &emojiShortCodes =
app->getEmotes()->getEmojis()->getShortCodes();
for (const auto &m : emojiShortCodes)
{
addString(QString(":%1:").arg(m), TaggedString::Type::Emoji);
Expand Down Expand Up @@ -231,20 +233,20 @@ void CompletionModel::refresh(const QString &prefix, bool isFirstWord)
addString(emote.first.string, TaggedString::Type::BTTVGlobalEmote);
}
#ifdef CHATTERINO_HAVE_PLUGINS
for (const auto &command : getApp()->commands->pluginCommands())
for (const auto &command : app->getCommands()->pluginCommands())
{
addString(command, TaggedString::PluginCommand);
}
#endif
// Custom Chatterino commands
for (const auto &command : getApp()->commands->items)
for (const auto &command : app->getCommands()->items)
{
addString(command.name, TaggedString::CustomCommand);
}

// Default Chatterino commands
for (const auto &command :
getApp()->commands->getDefaultChatterinoCommandList())
app->getCommands()->getDefaultChatterinoCommandList())
{
addString(command, TaggedString::ChatterinoCommand);
}
Expand All @@ -256,6 +258,19 @@ void CompletionModel::refresh(const QString &prefix, bool isFirstWord)
}
}

std::vector<QString> CompletionModel::allItems() const
{
std::shared_lock lock(this->itemsMutex_);

std::vector<QString> results;
results.reserve(this->items_.size());
for (const auto &item : this->items_)
{
results.push_back(item.string);
}
return results;
}

bool CompletionModel::compareStrings(const QString &a, const QString &b)
{
// try comparing insensitively, if they are the same then senstively
Expand Down
6 changes: 6 additions & 0 deletions src/common/CompletionModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <set>
#include <shared_mutex>

class InputCompletionTest;

namespace chatterino {

class Channel;
Expand Down Expand Up @@ -60,10 +62,14 @@ class CompletionModel : public QAbstractListModel
static bool compareStrings(const QString &a, const QString &b);

private:
std::vector<QString> allItems() const;

mutable std::shared_mutex itemsMutex_;
std::set<TaggedString> items_;

Channel &channel_;

friend class ::InputCompletionTest;
};

} // namespace chatterino
9 changes: 7 additions & 2 deletions src/providers/bttv/BttvEmotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ void BttvEmotes::loadEmotes()
{
if (!Settings::instance().enableBTTVGlobalEmotes)
{
this->global_.set(EMPTY_EMOTE_MAP);
this->setEmotes(EMPTY_EMOTE_MAP);
return;
}

Expand All @@ -203,13 +203,18 @@ void BttvEmotes::loadEmotes()
auto emotes = this->global_.get();
auto pair = parseGlobalEmotes(result.parseJsonArray(), *emotes);
if (pair.first)
this->global_.set(
this->setEmotes(
std::make_shared<EmoteMap>(std::move(pair.second)));
return pair.first;
})
.execute();
}

void BttvEmotes::setEmotes(std::shared_ptr<const EmoteMap> emotes)
{
this->global_.set(std::move(emotes));
}

void BttvEmotes::loadChannel(std::weak_ptr<Channel> channel,
const QString &channelId,
const QString &channelDisplayName,
Expand Down
1 change: 1 addition & 0 deletions src/providers/bttv/BttvEmotes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class BttvEmotes final
std::shared_ptr<const EmoteMap> emotes() const;
boost::optional<EmotePtr> emote(const EmoteName &name) const;
void loadEmotes();
void setEmotes(std::shared_ptr<const EmoteMap> emotes);
static void loadChannel(std::weak_ptr<Channel> channel,
const QString &channelId,
const QString &channelDisplayName,
Expand Down
14 changes: 12 additions & 2 deletions src/providers/emoji/Emojis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ void Emojis::loadEmojiSet()
}

std::vector<boost::variant<EmotePtr, QString>> Emojis::parse(
const QString &text)
const QString &text) const
{
auto result = std::vector<boost::variant<EmotePtr, QString>>();
int lastParsedEmojiEndIndex = 0;
Expand Down Expand Up @@ -359,7 +359,7 @@ std::vector<boost::variant<EmotePtr, QString>> Emojis::parse(
return result;
}

QString Emojis::replaceShortCodes(const QString &text)
QString Emojis::replaceShortCodes(const QString &text) const
{
QString ret(text);
auto it = this->findShortCodesRegex_.globalMatch(text);
Expand Down Expand Up @@ -393,4 +393,14 @@ QString Emojis::replaceShortCodes(const QString &text)
return ret;
}

const EmojiMap &Emojis::getEmojis() const
{
return this->emojis;
}

const std::vector<QString> &Emojis::getShortCodes() const
{
return this->shortCodes;
}

} // namespace chatterino
22 changes: 19 additions & 3 deletions src/providers/emoji/Emojis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,32 @@ struct EmojiData {

using EmojiMap = ConcurrentMap<QString, std::shared_ptr<EmojiData>>;

class Emojis
class IEmojis
{
public:
virtual ~IEmojis() = default;

virtual std::vector<boost::variant<EmotePtr, QString>> parse(
const QString &text) const = 0;
virtual const EmojiMap &getEmojis() const = 0;
virtual const std::vector<QString> &getShortCodes() const = 0;
virtual QString replaceShortCodes(const QString &text) const = 0;
};

class Emojis : public IEmojis
{
public:
void initialize();
void load();
std::vector<boost::variant<EmotePtr, QString>> parse(const QString &text);
std::vector<boost::variant<EmotePtr, QString>> parse(
const QString &text) const override;

EmojiMap emojis;
std::vector<QString> shortCodes;
QString replaceShortCodes(const QString &text);
QString replaceShortCodes(const QString &text) const override;

const EmojiMap &getEmojis() const override;
const std::vector<QString> &getShortCodes() const override;

private:
void loadEmojis();
Expand Down
9 changes: 7 additions & 2 deletions src/providers/ffz/FfzEmotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ void FfzEmotes::loadEmotes()
{
if (!Settings::instance().enableFFZGlobalEmotes)
{
this->global_.set(EMPTY_EMOTE_MAP);
this->setEmotes(EMPTY_EMOTE_MAP);
return;
}

Expand All @@ -199,13 +199,18 @@ void FfzEmotes::loadEmotes()
.timeout(30000)
.onSuccess([this](auto result) -> Outcome {
auto parsedSet = parseGlobalEmotes(result.parseJson());
this->global_.set(std::make_shared<EmoteMap>(std::move(parsedSet)));
this->setEmotes(std::make_shared<EmoteMap>(std::move(parsedSet)));

return Success;
})
.execute();
}

void FfzEmotes::setEmotes(std::shared_ptr<const EmoteMap> emotes)
{
this->global_.set(std::move(emotes));
}

void FfzEmotes::loadChannel(
std::weak_ptr<Channel> channel, const QString &channelID,
std::function<void(EmoteMap &&)> emoteCallback,
Expand Down
1 change: 1 addition & 0 deletions src/providers/ffz/FfzEmotes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class FfzEmotes final
std::shared_ptr<const EmoteMap> emotes() const;
boost::optional<EmotePtr> emote(const EmoteName &name) const;
void loadEmotes();
void setEmotes(std::shared_ptr<const EmoteMap> emotes);
static void loadChannel(
std::weak_ptr<Channel> channel, const QString &channelId,
std::function<void(EmoteMap &&)> emoteCallback,
Expand Down
10 changes: 8 additions & 2 deletions src/providers/seventv/SeventvEmotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ void SeventvEmotes::loadGlobalEmotes()
{
if (!Settings::instance().enableSevenTVGlobalEmotes)
{
this->global_.set(EMPTY_EMOTE_MAP);
this->setGlobalEmotes(EMPTY_EMOTE_MAP);
return;
}

Expand All @@ -289,7 +289,8 @@ void SeventvEmotes::loadGlobalEmotes()
auto emoteMap = parseEmotes(parsedEmotes, true);
qCDebug(chatterinoSeventv)
<< "Loaded" << emoteMap.size() << "7TV Global Emotes";
this->global_.set(std::make_shared<EmoteMap>(std::move(emoteMap)));
this->setGlobalEmotes(
std::make_shared<EmoteMap>(std::move(emoteMap)));

return Success;
})
Expand All @@ -300,6 +301,11 @@ void SeventvEmotes::loadGlobalEmotes()
.execute();
}

void SeventvEmotes::setGlobalEmotes(std::shared_ptr<const EmoteMap> emotes)
{
this->global_.set(std::move(emotes));
}

void SeventvEmotes::loadChannelEmotes(
const std::weak_ptr<Channel> &channel, const QString &channelId,
std::function<void(EmoteMap &&, ChannelInfo)> callback, bool manualRefresh)
Expand Down
1 change: 1 addition & 0 deletions src/providers/seventv/SeventvEmotes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class SeventvEmotes final
std::shared_ptr<const EmoteMap> globalEmotes() const;
boost::optional<EmotePtr> globalEmote(const EmoteName &name) const;
void loadGlobalEmotes();
void setGlobalEmotes(std::shared_ptr<const EmoteMap> emotes);
static void loadChannelEmotes(
const std::weak_ptr<Channel> &channel, const QString &channelId,
std::function<void(EmoteMap &&, ChannelInfo)> callback,
Expand Down
Loading