From c9f52b7223685d2e7fca925594171f94dd8c6e3b Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Wed, 15 May 2024 00:00:17 +0200 Subject: Ported to CMake, ... * Ported the project to CMake * Android and Mac support dropped for the time being. * Tests, BASS and Discord-RPC are now options * Restructured and reformated the project. * Merged `include` and `src` * Renamed `resource` to `data` * Renamed various files * External libraries headers are no longer included in `src` * Replaced header guards with #pragma once * Multiple refactors (keywords, headers) * Added Qt6 compatibility * Removed various unused functions and headers * Reworked AOPacket * When content is passed to AOPacket, it should be ensured that the content is already decoded. * Encoding/decoding are now static methods. * Fixed various memory leaks * Removed animation code for AOImage * AOImage is always using static images * Simplified ChatLogPiece --- test/CMakeLists.txt | 22 +++++++++++++++++----- test/test_aopacket.cpp | 18 ++++++++++++------ test/test_apng.cpp | 24 +++++++++++++++--------- test/test_bass.cpp | 19 ++++++++++++------- test/test_caseloading.cpp | 8 +++----- 5 files changed, 59 insertions(+), 32 deletions(-) (limited to 'test') diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 393a753..c6b191e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,8 +1,20 @@ -find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets REQUIRED) find_package(Catch2 REQUIRED) -add_executable(test test_aopacket.cpp test_caseloading.cpp test_apng.cpp test_bass.cpp ../include/aopacket.h ../src/aopacket.cpp) -target_include_directories(test PRIVATE ../include) +target_include_directories(test PRIVATE ../src) target_link_directories(test PRIVATE ../lib) -target_link_libraries(test PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Catch2::Catch2 bass bassmidi bassopus discord-rpc) -target_compile_definitions(Attorney_Online PRIVATE DISCORD) +target_link_libraries(test PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets Catch2::Catch2) + +add_executable(test + test_aopacket.cpp + test_caseloading.cpp + test_apng.cpp + ../src/aopacket.h + ../src/aopacket.cpp +) + +if(AO_ENABLE_BASS) + target_compile_definitions(Attorney_Online PRIVATE AO_ENABLE_BASS) + target_link_libraries(Attorney_Online PRIVATE bass bassmidi bassopus) + target_sources(test PRIVATE test_bass.cpp) +endif() diff --git a/test/test_aopacket.cpp b/test/test_aopacket.cpp index 0b31821..42ff778 100644 --- a/test/test_aopacket.cpp +++ b/test/test_aopacket.cpp @@ -3,27 +3,32 @@ #include "aopacket.h" -TEST_CASE("AOPacket construct", "[aopacket]") { +TEST_CASE("AOPacket construct", "[aopacket]") +{ // Parameters QString packet_string = "CT#MY_OOC_NAME#/doc https://docs.google.com/document/d/123/edit##%"; - SECTION("Packet string") { + SECTION("Packet string") + { AOPacket p(packet_string); REQUIRE(p.to_string() == packet_string); } - SECTION("Header and contents") { + SECTION("Header and contents") + { QStringList contents = {"MY_OOC_NAME", "/doc https://docs.google.com/document/d/123/edit#"}; AOPacket p("CT", contents); REQUIRE(p.to_string() == packet_string); } } -TEST_CASE("AOPacket encode/decode", "[aopacket]") { +TEST_CASE("AOPacket encode/decode", "[aopacket]") +{ // Parameters QString packet_string = "CT#MY_OOC_NAME#/doc https://docs.google.com/document/d/%$&/edit##%"; QString good_encode = "CT#MY_OOC_NAME#/doc https://docs.google.com/document/d//edit#%"; - SECTION("Bad encode/decode because packet string constructor splits the '#' after 'edit'") { + SECTION("Bad encode/decode because packet string constructor splits the '#' after 'edit'") + { AOPacket p(packet_string); p.net_encode(); REQUIRE(p.to_string() != good_encode); @@ -32,7 +37,8 @@ TEST_CASE("AOPacket encode/decode", "[aopacket]") { REQUIRE(p.to_string() == packet_string); } - SECTION("Good encode/decode with header and contents constructor") { + SECTION("Good encode/decode with header and contents constructor") + { QStringList contents = {"MY_OOC_NAME", "/doc https://docs.google.com/document/d/%$&/edit#"}; AOPacket p("CT", contents); diff --git a/test/test_apng.cpp b/test/test_apng.cpp index 20c7e92..c092191 100644 --- a/test/test_apng.cpp +++ b/test/test_apng.cpp @@ -1,12 +1,13 @@ #include -#include -#include #include #include +#include #include +#include -TEST_CASE("Support APNG Plugin", "[apng]") { +TEST_CASE("Support APNG Plugin", "[apng]") +{ // Check paths for libs QCoreApplication::addLibraryPath("."); QCoreApplication::addLibraryPath("lib"); @@ -19,38 +20,43 @@ TEST_CASE("Support APNG Plugin", "[apng]") { REQUIRE(QImageReader::supportedImageFormats().contains("apng")); } -TEST_CASE("Detect png animation", "[apng]") { +TEST_CASE("Detect png animation", "[apng]") +{ // Required for QPixmap methods int argc = 1; char bin[] = "test"; - char *argv[] = { bin }; + char *argv[] = {bin}; QGuiApplication app(argc, argv); // Instantiate reader QImageReader reader; - SECTION("Decide format from content fails on apng") { + SECTION("Decide format from content fails on apng") + { reader.setFileName("snackoo.png"); reader.setDecideFormatFromContent(true); REQUIRE(!reader.supportsAnimation()); REQUIRE(!QPixmap::fromImage(reader.read()).isNull()); } - SECTION("Auto detect fails on apng") { + SECTION("Auto detect fails on apng") + { reader.setFileName("snackoo.png"); reader.setAutoDetectImageFormat(true); REQUIRE(!reader.supportsAnimation()); REQUIRE(!QPixmap::fromImage(reader.read()).isNull()); } - SECTION("Detect apng supports animation") { + SECTION("Detect apng supports animation") + { reader.setFileName("snackoo.png"); reader.setFormat("apng"); REQUIRE(reader.supportsAnimation()); REQUIRE(!QPixmap::fromImage(reader.read()).isNull()); } - SECTION("Detect png frame has no animation") { + SECTION("Detect png frame has no animation") + { reader.setFileName("missle.png"); reader.setFormat("apng"); REQUIRE(!reader.supportsAnimation()); diff --git a/test/test_bass.cpp b/test/test_bass.cpp index e48decd..0e97b6a 100644 --- a/test/test_bass.cpp +++ b/test/test_bass.cpp @@ -1,14 +1,15 @@ -#include #include +#include -#include #include +#include #include "bass.h" #include "bassmidi.h" #include "bassopus.h" -TEST_CASE("BASS URL streaming", "[bass][noci]") { +TEST_CASE("BASS URL streaming", "[bass][noci]") +{ // Sample QString url = "https://raw.githubusercontent.com/skyedeving/aocharedit/master/Attorney%20Online%20Character%20Editor/Resources/about.mp3"; @@ -18,17 +19,21 @@ TEST_CASE("BASS URL streaming", "[bass][noci]") { // create stream from url HSTREAM stream; unsigned int flags = BASS_STREAM_AUTOFREE | BASS_STREAM_STATUS; - if (url.endsWith(".opus")) { + if (url.endsWith(".opus")) + { stream = BASS_OPUS_StreamCreateURL(url.toStdString().c_str(), 0, flags, nullptr, 0); } - else { + else + { stream = BASS_StreamCreateURL(url.toStdString().c_str(), 0, flags, nullptr, 0); } // Log http status const char *tags = BASS_ChannelGetTags(stream, BASS_TAG_HTTP); - if (tags) { - while(*tags) { + if (tags) + { + while (*tags) + { UNSCOPED_INFO(tags); tags += strlen(tags) + 1; } diff --git a/test/test_caseloading.cpp b/test/test_caseloading.cpp index 5df2782..dd82c7e 100644 --- a/test/test_caseloading.cpp +++ b/test/test_caseloading.cpp @@ -2,16 +2,14 @@ #include -TEST_CASE("Sort case evidence numerically", "[case]") { +TEST_CASE("Sort case evidence numerically", "[case]") +{ // Parameters QStringList case_evidence = {"1", "10", "11", "2", "3", "4", "5", "6", "7", "8", "9"}; QStringList case_evidence_sorted = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}; // Sort - std::sort(case_evidence.begin(), case_evidence.end(), - [] (const QString &a, const QString &b) { - return a.toInt() < b.toInt(); - }); + std::sort(case_evidence.begin(), case_evidence.end(), [](const QString &a, const QString &b) { return a.toInt() < b.toInt(); }); // Test REQUIRE(case_evidence == case_evidence_sorted); -- cgit From 657145035cd66c18ae777e1272fd5221dddca0ef Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Fri, 17 May 2024 23:54:41 +0200 Subject: Reimplemented unit tests, ... * Reimplemented unit tests and simplified addition of new tests * Minimal support of Qt is now 5.15 --- test/CMakeLists.txt | 35 ++++++++++--------- test/test_aopacket.cpp | 89 ++++++++++++++++++++++++++++------------------- test/test_apng.cpp | 67 ----------------------------------- test/test_bass.cpp | 46 ------------------------ test/test_caseloading.cpp | 16 --------- 5 files changed, 72 insertions(+), 181 deletions(-) delete mode 100644 test/test_apng.cpp delete mode 100644 test/test_bass.cpp delete mode 100644 test/test_caseloading.cpp (limited to 'test') diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c6b191e..4c1d098 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,20 +1,21 @@ -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets REQUIRED) -find_package(Catch2 REQUIRED) +project(tests LANGUAGES CXX C) -target_include_directories(test PRIVATE ../src) -target_link_directories(test PRIVATE ../lib) -target_link_libraries(test PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets Catch2::Catch2) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Test REQUIRED) -add_executable(test - test_aopacket.cpp - test_caseloading.cpp - test_apng.cpp - ../src/aopacket.h - ../src/aopacket.cpp -) +set(CMAKE_INCLUDE_CURRENT_DIR ON) -if(AO_ENABLE_BASS) - target_compile_definitions(Attorney_Online PRIVATE AO_ENABLE_BASS) - target_link_libraries(Attorney_Online PRIVATE bass bassmidi bassopus) - target_sources(test PRIVATE test_bass.cpp) -endif() +enable_testing(true) + +set(SKIP_AUTOMOC ON) + +function(ao_declare_test test_id) + message(STATUS "FOOBAR Adding test: ${test_id}") + message(STATUS "FOOBAR Source files: ${ARGN}") + add_executable(${test_id} ${ARGN}) + target_include_directories(${test_id} PRIVATE ../src src) + target_link_directories(${test_id} PRIVATE ../lib) + target_link_libraries(${test_id} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Test) + add_test(NAME ${test_id} COMMAND ${test_id}) +endfunction() + +ao_declare_test(test_aopacket test_aopacket.cpp ../src/aopacket.cpp) diff --git a/test/test_aopacket.cpp b/test/test_aopacket.cpp index 42ff778..4a24dcd 100644 --- a/test/test_aopacket.cpp +++ b/test/test_aopacket.cpp @@ -1,51 +1,70 @@ -#define CATCH_CONFIG_MAIN -#include - #include "aopacket.h" -TEST_CASE("AOPacket construct", "[aopacket]") +#include +#include + +class test_AOPacket : public QObject { - // Parameters - QString packet_string = "CT#MY_OOC_NAME#/doc https://docs.google.com/document/d/123/edit##%"; + Q_OBJECT + +private: + const QMap SYMBOL_MAP{ + {"#", ""}, + {"%", ""}, + {"$", ""}, + {"&", ""}, + }; - SECTION("Packet string") +private Q_SLOTS: + void constructPacket_data() { - AOPacket p(packet_string); - REQUIRE(p.to_string() == packet_string); + QTest::addColumn("header"); + QTest::addColumn("content"); + QTest::addColumn("result"); + + QTest::newRow("Basic Packet") << "CT" << QStringList{"MY_OOC_NAME", "/doc https://docs.google.com/document/d/123/edit"} << "CT#MY_OOC_NAME#/doc https://docs.google.com/document/d/123/edit#%"; } - SECTION("Header and contents") + + void constructPacket() { - QStringList contents = {"MY_OOC_NAME", "/doc https://docs.google.com/document/d/123/edit#"}; - AOPacket p("CT", contents); - REQUIRE(p.to_string() == packet_string); - } -} + QFETCH(QString, header); + QFETCH(QStringList, content); + QFETCH(QString, result); -TEST_CASE("AOPacket encode/decode", "[aopacket]") -{ - // Parameters - QString packet_string = "CT#MY_OOC_NAME#/doc https://docs.google.com/document/d/%$&/edit##%"; - QString good_encode = "CT#MY_OOC_NAME#/doc https://docs.google.com/document/d//edit#%"; + AOPacket packet(header, content); + QVERIFY(packet.toString(true) == result); + } - SECTION("Bad encode/decode because packet string constructor splits the '#' after 'edit'") + void encodeDecodeData_data() { - AOPacket p(packet_string); - p.net_encode(); - REQUIRE(p.to_string() != good_encode); + QTest::addColumn("what"); + QTest::addColumn("result"); + QTest::addColumn("encode"); - p.net_decode(); - REQUIRE(p.to_string() == packet_string); + for (auto it = SYMBOL_MAP.begin(); it != SYMBOL_MAP.end(); ++it) + { + QTest::newRow(QString("Encode %1").arg(it.key()).toUtf8()) << it.key() << it.value() << true; + QTest::newRow(QString("Decode %1").arg(it.value()).toUtf8()) << it.value() << it.key() << false; + } } - SECTION("Good encode/decode with header and contents constructor") + void encodeDecodeData() { - QStringList contents = {"MY_OOC_NAME", "/doc https://docs.google.com/document/d/%$&/edit#"}; - AOPacket p("CT", contents); - - p.net_encode(); - REQUIRE(p.to_string() == good_encode); + QFETCH(QString, what); + QFETCH(QString, result); + QFETCH(bool, encode); - p.net_decode(); - REQUIRE(p.to_string() == packet_string); + if (encode) + { + QVERIFY(AOPacket::encode(what) == result); + } + else + { + QVERIFY(AOPacket::decode(what) == result); + } } -} +}; + +#include "test/test_aopacket.moc" + +QTEST_MAIN(test_AOPacket) diff --git a/test/test_apng.cpp b/test/test_apng.cpp deleted file mode 100644 index c092191..0000000 --- a/test/test_apng.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -TEST_CASE("Support APNG Plugin", "[apng]") -{ - // Check paths for libs - QCoreApplication::addLibraryPath("."); - QCoreApplication::addLibraryPath("lib"); - - // Either it's loaded from system or we load local - QPluginLoader apngPlugin("qapng"); - apngPlugin.load(); - - INFO(QImageReader::supportedImageFormats().join(' ').toStdString()); - REQUIRE(QImageReader::supportedImageFormats().contains("apng")); -} - -TEST_CASE("Detect png animation", "[apng]") -{ - // Required for QPixmap methods - int argc = 1; - char bin[] = "test"; - char *argv[] = {bin}; - QGuiApplication app(argc, argv); - - // Instantiate reader - QImageReader reader; - - SECTION("Decide format from content fails on apng") - { - reader.setFileName("snackoo.png"); - reader.setDecideFormatFromContent(true); - REQUIRE(!reader.supportsAnimation()); - REQUIRE(!QPixmap::fromImage(reader.read()).isNull()); - } - - SECTION("Auto detect fails on apng") - { - reader.setFileName("snackoo.png"); - reader.setAutoDetectImageFormat(true); - REQUIRE(!reader.supportsAnimation()); - REQUIRE(!QPixmap::fromImage(reader.read()).isNull()); - } - - SECTION("Detect apng supports animation") - { - reader.setFileName("snackoo.png"); - reader.setFormat("apng"); - REQUIRE(reader.supportsAnimation()); - REQUIRE(!QPixmap::fromImage(reader.read()).isNull()); - } - - SECTION("Detect png frame has no animation") - { - reader.setFileName("missle.png"); - reader.setFormat("apng"); - REQUIRE(!reader.supportsAnimation()); - reader.setFormat("png"); - REQUIRE(!reader.supportsAnimation()); - REQUIRE(!QPixmap::fromImage(reader.read()).isNull()); - } -} diff --git a/test/test_bass.cpp b/test/test_bass.cpp deleted file mode 100644 index 0e97b6a..0000000 --- a/test/test_bass.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include - -#include -#include - -#include "bass.h" -#include "bassmidi.h" -#include "bassopus.h" - -TEST_CASE("BASS URL streaming", "[bass][noci]") -{ - // Sample - QString url = "https://raw.githubusercontent.com/skyedeving/aocharedit/master/Attorney%20Online%20Character%20Editor/Resources/about.mp3"; - - // initialize - BASS_Init(-1, 44100, 0, 0, nullptr); - - // create stream from url - HSTREAM stream; - unsigned int flags = BASS_STREAM_AUTOFREE | BASS_STREAM_STATUS; - if (url.endsWith(".opus")) - { - stream = BASS_OPUS_StreamCreateURL(url.toStdString().c_str(), 0, flags, nullptr, 0); - } - else - { - stream = BASS_StreamCreateURL(url.toStdString().c_str(), 0, flags, nullptr, 0); - } - - // Log http status - const char *tags = BASS_ChannelGetTags(stream, BASS_TAG_HTTP); - if (tags) - { - while (*tags) - { - UNSCOPED_INFO(tags); - tags += strlen(tags) + 1; - } - } - - // Test - REQUIRE(stream != 0); - REQUIRE(BASS_ChannelPlay(stream, TRUE) == TRUE); - // while (BASS_ChannelIsActive(stream) != BASS_ACTIVE_STOPPED); // block test to listen -} diff --git a/test/test_caseloading.cpp b/test/test_caseloading.cpp deleted file mode 100644 index dd82c7e..0000000 --- a/test/test_caseloading.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include - -TEST_CASE("Sort case evidence numerically", "[case]") -{ - // Parameters - QStringList case_evidence = {"1", "10", "11", "2", "3", "4", "5", "6", "7", "8", "9"}; - QStringList case_evidence_sorted = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}; - - // Sort - std::sort(case_evidence.begin(), case_evidence.end(), [](const QString &a, const QString &b) { return a.toInt() < b.toInt(); }); - - // Test - REQUIRE(case_evidence == case_evidence_sorted); -} -- cgit From f9c7205210fb9f768f583065971ece09e6b5eb03 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Sat, 18 May 2024 03:09:39 +0200 Subject: Clarified test message builder --- test/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4c1d098..c78740c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,8 +9,8 @@ enable_testing(true) set(SKIP_AUTOMOC ON) function(ao_declare_test test_id) - message(STATUS "FOOBAR Adding test: ${test_id}") - message(STATUS "FOOBAR Source files: ${ARGN}") + message(STATUS "Adding test: ${test_id}") + message(STATUS "Source files: ${ARGN}") add_executable(${test_id} ${ARGN}) target_include_directories(${test_id} PRIVATE ../src src) target_link_directories(${test_id} PRIVATE ../lib) -- cgit