tests: better test initializing allowing for better printing (#5379)

Co-authored-by: Nerixyz <nerixdev@outlook.de>
This commit is contained in:
pajlada 2024-05-05 15:01:07 +02:00 committed by GitHub
parent a88a2ac65c
commit 401feac0aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 198 additions and 178 deletions

View file

@ -3,6 +3,7 @@
## Unversioned
- Dev: Add doxygen build target. (#5377)
- Dev: Make printing of strings in tests easier. (#5379)
## 2.5.1

View file

@ -5,7 +5,8 @@ option(CHATTERINO_TEST_USE_PUBLIC_HTTPBIN "Use public httpbin for testing networ
set(test_SOURCES
${CMAKE_CURRENT_LIST_DIR}/src/main.cpp
${CMAKE_CURRENT_LIST_DIR}/resources/test-resources.qrc
${CMAKE_CURRENT_LIST_DIR}/src/TestHelpers.hpp
${CMAKE_CURRENT_LIST_DIR}/src/Test.hpp
${CMAKE_CURRENT_LIST_DIR}/src/Test.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ChannelChatters.cpp
${CMAKE_CURRENT_LIST_DIR}/src/AccessGuard.cpp
${CMAKE_CURRENT_LIST_DIR}/src/NetworkCommon.cpp

View file

@ -1,6 +1,6 @@
#include "common/UniqueAccess.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QDebug>
#include <QString>

View file

@ -1,7 +1,7 @@
#include "providers/liveupdates/BasicPubSubClient.hpp"
#include "providers/liveupdates/BasicPubSubManager.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>

View file

@ -1,6 +1,7 @@
#include "providers/bttv/BttvLiveUpdates.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <QString>
#include <optional>

View file

@ -1,8 +1,8 @@
#include "common/ChannelChatters.hpp"
#include "mocks/Channel.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QColor>
#include <QStringList>

View file

@ -1,6 +1,7 @@
#include "common/ChatterSet.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <QStringList>
TEST(ChatterSet, insert)

View file

@ -1,9 +1,8 @@
#include "providers/emoji/Emojis.hpp"
#include "common/Literals.hpp"
#include "TestHelpers.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QDebug>
#include <QString>

View file

@ -1,6 +1,6 @@
#include "util/ExponentialBackoff.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;

View file

@ -13,8 +13,8 @@
#include "providers/twitch/TwitchBadge.hpp"
#include "providers/twitch/TwitchMessageBuilder.hpp"
#include "singletons/Emotes.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QColor>
#include <QVariant>
@ -101,7 +101,7 @@ namespace chatterino::filters {
std::ostream &operator<<(std::ostream &os, Type t)
{
os << qUtf8Printable(typeToString(t));
os << typeToString(t);
return os;
}
@ -138,8 +138,8 @@ TEST(Filters, Validity)
auto filterResult = Filter::fromString(input);
bool isValid = std::holds_alternative<Filter>(filterResult);
EXPECT_EQ(isValid, expected)
<< "Filter::fromString( " << qUtf8Printable(input)
<< " ) should be " << (expected ? "valid" : "invalid");
<< "Filter::fromString( " << input << " ) should be "
<< (expected ? "valid" : "invalid");
}
}
@ -168,15 +168,14 @@ TEST(Filters, TypeSynthesis)
{
auto filterResult = Filter::fromString(input);
bool isValid = std::holds_alternative<Filter>(filterResult);
ASSERT_TRUE(isValid) << "Filter::fromString( " << qUtf8Printable(input)
<< " ) is invalid";
ASSERT_TRUE(isValid)
<< "Filter::fromString( " << input << " ) is invalid";
auto filter = std::move(std::get<Filter>(filterResult));
T type = filter.returnType();
EXPECT_EQ(type, expected)
<< "Filter{ " << qUtf8Printable(input) << " } has type " << type
<< " instead of " << expected << ".\nDebug: "
<< qUtf8Printable(filter.debugString(typingContext));
<< "Filter{ " << input << " } has type " << type << " instead of "
<< expected << ".\nDebug: " << filter.debugString(typingContext);
}
}
@ -244,17 +243,16 @@ TEST(Filters, Evaluation)
{
auto filterResult = Filter::fromString(input);
bool isValid = std::holds_alternative<Filter>(filterResult);
ASSERT_TRUE(isValid) << "Filter::fromString( " << qUtf8Printable(input)
<< " ) is invalid";
ASSERT_TRUE(isValid)
<< "Filter::fromString( " << input << " ) is invalid";
auto filter = std::move(std::get<Filter>(filterResult));
auto result = filter.execute(contextMap);
EXPECT_EQ(result, expected)
<< "Filter{ " << qUtf8Printable(input) << " } evaluated to "
<< qUtf8Printable(result.toString()) << " instead of "
<< qUtf8Printable(expected.toString()) << ".\nDebug: "
<< qUtf8Printable(filter.debugString(typingContext));
<< "Filter{ " << input << " } evaluated to " << result.toString()
<< " instead of " << expected.toString()
<< ".\nDebug: " << filter.debugString(typingContext);
}
}
@ -354,20 +352,17 @@ TEST_F(FiltersF, ExpressionDebug)
{
const auto filterResult = Filter::fromString(input);
const auto *filter = std::get_if<Filter>(&filterResult);
EXPECT_NE(filter, nullptr)
<< "Filter::fromString(" << qUtf8Printable(input)
EXPECT_NE(filter, nullptr) << "Filter::fromString(" << input
<< ") did not build a proper filter";
const auto actualDebugString = filter->debugString(typingContext);
EXPECT_EQ(actualDebugString, debugString)
<< "filter->debugString() on '" << qUtf8Printable(input)
<< "' should be '" << qUtf8Printable(debugString) << "', but got '"
<< qUtf8Printable(actualDebugString) << "'";
<< "filter->debugString() on '" << input << "' should be '"
<< debugString << "', but got '" << actualDebugString << "'";
const auto actualFilterString = filter->filterString();
EXPECT_EQ(actualFilterString, filterString)
<< "filter->filterString() on '" << qUtf8Printable(input)
<< "' should be '" << qUtf8Printable(filterString) << "', but got '"
<< qUtf8Printable(actualFilterString) << "'";
<< "filter->filterString() on '" << input << "' should be '"
<< filterString << "', but got '" << actualFilterString << "'";
}
}

View file

@ -1,6 +1,6 @@
#include "util/FormatTime.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <chrono>
@ -62,8 +62,8 @@ TEST(FormatTime, Int)
const auto actual = formatTime(input);
EXPECT_EQ(actual, expected)
<< qUtf8Printable(actual) << " (" << input
<< ") did not match expected value " << qUtf8Printable(expected);
<< actual << " (" << input << ") did not match expected value "
<< expected;
}
}
@ -130,8 +130,8 @@ TEST(FormatTime, QString)
const auto actual = formatTime(input);
EXPECT_EQ(actual, expected)
<< qUtf8Printable(actual) << " (" << qUtf8Printable(input)
<< ") did not match expected value " << qUtf8Printable(expected);
<< actual << " (" << input << ") did not match expected value "
<< expected;
}
}
@ -202,7 +202,6 @@ TEST(FormatTime, chrono)
const auto actual = formatTime(input);
EXPECT_EQ(actual, expected)
<< qUtf8Printable(actual) << " did not match expected value "
<< qUtf8Printable(expected);
<< actual << " did not match expected value " << expected;
}
}

View file

@ -1,6 +1,6 @@
#include "util/Helpers.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;
using namespace _helpers_internal;
@ -275,8 +275,8 @@ TEST(Helpers, skipSpace)
const auto actual = skipSpace(makeView(c.input), c.startIdx);
EXPECT_EQ(actual, c.expected)
<< actual << " (" << qUtf8Printable(c.input)
<< ") did not match expected value " << c.expected;
<< actual << " (" << c.input << ") did not match expected value "
<< c.expected;
}
}
@ -418,14 +418,13 @@ TEST(Helpers, findUnitMultiplierToSec)
if (c.expectedMultiplier == bad)
{
EXPECT_FALSE(actual.second) << qUtf8Printable(c.input);
EXPECT_FALSE(actual.second) << c.input;
}
else
{
EXPECT_TRUE(pos == c.expectedEndPos && actual.second &&
actual.first == c.expectedMultiplier)
<< qUtf8Printable(c.input)
<< ": Expected(end: " << c.expectedEndPos
<< c.input << ": Expected(end: " << c.expectedEndPos
<< ", mult: " << c.expectedMultiplier << ") Actual(end: " << pos
<< ", mult: " << actual.first << ")";
}
@ -503,7 +502,7 @@ TEST(Helpers, parseDurationToSeconds)
const auto actual = parseDurationToSeconds(c.input, c.noUnitMultiplier);
EXPECT_EQ(actual, c.output)
<< actual << " (" << qUtf8Printable(c.input)
<< ") did not match expected value " << c.output;
<< actual << " (" << c.input << ") did not match expected value "
<< c.output;
}
}

View file

@ -10,9 +10,8 @@
#include "providers/twitch/TwitchBadge.hpp" // for Badge
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "Test.hpp"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <QDebug>
#include <QDir>
#include <QFile>
@ -216,11 +215,9 @@ protected:
input.originalMessage, input.flags);
EXPECT_EQ(isMatch, expected.state)
<< qUtf8Printable(input.senderName) << ": "
<< qUtf8Printable(input.originalMessage);
<< input.senderName << ": " << input.originalMessage;
EXPECT_EQ(matchResult, expected.result)
<< qUtf8Printable(input.senderName) << ": "
<< qUtf8Printable(input.originalMessage);
<< input.senderName << ": " << input.originalMessage;
}
}

View file

@ -1,6 +1,6 @@
#include "controllers/highlights/HighlightPhrase.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;

View file

@ -1,6 +1,5 @@
#include "controllers/hotkeys/HotkeyHelpers.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <vector>

View file

@ -12,9 +12,9 @@
#include "singletons/Emotes.hpp"
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "Test.hpp"
#include "widgets/splits/InputCompletionPopup.hpp"
#include <gtest/gtest.h>
#include <QDir>
#include <QFile>
#include <QModelIndex>
@ -224,7 +224,7 @@ void containsRoughly(std::span<EmoteItem> span, std::set<QString> values)
}
}
ASSERT_TRUE(found) << qPrintable(v) << " was not found in the span";
ASSERT_TRUE(found) << v << " was not found in the span";
}
}

View file

@ -1,6 +1,7 @@
#include "util/IrcHelpers.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <QApplication>
#include <QDebug>
#include <QtConcurrent>
@ -55,7 +56,7 @@ TEST(IrcHelpers, ParseTagString)
const auto actual = parseTagString(input);
EXPECT_EQ(actual, expected)
<< qUtf8Printable(actual) << " (" << qUtf8Printable(input)
<< ") did not match expected value " << qUtf8Printable(expected);
<< actual << " (" << input << ") did not match expected value "
<< expected;
}
}

View file

@ -1,6 +1,6 @@
#include "messages/LimitedQueue.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <vector>

View file

@ -2,8 +2,7 @@
#include "common/Literals.hpp"
#include "SignalSpy.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;
using namespace literals;

View file

@ -1,8 +1,7 @@
#include "common/LinkParser.hpp"
#include "TestHelpers.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QString>
#include <QStringList>

View file

@ -1,6 +1,6 @@
#include "common/Literals.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino::literals;

View file

@ -10,8 +10,8 @@
#include "singletons/Settings.hpp"
#include "singletons/Theme.hpp"
#include "singletons/WindowManager.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QDebug>
#include <QString>

View file

@ -1,6 +1,6 @@
#include "common/network/NetworkCommon.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;

View file

@ -2,8 +2,8 @@
#include "common/network/NetworkManager.hpp"
#include "common/network/NetworkResult.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QCoreApplication>
using namespace chatterino;

View file

@ -1,6 +1,6 @@
#include "common/network/NetworkResult.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;

View file

@ -7,10 +7,9 @@
#include "singletons/Fonts.hpp"
#include "singletons/Settings.hpp"
#include "singletons/Theme.hpp"
#include "Test.hpp"
#include "widgets/Notebook.hpp"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <QDebug>
#include <QString>

View file

@ -2,8 +2,7 @@
#include "common/FlagsEnum.hpp"
#include "common/Literals.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;
using namespace literals;

View file

@ -1,6 +1,7 @@
#include "util/RatelimitBucket.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <QApplication>
#include <QDebug>
#include <QtConcurrent>

View file

@ -1,6 +1,6 @@
#include "messages/Selection.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
using namespace chatterino;

View file

@ -3,8 +3,8 @@
#include "providers/seventv/eventapi/Client.hpp"
#include "providers/seventv/eventapi/Dispatch.hpp"
#include "providers/seventv/eventapi/Message.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QString>
#include <optional>

View file

@ -12,11 +12,10 @@
#include "singletons/Settings.hpp"
#include "singletons/Theme.hpp"
#include "singletons/WindowManager.hpp"
#include "Test.hpp"
#include "widgets/Notebook.hpp"
#include "widgets/splits/Split.hpp"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <QDebug>
#include <QString>
@ -110,9 +109,8 @@ TEST_P(SplitInputTest, Reply)
auto reply = MessagePtr(message);
this->input.setReply(reply);
QString actual = this->input.getInputText();
ASSERT_EQ(expected, actual)
<< "Input text after setReply should be '" << qUtf8Printable(expected)
<< "', but got '" << qUtf8Printable(actual) << "'";
ASSERT_EQ(expected, actual) << "Input text after setReply should be '"
<< expected << "', but got '" << actual << "'";
}
INSTANTIATE_TEST_SUITE_P(

42
tests/src/Test.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "Test.hpp"
#include <QString>
#include <QStringView>
std::ostream &operator<<(std::ostream &os, QStringView str)
{
os << str.toString().toStdString();
return os;
}
std::ostream &operator<<(std::ostream &os, const QByteArray &bytes)
{
os << std::string_view{bytes.data(), static_cast<size_t>(bytes.size())};
return os;
}
std::ostream &operator<<(std::ostream &os, const QString &str)
{
os << str.toStdString();
return os;
}
// The PrintTo overloads use UniversalPrint to print strings in quotes.
// Even though this uses testing::internal, this is publically documented in
// gtest/gtest-printers.h.
void PrintTo(const QByteArray &bytes, std::ostream *os)
{
::testing::internal::UniversalPrint(bytes.toStdString(), os);
}
void PrintTo(QStringView str, std::ostream *os)
{
::testing::internal::UniversalPrint(
std::u16string{str.utf16(), static_cast<size_t>(str.size())}, os);
}
void PrintTo(const QString &str, std::ostream *os)
{
::testing::internal::UniversalPrint(str.toStdU16String(), os);
}

22
tests/src/Test.hpp Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <ostream>
class QString;
class QStringView;
class QByteArray;
// This file is included in all TUs in chatterino-test to avoid ODR violations.
std::ostream &operator<<(std::ostream &os, QStringView str);
std::ostream &operator<<(std::ostream &os, const QByteArray &bytes);
std::ostream &operator<<(std::ostream &os, const QString &str);
// NOLINTBEGIN(readability-identifier-naming)
// PrintTo is used for naming parameterized tests, and is part of gtest
void PrintTo(const QByteArray &bytes, std::ostream *os);
void PrintTo(QStringView str, std::ostream *os);
void PrintTo(const QString &str, std::ostream *os);
// NOLINTEND(readability-identifier-naming)

View file

@ -1,66 +0,0 @@
#pragma once
#include <QString>
#include <QStringView>
#include <mutex>
#include <ostream>
template <typename T>
class ReceivedMessage
{
mutable std::mutex mutex;
bool isSet{false};
T t;
public:
ReceivedMessage() = default;
explicit operator bool() const
{
std::unique_lock lock(this->mutex);
return this->isSet;
}
ReceivedMessage &operator=(const T &newT)
{
std::unique_lock lock(this->mutex);
this->isSet = true;
this->t = newT;
return *this;
}
bool operator==(const T &otherT) const
{
std::unique_lock lock(this->mutex);
return this->t == otherT;
}
const T *operator->() const
{
return &this->t;
}
};
inline std::ostream &operator<<(std::ostream &os, const QStringView &str)
{
os << qUtf8Printable(str.toString());
return os;
}
inline std::ostream &operator<<(std::ostream &os, const QByteArray &bytes)
{
os << bytes.toStdString();
return os;
}
inline std::ostream &operator<<(std::ostream &os, const QString &str)
{
os << qUtf8Printable(str);
return os;
}

View file

@ -15,9 +15,8 @@
#include "providers/seventv/SeventvBadges.hpp"
#include "providers/twitch/TwitchBadge.hpp"
#include "singletons/Emotes.hpp"
#include "TestHelpers.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <IrcConnection>
#include <QDebug>
#include <QString>

View file

@ -4,12 +4,12 @@
#include "providers/twitch/pubsubmessages/AutoMod.hpp"
#include "providers/twitch/pubsubmessages/Whisper.hpp"
#include "providers/twitch/TwitchAccount.hpp"
#include "TestHelpers.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QString>
#include <chrono>
#include <mutex>
#include <optional>
using namespace chatterino;
@ -33,6 +33,47 @@ using namespace std::chrono_literals;
#ifdef RUN_PUBSUB_TESTS
template <typename T>
class ReceivedMessage
{
mutable std::mutex mutex;
bool isSet{false};
T t;
public:
ReceivedMessage() = default;
explicit operator bool() const
{
std::unique_lock lock(this->mutex);
return this->isSet;
}
ReceivedMessage &operator=(const T &newT)
{
std::unique_lock lock(this->mutex);
this->isSet = true;
this->t = newT;
return *this;
}
bool operator==(const T &otherT) const
{
std::unique_lock lock(this->mutex);
return this->t == otherT;
}
const T *operator->() const
{
return &this->t;
}
};
class FTest : public PubSub
{
public:

View file

@ -1,8 +1,8 @@
#include "singletons/Updates.hpp"
#include "common/Version.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <semver/semver.hpp>
using namespace chatterino;

View file

@ -1,6 +1,6 @@
#include "Test.hpp"
#include "util/Twitch.hpp"
#include <gtest/gtest.h>
#include <QApplication>
#include <QDebug>
#include <QtConcurrent>
@ -72,9 +72,8 @@ TEST(UtilTwitch, StripUserName)
stripUserName(userName);
EXPECT_EQ(userName, expectedUserName)
<< qUtf8Printable(userName) << " (" << qUtf8Printable(inputUserName)
<< ") did not match expected value "
<< qUtf8Printable(expectedUserName);
<< userName << " (" << inputUserName
<< ") did not match expected value " << expectedUserName;
}
}
@ -153,10 +152,8 @@ TEST(UtilTwitch, StripChannelName)
stripChannelName(userName);
EXPECT_EQ(userName, expectedChannelName)
<< qUtf8Printable(userName) << " ("
<< qUtf8Printable(inputChannelName)
<< ") did not match expected value "
<< qUtf8Printable(expectedChannelName);
<< userName << " (" << inputChannelName
<< ") did not match expected value " << expectedChannelName;
}
}
@ -259,14 +256,12 @@ TEST(UtilTwitch, ParseUserNameOrID)
auto [actualUserName, actualUserID] = parseUserNameOrID(input);
EXPECT_EQ(actualUserName, expectedUserName)
<< "name " << qUtf8Printable(actualUserName) << " ("
<< qUtf8Printable(input) << ") did not match expected value "
<< qUtf8Printable(expectedUserName);
<< "name " << actualUserName << " (" << input
<< ") did not match expected value " << expectedUserName;
EXPECT_EQ(actualUserID, expectedUserID)
<< "id " << qUtf8Printable(actualUserID) << " ("
<< qUtf8Printable(input) << ") did not match expected value "
<< qUtf8Printable(expectedUserID);
<< "id " << actualUserID << " (" << input
<< ") did not match expected value " << expectedUserID;
}
}
@ -319,7 +314,7 @@ TEST(UtilTwitch, UserLoginRegexp)
auto actual = regexp.match(inputUserLogin);
EXPECT_EQ(match.hasMatch(), expectedMatch)
<< qUtf8Printable(inputUserLogin) << " did not match as expected";
<< inputUserLogin << " did not match as expected";
}
}
@ -371,7 +366,7 @@ TEST(UtilTwitch, UserNameRegexp)
auto actual = regexp.match(inputUserLogin);
EXPECT_EQ(match.hasMatch(), expectedMatch)
<< qUtf8Printable(inputUserLogin) << " did not match as expected";
<< inputUserLogin << " did not match as expected";
}
}
@ -405,8 +400,7 @@ TEST(UtilTwitch, CleanHelixColor)
cleanHelixColorName(actualColor);
EXPECT_EQ(actualColor, expectedColor)
<< qUtf8Printable(inputColor) << " cleaned up to "
<< qUtf8Printable(actualColor) << " instead of "
<< qUtf8Printable(expectedColor);
<< inputColor << " cleaned up to " << actualColor << " instead of "
<< expectedColor;
}
}

View file

@ -1,6 +1,7 @@
#include "util/XDGDesktopFile.hpp"
#include <gtest/gtest.h>
#include "Test.hpp"
#include <QDebug>
#if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN)

View file

@ -1,8 +1,7 @@
#include "util/XDGHelper.hpp"
#include "TestHelpers.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QDebug>
#if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN)

View file

@ -1,8 +1,8 @@
#include "common/network/NetworkManager.hpp"
#include "singletons/Resources.hpp"
#include "singletons/Settings.hpp"
#include "Test.hpp"
#include <gtest/gtest.h>
#include <QApplication>
#include <QJsonArray>
#include <QLoggingCategory>