aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml173
-rw-r--r--.github/workflows/test.yml87
-rw-r--r--CMakeLists.txt43
-rw-r--r--README_TEST.md17
-rw-r--r--include/CMakeLists.txt38
-rw-r--r--resource/logo_ao2.rc1
-rw-r--r--src/CMakeLists.txt38
-rw-r--r--test/CMakeLists.txt8
-rw-r--r--test/missle.pngbin0 -> 55423 bytes
-rw-r--r--test/snackoo.pngbin0 -> 92034 bytes
-rw-r--r--test/test_aopacket.cpp45
-rw-r--r--test/test_apng.cpp61
-rw-r--r--test/test_bass.cpp40
-rw-r--r--test/test_caseloading.cpp18
14 files changed, 569 insertions, 0 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..69b12842
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,173 @@
+name: build
+
+on:
+ push:
+ branches:
+ - add-tests
+
+env:
+ # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
+ BUILD_TYPE: Release
+
+jobs:
+ windows:
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install Catch2
+ shell: bash
+ run: |
+ curl -L https://github.com/catchorg/Catch2/archive/v2.13.4.tar.gz -o catch2.tar.gz
+ tar xvf catch2.tar.gz
+ cd Catch2-2.13.4
+ cmake -Bbuild -H. -DBUILD_TESTING=OFF
+ cmake --build build/ --target install
+
+ - name: Fetch external libs
+ run: |
+ # QtApng
+ curl -L https://github.com/Skycoder42/QtApng/releases/download/1.1.4/qtapng-msvc2017_64-5.14.1.zip -o apng.zip
+ unzip apng.zip
+
+ # discord-rpc
+ curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-win.zip -o discord_rpc_win.zip
+ unzip discord_rpc_win.zip
+ cp ./discord-rpc/win64-dynamic/lib/discord-rpc.lib ./lib
+
+ # BASS
+ curl http://www.un4seen.com/files/bass24.zip -o bass.zip
+ unzip bass.zip
+ cp ./c/x64/bass.lib ./lib
+
+ # BASS Opus
+ curl http://www.un4seen.com/files/bassopus24.zip -o bassopus.zip
+ unzip bassopus.zip
+ cp ./c/x64/bassopus.lib ./lib
+
+ - name: Cache Qt
+ id: cache-qt
+ uses: actions/cache@v1
+ with:
+ path: ../Qt
+ key: ${{ runner.os }}-qt5
+
+ - name: Install Qt
+ uses: jurplel/install-qt-action@v2
+ with:
+ version: '5.15.2'
+ cached: ${{steps.cache-qt.outputs.cache-hit}}
+
+ - name: Create Build Environment
+ run: cmake -E make_directory ${{github.workspace}}/build
+
+ - name: Configure CMake
+ shell: bash
+ working-directory: ${{github.workspace}}/build
+ run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+
+ - name: Build
+ working-directory: ${{github.workspace}}/build
+ shell: bash
+ run: cmake --build . --config $BUILD_TYPE --target Attorney_Online
+
+ - name: Deploy
+ working-directory: ${{github.workspace}}/build/Release
+ shell: bash
+ run: |
+ windeployqt .
+ cp ../../msvc2017_64/plugins/imageformats/qapng.dll ./imageformats/
+ cp ../../discord-rpc/win64-dynamic/bin/discord-rpc.dll .
+ cp ../../x64/bass.dll .
+ cp ../../x64/bassopus.dll .
+
+ - name: Upload Artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: Attorney_Online-x64
+ path: ${{github.workspace}}/build/Release/
+
+ # linux:
+ # # The CMake configure and build commands are platform agnostic and should work equally
+ # # well on Windows or Mac. You can convert this to a matrix build if you need
+ # # cross-platform coverage.
+ # # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
+ # runs-on: ubuntu-20.04
+
+ # steps:
+ # - uses: actions/checkout@v2
+
+ # - name: Install catch2
+ # run: |
+ # curl -L https://github.com/catchorg/Catch2/archive/v2.13.4.tar.gz -o catch2.tar.gz
+ # tar xvf catch2.tar.gz
+ # cd Catch2-2.13.4
+ # cmake -Bbuild -H. -DBUILD_TESTING=OFF
+ # sudo cmake --build build/ --target install
+
+ # - name: Fetch external libs
+ # run: |
+ # # Download
+ # curl http://www.un4seen.com/files/bass24-linux.zip -o bass_linux.zip
+ # curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus_linux.zip
+ # curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip -o discord_rpc_linux.zip
+ # # Extract
+ # unzip bass_linux.zip
+ # unzip bassopus_linux.zip
+ # unzip discord_rpc_linux.zip
+ # # Copy
+ # cp x64/libbass.so lib
+ # cp x64/libbassopus.so lib
+ # cp discord-rpc/linux-dynamic/lib/libdiscord-rpc.so lib
+
+ # - name: Install Qt5
+ # run: sudo apt update -y && sudo apt install -y qt5-default
+
+ # - name: Install QtApng
+ # run: |
+ # git clone https://github.com/Skycoder42/QtApng
+ # cd QtApng
+ # qmake
+ # make
+ # sudo make install
+
+ # - name: Create Build Environment
+ # # Some projects don't allow in-source building, so create a separate build directory
+ # # We'll use this as our working directory for all subsequent commands
+ # run: cmake -E make_directory ${{github.workspace}}/build
+
+ # - name: Configure CMake
+ # # Use a bash shell so we can use the same syntax for environment variable
+ # # access regardless of the host operating system
+ # shell: bash
+ # env:
+ # CC: gcc-10
+ # CXX: g++-10
+ # working-directory: ${{github.workspace}}/build
+ # # Note the current convention is to use the -S and -B options here to specify source
+ # # and build directories, but this is only available with CMake 3.13 and higher.
+ # # The CMake binaries on the Github Actions machines are (as of this writing) 3.12
+ # run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+
+ # - name: Build
+ # working-directory: ${{github.workspace}}/build
+ # shell: bash
+ # # Execute the build. You can specify a specific target with "--target <NAME>"
+ # run: cmake --build . --config $BUILD_TYPE --target Attorney_Online
+
+ # - name: Strip
+ # working-directory: ${{github.workspace}}/build
+ # shell: bash
+ # run: strip -s Attorney_Online
+
+ # - name: Compress
+ # working-directory: ${{github.workspace}}/build
+ # shell: bash
+ # run: tar czvf Attorney_Online-linux-x86_64.tgz Attorney_Online
+
+ # - name: Upload Artifact
+ # uses: actions/upload-artifact@v2
+ # with:
+ # name: Attorney_Online
+ # path: ${{github.workspace}}/build/Attorney_Online-linux-x86_64.tgz
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..4350a7c3
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,87 @@
+name: test
+
+on:
+ push:
+ branches:
+ - add-tests
+
+env:
+ # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
+ BUILD_TYPE: Release
+
+jobs:
+ build:
+ # The CMake configure and build commands are platform agnostic and should work equally
+ # well on Windows or Mac. You can convert this to a matrix build if you need
+ # cross-platform coverage.
+ # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install catch2
+ run: |
+ curl -L https://github.com/catchorg/Catch2/archive/v2.13.4.tar.gz -o catch2.tar.gz
+ tar xvf catch2.tar.gz
+ cd Catch2-2.13.4
+ cmake -Bbuild -H. -DBUILD_TESTING=OFF
+ sudo cmake --build build/ --target install
+
+ - name: Fetch external libs
+ run: |
+ # Download
+ curl http://www.un4seen.com/files/bass24-linux.zip -o bass_linux.zip
+ curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus_linux.zip
+ curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip -o discord_rpc_linux.zip
+ # Extract
+ unzip bass_linux.zip
+ unzip bassopus_linux.zip
+ unzip discord_rpc_linux.zip
+ # Copy
+ cp x64/libbass.so lib
+ cp x64/libbassopus.so lib
+ cp discord-rpc/linux-dynamic/lib/libdiscord-rpc.so lib
+
+ - name: Install Qt5
+ run: sudo apt update -y && sudo apt install -y qt5-default
+
+ - name: Install QtApng
+ run: |
+ git clone https://github.com/Skycoder42/QtApng
+ cd QtApng
+ qmake
+ make
+ sudo make install
+
+ - name: Create Build Environment
+ # Some projects don't allow in-source building, so create a separate build directory
+ # We'll use this as our working directory for all subsequent commands
+ run: cmake -E make_directory ${{github.workspace}}/build
+
+ - name: Configure CMake
+ # Use a bash shell so we can use the same syntax for environment variable
+ # access regardless of the host operating system
+ shell: bash
+ env:
+ CC: gcc-10
+ CXX: g++-10
+ working-directory: ${{github.workspace}}/build
+ # Note the current convention is to use the -S and -B options here to specify source
+ # and build directories, but this is only available with CMake 3.13 and higher.
+ # The CMake binaries on the Github Actions machines are (as of this writing) 3.12
+ run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+
+ - name: Build
+ working-directory: ${{github.workspace}}/build
+ shell: bash
+ # Execute the build. You can specify a specific target with "--target <NAME>"
+ run: cmake --build . --config $BUILD_TYPE --target test
+
+ - name: Test
+ working-directory: ${{github.workspace}}/build/test
+ shell: bash
+ env:
+ QT_QPA_PLATFORM: offscreen
+ run: |
+ ln -s ../../test/*.png .
+ ./test ~[noci]
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..b6b02106
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,43 @@
+# Configure cmake
+cmake_minimum_required(VERSION 3.1.0)
+cmake_policy(SET CMP0076 NEW) # silence warning
+
+project(AttorneyOnline)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(CMAKE_VERSION VERSION_LESS "3.7.0")
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+endif()
+
+# AO
+add_executable(Attorney_Online resources.qrc)
+
+# WIN32
+if(WIN32)
+ if(CMAKE_BUILD_TYPE STREQUAL "Release")
+ set_property(TARGET Attorney_Online PROPERTY WIN32_EXECUTABLE true)
+ set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/resource/logo_ao2.rc")
+ target_sources(Attorney_Online PRIVATE ${APP_ICON_RESOURCE_WINDOWS})
+ endif()
+endif()
+
+# Target Include
+target_include_directories(Attorney_Online PRIVATE include)
+
+# Target Lib
+find_package(Qt5 COMPONENTS Core Gui Network Widgets REQUIRED)
+target_link_directories(Attorney_Online PRIVATE lib)
+target_link_libraries(Attorney_Online PRIVATE Qt5::Core Qt5::Gui Qt5::Network Qt5::Widgets
+ bass bassopus discord-rpc)
+target_compile_definitions(Attorney_Online PRIVATE DISCORD)
+
+# Subdirectories
+add_subdirectory(test)
+add_subdirectory(src)
+add_subdirectory(include)
diff --git a/README_TEST.md b/README_TEST.md
new file mode 100644
index 00000000..774ad3cb
--- /dev/null
+++ b/README_TEST.md
@@ -0,0 +1,17 @@
+Running tests requires Catch2 and cmake
+
+# Running Tests
+```sh
+mkdir cbuild && cd cbuild
+cmake ..
+make test
+
+# usage: run all tests
+./test/test
+
+# usage: Optionally specify tests and success verbosity
+./test/test [bass] --success
+```
+
+# Writing Tests
+`[noci]` tag is used to disable a test on Github actions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644
index 00000000..18cf23ba
--- /dev/null
+++ b/include/CMakeLists.txt
@@ -0,0 +1,38 @@
+target_sources(Attorney_Online PRIVATE
+aoapplication.h
+aoblipplayer.h
+aobutton.h
+aocaseannouncerdialog.h
+aocharbutton.h
+aoclocklabel.h
+aoemotebutton.h
+aoevidencebutton.h
+aoevidencedisplay.h
+aoimage.h
+aolayer.h
+aolineedit.h
+aomusicplayer.h
+aooptionsdialog.h
+aopacket.h
+aosfxplayer.h
+aotextarea.h
+aotextedit.h
+bass.h
+bassopus.h
+chatlogpiece.h
+courtroom.h
+datatypes.h
+debug_functions.h
+demoserver.h
+discord-rpc.h
+discord_register.h
+discord_rich_presence.h
+discord_rpc.h
+file_functions.h
+hardware_functions.h
+lobby.h
+misc_functions.h
+networkmanager.h
+scrolltext.h
+text_file_functions.h
+)
diff --git a/resource/logo_ao2.rc b/resource/logo_ao2.rc
new file mode 100644
index 00000000..ed785de8
--- /dev/null
+++ b/resource/logo_ao2.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON "logo_ao2.ico"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 00000000..b04db8b3
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,38 @@
+target_sources(Attorney_Online PRIVATE
+aoapplication.cpp
+aoblipplayer.cpp
+aobutton.cpp
+aocaseannouncerdialog.cpp
+aocharbutton.cpp
+aoclocklabel.cpp
+aoemotebutton.cpp
+aoevidencebutton.cpp
+aoevidencedisplay.cpp
+aoimage.cpp
+aolayer.cpp
+aolineedit.cpp
+aomusicplayer.cpp
+aooptionsdialog.cpp
+aopacket.cpp
+aosfxplayer.cpp
+aotextarea.cpp
+aotextedit.cpp
+charselect.cpp
+chatlogpiece.cpp
+courtroom.cpp
+debug_functions.cpp
+demoserver.cpp
+discord_rich_presence.cpp
+emotes.cpp
+evidence.cpp
+file_functions.cpp
+hardware_functions.cpp
+lobby.cpp
+main.cpp
+misc_functions.cpp
+networkmanager.cpp
+packet_distribution.cpp
+path_functions.cpp
+scrolltext.cpp
+text_file_functions.cpp
+)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 00000000..e43b5517
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,8 @@
+find_package(Qt5 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_link_directories(test PRIVATE ../lib)
+target_link_libraries(test PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Catch2::Catch2 bass bassopus discord-rpc)
+target_compile_definitions(Attorney_Online PRIVATE DISCORD)
diff --git a/test/missle.png b/test/missle.png
new file mode 100644
index 00000000..6f373b45
--- /dev/null
+++ b/test/missle.png
Binary files differ
diff --git a/test/snackoo.png b/test/snackoo.png
new file mode 100644
index 00000000..31577a31
--- /dev/null
+++ b/test/snackoo.png
Binary files differ
diff --git a/test/test_aopacket.cpp b/test/test_aopacket.cpp
new file mode 100644
index 00000000..0b318213
--- /dev/null
+++ b/test/test_aopacket.cpp
@@ -0,0 +1,45 @@
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+#include "aopacket.h"
+
+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") {
+ AOPacket p(packet_string);
+ REQUIRE(p.to_string() == packet_string);
+ }
+ 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]") {
+ // 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/<percent><dollar><and>/edit<num>#%";
+
+ 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);
+
+ p.net_decode();
+ REQUIRE(p.to_string() == packet_string);
+ }
+
+ 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);
+
+ p.net_encode();
+ REQUIRE(p.to_string() == good_encode);
+
+ p.net_decode();
+ REQUIRE(p.to_string() == packet_string);
+ }
+}
diff --git a/test/test_apng.cpp b/test/test_apng.cpp
new file mode 100644
index 00000000..20c7e927
--- /dev/null
+++ b/test/test_apng.cpp
@@ -0,0 +1,61 @@
+#include <catch2/catch.hpp>
+
+#include <QPluginLoader>
+#include <QImageReader>
+#include <QCoreApplication>
+#include <QGuiApplication>
+#include <QPixmap>
+
+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
new file mode 100644
index 00000000..f5f9198d
--- /dev/null
+++ b/test/test_bass.cpp
@@ -0,0 +1,40 @@
+#include <iostream>
+#include <cstring>
+
+#include <catch2/catch.hpp>
+#include <QString>
+
+#include "bass.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
new file mode 100644
index 00000000..5df27823
--- /dev/null
+++ b/test/test_caseloading.cpp
@@ -0,0 +1,18 @@
+#include <catch2/catch.hpp>
+
+#include <QStringList>
+
+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);
+}