From 188d8d2d5f612e6fffd0141641d7a013319590eb Mon Sep 17 00:00:00 2001 From: Mete Istar <67550484+meteistar@users.noreply.github.com> Date: Tue, 17 Feb 2026 12:09:30 +0300 Subject: [PATCH 1/4] Integrate GoogleTest testing infrastructure --- CMakeLists.txt | 18 ++++++++++++++++++ tests/CMakeLists.txt | 11 +++++++++++ tests/smoke_test.cpp | 6 ++++++ 3 files changed, 35 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/smoke_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f9c5e77..f7e6f4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ project(CutScene VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) +include(CTest) + find_package(Qt6 6.4 REQUIRED COMPONENTS Core Gui Widgets Multimedia MultimediaWidgets) find_package(FFMPEG REQUIRED) @@ -74,3 +76,19 @@ install(TARGETS appCutScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) + +if(BUILD_TESTING) + include(FetchContent) + + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip + ) + + # Prevent GoogleTest from overriding our compiler/linker options on Windows. + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + + FetchContent_MakeAvailable(googletest) + + add_subdirectory(tests) +endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..0f13cc6 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(cutscene_tests + smoke_test.cpp +) + +target_link_libraries(cutscene_tests + PRIVATE + GTest::gtest_main +) + +include(GoogleTest) +gtest_discover_tests(cutscene_tests) diff --git a/tests/smoke_test.cpp b/tests/smoke_test.cpp new file mode 100644 index 0000000..fdc4ae5 --- /dev/null +++ b/tests/smoke_test.cpp @@ -0,0 +1,6 @@ +#include + +TEST(CutSceneSmokeTest, GoogleTestIsConfigured) +{ + EXPECT_EQ(2 + 2, 4); +} From a15a99306df7b5bc25daf4acf05f49039431ba99 Mon Sep 17 00:00:00 2001 From: Mete Istar <67550484+meteistar@users.noreply.github.com> Date: Tue, 17 Feb 2026 12:19:56 +0300 Subject: [PATCH 2/4] Add DropWidget unit tests with GoogleTest --- tests/CMakeLists.txt | 6 +++-- tests/drop_widget_test.cpp | 46 ++++++++++++++++++++++++++++++++++++++ tests/smoke_test.cpp | 6 ----- tests/test_main.cpp | 12 ++++++++++ 4 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 tests/drop_widget_test.cpp delete mode 100644 tests/smoke_test.cpp create mode 100644 tests/test_main.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0f13cc6..495f48d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,10 +1,12 @@ add_executable(cutscene_tests - smoke_test.cpp + test_main.cpp + drop_widget_test.cpp ) target_link_libraries(cutscene_tests PRIVATE - GTest::gtest_main + GTest::gtest + Qt6::Widgets ) include(GoogleTest) diff --git a/tests/drop_widget_test.cpp b/tests/drop_widget_test.cpp new file mode 100644 index 0000000..7bea7da --- /dev/null +++ b/tests/drop_widget_test.cpp @@ -0,0 +1,46 @@ +#include "../src/DropWidget.h" + +#include +#include + +class TestableDropWidget : public DropWidget { +public: + using DropWidget::DropWidget; + using DropWidget::dragEnterEvent; + using DropWidget::dropEvent; +}; + +TEST(DropWidgetTest, ConstructorSetsExpectedDefaults) +{ + TestableDropWidget widget; + + EXPECT_EQ(widget.text().toStdString(), "Drop Here"); + EXPECT_TRUE(widget.acceptDrops()); + EXPECT_EQ(widget.alignment(), Qt::AlignCenter); +} + +TEST(DropWidgetTest, DragEnterAcceptsTextMimeData) +{ + TestableDropWidget widget; + QMimeData mimeData; + mimeData.setText("clip.mp4"); + + QDragEnterEvent event(QPoint(5, 5), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); + + widget.dragEnterEvent(&event); + + EXPECT_TRUE(event.isAccepted()); +} + +TEST(DropWidgetTest, DropEventUpdatesDisplayedText) +{ + TestableDropWidget widget; + QMimeData mimeData; + mimeData.setText("new media"); + + QDropEvent event(QPointF(10, 10), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); + + widget.dropEvent(&event); + + EXPECT_EQ(widget.text().toStdString(), "new media"); +} diff --git a/tests/smoke_test.cpp b/tests/smoke_test.cpp deleted file mode 100644 index fdc4ae5..0000000 --- a/tests/smoke_test.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -TEST(CutSceneSmokeTest, GoogleTestIsConfigured) -{ - EXPECT_EQ(2 + 2, 4); -} diff --git a/tests/test_main.cpp b/tests/test_main.cpp new file mode 100644 index 0000000..96f1ec0 --- /dev/null +++ b/tests/test_main.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + +int main(int argc, char **argv) +{ + qputenv("QT_QPA_PLATFORM", QByteArray("offscreen")); + QApplication app(argc, argv); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 9d620f4f2a2c81cd3f0cc1addd0a7502724aa04a Mon Sep 17 00:00:00 2001 From: meteistar Date: Tue, 17 Feb 2026 12:32:06 +0300 Subject: [PATCH 3/4] Fix gtest Qt MOC linking and add VSCode test build tasks --- .vscode/tasks.json | 38 ++++++++++++++++++++++++++++++++++ scripts/build-tests-vscode.ps1 | 35 +++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 13 +++++++++++- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 .vscode/tasks.json create mode 100644 scripts/build-tests-vscode.ps1 diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..cd2bcb0 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,38 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build gtests (MSVC)", + "type": "shell", + "command": "powershell", + "args": [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-File", + "scripts/build-tests-vscode.ps1" + ], + "group": "build", + "problemMatcher": [ + "$msCompile" + ] + }, + { + "label": "Build + Run gtests (MSVC)", + "type": "shell", + "command": "powershell", + "args": [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-File", + "scripts/build-tests-vscode.ps1", + "-RunTests" + ], + "group": "test", + "problemMatcher": [ + "$msCompile" + ] + } + ] +} diff --git a/scripts/build-tests-vscode.ps1 b/scripts/build-tests-vscode.ps1 new file mode 100644 index 0000000..889cca2 --- /dev/null +++ b/scripts/build-tests-vscode.ps1 @@ -0,0 +1,35 @@ +param( + [string]$BuildDir = "build/vscode-msvc-debug", + [string]$QtDir = "C:/Qt/6.7.0/msvc2019_64", + [switch]$RunTests +) + +$ErrorActionPreference = "Stop" + +$vswhere = Join-Path ${env:ProgramFiles(x86)} "Microsoft Visual Studio\Installer\vswhere.exe" +if (-not (Test-Path $vswhere)) { + throw "vswhere not found: $vswhere" +} + +$vsInstall = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath +if (-not $vsInstall) { + throw "Visual Studio with C++ tools was not found." +} + +$devCmd = Join-Path $vsInstall "Common7\Tools\VsDevCmd.bat" +if (-not (Test-Path $devCmd)) { + throw "VsDevCmd.bat not found: $devCmd" +} + +$configureCmd = "cmake -S . -B `"$BuildDir`" -G `"Ninja`" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DCMAKE_PREFIX_PATH=`"$QtDir`"" +$buildCmd = "cmake --build `"$BuildDir`" --target cutscene_tests" +$testCmd = "ctest --test-dir `"$BuildDir`" --output-on-failure" + +$qtBinDir = Join-Path $QtDir "bin" +$fullCmd = "`"$devCmd`" -arch=x64 && set `"PATH=$qtBinDir;%PATH%`" && $configureCmd && $buildCmd" +if ($RunTests) { + $fullCmd += " && $testCmd" +} + +cmd.exe /c $fullCmd +exit $LASTEXITCODE diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 495f48d..7ec82d1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,13 +1,24 @@ add_executable(cutscene_tests test_main.cpp drop_widget_test.cpp + ../src/DropWidget.h +) + +set_target_properties(cutscene_tests PROPERTIES + AUTOMOC ON +) + +target_include_directories(cutscene_tests + PRIVATE + ../src ) target_link_libraries(cutscene_tests PRIVATE GTest::gtest + Qt6::Core Qt6::Widgets ) include(GoogleTest) -gtest_discover_tests(cutscene_tests) +gtest_add_tests(TARGET cutscene_tests) From 1caf76141b6b8e270959c9b469bc8831dbfb865a Mon Sep 17 00:00:00 2001 From: meteistar Date: Tue, 17 Feb 2026 12:40:19 +0300 Subject: [PATCH 4/4] Add HeaderBarWidget unit tests --- tests/CMakeLists.txt | 3 ++ tests/header_bar_widget_test.cpp | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/header_bar_widget_test.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7ec82d1..fffbebc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,10 @@ add_executable(cutscene_tests test_main.cpp drop_widget_test.cpp + header_bar_widget_test.cpp ../src/DropWidget.h + ../src/HeaderBarWidget.cpp + ../src/HeaderBarWidget.h ) set_target_properties(cutscene_tests PROPERTIES diff --git a/tests/header_bar_widget_test.cpp b/tests/header_bar_widget_test.cpp new file mode 100644 index 0000000..b3cb616 --- /dev/null +++ b/tests/header_bar_widget_test.cpp @@ -0,0 +1,53 @@ +#include "../src/HeaderBarWidget.h" + +#include +#include +#include +#include +#include + +namespace { +QPushButton *findButtonByText(HeaderBarWidget &widget, const QString &text) +{ + const QList buttons = widget.findChildren(); + for (QPushButton *button : buttons) { + if (button && button->text() == text) { + return button; + } + } + return nullptr; +} +} + +TEST(HeaderBarWidgetTest, ConstructorSetsExpectedTitleAndHeight) +{ + HeaderBarWidget widget; + + EXPECT_EQ(widget.minimumHeight(), 50); + EXPECT_EQ(widget.maximumHeight(), 50); + + const QList labels = widget.findChildren(); + bool foundTitle = false; + for (QLabel *label : labels) { + if (label && label->text() == "CutScene") { + foundTitle = true; + break; + } + } + EXPECT_TRUE(foundTitle); +} + +TEST(HeaderBarWidgetTest, FileButtonClickEmitsFileClickedSignal) +{ + HeaderBarWidget widget; + int emissionCount = 0; + QObject::connect(&widget, &HeaderBarWidget::fileClicked, [&emissionCount]() { + ++emissionCount; + }); + + QPushButton *fileButton = findButtonByText(widget, "File"); + ASSERT_NE(fileButton, nullptr); + + fileButton->click(); + EXPECT_EQ(emissionCount, 1); +}