diff --git a/.CI/chatterino-installer.iss b/.CI/chatterino-installer.iss index fddd668f98c..1f9816a2978 100644 --- a/.CI/chatterino-installer.iss +++ b/.CI/chatterino-installer.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "Chatterino" -#define MyAppVersion "2.5.0" +#define MyAppVersion "2.5.1" #define MyAppPublisher "Chatterino Team" #define MyAppURL "https://www.chatterino.com" #define MyAppExeName "chatterino.exe" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c21b747e22..614cf3ba05c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -126,7 +126,7 @@ jobs: skip-artifact: false skip-crashpad: false # macOS - - os: macos-latest + - os: macos-13 qt-version: 5.15.2 force-lto: false plugins: true @@ -222,7 +222,7 @@ jobs: - name: Setup sccache (Windows) # sccache v0.7.4 - uses: hendrikmuhs/ccache-action@v1.2.12 + uses: hendrikmuhs/ccache-action@v1.2.13 if: startsWith(matrix.os, 'windows') with: variant: sccache diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index f1c76e8cbb1..0b73ee84f30 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -69,7 +69,7 @@ jobs: - name: Setup sccache # sccache v0.7.4 - uses: hendrikmuhs/ccache-action@v1.2.12 + uses: hendrikmuhs/ccache-action@v1.2.13 with: variant: sccache # only save on the default (master) branch diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml new file mode 100644 index 00000000000..7e8a5091a70 --- /dev/null +++ b/.github/workflows/winget.yml @@ -0,0 +1,14 @@ +name: Publish to WinGet +on: + release: + types: [released] +jobs: + publish: + runs-on: windows-latest + if: ${{ startsWith(github.event.release.tag_name, 'v') }} + steps: + - uses: vedantmgoyal2009/winget-releaser@v2 + with: + identifier: ChatterinoTeam.Chatterino + installers-regex: ^Chatterino.Installer.exe$ + token: ${{ secrets.WINGET_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index f9d0c2a4ff5..d661e61d8e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unversioned +- Bugfix: If a network request errors with 200 OK, Qt's error code is now reported instead of the HTTP status. (#5378) +- Dev: Add doxygen build target. (#5377) +- Dev: Make printing of strings in tests easier. (#5379) + +## 2.5.1 + +- Bugfix: Fixed links without a protocol not being clickable. (#5345) + ## 2.5.0 ### Dankerino diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a08cf79ee1..eec6b7e1c8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ if(BUILD_BENCHMARKS) endif() project(chatterino - VERSION 2.5.0 + VERSION 2.5.1 DESCRIPTION "Chat client for twitch.tv" HOMEPAGE_URL "https://chatterino.com/" ) @@ -197,6 +197,7 @@ find_package(PajladaSerialize REQUIRED) find_package(PajladaSignals REQUIRED) find_package(LRUCache REQUIRED) find_package(MagicEnum REQUIRED) +find_package(Doxygen) if (USE_SYSTEM_PAJLADA_SETTINGS) find_package(PajladaSettings REQUIRED) diff --git a/lib/settings b/lib/settings index 70fbc7236aa..03e8af1934e 160000 --- a/lib/settings +++ b/lib/settings @@ -1 +1 @@ -Subproject commit 70fbc7236aa8bcf5db4748e7f56dad132d6fd402 +Subproject commit 03e8af1934e6151edfe8a44dfb025b747a31acdf diff --git a/resources/com.chatterino.chatterino.appdata.xml b/resources/com.chatterino.chatterino.appdata.xml index 69d1b9289d6..a2d09fecbdc 100644 --- a/resources/com.chatterino.chatterino.appdata.xml +++ b/resources/com.chatterino.chatterino.appdata.xml @@ -34,6 +34,9 @@ chatterino + + https://github.com/Chatterino/chatterino2/releases/tag/v2.5.1 + https://github.com/Chatterino/chatterino2/releases/tag/v2.5.0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9e112f754c6..3fab4b6a36f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1153,3 +1153,14 @@ if(NOT CHATTERINO_UPDATER) message(STATUS "Disabling the updater.") target_compile_definitions(${LIBRARY_PROJECT} PUBLIC CHATTERINO_DISABLE_UPDATER) endif() + +if (DOXYGEN_FOUND) + message(STATUS "Doxygen found, adding doxygen target") + # output will be in docs/html + set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/docs") + + doxygen_add_docs( + doxygen + ${CMAKE_CURRENT_LIST_DIR} + ) +endif () diff --git a/src/common/Version.hpp b/src/common/Version.hpp index 07a23a0acde..687f3094e00 100644 --- a/src/common/Version.hpp +++ b/src/common/Version.hpp @@ -24,7 +24,7 @@ * - 2.4.0-alpha.2 * - 2.4.0-alpha **/ -#define CHATTERINO_VERSION "2.5.0" +#define CHATTERINO_VERSION "2.5.1" #if defined(Q_OS_WIN) # define CHATTERINO_OS "win" diff --git a/src/common/network/NetworkResult.cpp b/src/common/network/NetworkResult.cpp index 177d2ae6f97..c6544eaad80 100644 --- a/src/common/network/NetworkResult.cpp +++ b/src/common/network/NetworkResult.cpp @@ -67,7 +67,9 @@ const QByteArray &NetworkResult::getData() const QString NetworkResult::formatError() const { - if (this->status_) + // Print the status for errors that mirror HTTP status codes (=0 || >99) + if (this->status_ && (this->error_ == QNetworkReply::NoError || + this->error_ > QNetworkReply::UnknownNetworkError)) { return QString::number(*this->status_); } @@ -77,6 +79,13 @@ QString NetworkResult::formatError() const this->error_); if (name == nullptr) { + if (this->status_) + { + return QStringLiteral("unknown error (status: %1, error: %2)") + .arg(QString::number(*this->status_), + QString::number(this->error_)); + } + return QStringLiteral("unknown error (%1)").arg(this->error_); } return name; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fb5730048b8..bd35b79dee9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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 diff --git a/tests/README.md b/tests/README.md index f9bc5798a9a..47ac1b202ae 100644 --- a/tests/README.md +++ b/tests/README.md @@ -7,4 +7,4 @@ docker run --network=host --detach ghcr.io/chatterino/twitch-pubsub-server-test: docker run -p 9051:80 --detach kennethreitz/httpbin ``` -If you're unable to use docker, you can use [httpbox](github.com/kevinastone/httpbox) (`httpbox --port 9051`) and [Chatterino/twitch-pubsub-server-test](https://github.com/Chatterino/twitch-pubsub-server-test/releases/latest) manually. +If you're unable to use docker, you can use [httpbox](https://github.com/kevinastone/httpbox) (`httpbox --port 9051`) and [Chatterino/twitch-pubsub-server-test](https://github.com/Chatterino/twitch-pubsub-server-test/releases/latest) manually. diff --git a/tests/src/AccessGuard.cpp b/tests/src/AccessGuard.cpp index a0d1c6d3199..56cbc727fea 100644 --- a/tests/src/AccessGuard.cpp +++ b/tests/src/AccessGuard.cpp @@ -1,6 +1,6 @@ #include "common/UniqueAccess.hpp" +#include "Test.hpp" -#include #include #include diff --git a/tests/src/BasicPubSub.cpp b/tests/src/BasicPubSub.cpp index dc277522028..6315970ff06 100644 --- a/tests/src/BasicPubSub.cpp +++ b/tests/src/BasicPubSub.cpp @@ -1,7 +1,7 @@ #include "providers/liveupdates/BasicPubSubClient.hpp" #include "providers/liveupdates/BasicPubSubManager.hpp" +#include "Test.hpp" -#include #include #include #include diff --git a/tests/src/BttvLiveUpdates.cpp b/tests/src/BttvLiveUpdates.cpp index 580f2e61f96..2d238f9b0b8 100644 --- a/tests/src/BttvLiveUpdates.cpp +++ b/tests/src/BttvLiveUpdates.cpp @@ -1,6 +1,7 @@ #include "providers/bttv/BttvLiveUpdates.hpp" -#include +#include "Test.hpp" + #include #include diff --git a/tests/src/ChannelChatters.cpp b/tests/src/ChannelChatters.cpp index c665836bb38..79711ce15af 100644 --- a/tests/src/ChannelChatters.cpp +++ b/tests/src/ChannelChatters.cpp @@ -1,8 +1,8 @@ #include "common/ChannelChatters.hpp" #include "mocks/Channel.hpp" +#include "Test.hpp" -#include #include #include diff --git a/tests/src/ChatterSet.cpp b/tests/src/ChatterSet.cpp index ac5b81ee926..57a67a77113 100644 --- a/tests/src/ChatterSet.cpp +++ b/tests/src/ChatterSet.cpp @@ -1,6 +1,7 @@ #include "common/ChatterSet.hpp" -#include +#include "Test.hpp" + #include TEST(ChatterSet, insert) diff --git a/tests/src/Emojis.cpp b/tests/src/Emojis.cpp index 141a64afbf7..42df110a426 100644 --- a/tests/src/Emojis.cpp +++ b/tests/src/Emojis.cpp @@ -1,9 +1,8 @@ #include "providers/emoji/Emojis.hpp" #include "common/Literals.hpp" -#include "TestHelpers.hpp" +#include "Test.hpp" -#include #include #include diff --git a/tests/src/ExponentialBackoff.cpp b/tests/src/ExponentialBackoff.cpp index 2a4259744a1..7099ea08a17 100644 --- a/tests/src/ExponentialBackoff.cpp +++ b/tests/src/ExponentialBackoff.cpp @@ -1,6 +1,6 @@ #include "util/ExponentialBackoff.hpp" -#include +#include "Test.hpp" using namespace chatterino; diff --git a/tests/src/Filters.cpp b/tests/src/Filters.cpp index ff1b0590212..89c0a510f88 100644 --- a/tests/src/Filters.cpp +++ b/tests/src/Filters.cpp @@ -13,8 +13,8 @@ #include "providers/twitch/TwitchBadge.hpp" #include "providers/twitch/TwitchMessageBuilder.hpp" #include "singletons/Emotes.hpp" +#include "Test.hpp" -#include #include #include @@ -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(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(filterResult); - ASSERT_TRUE(isValid) << "Filter::fromString( " << qUtf8Printable(input) - << " ) is invalid"; + ASSERT_TRUE(isValid) + << "Filter::fromString( " << input << " ) is invalid"; auto filter = std::move(std::get(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(filterResult); - ASSERT_TRUE(isValid) << "Filter::fromString( " << qUtf8Printable(input) - << " ) is invalid"; + ASSERT_TRUE(isValid) + << "Filter::fromString( " << input << " ) is invalid"; auto filter = std::move(std::get(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(&filterResult); - EXPECT_NE(filter, nullptr) - << "Filter::fromString(" << qUtf8Printable(input) - << ") did not build a proper filter"; + 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 << "'"; } } diff --git a/tests/src/FormatTime.cpp b/tests/src/FormatTime.cpp index bc15f44efe6..6fe82ab9a8c 100644 --- a/tests/src/FormatTime.cpp +++ b/tests/src/FormatTime.cpp @@ -1,6 +1,6 @@ #include "util/FormatTime.hpp" -#include +#include "Test.hpp" #include @@ -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; } } diff --git a/tests/src/Helpers.cpp b/tests/src/Helpers.cpp index 7fcd02837bc..0783c36e129 100644 --- a/tests/src/Helpers.cpp +++ b/tests/src/Helpers.cpp @@ -1,6 +1,6 @@ #include "util/Helpers.hpp" -#include +#include "Test.hpp" using namespace chatterino; using namespace _helpers_internal; @@ -279,8 +279,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; } } @@ -422,14 +422,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 << ")"; } @@ -507,7 +506,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; } } diff --git a/tests/src/HighlightController.cpp b/tests/src/HighlightController.cpp index a45bbf98c02..090acf37b15 100644 --- a/tests/src/HighlightController.cpp +++ b/tests/src/HighlightController.cpp @@ -10,9 +10,8 @@ #include "providers/twitch/TwitchBadge.hpp" // for Badge #include "singletons/Paths.hpp" #include "singletons/Settings.hpp" +#include "Test.hpp" -#include -#include #include #include #include @@ -216,11 +215,9 @@ class HighlightControllerTest : public ::testing::Test 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; } } diff --git a/tests/src/HighlightPhrase.cpp b/tests/src/HighlightPhrase.cpp index 374670b03d3..2ec2530f0f5 100644 --- a/tests/src/HighlightPhrase.cpp +++ b/tests/src/HighlightPhrase.cpp @@ -1,6 +1,6 @@ #include "controllers/highlights/HighlightPhrase.hpp" -#include +#include "Test.hpp" using namespace chatterino; diff --git a/tests/src/Hotkeys.cpp b/tests/src/Hotkeys.cpp index ebbfe50297f..7c3d8d10fe6 100644 --- a/tests/src/Hotkeys.cpp +++ b/tests/src/Hotkeys.cpp @@ -1,6 +1,5 @@ #include "controllers/hotkeys/HotkeyHelpers.hpp" - -#include +#include "Test.hpp" #include diff --git a/tests/src/InputCompletion.cpp b/tests/src/InputCompletion.cpp index 86003543871..22c42b31cb1 100644 --- a/tests/src/InputCompletion.cpp +++ b/tests/src/InputCompletion.cpp @@ -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 #include #include #include @@ -224,7 +224,7 @@ void containsRoughly(std::span span, std::set values) } } - ASSERT_TRUE(found) << qPrintable(v) << " was not found in the span"; + ASSERT_TRUE(found) << v << " was not found in the span"; } } diff --git a/tests/src/IrcHelpers.cpp b/tests/src/IrcHelpers.cpp index acae81c3537..d210b14e003 100644 --- a/tests/src/IrcHelpers.cpp +++ b/tests/src/IrcHelpers.cpp @@ -1,6 +1,7 @@ #include "util/IrcHelpers.hpp" -#include +#include "Test.hpp" + #include #include #include @@ -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; } } diff --git a/tests/src/LimitedQueue.cpp b/tests/src/LimitedQueue.cpp index 39a8bba86ac..0a94ea92874 100644 --- a/tests/src/LimitedQueue.cpp +++ b/tests/src/LimitedQueue.cpp @@ -1,6 +1,6 @@ #include "messages/LimitedQueue.hpp" -#include +#include "Test.hpp" #include diff --git a/tests/src/LinkInfo.cpp b/tests/src/LinkInfo.cpp index 91f065035ce..a06a78c0f9c 100644 --- a/tests/src/LinkInfo.cpp +++ b/tests/src/LinkInfo.cpp @@ -2,8 +2,7 @@ #include "common/Literals.hpp" #include "SignalSpy.hpp" - -#include +#include "Test.hpp" using namespace chatterino; using namespace literals; diff --git a/tests/src/LinkParser.cpp b/tests/src/LinkParser.cpp index cce5c8c6c52..9d964ce1542 100644 --- a/tests/src/LinkParser.cpp +++ b/tests/src/LinkParser.cpp @@ -1,8 +1,7 @@ #include "common/LinkParser.hpp" -#include "TestHelpers.hpp" +#include "Test.hpp" -#include #include #include diff --git a/tests/src/Literals.cpp b/tests/src/Literals.cpp index 77607b73977..17d459b1431 100644 --- a/tests/src/Literals.cpp +++ b/tests/src/Literals.cpp @@ -1,6 +1,6 @@ #include "common/Literals.hpp" -#include +#include "Test.hpp" using namespace chatterino::literals; diff --git a/tests/src/MessageLayout.cpp b/tests/src/MessageLayout.cpp index 9ce0c7f21e8..ab9a294c9b8 100644 --- a/tests/src/MessageLayout.cpp +++ b/tests/src/MessageLayout.cpp @@ -10,8 +10,8 @@ #include "singletons/Settings.hpp" #include "singletons/Theme.hpp" #include "singletons/WindowManager.hpp" +#include "Test.hpp" -#include #include #include diff --git a/tests/src/NetworkCommon.cpp b/tests/src/NetworkCommon.cpp index 481f951aee5..9beab8da68c 100644 --- a/tests/src/NetworkCommon.cpp +++ b/tests/src/NetworkCommon.cpp @@ -1,6 +1,6 @@ #include "common/network/NetworkCommon.hpp" -#include +#include "Test.hpp" using namespace chatterino; diff --git a/tests/src/NetworkRequest.cpp b/tests/src/NetworkRequest.cpp index 2f6b8102f96..ca723481efe 100644 --- a/tests/src/NetworkRequest.cpp +++ b/tests/src/NetworkRequest.cpp @@ -2,8 +2,8 @@ #include "common/network/NetworkManager.hpp" #include "common/network/NetworkResult.hpp" +#include "Test.hpp" -#include #include using namespace chatterino; diff --git a/tests/src/NetworkResult.cpp b/tests/src/NetworkResult.cpp index 72a2ca771f0..4d4c574210d 100644 --- a/tests/src/NetworkResult.cpp +++ b/tests/src/NetworkResult.cpp @@ -1,6 +1,6 @@ #include "common/network/NetworkResult.hpp" -#include +#include "Test.hpp" using namespace chatterino; @@ -37,12 +37,21 @@ TEST(NetworkResult, Errors) "RemoteHostClosedError"); // status code takes precedence - checkResult({Error::TimeoutError, 400, {}}, Error::TimeoutError, 400, - "400"); + checkResult({Error::InternalServerError, 400, {}}, + Error::InternalServerError, 400, "400"); + + // error takes precedence (1..=99) + checkResult({Error::BackgroundRequestNotAllowedError, 400, {}}, + Error::BackgroundRequestNotAllowedError, 400, + "BackgroundRequestNotAllowedError"); + checkResult({Error::UnknownNetworkError, 400, {}}, + Error::UnknownNetworkError, 400, "UnknownNetworkError"); } TEST(NetworkResult, InvalidError) { checkResult({static_cast(-1), {}, {}}, static_cast(-1), std::nullopt, "unknown error (-1)"); + checkResult({static_cast(-1), 42, {}}, static_cast(-1), 42, + "unknown error (status: 42, error: -1)"); } diff --git a/tests/src/NotebookTab.cpp b/tests/src/NotebookTab.cpp index 2ac4903f47e..36133b648c8 100644 --- a/tests/src/NotebookTab.cpp +++ b/tests/src/NotebookTab.cpp @@ -7,10 +7,9 @@ #include "singletons/Fonts.hpp" #include "singletons/Settings.hpp" #include "singletons/Theme.hpp" +#include "Test.hpp" #include "widgets/Notebook.hpp" -#include -#include #include #include diff --git a/tests/src/QMagicEnum.cpp b/tests/src/QMagicEnum.cpp index 80c265efe24..6778427fe43 100644 --- a/tests/src/QMagicEnum.cpp +++ b/tests/src/QMagicEnum.cpp @@ -2,8 +2,7 @@ #include "common/FlagsEnum.hpp" #include "common/Literals.hpp" - -#include +#include "Test.hpp" using namespace chatterino; using namespace literals; diff --git a/tests/src/RatelimitBucket.cpp b/tests/src/RatelimitBucket.cpp index c92a42234b8..850f14c68cb 100644 --- a/tests/src/RatelimitBucket.cpp +++ b/tests/src/RatelimitBucket.cpp @@ -1,6 +1,7 @@ #include "util/RatelimitBucket.hpp" -#include +#include "Test.hpp" + #include #include #include diff --git a/tests/src/Selection.cpp b/tests/src/Selection.cpp index 1f1f4a62137..a904b076656 100644 --- a/tests/src/Selection.cpp +++ b/tests/src/Selection.cpp @@ -1,6 +1,6 @@ #include "messages/Selection.hpp" -#include +#include "Test.hpp" using namespace chatterino; diff --git a/tests/src/SeventvEventAPI.cpp b/tests/src/SeventvEventAPI.cpp index 780f90bac10..4e2d3228193 100644 --- a/tests/src/SeventvEventAPI.cpp +++ b/tests/src/SeventvEventAPI.cpp @@ -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 #include #include diff --git a/tests/src/SplitInput.cpp b/tests/src/SplitInput.cpp index ed092f94baf..d84da81188a 100644 --- a/tests/src/SplitInput.cpp +++ b/tests/src/SplitInput.cpp @@ -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 -#include #include #include @@ -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( diff --git a/tests/src/Test.cpp b/tests/src/Test.cpp new file mode 100644 index 00000000000..5f245f5d7f2 --- /dev/null +++ b/tests/src/Test.cpp @@ -0,0 +1,42 @@ +#include "Test.hpp" + +#include +#include + +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(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(str.size())}, os); +} + +void PrintTo(const QString &str, std::ostream *os) +{ + ::testing::internal::UniversalPrint(str.toStdU16String(), os); +} diff --git a/tests/src/Test.hpp b/tests/src/Test.hpp new file mode 100644 index 00000000000..064f90c6d79 --- /dev/null +++ b/tests/src/Test.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#include + +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) diff --git a/tests/src/TestHelpers.hpp b/tests/src/TestHelpers.hpp deleted file mode 100644 index 30a2d0b1a25..00000000000 --- a/tests/src/TestHelpers.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -template -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; -} diff --git a/tests/src/TwitchMessageBuilder.cpp b/tests/src/TwitchMessageBuilder.cpp index 77ddcdf4659..d9d1d5a62f6 100644 --- a/tests/src/TwitchMessageBuilder.cpp +++ b/tests/src/TwitchMessageBuilder.cpp @@ -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 #include #include #include diff --git a/tests/src/TwitchPubSubClient.cpp b/tests/src/TwitchPubSubClient.cpp index 30e02e56759..728b0e5bbcc 100644 --- a/tests/src/TwitchPubSubClient.cpp +++ b/tests/src/TwitchPubSubClient.cpp @@ -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 #include #include +#include #include using namespace chatterino; @@ -33,6 +33,47 @@ using namespace std::chrono_literals; #ifdef RUN_PUBSUB_TESTS +template +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: diff --git a/tests/src/Updates.cpp b/tests/src/Updates.cpp index da4762517a6..ce16f329f6a 100644 --- a/tests/src/Updates.cpp +++ b/tests/src/Updates.cpp @@ -1,8 +1,8 @@ #include "singletons/Updates.hpp" #include "common/Version.hpp" +#include "Test.hpp" -#include #include using namespace chatterino; diff --git a/tests/src/UtilTwitch.cpp b/tests/src/UtilTwitch.cpp index 6a0b58d9fa6..3a2a7b41ba5 100644 --- a/tests/src/UtilTwitch.cpp +++ b/tests/src/UtilTwitch.cpp @@ -1,6 +1,6 @@ +#include "Test.hpp" #include "util/Twitch.hpp" -#include #include #include #include @@ -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; } } diff --git a/tests/src/XDGDesktopFile.cpp b/tests/src/XDGDesktopFile.cpp index bffe529aad2..69f4d370642 100644 --- a/tests/src/XDGDesktopFile.cpp +++ b/tests/src/XDGDesktopFile.cpp @@ -1,6 +1,7 @@ #include "util/XDGDesktopFile.hpp" -#include +#include "Test.hpp" + #include #if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN) diff --git a/tests/src/XDGHelper.cpp b/tests/src/XDGHelper.cpp index 3926d21d926..3ab48daa3d5 100644 --- a/tests/src/XDGHelper.cpp +++ b/tests/src/XDGHelper.cpp @@ -1,8 +1,7 @@ #include "util/XDGHelper.hpp" -#include "TestHelpers.hpp" +#include "Test.hpp" -#include #include #if defined(Q_OS_UNIX) and !defined(Q_OS_DARWIN) diff --git a/tests/src/main.cpp b/tests/src/main.cpp index 3b24a997885..6c82f632cb8 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -1,8 +1,8 @@ #include "common/network/NetworkManager.hpp" #include "singletons/Resources.hpp" #include "singletons/Settings.hpp" +#include "Test.hpp" -#include #include #include #include