diff --git a/.github/workflows/cpp-tests.yml b/.github/workflows/cpp-tests.yml index 5055b946..c57e9276 100644 --- a/.github/workflows/cpp-tests.yml +++ b/.github/workflows/cpp-tests.yml @@ -12,13 +12,8 @@ on: workflow_dispatch: env: - # Path to the solution file relative to the root of the project. - SOLUTION_FILE_PATH: ./Sources/backend-cpp/Windows/com.ctytler.dcs.sdPlugin.sln - - # Configuration type to build. - # You can convert this to a build matrix if you need coverage of multiple configuration types. - # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - BUILD_CONFIGURATION: Release + SOURCE_DIR: ./Sources/backend-cpp + BUILD_DIR: ./Sources/backend-cpp/build jobs: build: @@ -26,20 +21,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1.1 + uses: microsoft/setup-msbuild@v2 - - name: Restore NuGet packages - working-directory: ${{env.GITHUB_WORKSPACE}} - run: nuget restore ${{env.SOLUTION_FILE_PATH}} + - name: CMake + run: cmake -S ${{env.SOURCE_DIR}} -B ${{env.BUILD_DIR}} -A x64 -DBUILD_TESTING=ON - name: Build - working-directory: ${{env.GITHUB_WORKSPACE}} - # Add additional options to the MSBuild command line here (like platform or verbosity level). - # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference - run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} + run: cmake --build ${{env.BUILD_DIR}} --config RelWithDebInfo - name: Setup OpenCppCoverage and add to PATH id: setup_opencppcoverage @@ -50,7 +41,16 @@ jobs: - name: Run C++ Unit Tests and Generate Coverage Report id: generate_test_report shell: cmd - run: OpenCppCoverage.exe --sources Sources\backend-cpp --excluded_sources Vendor --excluded_sources Windows --export_type cobertura:StreamdeckDcsInterfaceCov.xml .\Sources\backend-cpp\Windows\x64\Release\Test.exe + run: | + OpenCppCoverage.exe ^ + --quiet ^ + --sources Sources\backend-cpp ^ + --excluded_sources Vendor ^ + --excluded_sources Windows ^ + --excluded_sources Tools ^ + --export_type cobertura:StreamdeckDcsInterfaceCov.xml ^ + --cover_children ^ + -- ctest --test-dir ./${{env.BUILD_DIR}} -C RelWithDebInfo --output-on-failure - name: Upload Report to Codecov uses: codecov/codecov-action@v5 @@ -58,3 +58,5 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} files: ./StreamdeckDcsInterfaceCov.xml flags: Cpp + disable_search: true + diff --git a/.gitignore b/.gitignore index 6fef6475..ba8e8b7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,53 @@ +# Project-specific Ignore List +settingsUI/ + +# --- CMake Artifacts --- +# Ignore the entire build directory (assuming you name it 'build' or 'out') +build/ +out/ +Testing/ + +# If you accidentally build in the root directory (In-Source Build), +# these lines will catch the mess: +CMakeFiles/ +CMakeCache.txt +CMakeScripts/ +cmake_install.cmake +install_manifest.txt +compile_commands.json +_deps/ +*.cmake + +# --- CMake Presets --- +# CMakePresets.json IS usually committed (it shares build configs with the team) +# CMakeUserPresets.json is NOT committed (it contains your personal paths) +CMakeUserPresets.json + +# --- IDE Specifics --- +# Visual Studio +.vs/ +*.sln +*.vcxproj +*.vcxproj.filters +*.user +*.suo +packages/ x64/ x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -settingsUI/ + +# VS Code +.vscode/ +!.vscode/extensions.json # Keep this if you want to suggest extensions + +# --- Output Binaries --- *.exe +*.dll *.pdb +*.lib +*.obj +*.ilk +*.exp + +# --- Log Files --- *.log -.vs/ -.vscode -*.user -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets \ No newline at end of file diff --git a/Sources/backend-cpp/CMakeLists.txt b/Sources/backend-cpp/CMakeLists.txt new file mode 100644 index 00000000..64ceba49 --- /dev/null +++ b/Sources/backend-cpp/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.23) + +# Note: C is included because of the Vendor/lua-5.4.8 C library +project(StreamdeckPluginBackend LANGUAGES C CXX) + +# Force the use of the Dynamic Runtime (/MD and /MDd) across the whole project +# This is added to align with the Vendored websocketpp library +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + +# Global C++ Settings +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if(MSVC) + add_compile_options( + /W3 # Warning Level 3 + /WX # Treat Warning As Error + /sdl # Enable Security Checks + /MP # Multi-processor compilation + /Zc:__cplusplus # Correct __cplusplus macro + ) +endif() + +add_compile_definitions(UNICODE _UNICODE _CONSOLE) +# TODO: If you are using _CONSOLE, you might see a black command prompt +# window pop up when your plugin starts. If you eventually want your +# plugin to run silently in the background without that window, +# you would change your project type to a Windows Application and use +# _WINDOWS instead of _CONSOLE, but for development and debugging, +# using _CONSOLE is much easier because you can see your log output. + +# Testing +include(CTest) + +if(BUILD_TESTING) + include(FetchContent) + + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest + GIT_TAG v1.17.0 + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + + # For Windows: Prevent overriding the parent project's compiler/linker settings + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + + FetchContent_MakeAvailable(googletest) +endif() + +# Libraries +add_subdirectory(Vendor) +add_subdirectory(Utilities) +add_subdirectory(ElgatoSD) +add_subdirectory(SimulatorInterface) +add_subdirectory(StreamdeckContext) + +# Executable +add_subdirectory(StreamdeckInterface) diff --git a/Sources/backend-cpp/ElgatoSD/CMakeLists.txt b/Sources/backend-cpp/ElgatoSD/CMakeLists.txt new file mode 100644 index 00000000..dcc495fe --- /dev/null +++ b/Sources/backend-cpp/ElgatoSD/CMakeLists.txt @@ -0,0 +1,29 @@ +add_library(ElgatoSD STATIC) + +target_sources( + ElgatoSD + PRIVATE + ESDConnectionManager.cpp + ESDLocalizer.cpp + ESDUtilitiesWindows.cpp + pch.cpp + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${CMAKE_SOURCE_DIR} + FILES + EPLJSONUtils.h + ESDBasePlugin.h + ESDConnectionManager.h + ESDLocalizer.h + ESDSDKDefines.h + ESDUtilities.h + pch.h + # TODO: Consider deleting the pch.* files, + # as they are not used as precompiled headers +) + +target_link_libraries(ElgatoSD PUBLIC nlohmann_json websocketpp) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/Sources/backend-cpp/ElgatoSD/ESDConnectionManager.h b/Sources/backend-cpp/ElgatoSD/ESDConnectionManager.h index e3e90741..697ac604 100644 --- a/Sources/backend-cpp/ElgatoSD/ESDConnectionManager.h +++ b/Sources/backend-cpp/ElgatoSD/ESDConnectionManager.h @@ -15,11 +15,13 @@ #include "ESDBasePlugin.h" #include "ESDSDKDefines.h" +#ifndef ASIO_STANDALONE #define ASIO_STANDALONE -#include -#include -#include -#include +#endif +#include +#include +#include +#include typedef websocketpp::config::asio_client::message_type::ptr message_ptr; typedef websocketpp::client WebsocketClient; diff --git a/Sources/backend-cpp/ElgatoSD/test/CMakeLists.txt b/Sources/backend-cpp/ElgatoSD/test/CMakeLists.txt new file mode 100644 index 00000000..f0cbb509 --- /dev/null +++ b/Sources/backend-cpp/ElgatoSD/test/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(MockESDConnectionManager INTERFACE) + +target_sources(MockESDConnectionManager INTERFACE MockESDConnectionManager.h) + +target_include_directories( + MockESDConnectionManager + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/Sources/backend-cpp/ElgatoSD/test/MockESDConnectionManager.h b/Sources/backend-cpp/ElgatoSD/test/MockESDConnectionManager.h new file mode 100644 index 00000000..d2ea07af --- /dev/null +++ b/Sources/backend-cpp/ElgatoSD/test/MockESDConnectionManager.h @@ -0,0 +1,109 @@ +// Copyright 2021 Charles Tytler + +/*** + * + * This file holds Mock classes of Elgato Streamdeck code that can be passed to plugin code for unit testing Streamdeck + * context management. The mocked ESDConnectionManager prevents actual websockets to the Streamdeck from being opened in + * the unit tests and instead allows output commands to be inspected. + * + ***/ + +#pragma once + +#include "ElgatoSD/ESDBasePlugin.h" +#include "ElgatoSD/ESDConnectionManager.h" + +class MockPlugin : public ESDBasePlugin +{ + public: + MockPlugin() {} + virtual ~MockPlugin() {} + + void SetConnectionManager(ESDConnectionManager *inConnectionManager) { mConnectionManager = inConnectionManager; } + + virtual void KeyDownForAction(const std::string &inAction, + const std::string &inContext, + const json &inPayload, + const std::string &inDeviceID) + { + } + virtual void KeyUpForAction(const std::string &inAction, + const std::string &inContext, + const json &inPayload, + const std::string &inDeviceID) + { + } + + virtual void WillAppearForAction(const std::string &inAction, + const std::string &inContext, + const json &inPayload, + const std::string &inDeviceID) + { + } + virtual void WillDisappearForAction(const std::string &inAction, + const std::string &inContext, + const json &inPayload, + const std::string &inDeviceID) + { + } + + virtual void DeviceDidConnect(const std::string &inDeviceID, const json &inDeviceInfo) {} + virtual void DeviceDidDisconnect(const std::string &inDeviceID) {} + + virtual void DidReceiveGlobalSettings(const json &inPayload) {} + + virtual void SendToPlugin(const std::string &inAction, + const std::string &inContext, + const json &inPayload, + const std::string &inDeviceID) + { + } +}; + +class MockESDConnectionManager : public ESDConnectionManager +{ + public: + // MOCK_METHOD(void, SetState, (int state, std::string context), (override)); + // MOCK_METHOD(void, SetTitle, (std::string title, std::string context, int flag), (override)); + MockESDConnectionManager() : ESDConnectionManager(0, "", "", "", &plugin_) {} + // ESDBasePlugin *inPlugin) {} + + void SetState(int inState, const std::string &inContext) + { + context_ = inContext; + state_ = inState; + num_calls_to_SetState++; + } + + void SetImage(const std::string &inBase64ImageString, const std::string &inContext, ESDSDKTarget inTarget) + { + context_ = inContext; + base64_image_string_ = inBase64ImageString; + num_calls_to_SetImage++; + } + + void SetTitle(const std::string &inTitle, const std::string &inContext, ESDSDKTarget inTarget) + { + context_ = inContext; + title_ = inTitle; + num_calls_to_SetTitle++; + } + + // Only in mock class: + void clear_buffer() + { + context_ = ""; + state_ = 0; + title_ = ""; + } + + MockPlugin plugin_; + std::string context_ = ""; + int state_ = 0; + std::string base64_image_string_ = ""; + std::string title_ = ""; + + int num_calls_to_SetState = 0; + int num_calls_to_SetImage = 0; + int num_calls_to_SetTitle = 0; +}; diff --git a/Sources/backend-cpp/SimulatorInterface/CMakeLists.txt b/Sources/backend-cpp/SimulatorInterface/CMakeLists.txt new file mode 100644 index 00000000..2dd61bde --- /dev/null +++ b/Sources/backend-cpp/SimulatorInterface/CMakeLists.txt @@ -0,0 +1,29 @@ +add_library(SimulatorInterface STATIC) + +target_sources( + SimulatorInterface + PRIVATE + SimConnectionManager.cpp + SimulatorInterface.cpp + Protocols/DcsBiosProtocol.cpp + Protocols/DcsBiosProtocol.h + Protocols/DcsBiosStreamParser.cpp + Protocols/DcsBiosStreamParser.h + Protocols/DcsExportScriptProtocol.cpp + Protocols/DcsExportScriptProtocol.h + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${CMAKE_SOURCE_DIR} + FILES + SimConnectionManager.h + SimulatorInterface.h + SimulatorInterfaceParameters.h + SimulatorProtocolTypes.h +) + +target_link_libraries(SimulatorInterface PUBLIC Utilities) + +if(BUILD_TESTING) + add_subdirectory(test) + add_subdirectory(Protocols/test) +endif() diff --git a/Sources/backend-cpp/SimulatorInterface/Protocols/test/CMakeLists.txt b/Sources/backend-cpp/SimulatorInterface/Protocols/test/CMakeLists.txt new file mode 100644 index 00000000..5538c117 --- /dev/null +++ b/Sources/backend-cpp/SimulatorInterface/Protocols/test/CMakeLists.txt @@ -0,0 +1,18 @@ +add_executable(ProtocolsTest) + +target_sources( + ProtocolsTest + PRIVATE + DcsBiosProtocolTest.cpp + DcsBiosStreamParserTest.cpp + DcsExportScriptProtocolTest.cpp +) + +target_link_libraries( + ProtocolsTest + PRIVATE SimulatorInterface GTest::gtest_main +) + +include(GoogleTest) + +gtest_discover_tests(ProtocolsTest) diff --git a/Sources/backend-cpp/SimulatorInterface/test/CMakeLists.txt b/Sources/backend-cpp/SimulatorInterface/test/CMakeLists.txt new file mode 100644 index 00000000..69207418 --- /dev/null +++ b/Sources/backend-cpp/SimulatorInterface/test/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(SimulatorInterfaceTest) + +target_sources( + SimulatorInterfaceTest + PRIVATE SimConnectionManagerTest.cpp SimulatorInterfaceTest.cpp +) + +target_link_libraries( + SimulatorInterfaceTest + PRIVATE SimulatorInterface GTest::gtest_main +) + +include(GoogleTest) + +gtest_discover_tests(SimulatorInterfaceTest) diff --git a/Sources/backend-cpp/StreamdeckContext/CMakeLists.txt b/Sources/backend-cpp/StreamdeckContext/CMakeLists.txt new file mode 100644 index 00000000..ac8a6c30 --- /dev/null +++ b/Sources/backend-cpp/StreamdeckContext/CMakeLists.txt @@ -0,0 +1,38 @@ +add_library(StreamdeckContext STATIC) + +target_sources( + StreamdeckContext + PRIVATE + BackwardsCompatibilityHandler.cpp + StreamdeckContext.cpp + ExportMonitors/ImageStateMonitor.cpp + ExportMonitors/ImageStateMonitor.h + ExportMonitors/IncrementMonitor.cpp + ExportMonitors/IncrementMonitor.h + ExportMonitors/TitleMonitor.cpp + ExportMonitors/TitleMonitor.h + SendActions/IncrementAction.cpp + SendActions/IncrementAction.h + SendActions/MomentaryAction.cpp + SendActions/MomentaryAction.h + SendActions/SendActionFactory.cpp + SendActions/SendActionFactory.h + SendActions/SendActionInterface.h + SendActions/SwitchAction.cpp + SendActions/SwitchAction.h + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${CMAKE_SOURCE_DIR} + FILES BackwardsCompatibilityHandler.h StreamdeckContext.h +) + +target_link_libraries( + StreamdeckContext + PUBLIC ElgatoSD nlohmann_json SimulatorInterface Utilities +) + +if(BUILD_TESTING) + add_subdirectory(test) + add_subdirectory(ExportMonitors/test) + add_subdirectory(SendActions/test) +endif() diff --git a/Sources/backend-cpp/StreamdeckContext/ExportMonitors/test/CMakeLists.txt b/Sources/backend-cpp/StreamdeckContext/ExportMonitors/test/CMakeLists.txt new file mode 100644 index 00000000..823936ff --- /dev/null +++ b/Sources/backend-cpp/StreamdeckContext/ExportMonitors/test/CMakeLists.txt @@ -0,0 +1,18 @@ +add_executable(ExportMonitorsTest) + +target_sources( + ExportMonitorsTest + PRIVATE + ImageStateMonitorTest.cpp + IncrementMonitorTest.cpp + TitleMonitorTest.cpp +) + +target_link_libraries( + ExportMonitorsTest + PRIVATE StreamdeckContext GTest::gtest_main +) + +include(GoogleTest) + +gtest_discover_tests(ExportMonitorsTest) diff --git a/Sources/backend-cpp/StreamdeckContext/SendActions/test/CMakeLists.txt b/Sources/backend-cpp/StreamdeckContext/SendActions/test/CMakeLists.txt new file mode 100644 index 00000000..02652bcf --- /dev/null +++ b/Sources/backend-cpp/StreamdeckContext/SendActions/test/CMakeLists.txt @@ -0,0 +1,19 @@ +add_executable(SendActionsTest) + +target_sources( + SendActionsTest + PRIVATE + IncrementActionTest.cpp + MomentaryActionTest.cpp + SendActionFactoryTest.cpp + SwitchActionTest.cpp +) + +target_link_libraries( + SendActionsTest + PRIVATE StreamdeckContext MockESDConnectionManager GTest::gtest_main +) + +include(GoogleTest) + +gtest_discover_tests(SendActionsTest) diff --git a/Sources/backend-cpp/StreamdeckContext/SendActions/test/IncrementActionTest.cpp b/Sources/backend-cpp/StreamdeckContext/SendActions/test/IncrementActionTest.cpp index 791f41b0..000ac419 100644 --- a/Sources/backend-cpp/StreamdeckContext/SendActions/test/IncrementActionTest.cpp +++ b/Sources/backend-cpp/StreamdeckContext/SendActions/test/IncrementActionTest.cpp @@ -5,7 +5,7 @@ #include "SimulatorInterface/SimConnectionManager.h" #include "StreamdeckContext/SendActions/IncrementAction.h" -#include "Test/MockESDConnectionManager.h" +#include "MockESDConnectionManager.h" namespace test { diff --git a/Sources/backend-cpp/StreamdeckContext/SendActions/test/MomentaryActionTest.cpp b/Sources/backend-cpp/StreamdeckContext/SendActions/test/MomentaryActionTest.cpp index c476b2b8..91087488 100644 --- a/Sources/backend-cpp/StreamdeckContext/SendActions/test/MomentaryActionTest.cpp +++ b/Sources/backend-cpp/StreamdeckContext/SendActions/test/MomentaryActionTest.cpp @@ -5,7 +5,7 @@ #include "SimulatorInterface/SimConnectionManager.h" #include "StreamdeckContext/SendActions/MomentaryAction.h" -#include "Test/MockESDConnectionManager.h" +#include "MockESDConnectionManager.h" namespace test { diff --git a/Sources/backend-cpp/StreamdeckContext/SendActions/test/SwitchActionTest.cpp b/Sources/backend-cpp/StreamdeckContext/SendActions/test/SwitchActionTest.cpp index bc473081..01f03889 100644 --- a/Sources/backend-cpp/StreamdeckContext/SendActions/test/SwitchActionTest.cpp +++ b/Sources/backend-cpp/StreamdeckContext/SendActions/test/SwitchActionTest.cpp @@ -4,8 +4,8 @@ #include "StreamdeckContext/SendActions/SwitchAction.h" +#include "MockESDConnectionManager.h" #include "SimulatorInterface/SimConnectionManager.h" -#include "Test/MockESDConnectionManager.h" namespace test { diff --git a/Sources/backend-cpp/StreamdeckContext/test/CMakeLists.txt b/Sources/backend-cpp/StreamdeckContext/test/CMakeLists.txt new file mode 100644 index 00000000..acc074f7 --- /dev/null +++ b/Sources/backend-cpp/StreamdeckContext/test/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(StreamdeckContextTest) + +target_sources( + StreamdeckContextTest + PRIVATE BackwardsCompatibilityHandlerTest.cpp StreamdeckContextTest.cpp +) + +target_link_libraries( + StreamdeckContextTest + PRIVATE StreamdeckContext MockESDConnectionManager GTest::gtest_main +) + +include(GoogleTest) + +gtest_discover_tests(StreamdeckContextTest) diff --git a/Sources/backend-cpp/StreamdeckContext/test/StreamdeckContextTest.cpp b/Sources/backend-cpp/StreamdeckContext/test/StreamdeckContextTest.cpp index ee247ca7..6373c198 100644 --- a/Sources/backend-cpp/StreamdeckContext/test/StreamdeckContextTest.cpp +++ b/Sources/backend-cpp/StreamdeckContext/test/StreamdeckContextTest.cpp @@ -3,7 +3,7 @@ #include "gtest/gtest.h" #include -#include "Test/MockESDConnectionManager.h" // Must be called before other includes +#include "MockESDConnectionManager.h" // Must be called before other includes #include "SimulatorInterface/SimConnectionManager.h" #include "StreamdeckContext/StreamdeckContext.h" diff --git a/Sources/backend-cpp/StreamdeckInterface/CMakeLists.txt b/Sources/backend-cpp/StreamdeckInterface/CMakeLists.txt new file mode 100644 index 00000000..3ae89bfc --- /dev/null +++ b/Sources/backend-cpp/StreamdeckInterface/CMakeLists.txt @@ -0,0 +1,39 @@ +add_executable(StreamdeckInterface) + +target_sources( + StreamdeckInterface + PRIVATE main.cpp StreamdeckInterface.cpp + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${CMAKE_SOURCE_DIR} + FILES StreamdeckInterface.h +) + +target_link_libraries( + StreamdeckInterface + PRIVATE ElgatoSD SimulatorInterface StreamdeckContext Utilities +) + +set_target_properties( + StreamdeckInterface + PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ON +) + +set_target_properties( + StreamdeckInterface + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) + +include(InstallRequiredSystemLibraries) + +if(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS) + add_custom_command( + TARGET StreamdeckInterface + POST_BUILD + COMMAND + ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} + "$" + COMMENT "Copying system runtime DLLs to output directory..." + ) +endif() diff --git a/Sources/backend-cpp/Utilities/CMakeLists.txt b/Sources/backend-cpp/Utilities/CMakeLists.txt new file mode 100644 index 00000000..4a8c7e08 --- /dev/null +++ b/Sources/backend-cpp/Utilities/CMakeLists.txt @@ -0,0 +1,26 @@ +add_library(Utilities STATIC) + +target_sources( + Utilities + PRIVATE + Decimal.cpp + JsonReader.cpp + LuaReader.cpp + StringUtilities.cpp + UdpSocket.cpp + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${CMAKE_SOURCE_DIR} + FILES + Decimal.h + JsonReader.h + LuaReader.h + StringUtilities.h + UdpSocket.h +) + +target_link_libraries(Utilities PUBLIC nlohmann_json PRIVATE lua-5.4.8) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/Sources/backend-cpp/Utilities/test/CMakeLists.txt b/Sources/backend-cpp/Utilities/test/CMakeLists.txt new file mode 100644 index 00000000..15f72ee2 --- /dev/null +++ b/Sources/backend-cpp/Utilities/test/CMakeLists.txt @@ -0,0 +1,18 @@ +add_executable(UtilitiesTest) + +target_sources( + UtilitiesTest + PRIVATE + DecimalTest.cpp + JsonReaderTest.cpp + LuaReaderTest.cpp + StringUtilitiesTest.cpp + UdpSocketTest.cpp + sample.json +) + +target_link_libraries(UtilitiesTest PRIVATE Utilities GTest::gtest_main) + +include(GoogleTest) + +gtest_discover_tests(UtilitiesTest WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) diff --git a/Sources/backend-cpp/Utilities/test/JsonReaderTest.cpp b/Sources/backend-cpp/Utilities/test/JsonReaderTest.cpp index c30d8881..e495502f 100644 --- a/Sources/backend-cpp/Utilities/test/JsonReaderTest.cpp +++ b/Sources/backend-cpp/Utilities/test/JsonReaderTest.cpp @@ -15,42 +15,42 @@ TEST(JsonReaderTest, getModuleListNonexistantPath) TEST(JsonReaderTest, getModuleTestPath) { - const std::string path = "Sources\\backend-cpp\\Utilities\\test"; + const std::string path = "Utilities\\test"; const auto maybe_module_list = get_module_list(path); ASSERT_TRUE(maybe_module_list); const auto module_list = maybe_module_list.value(); EXPECT_EQ(module_list.size(), 1); - EXPECT_EQ(module_list[0], "Sources\\backend-cpp\\Utilities\\test\\sample.json"); + EXPECT_EQ(module_list[0], "Utilities\\test\\sample.json"); } TEST(JsonReaderTest, getModuleUnderRecursiveTestPath) { - const std::string path = "Sources\\backend-cpp\\Utilities\\"; + const std::string path = "Utilities\\"; const auto maybe_module_list = get_module_list(path); ASSERT_TRUE(maybe_module_list); const auto module_list = maybe_module_list.value(); EXPECT_EQ(module_list.size(), 1); - EXPECT_EQ(module_list[0], "Sources\\backend-cpp\\Utilities\\test\\sample.json"); + EXPECT_EQ(module_list[0], "Utilities\\test\\sample.json"); } TEST(JsonReaderTest, getModuleTestPathWithForwardSlashes) { - const std::string path = "Sources/backend-cpp/Utilities/test"; + const std::string path = "Utilities/test"; const auto maybe_module_list = get_module_list(path); ASSERT_TRUE(maybe_module_list); const auto module_list = maybe_module_list.value(); EXPECT_EQ(module_list.size(), 1); - EXPECT_EQ(module_list[0], "Sources/backend-cpp/Utilities/test\\sample.json"); + EXPECT_EQ(module_list[0], "Utilities/test\\sample.json"); } TEST(JsonReaderTest, getModuleTestPathWithForwardSlashesTrailing) { - const std::string path = "Sources/backend-cpp/Utilities/test/"; + const std::string path = "Utilities/test/"; const auto maybe_module_list = get_module_list(path); ASSERT_TRUE(maybe_module_list); const auto module_list = maybe_module_list.value(); EXPECT_EQ(module_list.size(), 1); - EXPECT_EQ(module_list[0], "Sources/backend-cpp/Utilities/test/sample.json"); + EXPECT_EQ(module_list[0], "Utilities/test/sample.json"); } TEST(JsonReaderTest, nonexistantJsonFile) @@ -62,7 +62,7 @@ TEST(JsonReaderTest, nonexistantJsonFile) TEST(JsonReaderTest, readSampleJsonFile) { - const std::string json_file = "Sources/backend-cpp/Utilities/test/sample.json"; + const std::string json_file = "Utilities/test/sample.json"; const auto maybe_json = read_json_file(json_file); ASSERT_TRUE(maybe_json); const auto json_obj = maybe_json.value(); @@ -70,4 +70,4 @@ TEST(JsonReaderTest, readSampleJsonFile) EXPECT_EQ(json_obj["field2"]["d"], 4); } -} // namespace test \ No newline at end of file +} // namespace test diff --git a/Sources/backend-cpp/Vendor/CMakeLists.txt b/Sources/backend-cpp/Vendor/CMakeLists.txt new file mode 100644 index 00000000..ff2050a2 --- /dev/null +++ b/Sources/backend-cpp/Vendor/CMakeLists.txt @@ -0,0 +1,25 @@ +# --- JSON --- +add_library(nlohmann_json INTERFACE) +target_include_directories( + nlohmann_json + INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" +) + +# --- ASIO --- +add_library(asio INTERFACE) +target_include_directories( + asio + INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/asio/include" +) +target_compile_definitions(asio INTERFACE ASIO_STANDALONE) + +# --- Websocketpp --- +add_library(websocketpp INTERFACE) +target_include_directories( + websocketpp + INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/websocketpp" +) +target_link_libraries(websocketpp INTERFACE asio) + +# --- Lua --- +add_subdirectory(lua-5.4.8) diff --git a/Sources/backend-cpp/Vendor/lua-5.4.8/CMakeLists.txt b/Sources/backend-cpp/Vendor/lua-5.4.8/CMakeLists.txt new file mode 100644 index 00000000..95b1dc0d --- /dev/null +++ b/Sources/backend-cpp/Vendor/lua-5.4.8/CMakeLists.txt @@ -0,0 +1,80 @@ +add_library(lua-5.4.8 STATIC) +# set_target_properties(lua-5.4.8 PROPERTIES LINKER_LANGUAGE C) + +target_sources( + lua-5.4.8 + PUBLIC + FILE_SET HEADERS + BASE_DIRS + src/ # Include lua.hpp directly + FILES src/lua.hpp src/lua.h src/lualib.h src/lauxlib.h +) + +target_sources( + lua-5.4.8 + PRIVATE + src/lapi.c + src/lauxlib.c + src/lbaselib.c + src/lcode.c + src/lcorolib.c + src/lctype.c + src/ldblib.c + src/ldebug.c + src/ldo.c + src/ldump.c + src/lfunc.c + src/lgc.c + src/linit.c + src/liolib.c + src/llex.c + src/lmathlib.c + src/lmem.c + src/loadlib.c + src/lobject.c + src/lopcodes.c + src/loslib.c + src/lparser.c + src/lstate.c + src/lstring.c + src/lstrlib.c + src/ltable.c + src/ltablib.c + src/ltm.c + src/lundump.c + src/lutf8lib.c + src/lvm.c + src/lzio.c + # Standalone files lua.c and luac.c are excluded as + # they have their own 'main()' functions + src/lapi.h + src/lcode.h + src/lctype.h + src/ldebug.h + src/ldo.h + src/lfunc.h + src/lgc.h + src/ljumptab.h + src/llex.h + src/llimits.h + src/lmem.h + src/lobject.h + src/lopcodes.h + src/lopnames.h + src/lparser.h + src/lprefix.h + src/lstate.h + src/lstring.h + src/ltable.h + src/ltm.h + src/luaconf.h + src/lundump.h + src/lvm.h + src/lzio.h +) + +# MSVC specific security and compatibility fixes +# (Avoids warnings from using standard C functions as opposed to "secure" ones) +if(MSVC) + target_compile_definitions(lua-5.4.8 PRIVATE _CRT_SECURE_NO_WARNINGS) +endif() diff --git a/Tools/build_plugin.bat b/Tools/build_plugin.bat index 422b2179..25719984 100644 --- a/Tools/build_plugin.bat +++ b/Tools/build_plugin.bat @@ -5,22 +5,19 @@ :: Change directory to the project root (directory above this batch file location) cd /D "%~dp0"\.. -:: Restore NuGet packages -MSBuild.exe .\Sources\backend-cpp\Windows\com.ctytler.dcs.sdPlugin.sln /t:Restore /p:RestorePackagesConfig=true -if %errorlevel% neq 0 echo "Canceling plugin build due to failure to restore NuGet packages" && pause && exit /b %errorlevel% - :: Build C++ executable: -MSBuild.exe .\Sources\backend-cpp\Windows\com.ctytler.dcs.sdPlugin.sln /p:Configuration="Release" +cmake -S ./Sources/backend-cpp -B ./Sources/backend-cpp/build +cmake --build ./Sources/backend-cpp/build --config Release if %errorlevel% neq 0 echo "Canceling plugin build due to failed backend build" && pause && exit /b %errorlevel% :: Run unit tests, only continue if all tests pass -Sources\backend-cpp\Windows\x64\Release\Test.exe +ctest --test-dir ./Sources/backend-cpp/build --output-on-failure if %errorlevel% neq 0 echo "Canceling plugin build due to failed unit tests" && pause && exit /b %errorlevel% :: Copy C++ executable and DLLs to StreamDeck Plugin package: echo. && echo *** C++ binary compilation complete, published to Sources/com.ctytler.dcs.sdPlugin/bin/ *** && echo. -copy Sources\backend-cpp\Windows\x64\Release\streamdeck_dcs_interface.exe Sources\com.ctytler.dcs.sdPlugin\bin\ -copy Sources\backend-cpp\Windows\x64\Release\*.dll Sources\com.ctytler.dcs.sdPlugin\bin\ +copy Sources\backend-cpp\build\bin\Release\StreamdeckInterface.exe Sources\com.ctytler.dcs.sdPlugin\bin\streamdeck_dcs_interface.exe +copy Sources\backend-cpp\build\bin\Release\*.dll Sources\com.ctytler.dcs.sdPlugin\bin\ :: Remove any prior build of the Plugin: echo. && echo *** Removing any previous builds of com.ctytler.dcs.streamDeckPlugin from Release/ *** diff --git a/codecov.yml b/codecov.yml index a7ee2619..f679c028 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,15 +1,24 @@ +codecov: + require_ci_to_pass: true + notify: + after_n_builds: 2 + coverage: status: - default_rules: project: - default: - target: auto - threshold: 1% + cpp: + informational: true flags: - Cpp + + react: + informational: true + flags: - ReactJS -codecov: - notify: - after_n_builds: 2 + patch: + default: + informational: true + comment: after_n_builds: 2 +