From 91559a36462d4653a1713831f8b8eb89aba24dce Mon Sep 17 00:00:00 2001 From: Alex Tanskanen Date: Thu, 16 Apr 2020 15:38:49 +0200 Subject: [PATCH] Add unit tests for EmulateMB --- tests/unit/CMakeLists.txt | 4 + tests/unit/emulatemb.cxx | 429 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 433 insertions(+) create mode 100644 tests/unit/emulatemb.cxx diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index acc3adcd..e568660a 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -1,4 +1,5 @@ include_directories(${CMAKE_SOURCE_DIR}/common) +include_directories(${CMAKE_SOURCE_DIR}/vncviewer) add_executable(conv conv.cxx) target_link_libraries(conv rfb) @@ -11,3 +12,6 @@ target_link_libraries(hostport rfb) add_executable(pixelformat pixelformat.cxx) target_link_libraries(pixelformat rfb) + +add_executable(emulatemb emulatemb.cxx ../../vncviewer/EmulateMB.cxx) +target_link_libraries(emulatemb rfb ${GETTEXT_LIBRARIES}) \ No newline at end of file diff --git a/tests/unit/emulatemb.cxx b/tests/unit/emulatemb.cxx new file mode 100644 index 00000000..b04b647b --- /dev/null +++ b/tests/unit/emulatemb.cxx @@ -0,0 +1,429 @@ +/* Copyright 2020 Alex Tanskanen for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include + +#include +#include +#include "EmulateMB.h" + +// The button masks for the mouse buttons +static const int empty = 0x00; +static const int left = 0x01; +static const int middle = 0x02; +static const int middleAndLeft = 0x03; +static const int right = 0x04; +static const int both = 0x05; +static const int middleAndRight = 0x06; + +rfb::BoolParameter emulateMiddleButton("dummy_name", "dummy_desc", true); + +class TestClass : public EmulateMB +{ +public: + virtual void sendPointerEvent(const rfb::Point& pos, int buttonMask); + + struct PointerEventParams {rfb::Point pos; int mask; }; + + std::vector results; +}; + +void TestClass::sendPointerEvent(const rfb::Point& pos, int buttonMask) +{ + PointerEventParams params; + params.pos = pos; + params.mask = buttonMask; + results.push_back(params); +} + +#define ASSERT_EQ(expr, val) if ((expr) != (val)) { \ + printf("FAILED on line %d (%s equals %d, expected %d)\n", __LINE__, #expr, (int)(expr), (int)(val)); \ + return; \ +} + +void testDisabledOption() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(false); + test.filterPointerEvent(rfb::Point(0, 10), left); + + ASSERT_EQ(test.results.size(), 1); + + ASSERT_EQ(test.results[0].pos.x, 0); + ASSERT_EQ(test.results[0].pos.y, 10); + ASSERT_EQ(test.results[0].mask, left); + + printf("OK\n"); +} + +void testLeftClick() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(0, 0), left); + test.filterPointerEvent(rfb::Point(0, 0), empty); + + ASSERT_EQ(test.results.size(), 3); + + ASSERT_EQ(test.results[0].pos.x, 0); + ASSERT_EQ(test.results[0].pos.y, 0); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 0); + ASSERT_EQ(test.results[1].pos.y, 0); + ASSERT_EQ(test.results[1].mask, left); + + ASSERT_EQ(test.results[2].pos.x, 0); + ASSERT_EQ(test.results[2].pos.y, 0); + ASSERT_EQ(test.results[2].mask, empty); + + printf("OK\n"); +} + +void testNormalLeftPress() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(10, 20), left); + usleep(100000); // 0.1s + rfb::Timer::checkTimeouts(); + + ASSERT_EQ(test.results.size(), 2); + + ASSERT_EQ(test.results[0].pos.x, 10); + ASSERT_EQ(test.results[0].pos.y, 20); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 10); + ASSERT_EQ(test.results[1].pos.y, 20); + ASSERT_EQ(test.results[1].mask, left); + + printf("OK\n"); +} + +void testNormalMiddlePress() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(0, 0), middle); + + ASSERT_EQ(test.results.size(), 1); + + ASSERT_EQ(test.results[0].pos.x, 0); + ASSERT_EQ(test.results[0].pos.y, 0); + ASSERT_EQ(test.results[0].mask, middle); + + printf("OK\n"); +} + +void testNormalRightPress() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(0, 0), right); + usleep(100000); // 0.1s + rfb::Timer::checkTimeouts(); + + ASSERT_EQ(test.results.size(), 2); + + ASSERT_EQ(test.results[0].pos.x, 0); + ASSERT_EQ(test.results[0].pos.y, 0); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 0); + ASSERT_EQ(test.results[1].pos.y, 0); + ASSERT_EQ(test.results[1].mask, right); + + printf("OK\n"); +} + +void testEmulateMiddleMouseButton() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(20, 30), right); + test.filterPointerEvent(rfb::Point(20, 30), both); + + ASSERT_EQ(test.results.size(), 2); + + ASSERT_EQ(test.results[0].pos.x, 20); + ASSERT_EQ(test.results[0].pos.y, 30); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 20); + ASSERT_EQ(test.results[1].pos.y, 30); + ASSERT_EQ(test.results[1].mask, middle); + + printf("OK\n"); +} + +void testLeftReleaseAfterEmulate() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(20, 30), left); + test.filterPointerEvent(rfb::Point(20, 30), both); + test.filterPointerEvent(rfb::Point(20, 30), right); // left released + + ASSERT_EQ(test.results.size(), 3); + + ASSERT_EQ(test.results[0].pos.x, 20); + ASSERT_EQ(test.results[0].pos.y, 30); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 20); + ASSERT_EQ(test.results[1].pos.y, 30); + ASSERT_EQ(test.results[1].mask, middle); + + ASSERT_EQ(test.results[2].pos.x, 20); + ASSERT_EQ(test.results[2].pos.y, 30); + ASSERT_EQ(test.results[2].mask, middle); + + printf("OK\n"); +} + +void testRightReleaseAfterEmulate() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(20, 30), right); + test.filterPointerEvent(rfb::Point(20, 30), both); + test.filterPointerEvent(rfb::Point(20, 30), left); // right released + + ASSERT_EQ(test.results.size(), 3); + + ASSERT_EQ(test.results[0].pos.x, 20); + ASSERT_EQ(test.results[0].pos.y, 30); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 20); + ASSERT_EQ(test.results[1].pos.y, 30); + ASSERT_EQ(test.results[1].mask, middle); + + ASSERT_EQ(test.results[2].pos.x, 20); + ASSERT_EQ(test.results[2].pos.y, 30); + ASSERT_EQ(test.results[2].mask, middle); + + printf("OK\n"); +} + +void testLeftRepressAfterEmulate() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(20, 30), left); + test.filterPointerEvent(rfb::Point(20, 30), both); + test.filterPointerEvent(rfb::Point(20, 30), right); // left released + test.filterPointerEvent(rfb::Point(20, 30), both); + + ASSERT_EQ(test.results.size(), 4); + + ASSERT_EQ(test.results[0].pos.x, 20); + ASSERT_EQ(test.results[0].pos.y, 30); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 20); + ASSERT_EQ(test.results[1].pos.y, 30); + ASSERT_EQ(test.results[1].mask, middle); + + ASSERT_EQ(test.results[2].pos.x, 20); + ASSERT_EQ(test.results[2].pos.y, 30); + ASSERT_EQ(test.results[2].mask, middle); + + ASSERT_EQ(test.results[3].pos.x, 20); + ASSERT_EQ(test.results[3].pos.y, 30); + ASSERT_EQ(test.results[3].mask, middleAndLeft); + + printf("OK\n"); +} + +void testRightRepressAfterEmulate() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(20, 30), right); + test.filterPointerEvent(rfb::Point(20, 30), both); + test.filterPointerEvent(rfb::Point(20, 30), left); // right released + test.filterPointerEvent(rfb::Point(20, 30), both); + + ASSERT_EQ(test.results.size(), 4); + + ASSERT_EQ(test.results[0].pos.x, 20); + ASSERT_EQ(test.results[0].pos.y, 30); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 20); + ASSERT_EQ(test.results[1].pos.y, 30); + ASSERT_EQ(test.results[1].mask, middle); + + ASSERT_EQ(test.results[2].pos.x, 20); + ASSERT_EQ(test.results[2].pos.y, 30); + ASSERT_EQ(test.results[2].mask, middle); + + ASSERT_EQ(test.results[3].pos.x, 20); + ASSERT_EQ(test.results[3].pos.y, 30); + ASSERT_EQ(test.results[3].mask, middleAndRight); + + printf("OK\n"); +} + +void testBothPressAfterLeftTimeout() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(10, 20), left); + usleep(100000); // 0.1s + rfb::Timer::checkTimeouts(); + test.filterPointerEvent(rfb::Point(10, 20), both); + + ASSERT_EQ(test.results.size(), 3); + + ASSERT_EQ(test.results[0].pos.x, 10); + ASSERT_EQ(test.results[0].pos.y, 20); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 10); + ASSERT_EQ(test.results[1].pos.y, 20); + ASSERT_EQ(test.results[1].mask, left); + + ASSERT_EQ(test.results[2].pos.x, 10); + ASSERT_EQ(test.results[2].pos.y, 20); + ASSERT_EQ(test.results[2].mask, both); + + printf("OK\n"); +} + +void testBothPressAfterRightTimeout() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(10, 20), right); + usleep(100000); // 0.1s + rfb::Timer::checkTimeouts(); + test.filterPointerEvent(rfb::Point(10, 20), both); + + ASSERT_EQ(test.results.size(), 3); + + ASSERT_EQ(test.results[0].pos.x, 10); + ASSERT_EQ(test.results[0].pos.y, 20); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 10); + ASSERT_EQ(test.results[1].pos.y, 20); + ASSERT_EQ(test.results[1].mask, right); + + ASSERT_EQ(test.results[2].pos.x, 10); + ASSERT_EQ(test.results[2].pos.y, 20); + ASSERT_EQ(test.results[2].mask, both); + + printf("OK\n"); +} + +void testTimeoutDuringDrag() +{ + TestClass test; + + printf("%s: ", __func__); + + emulateMiddleButton.setParam(true); + test.filterPointerEvent(rfb::Point(0, 0), left); + usleep(100000); //0.1s + rfb::Timer::checkTimeouts(); + test.filterPointerEvent(rfb::Point(10, 10), left); + + ASSERT_EQ(test.results.size(), 3); + + ASSERT_EQ(test.results[0].pos.x, 0); + ASSERT_EQ(test.results[0].pos.y, 0); + ASSERT_EQ(test.results[0].mask, empty); + + ASSERT_EQ(test.results[1].pos.x, 0); + ASSERT_EQ(test.results[1].pos.y, 0); + ASSERT_EQ(test.results[1].mask, left); + + ASSERT_EQ(test.results[2].pos.x, 10); + ASSERT_EQ(test.results[2].pos.y, 10); + ASSERT_EQ(test.results[2].mask, left); + + printf("OK\n"); +} + +int main(int argc, char** argv) +{ + testDisabledOption(); + + testLeftClick(); + + testNormalLeftPress(); + testNormalMiddlePress(); + testNormalRightPress(); + + testEmulateMiddleMouseButton(); + + testLeftReleaseAfterEmulate(); + testRightReleaseAfterEmulate(); + + testLeftRepressAfterEmulate(); + testRightRepressAfterEmulate(); + + testBothPressAfterLeftTimeout(); + testBothPressAfterRightTimeout(); + + testTimeoutDuringDrag(); + + + return 0; +} -- 2.39.5