From 803f2b07ce77e2b3ad35e4fab1e884969e28693f Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:10:32 +0200 Subject: [PATCH] tests/gesturerecognizer: extract common tests into another class --- README.md | 2 +- tests/CMakeLists.txt | 2 +- tests/libgesture/gestures/CMakeLists.txt | 7 - .../gestures/test_gesturerecognizer_hold.cpp | 99 ------------ .../CMakeLists.txt | 0 tests/libgestures/README.md | 2 + tests/libgestures/gestures/CMakeLists.txt | 11 ++ .../gestures/test_gesturerecognizer_hold.cpp | 135 +++++++++++++++++ .../gestures/test_gesturerecognizer_hold.h | 8 +- .../test_gesturerecognizer_shared.cpp | 141 ++++++++++++++++++ .../gestures/test_gesturerecognizer_shared.h | 59 ++++++++ 11 files changed, 354 insertions(+), 112 deletions(-) delete mode 100644 tests/libgesture/gestures/CMakeLists.txt delete mode 100644 tests/libgesture/gestures/test_gesturerecognizer_hold.cpp rename tests/{libgesture => libgestures}/CMakeLists.txt (100%) create mode 100644 tests/libgestures/README.md create mode 100644 tests/libgestures/gestures/CMakeLists.txt create mode 100644 tests/libgestures/gestures/test_gesturerecognizer_hold.cpp rename tests/{libgesture => libgestures}/gestures/test_gesturerecognizer_hold.h (74%) create mode 100644 tests/libgestures/gestures/test_gesturerecognizer_shared.cpp create mode 100644 tests/libgestures/gestures/test_gesturerecognizer_shared.h diff --git a/README.md b/README.md index d0e72e1..5428ebc 100644 --- a/README.md +++ b/README.md @@ -114,4 +114,4 @@ Before reporting any issues related to gesture recognition, run ``libinput debug Depending on the touchpad, 3 or 4-finger pinch gestures may sometimes be incorrectly interpreted as swipe gestures due to the touchpad only being able to track 2 fingers. As a workaround, move only 2 fingers in opposite directions. See https://wayland.freedesktop.org/libinput/doc/1.25.0/gestures.html#gestures-on-two-finger-touchpads for more information. # Credits -- [KWin](https://invent.kde.org/plasma/kwin) - Gesture recognition, sending keystrokes \ No newline at end of file +- [KWin](https://invent.kde.org/plasma/kwin) - Gesture recognition code in early versions, sending keystrokes \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a4ed6f9..3fe90a0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1 +1 @@ -add_subdirectory(libgesture) \ No newline at end of file +add_subdirectory(libgestures) \ No newline at end of file diff --git a/tests/libgesture/gestures/CMakeLists.txt b/tests/libgesture/gestures/CMakeLists.txt deleted file mode 100644 index 89d372c..0000000 --- a/tests/libgesture/gestures/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -qt_add_executable(testGestureRecognizerHold test_gesturerecognizer_hold.cpp) -add_test(NAME "gesturerecognizer_hold" COMMAND testGestureRecognizerHold) -target_link_libraries(testGestureRecognizerHold PRIVATE - libgestures - Qt::Core - Qt::Test -) \ No newline at end of file diff --git a/tests/libgesture/gestures/test_gesturerecognizer_hold.cpp b/tests/libgesture/gestures/test_gesturerecognizer_hold.cpp deleted file mode 100644 index 12eb482..0000000 --- a/tests/libgesture/gestures/test_gesturerecognizer_hold.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "test_gesturerecognizer_hold.h" -#include - -void TestGestureRecognizerHold::init() -{ - m_gestureRecognizer = std::make_unique(); - m_hold2 = std::make_shared(false, 2, 2, false, 0); - m_hold2To3 = std::make_shared(false, 2, 3, false, 0); - m_hold3To4 = std::make_shared(false, 3, 4, false, 0); - - m_hold2_2actions_trigger1only = std::make_shared(true, 2, 2, true, 1); - m_hold2_2actions_trigger1only->addAction(std::make_shared(0)); - m_hold2_2actions_trigger1only->addAction(std::make_shared(0)); -} - -void TestGestureRecognizerHold::holdGestureBegin_holdGestureConditionsNotSatisfied_hasNoActiveHoldGestures() -{ - m_gestureRecognizer->registerGesture(m_hold2); - - m_gestureRecognizer->holdGestureBegin(3); - - QVERIFY(m_gestureRecognizer->m_activeHoldGestures.empty()); -} - -void TestGestureRecognizerHold::holdGestureBegin_twoHoldGesturesWithSatisfiedConditions_hasTwoActiveHoldGestures() -{ - m_gestureRecognizer->registerGesture(m_hold2To3); - m_gestureRecognizer->registerGesture(m_hold3To4); - - m_gestureRecognizer->holdGestureBegin(3); - - QCOMPARE(m_gestureRecognizer->m_activeHoldGestures.size(), 2); -} - -void TestGestureRecognizerHold::holdGestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndGestureNotEndedPrematurely() -{ - QSignalSpy spy(m_hold2.get(), &Gesture::updated); - m_gestureRecognizer->registerGesture(m_hold2); - - m_gestureRecognizer->holdGestureBegin(2); - auto endedPrematurely = false; - const auto delta = 1; - m_gestureRecognizer->holdGestureUpdate(delta, endedPrematurely); - - QCOMPARE(spy.count(), 1); - const auto signal = spy.takeFirst(); - QCOMPARE(signal.at(0).toReal(), delta); - QVERIFY(!endedPrematurely); -} - -void TestGestureRecognizerHold::holdGestureUpdate_twoActiveGesturesAndOneEndsPrematurely_endedPrematurelySetToTrueAndOnlyOneGestureUpdated() -{ - QSignalSpy spy(m_hold2_2actions_trigger1only.get(), &Gesture::updated); - m_gestureRecognizer->registerGesture(m_hold2_2actions_trigger1only); - m_gestureRecognizer->registerGesture(m_hold2_2actions_trigger1only); - - m_gestureRecognizer->holdGestureBegin(2); - auto endedPrematurely = false; - m_gestureRecognizer->holdGestureUpdate(1, endedPrematurely); - - QCOMPARE(spy.count(), 1); - QVERIFY(endedPrematurely); -} - -void TestGestureRecognizerHold::holdGestureCancelled_twoActiveGestures_gestureCancelledSignalEmittedForAllGesturesAndActiveHoldGesturesCleared() -{ - QSignalSpy spy1(m_hold2To3.get(), &Gesture::cancelled); - QSignalSpy spy2(m_hold3To4.get(), &Gesture::cancelled); - m_gestureRecognizer->registerGesture(m_hold2To3); - m_gestureRecognizer->registerGesture(m_hold3To4); - - m_gestureRecognizer->holdGestureBegin(3); - m_gestureRecognizer->holdGestureCancelled(); - - QCOMPARE(spy1.count(), 1); - QCOMPARE(spy2.count(), 1); - QVERIFY(m_gestureRecognizer->m_activeHoldGestures.empty()); -} - -void TestGestureRecognizerHold::holdGestureEnd_noActiveGestures_returnsFalse() -{ - QVERIFY(!m_gestureRecognizer->holdGestureEnd()); -} - -void TestGestureRecognizerHold::holdGestureEnd_activeGesture_gestureEndedSignalEmittedAndActiveHoldGesturesClearedAndReturnsTrue() -{ - QSignalSpy spy(m_hold2.get(), &Gesture::ended); - m_gestureRecognizer->registerGesture(m_hold2); - - m_gestureRecognizer->holdGestureBegin(2); - const auto returnValue = m_gestureRecognizer->holdGestureEnd(); - - QCOMPARE(spy.count(), 1); - QVERIFY(m_gestureRecognizer->m_activeHoldGestures.empty()); - QVERIFY(returnValue); -} - -QTEST_MAIN(TestGestureRecognizerHold) -#include "test_gesturerecognizer_hold.moc" \ No newline at end of file diff --git a/tests/libgesture/CMakeLists.txt b/tests/libgestures/CMakeLists.txt similarity index 100% rename from tests/libgesture/CMakeLists.txt rename to tests/libgestures/CMakeLists.txt diff --git a/tests/libgestures/README.md b/tests/libgestures/README.md new file mode 100644 index 0000000..cb61474 --- /dev/null +++ b/tests/libgestures/README.md @@ -0,0 +1,2 @@ +# libgestures +libgestures is a library for recognizing and handling gestures. \ No newline at end of file diff --git a/tests/libgestures/gestures/CMakeLists.txt b/tests/libgestures/gestures/CMakeLists.txt new file mode 100644 index 0000000..dcd0cef --- /dev/null +++ b/tests/libgestures/gestures/CMakeLists.txt @@ -0,0 +1,11 @@ +set(testGestureRecognizerHold_SRCS + test_gesturerecognizer_hold.cpp + test_gesturerecognizer_shared.cpp +) +qt_add_executable(testGestureRecognizerHold ${testGestureRecognizerHold_SRCS}) +add_test(NAME "gesturerecognizer_hold" COMMAND testGestureRecognizerHold) +target_link_libraries(testGestureRecognizerHold PRIVATE + libgestures + Qt::Core + Qt::Test +) \ No newline at end of file diff --git a/tests/libgestures/gestures/test_gesturerecognizer_hold.cpp b/tests/libgestures/gestures/test_gesturerecognizer_hold.cpp new file mode 100644 index 0000000..7e8ce8a --- /dev/null +++ b/tests/libgestures/gestures/test_gesturerecognizer_hold.cpp @@ -0,0 +1,135 @@ +#include "test_gesturerecognizer_shared.h" +#include "test_gesturerecognizer_hold.h" +#include + +void TestGestureRecognizerHold::init() +{ + m_gestureRecognizer = std::make_shared(); + m_hold2 = std::make_shared(false, 2, 2, false, 0); + m_hold2To3 = std::make_shared(false, 2, 3, false, 0); + m_hold3To4 = std::make_shared(false, 3, 4, false, 0); + + m_hold2_2actions_trigger1only = std::make_shared(true, 2, 2, true, 1); + m_hold2_2actions_trigger1only->addAction(std::make_shared(0)); + m_hold2_2actions_trigger1only->addAction(std::make_shared(0)); +} + +void TestGestureRecognizerHold::holdGestureBegin_gestureConditionsNotSatisfied_hasNoActiveGestures() +{ + TestGestureRecognizerShared::gestureBegin_gestureConditionsNotSatisfied_hasNoActiveGestures + ( + m_gestureRecognizer, + m_hold2, + [this]() + { + m_gestureRecognizer->holdGestureBegin(3); + }, + [this]() + { + return m_gestureRecognizer->m_activeHoldGestures; + } + ); +} + +void TestGestureRecognizerHold::holdGestureBegin_twoGesturesWithSatisfiedConditions_hasTwoActiveGestures() +{ + TestGestureRecognizerShared::gestureBegin_twoGesturesWithSatisfiedConditions_hasTwoActiveGestures + ( + m_gestureRecognizer, + { m_hold2To3, m_hold3To4 }, + [this]() + { + m_gestureRecognizer->holdGestureBegin(3); + }, + [this]() + { + return m_gestureRecognizer->m_activeHoldGestures; + } + ); +} + +void TestGestureRecognizerHold::holdGestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndDeltaMatchesAndGestureNotEndedPrematurely() +{ + TestGestureRecognizerShared::gestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndDeltaMatchesAndGestureNotEndedPrematurely + ( + m_gestureRecognizer, + m_hold2, + [this]() { + m_gestureRecognizer->holdGestureBegin(2); + }, + [this](const qreal & delta, bool &endedPrematurely) { + m_gestureRecognizer->holdGestureUpdate(delta, endedPrematurely); + }, + 1 + ); +} + +void TestGestureRecognizerHold::holdGestureUpdate_twoActiveGesturesAndOneEndsPrematurely_endedPrematurelySetToTrueAndOnlyOneGestureUpdated() +{ + const auto delta = 1; + TestGestureRecognizerShared::gestureUpdate_twoActiveGesturesAndOneEndsPrematurely_endedPrematurelySetToTrueAndOnlyOneGestureUpdated + ( + m_gestureRecognizer, + m_hold2_2actions_trigger1only, + m_hold2, + [this]() + { + m_gestureRecognizer->holdGestureBegin(2); + }, + [this](bool &endedPrematurely) + { + m_gestureRecognizer->holdGestureUpdate(delta, endedPrematurely); + } + ); +} + +void TestGestureRecognizerHold::holdGestureCancelled_twoActiveGestures_gestureCancelledSignalEmittedForAllGesturesAndActiveHoldGesturesCleared() +{ + TestGestureRecognizerShared::gestureCancelled_twoActiveGestures_gestureCancelledSignalEmittedForAllGesturesAndActiveGesturesCleared + ( + m_gestureRecognizer, + m_hold2To3, + m_hold3To4, + [this]() + { + m_gestureRecognizer->holdGestureBegin(3); + }, + [this]() + { + return m_gestureRecognizer->holdGestureCancelled(); + }, + [this]() + { + return m_gestureRecognizer->m_activeHoldGestures; + } + ); +} + +void TestGestureRecognizerHold::holdGestureEnd_noActiveGestures_returnsFalse() +{ + QVERIFY(!m_gestureRecognizer->holdGestureEnd()); +} + +void TestGestureRecognizerHold::holdGestureEnd_activeGesture_gestureEndedSignalEmittedAndActiveHoldGesturesClearedAndReturnsTrue() +{ + TestGestureRecognizerShared::gestureEnd_activeGesture_gestureEndedSignalEmittedAndActiveHoldGesturesClearedAndReturnsTrue + ( + m_gestureRecognizer, + m_hold2, + [this]() + { + m_gestureRecognizer->holdGestureBegin(2); + }, + [this]() + { + return m_gestureRecognizer->holdGestureEnd(); + }, + [this]() + { + return m_gestureRecognizer->m_activeHoldGestures; + } + ); +} + +QTEST_MAIN(TestGestureRecognizerHold) +#include "test_gesturerecognizer_hold.moc" \ No newline at end of file diff --git a/tests/libgesture/gestures/test_gesturerecognizer_hold.h b/tests/libgestures/gestures/test_gesturerecognizer_hold.h similarity index 74% rename from tests/libgesture/gestures/test_gesturerecognizer_hold.h rename to tests/libgestures/gestures/test_gesturerecognizer_hold.h index 7a4da96..d5335f5 100644 --- a/tests/libgesture/gestures/test_gesturerecognizer_hold.h +++ b/tests/libgestures/gestures/test_gesturerecognizer_hold.h @@ -7,10 +7,10 @@ class TestGestureRecognizerHold : public QObject private slots: void init(); - void holdGestureBegin_holdGestureConditionsNotSatisfied_hasNoActiveHoldGestures(); - void holdGestureBegin_twoHoldGesturesWithSatisfiedConditions_hasTwoActiveHoldGestures(); + void holdGestureBegin_gestureConditionsNotSatisfied_hasNoActiveGestures(); + void holdGestureBegin_twoGesturesWithSatisfiedConditions_hasTwoActiveGestures(); - void holdGestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndGestureNotEndedPrematurely(); + void holdGestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndDeltaMatchesAndGestureNotEndedPrematurely(); void holdGestureUpdate_twoActiveGesturesAndOneEndsPrematurely_endedPrematurelySetToTrueAndOnlyOneGestureUpdated(); void holdGestureCancelled_twoActiveGestures_gestureCancelledSignalEmittedForAllGesturesAndActiveHoldGesturesCleared(); @@ -18,7 +18,7 @@ private slots: void holdGestureEnd_noActiveGestures_returnsFalse(); void holdGestureEnd_activeGesture_gestureEndedSignalEmittedAndActiveHoldGesturesClearedAndReturnsTrue(); private: - std::unique_ptr m_gestureRecognizer; + std::shared_ptr m_gestureRecognizer; std::shared_ptr m_hold2; std::shared_ptr m_hold2To3; diff --git a/tests/libgestures/gestures/test_gesturerecognizer_shared.cpp b/tests/libgestures/gestures/test_gesturerecognizer_shared.cpp new file mode 100644 index 0000000..61b993c --- /dev/null +++ b/tests/libgestures/gestures/test_gesturerecognizer_shared.cpp @@ -0,0 +1,141 @@ +#include "test_gesturerecognizer_shared.h" + +#include +#include + +template void TestGestureRecognizerShared::gestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndDeltaMatchesAndGestureNotEndedPrematurely +( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function gestureUpdate, + const qreal &delta +); +template void TestGestureRecognizerShared::gestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndDeltaMatchesAndGestureNotEndedPrematurely +( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function gestureUpdate, + const QPointF &delta +); + +void TestGestureRecognizerShared::gestureBegin_gestureConditionsNotSatisfied_hasNoActiveGestures +( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function>(void)> activeGestures +) +{ + gestureRecognizer->registerGesture(gesture); + + gestureBegin(); + + QVERIFY(activeGestures().empty()); +} + +void TestGestureRecognizerShared::gestureBegin_twoGesturesWithSatisfiedConditions_hasTwoActiveGestures +( + std::shared_ptr gestureRecognizer, + std::vector> gestures, + std::function gestureBegin, + std::function>(void)> activeGestures +) +{ + for (const auto gesture : gestures) + gestureRecognizer->registerGesture(gesture); + + gestureBegin(); + + QCOMPARE(activeGestures().size(), 2); +} + +template +void TestGestureRecognizerShared::gestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndDeltaMatchesAndGestureNotEndedPrematurely +( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function gestureUpdate, + const TDelta &delta +) +{ + QSignalSpy spy(gesture.get(), &Gesture::updated); + gestureRecognizer->registerGesture(gesture); + + gestureBegin(); + auto endedPrematurely = false; + gestureUpdate(delta, endedPrematurely); + + QCOMPARE(spy.count(), 1); + const auto signal = spy.takeFirst(); + QCOMPARE(signal.at(0), delta); + QVERIFY(!endedPrematurely); +} + +void TestGestureRecognizerShared::gestureUpdate_twoActiveGesturesAndOneEndsPrematurely_endedPrematurelySetToTrueAndOnlyOneGestureUpdated +( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture1, + std::shared_ptr gesture2, + std::function gestureBegin, + std::function gestureUpdate +) +{ + QSignalSpy spy1(gesture1.get(), &Gesture::updated); + QSignalSpy spy2(gesture2.get(), &Gesture::updated); + gestureRecognizer->registerGesture(gesture1); + gestureRecognizer->registerGesture(gesture2); + + gestureBegin(); + auto endedPrematurely = false; + gestureUpdate(endedPrematurely); + + QCOMPARE(spy1.count(), 1); + QCOMPARE(spy2.count(), 0); + QVERIFY(endedPrematurely); +} + +void TestGestureRecognizerShared::gestureCancelled_twoActiveGestures_gestureCancelledSignalEmittedForAllGesturesAndActiveGesturesCleared +( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture1, + std::shared_ptr gesture2, + std::function gestureBegin, + std::function gestureCancel, + std::function>(void)> activeGestures +) +{ + QSignalSpy spy1(gesture1.get(), &Gesture::cancelled); + QSignalSpy spy2(gesture2.get(), &Gesture::cancelled); + gestureRecognizer->registerGesture(gesture1); + gestureRecognizer->registerGesture(gesture2); + + gestureBegin(); + gestureCancel(); + + QCOMPARE(spy1.count(), 1); + QCOMPARE(spy2.count(), 1); + QVERIFY(activeGestures().empty()); +}; + +void TestGestureRecognizerShared::gestureEnd_activeGesture_gestureEndedSignalEmittedAndActiveHoldGesturesClearedAndReturnsTrue +( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function gestureEnd, + std::function>(void)> activeGestures +) +{ + QSignalSpy spy(gesture.get(), &Gesture::ended); + gestureRecognizer->registerGesture(gesture); + + gestureBegin(); + const auto returnValue = gestureEnd(); + + QCOMPARE(spy.count(), 1); + QVERIFY(activeGestures().empty()); + QVERIFY(returnValue); +} \ No newline at end of file diff --git a/tests/libgestures/gestures/test_gesturerecognizer_shared.h b/tests/libgestures/gestures/test_gesturerecognizer_shared.h new file mode 100644 index 0000000..0b1c96e --- /dev/null +++ b/tests/libgestures/gestures/test_gesturerecognizer_shared.h @@ -0,0 +1,59 @@ +#pragma once + +#include "gestures/gesturerecognizer.h" + +class TestGestureRecognizerShared +{ +public: + static void gestureBegin_gestureConditionsNotSatisfied_hasNoActiveGestures + ( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function>(void)> activeGestures + ); + static void gestureBegin_twoGesturesWithSatisfiedConditions_hasTwoActiveGestures + ( + std::shared_ptr gestureRecognizer, + std::vector> gestures, + std::function gestureBegin, + std::function>(void)> activeGestures + ); + + template + static void gestureUpdate_activeGesture_gestureUpdateSignalEmittedExactlyOneTimeAndDeltaMatchesAndGestureNotEndedPrematurely + ( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function gestureUpdate, + const TDelta &delta + ); + static void gestureUpdate_twoActiveGesturesAndOneEndsPrematurely_endedPrematurelySetToTrueAndOnlyOneGestureUpdated + ( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture1, + std::shared_ptr gesture2, + std::function gestureBegin, + std::function gestureUpdate + ); + + static void gestureCancelled_twoActiveGestures_gestureCancelledSignalEmittedForAllGesturesAndActiveGesturesCleared + ( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture1, + std::shared_ptr gesture2, + std::function gestureBegin, + std::function gestureCancel, + std::function>(void)> activeGestures + ); + + static void gestureEnd_activeGesture_gestureEndedSignalEmittedAndActiveHoldGesturesClearedAndReturnsTrue + ( + std::shared_ptr gestureRecognizer, + std::shared_ptr gesture, + std::function gestureBegin, + std::function gestureEnd, + std::function>(void)> activeGestures + ); +}; \ No newline at end of file