diff options
Diffstat (limited to 'tests/test-gestures')
20 files changed, 1131 insertions, 0 deletions
diff --git a/tests/test-gestures/CMakeLists.txt b/tests/test-gestures/CMakeLists.txt new file mode 100644 index 000000000..8d85541f7 --- /dev/null +++ b/tests/test-gestures/CMakeLists.txt @@ -0,0 +1,71 @@ +if (GTEST_SRC_DIR) + set(UNITY_SRC ${CMAKE_SOURCE_DIR}/plugins/unityshell/src) + + add_custom_command(OUTPUT UnityGestureBroker.cpp + UnityGestureBroker.h + UBusMessages.h + WindowGestureTarget.h + WindowGestureTarget.cpp + + COMMAND cp ${UNITY_SRC}/UnityGestureBroker.cpp + ${UNITY_SRC}/UnityGestureBroker.h + ${CMAKE_SOURCE_DIR}/unity-shared//UBusMessages.h + ${UNITY_SRC}/WindowGestureTarget.h + ${UNITY_SRC}/WindowGestureTarget.cpp + ${CMAKE_CURRENT_BINARY_DIR} + + COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_broker + ${UNITY_SRC}/UnityGestureBroker.cpp > ${CMAKE_CURRENT_BINARY_DIR}/UnityGestureBroker.cpp + + COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_broker + ${UNITY_SRC}/UnityGestureBroker.h > ${CMAKE_CURRENT_BINARY_DIR}/UnityGestureBroker.h + + COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_gesture + ${UNITY_SRC}/WindowGestureTarget.h > ${CMAKE_CURRENT_BINARY_DIR}/WindowGestureTarget.h + + COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_gesture + ${UNITY_SRC}/WindowGestureTarget.cpp > ${CMAKE_CURRENT_BINARY_DIR}/WindowGestureTarget.cpp + + DEPENDS ${UNITY_SRC}/UnityGestureBroker.cpp + ${UNITY_SRC}/UnityGestureBroker.h + ${CMAKE_SOURCE_DIR}/unity-shared/UBusMessages.h + ${UNITY_SRC}/WindowGestureTarget.h + ${UNITY_SRC}/WindowGestureTarget.cpp + sed_script_broker + sed_script_gesture + + COMMENT "Copying and modifying sources under test.") + + # Clean-up includes and definitions made in ../CmakeLists.txt + remove_definitions(${CFLAGS}) + set_directory_properties(PROPERTY INCLUDE_DIRECTORIES "") + # And make our own + pkg_check_modules (TEST_GESTURES_DEPS REQUIRED QUIET "${UNITY_PLUGIN_DEPS}") + set(TEST_GESTURES_CFLAGS + "-g" + "-I${CMAKE_CURRENT_SOURCE_DIR}" + "-I${CMAKE_CURRENT_BINARY_DIR}" + ${TEST_GESTURES_DEPS_CFLAGS} + ) + add_definitions(${TEST_GESTURES_CFLAGS}) + + pkg_check_modules (COMPIZ REQUIRED QUIET compiz) + link_directories (${COMPIZ_LIBDIR}) + + add_executable(test-gestures + test_gestures_main.cpp + test_gesture_broker.cpp + test_window_gesture_target.cpp + X11_mock.cpp + UnityGestureBroker.cpp + WindowGestureTarget.cpp + PluginAdapterMock.cpp + ubus-server-mock.cpp + UnityGestureTargetMock.h + ) + target_link_libraries(test-gestures gtest ${TEST_GESTURES_DEPS_LIBRARIES} -lcompiz_core) + add_test(UnityGTestGestures test-gestures) + add_dependencies(test-gestures gtest unity-core-${UNITY_API_VERSION}) + + add_custom_target (check-gestures COMMAND ./test-gestures DEPENDS test-gestures) +endif (GTEST_SRC_DIR) diff --git a/tests/test-gestures/FakeGestureEvent.h b/tests/test-gestures/FakeGestureEvent.h new file mode 100644 index 000000000..9cc13aa76 --- /dev/null +++ b/tests/test-gestures/FakeGestureEvent.h @@ -0,0 +1,63 @@ +#ifndef FAKE_GESTURE_EVENT_H +#define FAKE_GESTURE_EVENT_H + +#include <NuxGraphics/GestureEvent.h> +#include <map> + +namespace nux { +class FakeGestureEvent +{ + public: + nux::EventType type; + + int gesture_id; + int gesture_classes; + bool is_direct_touch; + int timestamp; + nux::Point2D<float> focus; + nux::Point2D<float> delta; + float angle; + float angle_delta; + float angular_velocity; + int tap_duration; + nux::Point2D<float> velocity; + float radius; + float radius_delta; + float radial_velocity; + std::vector<nux::TouchPoint> touches; + bool is_construction_finished; + + nux::GestureEvent &ToGestureEvent() + { + event_.type = type; + + event_.gesture_id_ = gesture_id; + event_.gesture_classes_ = gesture_classes; + event_.is_direct_touch_ = is_direct_touch; + event_.timestamp_ = timestamp; + event_.focus_ = focus; + event_.delta_ = delta; + event_.angle_ = angle; + event_.angle_delta_ = angle_delta; + event_.angular_velocity_ = angular_velocity; + event_.tap_duration_ = tap_duration; + event_.velocity_ = velocity; + event_.radius_ = radius; + event_.radius_delta_ = radius_delta; + event_.radial_velocity_ = radial_velocity; + event_.touches_ = touches; + event_.is_construction_finished_ = is_construction_finished; + + return event_; + } + + private: + nux::GestureEvent event_; +}; +} // namespace nux + +// maps a gesture id to its acceptance +extern std::map<int, int> g_gesture_event_accept_count; +extern std::map<int, int> g_gesture_event_reject_count; + +#endif // FAKE_GESTURE_EVENT_H diff --git a/tests/test-gestures/NuxMock.h b/tests/test-gestures/NuxMock.h new file mode 100644 index 000000000..28dfe7bf8 --- /dev/null +++ b/tests/test-gestures/NuxMock.h @@ -0,0 +1,19 @@ +#ifndef NUX_MOCK_H +#define NUX_MOCK_H + +#include <Nux/Nux.h> + +namespace nux +{ + +class InputAreaMock : public Object +{ + public: + void GestureEvent(const GestureEvent &event) + { + } +}; + +} // namespace nux + +#endif // NUX_MOCK_H diff --git a/tests/test-gestures/PluginAdapterMock.cpp b/tests/test-gestures/PluginAdapterMock.cpp new file mode 100644 index 000000000..a71af2421 --- /dev/null +++ b/tests/test-gestures/PluginAdapterMock.cpp @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#include "PluginAdapterMock.h" + +PluginAdapterMock *PluginAdapterMock::_default = 0; + +PluginAdapterMock *PluginAdapterMock::Default() { + if (!_default) { + _default = new PluginAdapterMock; + } + return _default; +} + +void PluginAdapterMock::ShowGrabHandles(CompWindowMock* window, bool use_timer) { +} diff --git a/tests/test-gestures/PluginAdapterMock.h b/tests/test-gestures/PluginAdapterMock.h new file mode 100644 index 000000000..2b111a68b --- /dev/null +++ b/tests/test-gestures/PluginAdapterMock.h @@ -0,0 +1,37 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#ifndef PLUGINADAPTER_MOCK_H +#define PLUGINADAPTER_MOCK_H + +#include <compiz_mock/core/core.h> + +class PluginAdapterMock { +public: + static PluginAdapterMock *Default(); + + void ShowGrabHandles(CompWindowMock* window, bool use_timer); + +private: + PluginAdapterMock() {} + static PluginAdapterMock* _default; +}; + +#endif diff --git a/tests/test-gestures/UnityGestureTargetMock.h b/tests/test-gestures/UnityGestureTargetMock.h new file mode 100644 index 000000000..9fd621fb8 --- /dev/null +++ b/tests/test-gestures/UnityGestureTargetMock.h @@ -0,0 +1,15 @@ +#ifndef UNITY_GESTURE_TARGET_MOCK_H +#define UNITY_GESTURE_TARGET_MOCK_H + +#include <Nux/Gesture.h> + +class UnityGestureTargetMock : public nux::GestureTarget +{ + public: + virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event) + { + return nux::GestureDeliveryRequest::NONE; + } +}; + +#endif // UNITY_GESTURE_TARGET_MOCK_H diff --git a/tests/test-gestures/WindowGestureTargetMock.h b/tests/test-gestures/WindowGestureTargetMock.h new file mode 100644 index 000000000..e43bad80c --- /dev/null +++ b/tests/test-gestures/WindowGestureTargetMock.h @@ -0,0 +1,55 @@ +#ifndef WINDOW_GESTURE_TARGET_MOCK_H +#define WINDOW_GESTURE_TARGET_MOCK_H + +#include <Nux/Gesture.h> + +#include <set> + +class CompWindowMock; +class WindowGestureTargetMock; + +extern std::set<WindowGestureTargetMock*> g_window_target_mocks; + +class WindowGestureTargetMock : public nux::GestureTarget +{ + public: + WindowGestureTargetMock(CompWindowMock *window) : window(window) + { + g_window_target_mocks.insert(this); + } + + virtual ~WindowGestureTargetMock() + { + g_window_target_mocks.erase(this); + } + + virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event) + { + events_received.push_back(event); + return nux::GestureDeliveryRequest::NONE; + } + + CompWindowMock *window; + std::list<nux::GestureEvent> events_received; + + static Cursor fleur_cursor; + private: + virtual bool Equals(const nux::GestureTarget& other) const + { + const WindowGestureTargetMock *window_target = dynamic_cast<const WindowGestureTargetMock *>(&other); + + if (window_target) + { + if (window && window_target->window) + return window->id() == window_target->window->id(); + else + return window == window_target->window; + } + else + { + return false; + } + } +}; + +#endif // WINDOW_GESTURE_TARGET_MOCK_H diff --git a/tests/test-gestures/X11_mock.cpp b/tests/test-gestures/X11_mock.cpp new file mode 100644 index 000000000..5560aa9ac --- /dev/null +++ b/tests/test-gestures/X11_mock.cpp @@ -0,0 +1,40 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#include <X11/Xlib.h> + +Cursor XCreateFontCursorMock(Display * /*display*/, unsigned int /*shape*/) { + return 1; +} + +int XFreeCursorMock(Display * /*display*/, Cursor /*cursor*/) { + return 1; +} + +int XSyncMock(Display *display, Bool discard) { + return 1; +} + +int XWarpPointerMock(Display *display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y) { + return 1; +} diff --git a/tests/test-gestures/X11_mock.h b/tests/test-gestures/X11_mock.h new file mode 100644 index 000000000..f98e028be --- /dev/null +++ b/tests/test-gestures/X11_mock.h @@ -0,0 +1,37 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#ifndef X11_MOCK_H +#define X11_MOCK_H + +#include <X11/Xlib.h> + +Cursor XCreateFontCursorMock(Display *display, unsigned int shape); + +int XFreeCursorMock(Display *display, Cursor cursor); + +int XSyncMock(Display *display, Bool discard); + +int XWarpPointerMock(Display *display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y); + +#endif // X11_MOCK_H diff --git a/tests/test-gestures/compiz_mock/core/core.h b/tests/test-gestures/compiz_mock/core/core.h new file mode 100644 index 000000000..f1c358fbf --- /dev/null +++ b/tests/test-gestures/compiz_mock/core/core.h @@ -0,0 +1,29 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#ifndef COMPIZ_CORE_MOCK_H +#define COMPIZ_CORE_MOCK_H + +#include <X11_mock.h> + +#include <compiz_mock/core/window.h> +#include <compiz_mock/core/screen.h> + +#endif diff --git a/tests/test-gestures/compiz_mock/core/screen.h b/tests/test-gestures/compiz_mock/core/screen.h new file mode 100644 index 000000000..225d41c65 --- /dev/null +++ b/tests/test-gestures/compiz_mock/core/screen.h @@ -0,0 +1,77 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#ifndef COMPIZ_SCREEN_MOCK_H +#define COMPIZ_SCREEN_MOCK_H + +#include <X11/Xlib.h> +#include <vector> + +// The real CompScreen +#include <core/screen.h> + +typedef std::vector<CompWindowMock*> CompWindowMockVector; + +class CompScreenMock { +public: + CompScreenMock() : grab_count_(0), next_grab_handle_(1) {} + + typedef int GrabHandle; + + int width() const {return width_;} + int height() const {return height_;} + + Display *dpy() {return dpy_;} + + const CompWindowMockVector & clientList(bool stackingOrder = true) { + if (stackingOrder) + return client_list_stacking_; + else + return client_list_; + } + + Window root() {return root_;} + + GrabHandle pushGrab(Cursor cursor, const char *name) { + grab_count_++; + return next_grab_handle_++; + } + void removeGrab(GrabHandle handle, CompPoint *restorePointer) { + grab_count_--; + } + + Cursor invisibleCursor() {return 1;} + + int width_; + int height_; + Display *dpy_; + CompWindowMockVector client_list_; + CompWindowMockVector client_list_stacking_; + Window root_; + int grab_count_; + int next_grab_handle_; +}; + +extern CompScreenMock *screen_mock; +extern int pointerX_mock; +extern int pointerY_mock; + +#endif + diff --git a/tests/test-gestures/compiz_mock/core/window.h b/tests/test-gestures/compiz_mock/core/window.h new file mode 100644 index 000000000..f5e930107 --- /dev/null +++ b/tests/test-gestures/compiz_mock/core/window.h @@ -0,0 +1,79 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#ifndef COMPIZ_WINDOW_MOCK_H +#define COMPIZ_WINDOW_MOCK_H + +/* The real CompWindow */ +#include <core/window.h> + +class CompWindowMock +{ +public: + CompWindowMock() : moved_(false), maximize_count_(0), maximize_state_(0), + minimized_(false) {} + + int x() const {return geometry_.x();} + int y() const {return geometry_.y();} + int width() const {return geometry_.width() + (geometry_.border()*2);} + int height() const {return geometry_.height() + (geometry_.border()*2);} + int id() { return id_; } + + void move(int dx, int dy, bool immediate = true) + { + moved_ = true; + movement_x_ = dx; + movement_y_ = dy; + } + + unsigned int actions () {return actions_;} + + bool minimized() { return minimized_; } + + void maximize(int state) {++maximize_count_; maximize_state_ = state;} + + /* OBS: I wonder why it returns a reference */ + unsigned int &state() {return state_;} + + void grabNotify(int x, int y, unsigned int state, unsigned int mask) {} + void ungrabNotify() {} + + void syncPosition() {} + + compiz::window::Geometry &serverGeometry() {return server_geometry_;} + + unsigned int actions_; + unsigned int state_; + compiz::window::Geometry server_geometry_; + compiz::window::Geometry geometry_; + + bool moved_; + int movement_x_; + int movement_y_; + + int maximize_count_; + int maximize_state_; + + int id_; + + bool minimized_; +}; + +#endif diff --git a/tests/test-gestures/sed_script_broker b/tests/test-gestures/sed_script_broker new file mode 100644 index 000000000..3f256b0f6 --- /dev/null +++ b/tests/test-gestures/sed_script_broker @@ -0,0 +1,11 @@ +s|<core/core.h>|<compiz_mock/core/core.h>| +s|\<CompScreen\>|CompScreenMock|g +s|\<CompWindow\>|CompWindowMock|g +s|\<CompWindowVector\>|CompWindowMockVector|g +s|\<screen\>|screen_mock|g +s|\<pointerX\>|pointerX_mock|g +s|\<pointerY\>|pointerY_mock|g +s|\<XFreeCursor\>|XFreeCursorMock|g +s|\<XCreateFontCursor\>|XCreateFontCursorMock|g +s|\<WindowGestureTarget\>|WindowGestureTargetMock|g +s|\<UnityGestureTarget\>|UnityGestureTargetMock|g diff --git a/tests/test-gestures/sed_script_gesture b/tests/test-gestures/sed_script_gesture new file mode 100644 index 000000000..c2e3ffa48 --- /dev/null +++ b/tests/test-gestures/sed_script_gesture @@ -0,0 +1,18 @@ +s|<core/core.h>|<compiz_mock/core/core.h>| +s|\<CompScreen\>|CompScreenMock|g +s|\<CompWindow\>|CompWindowMock|g +s|\<CompWindowVector\>|CompWindowMockVector|g +s|\<screen\>|screen_mock|g +s|\<pointerX\>|pointerX_mock|g +s|\<pointerY\>|pointerY_mock|g +s|\<XSync\>|XSyncMock|g +s|\<XWarpPointer\>|XWarpPointerMock|g +s|\<XFreeCursor\>|XFreeCursorMock|g +s|\<XCreateFontCursor\>|XCreateFontCursorMock|g +s|\<ubus-server.h\>|ubus-server-mock.h|g +s|\<unityshell.h\>|unityshell_mock.h|g +s|\<PluginAdapter\>|PluginAdapterMock|g +s|\<UnityWindow\>|UnityWindowMock|g +s|\<UnityScreen\>|UnityScreenMock|g +s|\<InputArea\>|InputAreaMock|g +s|\<Nux/Nux\.h\>|NuxMock.h|g diff --git a/tests/test-gestures/test_gesture_broker.cpp b/tests/test-gestures/test_gesture_broker.cpp new file mode 100644 index 000000000..b7f30ec04 --- /dev/null +++ b/tests/test-gestures/test_gesture_broker.cpp @@ -0,0 +1,137 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#include <gtest/gtest.h> +#include <compiz_mock/core/core.h> +#include "UnityGestureBroker.h" +#include "FakeGestureEvent.h" +#include "unityshell_mock.h" +#include "WindowGestureTargetMock.h" + +class GestureBrokerTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + screen_mock->width_ = 1280; + screen_mock->height_ = 1024; + + GenerateWindows(); + } + + private: + void GenerateWindows() + { + /* remove windows from previous test */ + for (auto window : screen_mock->client_list_stacking_) { + delete window; + } + screen_mock->client_list_stacking_.clear(); + + /* and generate new ones */ + CompWindowMock *window; + + /* the root window */ + window = new unity::UnityWindowMock; + window->id_ = 0; + /* x, y, width, height, border */ + window->geometry_.set(0, 0, screen_mock->width(), screen_mock->height(), 0); + window->server_geometry_ = window->geometry_; + window->actions_ = 0; + window->state_ = 0; + screen_mock->client_list_stacking_.push_back(window); + + /* middle window */ + window = new unity::UnityWindowMock; + window->id_ = 1; + window->geometry_.set(10, 10, 400, 400, 0); + window->server_geometry_ = window->geometry_; + window->actions_ = CompWindowActionMoveMask; + window->state_ = 0; + screen_mock->client_list_stacking_.push_back(window); + + /* top-level window */ + window = new unity::UnityWindowMock; + window->id_ = 2; + window->geometry_.set(500, 500, 410, 410, 0); + window->server_geometry_ = window->geometry_; + window->actions_ = CompWindowActionMoveMask; + window->state_ = 0; + screen_mock->client_list_stacking_.push_back(window); + + screen_mock->client_list_ = screen_mock->client_list_stacking_; + std::reverse(screen_mock->client_list_.begin(), + screen_mock->client_list_.end()); + } +}; + +/* + Tests that events from a three-fingers' Touch gesture goes to the + correct window. I.e., to the window that lies where the gesture starts. + */ +TEST_F(GestureBrokerTest, ThreeFingersTouchHitsCorrectWindow) +{ + UnityGestureBroker gesture_broker; + CompWindowMock *middle_window = screen_mock->client_list_stacking_[1]; + nux::FakeGestureEvent fake_event; + + // init counters + g_gesture_event_accept_count[0] = 0; + g_gesture_event_reject_count[0] = 0; + + /* prepare and send the fake event */ + fake_event.type = nux::EVENT_GESTURE_BEGIN; + fake_event.gesture_id = 0; + fake_event.is_direct_touch = false; + fake_event.focus.x = 100.0f; // hits the middle window + fake_event.focus.y = 100.0f; + // in touch device's coordinate system (because it's not a direct device). + // Thus not used by WindowCompositor + fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); + fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); + fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f)); + fake_event.is_construction_finished = false; + gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent()); + + // Gesture shouldn't be accepted as constructions hasn't finished + ASSERT_EQ(0, g_gesture_event_accept_count[0]); + ASSERT_EQ(0, g_gesture_event_reject_count[0]); + ASSERT_EQ(1, g_window_target_mocks.size()); + WindowGestureTargetMock *target_mock = *g_window_target_mocks.begin(); + ASSERT_TRUE(target_mock->window == middle_window); + // No events yet as the broker didn't accept the gesture yet + ASSERT_EQ(0, target_mock->events_received.size()); + + fake_event.type = nux::EVENT_GESTURE_UPDATE; + fake_event.delta.x += 10.0f; + fake_event.delta.y += 20.0f; + fake_event.focus.x += fake_event.delta.x; + fake_event.focus.y += fake_event.delta.y; + fake_event.is_construction_finished = true; + gesture_broker.ProcessGestureUpdate(fake_event.ToGestureEvent()); + + // Gesture should have been accepted now since the construction has finished. + ASSERT_EQ(1, g_gesture_event_accept_count[0]); + ASSERT_EQ(0, g_gesture_event_reject_count[0]); + // Check that this gesture target is still valid + ASSERT_EQ(1, g_window_target_mocks.count(target_mock)); + // Gesture events should have been sent to the target by now + ASSERT_EQ(2, target_mock->events_received.size()); +} diff --git a/tests/test-gestures/test_gestures_main.cpp b/tests/test-gestures/test_gestures_main.cpp new file mode 100644 index 000000000..d362b5746 --- /dev/null +++ b/tests/test-gestures/test_gestures_main.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#include <gtest/gtest.h> +#include <compiz_mock/core/core.h> +#include <NuxGraphics/GestureEvent.h> +#include "WindowGestureTargetMock.h" +#include "unityshell_mock.h" + +unity::UnityScreenMock concrete_screen_mock; +CompScreenMock *screen_mock = &concrete_screen_mock; +int pointerX_mock = 0; +int pointerY_mock = 0; + +std::map<int, int> g_gesture_event_accept_count; +void nux::GestureEvent::Accept() +{ + g_gesture_event_accept_count[gesture_id_] = + g_gesture_event_accept_count[gesture_id_] + 1; +} + +std::map<int, int> g_gesture_event_reject_count; +void nux::GestureEvent::Reject() +{ + g_gesture_event_reject_count[gesture_id_] = + g_gesture_event_reject_count[gesture_id_] + 1; +} + +Cursor WindowGestureTargetMock::fleur_cursor = 0; +std::set<WindowGestureTargetMock*> g_window_target_mocks; + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + int ret = RUN_ALL_TESTS(); + + return ret; +} diff --git a/tests/test-gestures/test_window_gesture_target.cpp b/tests/test-gestures/test_window_gesture_target.cpp new file mode 100644 index 000000000..4491a9ca3 --- /dev/null +++ b/tests/test-gestures/test_window_gesture_target.cpp @@ -0,0 +1,235 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#include <gtest/gtest.h> +#include <compiz_mock/core/core.h> +#include "FakeGestureEvent.h" +#include "unityshell_mock.h" +#include <WindowGestureTarget.h> + +class WindowGestureTargetTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + screen_mock->width_ = 1280; + screen_mock->height_ = 1024; + } + + void PerformPinch(WindowGestureTarget &gesture_target, float peak_radius) + { + nux::FakeGestureEvent fake_event; + + fake_event.type = nux::EVENT_GESTURE_BEGIN; + fake_event.gesture_id = 0; + fake_event.gesture_classes = nux::PINCH_GESTURE; + fake_event.is_direct_touch = false; + // in touch device's coordinate system (because it's not a direct device). + // Thus not used by WindowCompositor + fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); + fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); + fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f)); + fake_event.focus.x = gesture_target.window()->geometry_.centerX(); + fake_event.focus.y = gesture_target.window()->geometry_.centerY();; + fake_event.radius = 1.0; + fake_event.is_construction_finished = false; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + fake_event.type = nux::EVENT_GESTURE_UPDATE; + fake_event.radius = peak_radius; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + fake_event.type = nux::EVENT_GESTURE_END; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + } +}; + +TEST_F(WindowGestureTargetTest, ThreeFingersDragMovesWindow) +{ + unity::UnityWindowMock window; + window.geometry_.set(10, 10, 400, 400, 0); + window.server_geometry_ = window.geometry_; + window.actions_ = CompWindowActionMoveMask; + window.state_ = 0; + window.id_ = 1; + + WindowGestureTarget gesture_target(&window); + + nux::FakeGestureEvent fake_event; + + /* prepare and send the fake event */ + fake_event.type = nux::EVENT_GESTURE_BEGIN; + fake_event.gesture_id = 0; + fake_event.gesture_classes = nux::TOUCH_GESTURE; + fake_event.is_direct_touch = false; + fake_event.focus.x = 100.0f; // hits the middle window + fake_event.focus.y = 100.0f; + // in touch device's coordinate system (because it's not a direct device). + // Thus not used by WindowCompositor + fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); + fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); + fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f)); + fake_event.is_construction_finished = false; + fake_event.radius = 1.0f; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + ASSERT_FALSE(window.moved_); + + fake_event.type = nux::EVENT_GESTURE_UPDATE; + fake_event.gesture_classes = nux::TOUCH_GESTURE | nux::DRAG_GESTURE; + fake_event.delta.x = 10.0f; + fake_event.delta.y = 20.0f; + fake_event.focus.x += fake_event.delta.x; + fake_event.focus.y += fake_event.delta.y; + fake_event.is_construction_finished = true; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + ASSERT_TRUE(window.moved_); + ASSERT_EQ(fake_event.delta.x, window.movement_x_); + ASSERT_EQ(fake_event.delta.y, window.movement_y_); +} + +TEST_F(WindowGestureTargetTest, ThreeFingersDragDoesntMoveStaticWindow) +{ + + unity::UnityWindowMock window; + window.geometry_.set(10, 10, 400, 400, 0); + window.server_geometry_ = window.geometry_; + window.actions_ = 0; /* can't be moved */ + window.state_ = 0; + window.id_ = 1; + + WindowGestureTarget gesture_target(&window); + + nux::FakeGestureEvent fake_event; + + /* prepare and send the fake event */ + fake_event.type = nux::EVENT_GESTURE_BEGIN; + fake_event.gesture_id = 0; + fake_event.is_direct_touch = false; + fake_event.focus.x = 100.0f; // hits the middle window + fake_event.focus.y = 100.0f; + // in touch device's coordinate system (because it's not a direct device). + // Thus not used by WindowCompositor + fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); + fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); + fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f)); + fake_event.is_construction_finished = false; + fake_event.radius = 1.0f; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + ASSERT_FALSE(window.moved_); + + fake_event.type = nux::EVENT_GESTURE_UPDATE; + fake_event.delta.x += 10.0f; + fake_event.delta.y += 20.0f; + fake_event.focus.x += fake_event.delta.x; + fake_event.focus.y += fake_event.delta.y; + fake_event.is_construction_finished = true; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + ASSERT_FALSE(window.moved_); +} + +TEST_F(WindowGestureTargetTest, ThreeFingersPinchMaximizesWindow) +{ + unity::UnityWindowMock window; + window.geometry_.set(10, 10, 400, 400, 0); + window.server_geometry_ = window.geometry_; + window.actions_ = CompWindowActionMoveMask; + window.state_ = 0; + window.id_ = 1; + + WindowGestureTarget gesture_target(&window); + + PerformPinch(gesture_target, 2.0); + + ASSERT_EQ(1, window.maximize_count_); + ASSERT_EQ(MAXIMIZE_STATE, window.maximize_state_); +} + +TEST_F(WindowGestureTargetTest, ThreeFingersPinchRestoresWindow) +{ + unity::UnityWindowMock window; + window.geometry_.set(10, 10, 400, 400, 0); + window.server_geometry_ = window.geometry_; + window.actions_ = CompWindowActionMoveMask; + window.state_ = MAXIMIZE_STATE; + window.id_ = 1; + + WindowGestureTarget gesture_target(&window); + + PerformPinch(gesture_target, 0.3); + + ASSERT_EQ(1, window.maximize_count_); + ASSERT_EQ(0, window.maximize_state_); +} + +TEST_F(WindowGestureTargetTest, MinimalThreeFingersPinchDoesNothing) +{ + unity::UnityWindowMock window; + window.geometry_.set(10, 10, 400, 400, 0); + window.server_geometry_ = window.geometry_; + window.actions_ = CompWindowActionMoveMask; + window.state_ = 0; + window.id_ = 1; + + WindowGestureTarget gesture_target(&window); + + PerformPinch(gesture_target, 1.1); + + ASSERT_EQ(0, window.maximize_count_); +} + +/* Regression test for lp:979418, where the grab is not removed if the gesture + * id is 0. */ +TEST_F(WindowGestureTargetTest, DragGrabCheck) +{ + screen_mock->grab_count_ = 0; + + unity::UnityWindowMock window; + window.geometry_.set(10, 10, 400, 400, 0); + window.server_geometry_ = window.geometry_; + window.actions_ = CompWindowActionMoveMask; + window.state_ = 0; + window.id_ = 1; + + WindowGestureTarget gesture_target(&window); + + /* prepare and send the fake event */ + nux::FakeGestureEvent fake_event; + fake_event.type = nux::EVENT_GESTURE_BEGIN; + fake_event.gesture_id = 0; + fake_event.is_direct_touch = false; + fake_event.focus.x = 100.0f; // hits the middle window + fake_event.focus.y = 100.0f; + // in touch device's coordinate system (because it's not a direct device). + // Thus not used by WindowCompositor + fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); + fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); + fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f)); + fake_event.is_construction_finished = false; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + fake_event.type = nux::EVENT_GESTURE_END; + gesture_target.GestureEvent(fake_event.ToGestureEvent()); + + ASSERT_EQ(0, screen_mock->grab_count_); +} diff --git a/tests/test-gestures/ubus-server-mock.cpp b/tests/test-gestures/ubus-server-mock.cpp new file mode 100644 index 000000000..8305aedff --- /dev/null +++ b/tests/test-gestures/ubus-server-mock.cpp @@ -0,0 +1,32 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#include <ubus-server-mock.h> + +UBusServer default_server; + +UBusServer* ubus_server_get_default() { + return &default_server; +} + +void ubus_server_send_message(UBusServer* server, + const gchar* message, + GVariant* data) { +} diff --git a/tests/test-gestures/ubus-server-mock.h b/tests/test-gestures/ubus-server-mock.h new file mode 100644 index 000000000..21a642253 --- /dev/null +++ b/tests/test-gestures/ubus-server-mock.h @@ -0,0 +1,35 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY 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 + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> + * + */ + +#ifndef UBUS_SERVER_MOCK_H +#define UBUS_SERVER_MOCK_H + +#include <glib-object.h> +#include <glib.h> + +class UBusServer { +}; + +UBusServer* ubus_server_get_default(); + +void ubus_server_send_message(UBusServer* server, + const gchar* message, + GVariant* data); +#endif // UBUS_SERVER_MOCK_H diff --git a/tests/test-gestures/unityshell_mock.h b/tests/test-gestures/unityshell_mock.h new file mode 100644 index 000000000..dd054abf4 --- /dev/null +++ b/tests/test-gestures/unityshell_mock.h @@ -0,0 +1,52 @@ +#ifndef UNITYSHELL_MOCK_H +#define UNITYSHELL_MOCK_H + +#include <compiz_mock/core/core.h> +#include <sigc++/sigc++.h> +#include <NuxMock.h> + +namespace unity +{ + +class UnityWindowMock : public CompWindowMock +{ + public: + static UnityWindowMock *get(CompWindowMock *window) + { + return static_cast<UnityWindowMock*>(window); + + } + + sigc::signal<void> being_destroyed; +}; + +class UnityScreenMock : public CompScreenMock +{ + public: + UnityScreenMock() + : launcher_(new nux::InputAreaMock) + { + } + + virtual ~UnityScreenMock() + { + launcher_->Dispose(); + } + + static UnityScreenMock *get(CompScreenMock *screen) + { + return static_cast<UnityScreenMock*>(screen); + + } + + nux::InputAreaMock *LauncherView() + { + return launcher_; + } + + nux::InputAreaMock *launcher_; +}; + +} // namespace unity + +#endif // UNITYSHELL_MOCK_H |
