summaryrefslogtreecommitdiff
path: root/tests
diff options
authorChristopher Lee <chris.lee@canonical.com>2012-08-27 15:01:36 +1200
committerChristopher Lee <chris.lee@canonical.com>2012-08-27 15:01:36 +1200
commitd5cb12609edc74f620a97b7d1f9089427eeda689 (patch)
treeefca7ffe0910b03b0cdd42b200b8966db2152253 /tests
parent1ac4b147b06f56968effc55bdf3e2ad375074594 (diff)
parent2e9c835e6ff61cd09074609e022920bdd1507e52 (diff)
Merged trunk and resolved conflict
(bzr r2490.2.9)
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt107
-rw-r--r--tests/autopilot/unity/emulators/dash.py254
-rw-r--r--tests/autopilot/unity/emulators/hud.py5
-rw-r--r--tests/autopilot/unity/emulators/launcher.py6
-rw-r--r--tests/autopilot/unity/emulators/panel.py6
-rw-r--r--tests/autopilot/unity/emulators/unity.py17
-rw-r--r--tests/autopilot/unity/tests/__init__.py19
-rw-r--r--tests/autopilot/unity/tests/launcher/test_capture.py18
-rw-r--r--tests/autopilot/unity/tests/launcher/test_icon_behavior.py67
-rw-r--r--tests/autopilot/unity/tests/launcher/test_reveal.py28
-rw-r--r--tests/autopilot/unity/tests/test_dash.py306
-rw-r--r--tests/autopilot/unity/tests/test_hud.py75
-rw-r--r--tests/autopilot/unity/tests/test_ibus.py218
-rw-r--r--tests/autopilot/unity/tests/test_panel.py141
-rw-r--r--tests/autopilot/unity/tests/test_quicklist.py94
-rw-r--r--tests/autopilot/unity/tests/test_shortcut_hint.py10
-rw-r--r--tests/autopilot/unity/tests/test_showdesktop.py9
-rw-r--r--tests/autopilot/unity/tests/test_switcher.py95
-rw-r--r--tests/data/no-icon.desktop7
-rw-r--r--tests/gmockvolume.c176
-rw-r--r--tests/gmockvolume.h53
-rw-r--r--tests/test-gesture-engine/CMakeLists.txt40
-rw-r--r--tests/test-gesture-engine/GeisAdapterMock.cpp31
-rw-r--r--tests/test-gesture-engine/GeisAdapterMock.h148
-rw-r--r--tests/test-gesture-engine/test_gesture_engine.cpp251
-rw-r--r--tests/test-gestures/CMakeLists.txt94
-rw-r--r--tests/test-gestures/FakeGestureEvent.h63
-rw-r--r--tests/test-gestures/GesturalWindowSwitcherMock.h40
-rw-r--r--tests/test-gestures/NuxMock.h27
-rw-r--r--tests/test-gestures/PluginAdapterMock.cpp (renamed from tests/test-gesture-engine/PluginAdapterMock.cpp)0
-rw-r--r--tests/test-gestures/PluginAdapterMock.h (renamed from tests/test-gesture-engine/PluginAdapterMock.h)0
-rw-r--r--tests/test-gestures/SwitcherControllerMock.h97
-rw-r--r--tests/test-gestures/UnityGestureTargetMock.h15
-rw-r--r--tests/test-gestures/WindowGestureTargetMock.h55
-rw-r--r--tests/test-gestures/X11_mock.cpp (renamed from tests/test-gesture-engine/X11_mock.cpp)0
-rw-r--r--tests/test-gestures/X11_mock.h (renamed from tests/test-gesture-engine/X11_mock.h)0
-rw-r--r--tests/test-gestures/compiz_mock/core/core.h (renamed from tests/test-gesture-engine/compiz_mock/core/core.h)0
-rw-r--r--tests/test-gestures/compiz_mock/core/screen.h (renamed from tests/test-gesture-engine/compiz_mock/core/screen.h)35
-rw-r--r--tests/test-gestures/compiz_mock/core/timer.h79
-rw-r--r--tests/test-gestures/compiz_mock/core/window.h (renamed from tests/test-gesture-engine/compiz_mock/core/window.h)56
-rw-r--r--tests/test-gestures/sed_script_broker12
-rw-r--r--tests/test-gestures/sed_script_gesture (renamed from tests/test-gesture-engine/sed_script)8
-rw-r--r--tests/test-gestures/sed_script_switcher25
-rw-r--r--tests/test-gestures/test_compound_gesture_recognizer.cpp189
-rw-r--r--tests/test-gestures/test_gestural_window_switcher.cpp323
-rw-r--r--tests/test-gestures/test_gesture_broker.cpp137
-rw-r--r--tests/test-gestures/test_gestures_main.cpp59
-rw-r--r--tests/test-gestures/test_window_gesture_target.cpp235
-rw-r--r--tests/test-gestures/ubus-server-mock.cpp (renamed from tests/test-gesture-engine/ubus-server-mock.cpp)0
-rw-r--r--tests/test-gestures/ubus-server-mock.h (renamed from tests/test-gesture-engine/ubus-server-mock.h)0
-rw-r--r--tests/test-gestures/unityshell_mock.h68
-rw-r--r--tests/test_bamflaunchericon.cpp32
-rw-r--r--tests/test_bfb_launcher_icon.cpp54
-rw-r--r--tests/test_device_launcher_section.cpp111
-rw-r--r--tests/test_edge_barrier_controller.cpp272
-rw-r--r--tests/test_favorite_store_gsettings.cpp77
-rw-r--r--tests/test_filesystem_lenses.cpp14
-rw-r--r--tests/test_glib_signals.cpp39
-rw-r--r--tests/test_home_lens.cpp35
-rw-r--r--tests/test_icon_loader.cpp25
-rw-r--r--tests/test_launcher.cpp158
-rw-r--r--tests/test_launcher_controller.cpp233
-rw-r--r--tests/test_lens.cpp110
-rw-r--r--tests/test_model_iterator.cpp126
-rw-r--r--tests/test_panel_style.cpp81
-rw-r--r--tests/test_pointer_barrier.cpp141
-rw-r--r--tests/test_previews.cpp266
-rw-r--r--tests/test_previews_application.cpp124
-rw-r--r--tests/test_previews_generic.cpp107
-rw-r--r--tests/test_previews_movie.cpp114
-rw-r--r--tests/test_previews_music.cpp109
-rw-r--r--tests/test_quicklist_menu_item.cpp177
-rw-r--r--tests/test_quicklist_view.cpp125
-rw-r--r--tests/test_results.cpp90
-rw-r--r--tests/test_service_lens.c26
-rw-r--r--tests/test_service_model.c2
-rw-r--r--tests/test_single_monitor_launcher_icon.cpp4
-rw-r--r--tests/test_switcher_controller.cpp23
-rw-r--r--tests/test_thumbnail_generator.cpp266
-rw-r--r--tests/test_uscreen_mock.h85
-rw-r--r--tests/unit/TestMain.cpp2
-rw-r--r--tests/unit/TestQuicklistMenuitems.cpp258
82 files changed, 5929 insertions, 1155 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 0cea996e3..453e3082c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -11,6 +11,8 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/data/update-manager.desktop
${CMAKE_BINARY_DIR}/tests/data/update-manager.desktop)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/data/bzr-handle-patch.desktop
${CMAKE_BINARY_DIR}/tests/data/bzr-handle-patch.desktop)
+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/data/no-icon.desktop
+ ${CMAKE_BINARY_DIR}/tests/data/no-icon.desktop)
#
# Unit tests
#
@@ -37,7 +39,7 @@ set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lcompi
link_libraries (${LIBS})
set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS})
-link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS})
+link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS} ${COMPIZ_LIBDIR})
include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR})
include_directories (${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src)
@@ -60,18 +62,11 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.c
add_executable (test-unit
unit/TestMain.cpp
- unit/TestQuicklistMenuitems.cpp
unit/TestPanelService.cpp
unit/TestUBus.cpp
unit/TestStaticCairoText.cpp
${CMAKE_SOURCE_DIR}/launcher/CairoBaseWindow.cpp
${CMAKE_SOURCE_DIR}/unity-shared/Introspectable.cpp
- ${CMAKE_SOURCE_DIR}/launcher/QuicklistMenuItem.cpp
- ${CMAKE_SOURCE_DIR}/launcher/QuicklistMenuItemCheckmark.cpp
- ${CMAKE_SOURCE_DIR}/launcher/QuicklistMenuItemLabel.cpp
- ${CMAKE_SOURCE_DIR}/launcher/QuicklistMenuItemRadio.cpp
- ${CMAKE_SOURCE_DIR}/launcher/QuicklistMenuItemSeparator.cpp
- ${CMAKE_SOURCE_DIR}/launcher/QuicklistView.cpp
${CMAKE_SOURCE_DIR}/unity-shared/StaticCairoText.cpp
../services/panel-service.c
${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.c
@@ -122,6 +117,7 @@ if (GTEST_SRC_DIR AND
# The actual test executable (xless) - do not put anything that requires X in here
add_executable(test-gtest-xless
+ test_main_xless.cpp
test_animator.cpp
test_launcher_model.cpp
test_glib_object.cpp
@@ -132,24 +128,26 @@ if (GTEST_SRC_DIR AND
test_glib_signals_utils.h
test_glib_source.cpp
test_glib_variant.cpp
+ test_grabhandle.cpp
test_desktop_utilities.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
+ test_hud_private.cpp
test_indicator.cpp
test_indicator_appmenu.cpp
test_indicator_entry.cpp
test_indicators.cpp
+ test_introspection.cpp
test_favorite_store_gsettings.cpp
test_favorite_store_private.cpp
test_home_lens.cpp
test_launcher_entry_remote.cpp
+ test_model_iterator.cpp
+ test_pointer_barrier.cpp
+ test_previews.cpp
test_shortcut_model.cpp
test_shortcut_private.cpp
- test_introspection.cpp
- test_main_xless.cpp
- test_grabhandle.cpp
- test_unityshell_private.cpp
test_showdesktop_handler.cpp
- test_hud_private.cpp
+ test_unityshell_private.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
${CMAKE_SOURCE_DIR}/launcher/AbstractLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/unity-shared/Animator.cpp
${UNITY_SRC}/DebugDBusInterface.cpp
@@ -159,7 +157,9 @@ if (GTEST_SRC_DIR AND
${CMAKE_SOURCE_DIR}/unity-shared/IconTextureSource.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherModel.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherEntryRemote.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/MockLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/PointerBarrier.cpp
${CMAKE_SOURCE_DIR}/shortcuts/ShortcutModel.cpp
${CMAKE_SOURCE_DIR}/shortcuts/ShortcutHintPrivate.cpp
${CMAKE_SOURCE_DIR}/unity-shared/Introspectable.cpp
@@ -199,27 +199,51 @@ if (GTEST_SRC_DIR AND
# Tests that require X
add_executable(test-gtest
+ test_main.cpp
test_bamflaunchericon.cpp
- test_hud_button.cpp
- test_hud_controller.cpp
+ test_bfb_launcher_icon.cpp
test_dashview_impl.cpp
- test_texture_cache.cpp
- test_main.cpp
+ test_edge_barrier_controller.cpp
+ test_launcher.cpp
+ test_device_launcher_section.cpp
test_lensview_impl.cpp
+ test_hud_button.cpp
+ test_hud_controller.cpp
+ test_hud_view.cpp
test_icon_loader.cpp
test_im_text_entry.cpp
- test_hud_view.cpp
+ test_launcher_controller.cpp
test_keyboard_util.cpp
+ test_panel_style.cpp
+ test_previews_application.cpp
+ test_previews_generic.cpp
+ test_previews_movie.cpp
+ test_previews_music.cpp
+ test_quicklist_menu_item.cpp
+ test_quicklist_view.cpp
test_resultviewgrid.cpp
test_single_monitor_launcher_icon.cpp
test_switcher_controller.cpp
test_switcher_model.cpp
+ test_texture_cache.cpp
+ test_thumbnail_generator.cpp
+ gmockvolume.c
${CMAKE_SOURCE_DIR}/dash/AbstractPlacesGroup.cpp
${CMAKE_SOURCE_DIR}/dash/DashViewPrivate.cpp
${CMAKE_SOURCE_DIR}/dash/LensViewPrivate.cpp
${CMAKE_SOURCE_DIR}/dash/ResultRenderer.cpp
${CMAKE_SOURCE_DIR}/dash/ResultView.cpp
${CMAKE_SOURCE_DIR}/dash/ResultViewGrid.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/ActionButton.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/ApplicationPreview.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/GenericPreview.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/MoviePreview.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/MusicPreview.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/Preview.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/PreviewInfoHintWidget.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/PreviewRatingsWidget.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/Tracks.cpp
+ ${CMAKE_SOURCE_DIR}/dash/previews/Track.cpp
${CMAKE_SOURCE_DIR}/hud/HudAbstractView.cpp
${CMAKE_SOURCE_DIR}/hud/HudButton.cpp
${CMAKE_SOURCE_DIR}/hud/HudController.cpp
@@ -229,22 +253,32 @@ if (GTEST_SRC_DIR AND
${CMAKE_SOURCE_DIR}/hud/HudView.cpp
${CMAKE_SOURCE_DIR}/launcher/AbstractLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/BamfLauncherIcon.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/BFBLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/CairoBaseWindow.cpp
${CMAKE_SOURCE_DIR}/launcher/DNDCollectionWindow.cpp
${CMAKE_SOURCE_DIR}/launcher/Decaymulator.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/DesktopLauncherIcon.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/DeviceLauncherIcon.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/DeviceLauncherSection.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/DevicesSettings.cpp
${CMAKE_SOURCE_DIR}/launcher/DndData.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/EdgeBarrierController.cpp
${CMAKE_SOURCE_DIR}/launcher/FavoriteStore.cpp
${CMAKE_SOURCE_DIR}/launcher/FavoriteStoreGSettings.cpp
${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp
- ${CMAKE_SOURCE_DIR}/launcher/GeisAdapter.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/HudLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/Launcher.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/LauncherController.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherDragWindow.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherEntryRemote.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/LauncherEntryRemoteModel.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherHideMachine.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherHoverMachine.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherModel.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/LauncherOptions.cpp
${CMAKE_SOURCE_DIR}/launcher/LayoutSystem.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/MockLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/PointerBarrier.cpp
${CMAKE_SOURCE_DIR}/launcher/QuicklistManager.cpp
${CMAKE_SOURCE_DIR}/launcher/QuicklistMenuItem.cpp
@@ -255,14 +289,19 @@ if (GTEST_SRC_DIR AND
${CMAKE_SOURCE_DIR}/launcher/QuicklistView.cpp
${CMAKE_SOURCE_DIR}/launcher/SimpleLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/SingleMonitorLauncherIcon.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/SoftwareCenterLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/SpacerLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/SwitcherController.cpp
${CMAKE_SOURCE_DIR}/launcher/SwitcherModel.cpp
${CMAKE_SOURCE_DIR}/launcher/SwitcherView.cpp
${CMAKE_SOURCE_DIR}/launcher/Tooltip.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/TrashLauncherIcon.cpp
+ ${CMAKE_SOURCE_DIR}/launcher/VolumeMonitorWrapper.cpp
${CMAKE_SOURCE_DIR}/unity-shared/Animator.cpp
${CMAKE_SOURCE_DIR}/unity-shared/BackgroundEffectHelper.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/CoverArt.cpp
${CMAKE_SOURCE_DIR}/unity-shared/DashStyle.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/DefaultThumbnailProvider.cpp
${CMAKE_SOURCE_DIR}/unity-shared/IconLoader.cpp
${CMAKE_SOURCE_DIR}/unity-shared/IconRenderer.cpp
${CMAKE_SOURCE_DIR}/unity-shared/IconTexture.cpp
@@ -274,17 +313,23 @@ if (GTEST_SRC_DIR AND
${CMAKE_SOURCE_DIR}/unity-shared/KeyboardUtil.cpp
${CMAKE_SOURCE_DIR}/unity-shared/OverlayRenderer.cpp
${CMAKE_SOURCE_DIR}/unity-shared/PanelStyle.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/PlacesVScrollBar.cpp
${CMAKE_SOURCE_DIR}/unity-shared/PluginAdapterStandalone.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/PreviewStyle.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/RatingsButton.cpp
${CMAKE_SOURCE_DIR}/unity-shared/SearchBar.cpp
${CMAKE_SOURCE_DIR}/unity-shared/SearchBarSpinner.cpp
${CMAKE_SOURCE_DIR}/unity-shared/StaticCairoText.cpp
${CMAKE_SOURCE_DIR}/unity-shared/TextureCache.cpp
${CMAKE_SOURCE_DIR}/unity-shared/Timer.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/TextureThumbnailProvider.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/ThumbnailGenerator.cpp
${CMAKE_SOURCE_DIR}/unity-shared/UBusWrapper.cpp
${CMAKE_SOURCE_DIR}/unity-shared/UScreen.cpp
${CMAKE_SOURCE_DIR}/unity-shared/UnitySettings.cpp
${CMAKE_SOURCE_DIR}/unity-shared/UnityWindowStyle.cpp
${CMAKE_SOURCE_DIR}/unity-shared/UnityWindowView.cpp
+ ${CMAKE_SOURCE_DIR}/unity-shared/UserThumbnailProvider.cpp
${CMAKE_SOURCE_DIR}/unity-shared/WindowManager.cpp
${CMAKE_SOURCE_DIR}/unity-shared/ubus-server.cpp
)
@@ -296,7 +341,7 @@ endif (GTEST_SRC_DIR AND
GMOCK_LIB AND
GMOCK_MAIN_LIB)
-add_subdirectory (test-gesture-engine)
+add_subdirectory (test-gestures)
#
# check target
@@ -307,25 +352,25 @@ set (TEST_RESULT_HTML ${TEST_RESULT_DIR}/test-results.html)
set (GTEST_TEST_COMMAND ./test-gtest)
set (GTEST_TEST_COMMAND_XLESS ./test-gtest-xless)
set (GTEST_TEST_COMMAND_DBUS dbus-test-runner --task ./test-gtest-service --task ./test-gtest-dbus)
-set (GTEST_TEST_COMMAND_GESTURE_ENGINE ./test-gesture-engine/test-gesture-engine)
+set (GTEST_TEST_COMMAND_GESTURES ./test-gestures/test-gestures)
set (TEST_COMMAND
gtester --verbose -k --g-fatal-warnings -o=${TEST_RESULT_XML} ./test-unit
- && ${GTEST_TEST_COMMAND}
- && ${GTEST_TEST_COMMAND_XLESS}
- && ${GTEST_TEST_COMMAND_GESTURE_ENGINE}
- && ${GTEST_TEST_COMMAND_DBUS}
+ && ${GTEST_TEST_COMMAND} --gtest_output=xml:./
+ && ${GTEST_TEST_COMMAND_XLESS} --gtest_output=xml:./
+ && ${GTEST_TEST_COMMAND_GESTURES} --gtest_output=xml:./
+ && ${GTEST_TEST_COMMAND_DBUS} --gtest_output=xml:./
)
set (TEST_COMMAND_HEADLESS
- ${GTEST_TEST_COMMAND_XLESS}
- && ${GTEST_TEST_COMMAND_GESTURE_ENGINE}
- #&& ${GTEST_TEST_COMMAND_DBUS}
+ ${GTEST_TEST_COMMAND_XLESS} --gtest_output=xml:./
+ && ${GTEST_TEST_COMMAND_GESTURES} --gtest_output=xml:./
+ #&& ${GTEST_TEST_COMMAND_DBUS} --gtest_output=xml:./
&& echo "Warning, DBus test cases are disabled!!")
if (GTEST_SRC_DIR)
- add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-xless test-gtest-dbus test-gesture-engine)
- add_custom_target (check-headless COMMAND ${TEST_COMMAND_HEADLESS} DEPENDS test-gtest-xless test-gtest-dbus test-gesture-engine)
+ add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-xless test-gtest-dbus test-gestures)
+ add_custom_target (check-headless COMMAND ${TEST_COMMAND_HEADLESS} DEPENDS test-gtest-xless test-gtest-dbus test-gestures)
add_custom_target (check-report COMMAND ${TEST_UNIT_COMMAND} && gtester-report ${TEST_RESULT_XML} > ${TEST_RESULT_HTML})
add_custom_target (gcheck COMMAND ${DBUS_TEST_COMMAND} DEPENDS test-gtest test-gtest-xless)
else (GTEST_SRC_DIR)
diff --git a/tests/autopilot/unity/emulators/dash.py b/tests/autopilot/unity/emulators/dash.py
index f7d315b65..86c747f4b 100644
--- a/tests/autopilot/unity/emulators/dash.py
+++ b/tests/autopilot/unity/emulators/dash.py
@@ -9,12 +9,13 @@
from __future__ import absolute_import
-from autopilot.introspection.dbus import make_introspection_object
from autopilot.emulators.X11 import Keyboard, Mouse
from autopilot.keybindings import KeybindingsHelper
+from testtools.matchers import GreaterThan
from unity.emulators import UnityIntrospectionObject
import logging
+from time import sleep
logger = logging.getLogger(__name__)
@@ -82,6 +83,11 @@ class Dash(KeybindingsHelper):
"""Returns the searchbar attached to the dash."""
return self.view.get_searchbar()
+ @property
+ def preview_displaying(self):
+ """Returns true if the dash is currently displaying a preview"""
+ return self.view.preview_displaying;
+
def get_num_rows(self):
"""Returns the number of displayed rows in the dash."""
return self.view.num_rows
@@ -114,6 +120,12 @@ class Dash(KeybindingsHelper):
self._reveal_lens("lens_reveal/files", clear_search)
return self.view.get_lensview_by_name("files.lens")
+ def reveal_video_lens(self, clear_search=True):
+ """Reveal the video lens"""
+ logger.debug("Revealing video lens with Super+v.")
+ self._reveal_lens("lens_reveal/video", clear_search)
+ return self.view.get_lensview_by_name("video.lens")
+
def reveal_command_lens(self, clear_search=True):
"""Reveal the 'run command' lens."""
logger.debug("Revealing command lens with Alt+F2.")
@@ -164,6 +176,13 @@ class DashView(UnityIntrospectionObject):
if lens.name == lens_name:
return lens
+ def get_preview_container(self):
+ """Get the preview container attached to this dash view."""
+ preview_containers = self.get_children_by_type(PreviewContainer)
+ for preview_container in preview_containers:
+ return preview_container
+ return None
+
class SearchBar(UnityIntrospectionObject):
"""The search bar for the dash view."""
@@ -238,6 +257,20 @@ class ResultView(UnityIntrospectionObject):
class Result(UnityIntrospectionObject):
"""A single result in the dash."""
+ def activate(self):
+ tx = self.x + (self.width / 2)
+ ty = self.y + (self.height / 2)
+ m = Mouse()
+ m.move(tx, ty)
+ m.click(1)
+
+ def preview(self):
+ tx = self.x + (self.width / 2)
+ ty = self.y + (self.height / 2)
+ m = Mouse()
+ m.move(tx, ty)
+ m.click(3)
+
class FilterBar(UnityIntrospectionObject):
"""A filterbar, as shown inside a lens."""
@@ -293,8 +326,225 @@ class FilterBar(UnityIntrospectionObject):
"""
searchbar_state = self.get_state_by_path("//DashView/SearchBar")
assert(len(searchbar_state) == 1)
- return make_introspection_object(searchbar_state[0])
+ return self.make_introspection_object(searchbar_state[0])
class FilterExpanderLabel(UnityIntrospectionObject):
"""A label that expands into a filter within a filter bar."""
+
+ def ensure_expanded(self):
+ """Expand the filter expander label, if it's not already"""
+ if not self.expanded:
+ tx = x + width / 2
+ ty = y + height / 2
+ m = Mouse()
+ m.move(tx, ty)
+ m.click()
+ self.expanded.wait_for(True)
+
+ def ensure_collapsed(self):
+ """Collapse the filter expander label, if it's not already"""
+ if self.expanded:
+ tx = x + width / 2
+ ty = y + height / 2
+ m = Mouse()
+ m.move(tx, ty)
+ m.click()
+ self.expanded.wait_for(False)
+
+
+class CoverArt(UnityIntrospectionObject):
+ """A view which can be used to show a texture, or generate one using a thumbnailer."""
+
+
+class RatingsButton(UnityIntrospectionObject):
+ """A button which shows user rating as a function of stars."""
+
+
+class Preview(UnityIntrospectionObject):
+ """A preview of a dash lens result."""
+
+ def get_num_actions(self):
+ """Get the number of actions for the preview."""
+ actions = self.get_children_by_type(ActionButton)
+ return len(actions)
+
+ def get_action_by_id(self, action_id):
+ """Returns the action given it's action hint."""
+ actions = self.get_children_by_type(ActionButton)
+ for action in actions:
+ if action.action == action_id:
+ return action
+ return None
+
+ def execute_action_by_id(action_id, action):
+ """Executes an action given by the id."""
+ action = self.get_action_by_id(action_id)
+ if action:
+ tx = action.x + (searchbar.width / 2)
+ ty = action.y + (searchbar.height / 2)
+ m = Mouse()
+ m.move(tx, ty)
+ m.click()
+
+ @property
+ def cover_art(self):
+ return self.get_children_by_type(CoverArt)[0]
+
+class ApplicationPreview(Preview):
+ """A application preview of a dash lens result."""
+
+class GenericPreview(Preview):
+ """A generic preview of a dash lens result."""
+
+class MusicPreview(Preview):
+ """A music preview of a dash lens result."""
+
+class MoviePreview(Preview):
+ """A movie preview of a dash lens result."""
+
+class PreviewContent(UnityIntrospectionObject):
+ """A preview content layout for the dash previews."""
+
+ def get_current_preview(self):
+ previews = self.get_children_by_type(Preview)
+ if len(previews) > 0:
+ return previews[0]
+ return None
+
+
+class PreviewContainer(UnityIntrospectionObject):
+ """A container view for the main dash preview widget."""
+
+ @property
+ def content(self):
+ return self.get_content()
+
+ def get_num_previews(self):
+ """Get the number of previews queued and current in the container."""
+ previews = self.content.get_children_by_type(Preview)
+ return len(previews)
+
+ def get_content(self):
+ """Get the preview content layout for the container."""
+ return self.get_children_by_type(PreviewContent)[0]
+
+ def get_left_navigator(self):
+ """Return the left navigator object"""
+ navigators = self.get_children_by_type(PreviewNavigator)
+ for nav in navigators:
+ if nav.direction == 2:
+ return nav
+ return None
+
+ def get_right_navigator(self):
+ """Return the right navigator object"""
+ navigators = self.get_children_by_type(PreviewNavigator)
+ for nav in navigators:
+ if nav.direction == 3:
+ return nav
+ return None
+
+ def navigate_left(self, count=1):
+ """Navigate preview left"""
+ navigator = self.get_left_navigator()
+
+ tx = navigator.button_x + (navigator.button_width / 2)
+ ty = navigator.button_y + (navigator.button_height / 2)
+ m = Mouse()
+ m.move(tx, ty)
+
+ old_preview_initiate_count = self.preview_initiate_count
+
+ for i in range(count):
+ self.navigate_left_enabled.wait_for(True)
+ m.click()
+ self.preview_initiate_count.wait_for(GreaterThan(old_preview_initiate_count))
+ old_preview_initiate_count = self.preview_initiate_count
+
+ def navigate_right(self, count=1):
+ """Navigate preview right"""
+ navigator = self.get_right_navigator()
+
+ tx = navigator.button_x + (navigator.button_width / 2)
+ ty = navigator.button_y + (navigator.button_height / 2)
+ m = Mouse()
+ m.move(tx, ty)
+
+ old_preview_initiate_count = self.preview_initiate_count
+
+ for i in range(count):
+ self.navigate_right_enabled.wait_for(True)
+ m.click()
+ self.preview_initiate_count.wait_for(GreaterThan(old_preview_initiate_count))
+ old_preview_initiate_count = self.preview_initiate_count
+
+ @property
+ def animating(self):
+ """Return True if the preview is animating, False otherwise."""
+ return self.content.animating
+
+ @property
+ def waiting_preview(self):
+ """Return True if waiting for a preview, False otherwise."""
+ return self.content.waiting_preview
+
+ @property
+ def animation_progress(self):
+ """Return the progress of the current preview animation."""
+ return self.content.animation_progress
+
+ @property
+ def current_preview(self):
+ """Return the current preview object."""
+ return self.content.get_current_preview()
+ preview_initiate_count_
+
+ @property
+ def preview_initiate_count(self):
+ """Return the number of initiated previews since opened."""
+ return self.content.preview_initiate_count
+
+ @property
+ def navigation_complete_count(self):
+ """Return the number of completed previews since opened."""
+ return self.content.navigation_complete_count
+
+ @property
+ def relative_nav_index(self):
+ """Return the navigation position relative to the direction of movement."""
+ return self.content.relative_nav_index
+
+ @property
+ def navigate_right_enabled(self):
+ """Return True if right preview navigation is enabled, False otherwise."""
+ return self.content.navigate_right_enabled
+
+ @property
+ def navigate_left_enabled(self):
+ """Return True if left preview navigation is enabled, False otherwise."""
+ return self.content.navigate_left_enabled
+
+
+class PreviewNavigator(UnityIntrospectionObject):
+ """A view containing a button to nagivate between previews."""
+
+ def icon(self):
+ return self.get_children_by_type(IconTexture);
+
+
+class PreviewRatingsWidget(UnityIntrospectionObject):
+ """A view containing a rating button and user rating count."""
+
+
+class Tracks(UnityIntrospectionObject):
+ """A view containing music tracks."""
+
+
+class Track(UnityIntrospectionObject):
+ """A singular music track for dash prevews."""
+
+
+class ActionButton(UnityIntrospectionObject):
+ """A preview action button."""
+
diff --git a/tests/autopilot/unity/emulators/hud.py b/tests/autopilot/unity/emulators/hud.py
index c0e841ead..500a607a8 100644
--- a/tests/autopilot/unity/emulators/hud.py
+++ b/tests/autopilot/unity/emulators/hud.py
@@ -32,6 +32,11 @@ class Hud(KeybindingsHelper):
def ensure_hidden(self):
"""Hides the hud if it's not already hidden."""
if self.visible:
+ if self.search_string:
+ # need this to clear the search string, and then another to
+ # close the hud.
+ self.keyboard.press_and_release("Escape")
+ self.search_string.wait_for("")
self.keyboard.press_and_release("Escape")
self.visible.wait_for(False)
diff --git a/tests/autopilot/unity/emulators/launcher.py b/tests/autopilot/unity/emulators/launcher.py
index 1ae9bb40d..fa5361ac5 100644
--- a/tests/autopilot/unity/emulators/launcher.py
+++ b/tests/autopilot/unity/emulators/launcher.py
@@ -305,9 +305,10 @@ class Launcher(UnityIntrospectionObject, KeybindingsHelper):
self._perform_switcher_binding("launcher/switcher/down")
self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection))
- def click_launcher_icon(self, icon, button=1):
+ def click_launcher_icon(self, icon, button=1, move_mouse_after=True):
"""Move the mouse over the launcher icon, and click it.
`icon` must be an instance of SimpleLauncherIcon or it's descendants.
+ `move_mouse_after` moves the mouse outside the launcher if true.
"""
if not isinstance(icon, SimpleLauncherIcon):
raise TypeError("icon must be a LauncherIcon, not %s" % type(icon))
@@ -325,7 +326,8 @@ class Launcher(UnityIntrospectionObject, KeybindingsHelper):
self._mouse.move(target_x, target_y )
sleep(1)
self._mouse.click(button)
- self.move_mouse_to_right_of_launcher()
+ if (move_mouse_after):
+ self.move_mouse_to_right_of_launcher()
def drag_icon_to_position(self, icon, pos, drag_type=IconDragType.INSIDE):
"""Place the supplied icon above the icon in the position pos.
diff --git a/tests/autopilot/unity/emulators/panel.py b/tests/autopilot/unity/emulators/panel.py
index 2b0d69254..147afba88 100644
--- a/tests/autopilot/unity/emulators/panel.py
+++ b/tests/autopilot/unity/emulators/panel.py
@@ -338,3 +338,9 @@ class IndicatorEntry(UnityIntrospectionObject):
"""Returns a tuple of (x,y,w,h) for the opened menu geometry."""
return (self.menu_x, self.menu_y, self.menu_width, self.menu_height)
+ def __repr__(self):
+ return "<IndicatorEntry 0x%x (%s)>" % (id(self), self.label)
+
+
+class Tray(UnityIntrospectionObject):
+ """A panel tray object."""
diff --git a/tests/autopilot/unity/emulators/unity.py b/tests/autopilot/unity/emulators/unity.py
index 69ecab582..97b1840a0 100644
--- a/tests/autopilot/unity/emulators/unity.py
+++ b/tests/autopilot/unity/emulators/unity.py
@@ -18,17 +18,22 @@ DEBUG_PATH = '/com/canonical/Unity/Debug'
LOGGING_IFACE = 'com.canonical.Unity.Debug.Logging'
-_debug_proxy_obj = session_bus.get_object(UNITY_BUS_NAME, DEBUG_PATH)
-_logging_iface = Interface(_debug_proxy_obj, LOGGING_IFACE)
+def get_dbus_proxy_object():
+ return session_bus.get_object(UNITY_BUS_NAME, DEBUG_PATH)
+
+
+def get_dbus_logging_interface():
+ return Interface(get_dbus_proxy_object(), LOGGING_IFACE)
+
def start_log_to_file(file_path):
"""Instruct Unity to start logging to the given file."""
- _logging_iface.StartLogToFile(file_path)
+ get_dbus_logging_interface().StartLogToFile(file_path)
def reset_logging():
"""Instruct Unity to stop logging to a file."""
- _logging_iface.ResetLogging()
+ get_dbus_logging_interface().ResetLogging()
def set_log_severity(component, severity):
@@ -39,7 +44,7 @@ def set_log_severity(component, severity):
'severity' is the severity name (like 'DEBUG', 'INFO' etc.)
"""
- _logging_iface.SetLogSeverity(component, severity)
+ get_dbus_logging_interface().SetLogSeverity(component, severity)
def log_unity_message(severity, message):
@@ -53,5 +58,5 @@ def log_unity_message(severity, message):
test, use the python logging framework instead.
"""
- _logging_iface.LogMessage(severity, message)
+ get_dbus_logging_interface().LogMessage(severity, message)
diff --git a/tests/autopilot/unity/tests/__init__.py b/tests/autopilot/unity/tests/__init__.py
index a241a0a63..90b7c10ae 100644
--- a/tests/autopilot/unity/tests/__init__.py
+++ b/tests/autopilot/unity/tests/__init__.py
@@ -65,37 +65,37 @@ class UnityTestCase(AutopilotTestCase):
log.info("Checking system state for badly behaving test...")
# Have we switched workspace?
- if self.workspace.current_workspace != self._initial_workspace_num:
+ if not self.well_behaved(self.workspace, current_workspace=self._initial_workspace_num):
well_behaved = False
reasons.append("The test changed the active workspace from %d to %d." \
% (self._initial_workspace_num, self.workspace.current_workspace))
log.warning("Test changed the active workspace, changing it back...")
self.workspace.switch_to(self._initial_workspace_num)
# Have we left the dash open?
- if self.dash.visible:
+ if not self.well_behaved(self.dash, visible=False):
well_behaved = False
reasons.append("The test left the dash open.")
log.warning("Test left the dash open, closing it...")
self.dash.ensure_hidden()
# ... or the hud?
- if self.hud.visible:
+ if not self.well_behaved(self.hud, visible=False):
well_behaved = False
reasons.append("The test left the hud open.")
log.warning("Test left the hud open, closing it...")
self.hud.ensure_hidden()
# Are we in show desktop mode?
- if self.window_manager.showdesktop_active:
+ if not self.well_behaved(self.window_manager, showdesktop_active=False):
well_behaved = False
reasons.append("The test left the system in show_desktop mode.")
log.warning("Test left the system in show desktop mode, exiting it...")
self.window_manager.leave_show_desktop()
for launcher in self.launcher.get_launchers():
- if launcher.in_keynav_mode:
+ if not self.well_behaved(launcher, in_keynav_mode=False):
well_behaved = False
reasons.append("The test left the launcher keynav mode enabled.")
log.warning("Test left the launcher in keynav mode, exiting it...")
launcher.key_nav_cancel()
- if launcher.in_switcher_mode:
+ if not self.well_behaved(launcher, in_switcher_mode=False):
well_behaved = False
reasons.append("The test left the launcher in switcher mode.")
log.warning("Test left the launcher in switcher mode, exiting it...")
@@ -106,6 +106,13 @@ class UnityTestCase(AutopilotTestCase):
else:
log.info("Test was well behaved.")
+ def well_behaved(self, object, **kwargs):
+ try:
+ self.assertProperty(object, **kwargs)
+ except AssertionError:
+ return False
+ return True
+
@property
def dash(self):
if not getattr(self, '__dash', None):
diff --git a/tests/autopilot/unity/tests/launcher/test_capture.py b/tests/autopilot/unity/tests/launcher/test_capture.py
index a6f4b602e..6783301bf 100644
--- a/tests/autopilot/unity/tests/launcher/test_capture.py
+++ b/tests/autopilot/unity/tests/launcher/test_capture.py
@@ -80,9 +80,25 @@ class LauncherCaptureTests(UnityTestCase):
# The launcher should have held the mouse a little bit
self.assertThat(x_fin, Equals(x - width / 2))
+ def test_launcher_capture_while_not_sticky_and_hidden(self):
+ """Tests that the launcher captures the mouse when moving between monitors
+ while hidden and sticky is off. (moving left)
+ """
+
+ self.set_unity_option('launcher_capture_mouse', False)
+ self.setHideMode(1)
+
+ x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor())
+ self.mouse.move(x + width / 2, y + height / 2, False)
+ self.mouse.move(x - width / 2, y + height / 2, True, 5, .002)
+
+ x_fin, y_fin = self.mouse.position()
+ # The launcher should have held the mouse a little bit
+ self.assertThat(x_fin, GreaterThan(x - width / 2))
+
def test_launcher_not_capture_while_not_sticky_and_hidden_moving_right(self):
"""Tests that the launcher doesn't capture the mouse when moving between monitors
- while hidden and sticky is off.
+ while hidden and sticky is off (moving right).
"""
self.set_unity_option('launcher_capture_mouse', False)
diff --git a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
index f214b3a08..798283d21 100644
--- a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
+++ b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py
@@ -66,54 +66,75 @@ class LauncherIconsTests(LauncherTestCase):
of that application.
"""
- mah_win1 = self.start_app_window("Mahjongg")
+ char_win1 = self.start_app_window("Character Map")
calc_win = self.start_app_window("Calculator")
- mah_win2 = self.start_app_window("Mahjongg")
+ char_win2 = self.start_app_window("Character Map")
- self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+ self.assertVisibleWindowStack([char_win2, calc_win, char_win1])
- mahj_icon = self.launcher.model.get_icon(
- desktop_id=mah_win2.application.desktop_file)
+ char_icon = self.launcher.model.get_icon(
+ desktop_id=char_win2.application.desktop_file)
calc_icon = self.launcher.model.get_icon(
desktop_id=calc_win.application.desktop_file)
self.launcher_instance.click_launcher_icon(calc_icon)
self.assertProperty(calc_win, is_focused=True)
- self.assertVisibleWindowStack([calc_win, mah_win2, mah_win1])
+ self.assertVisibleWindowStack([calc_win, char_win2, char_win1])
- self.launcher_instance.click_launcher_icon(mahj_icon)
- self.assertProperty(mah_win2, is_focused=True)
- self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+ self.launcher_instance.click_launcher_icon(char_icon)
+ self.assertProperty(char_win2, is_focused=True)
+ self.assertVisibleWindowStack([char_win2, calc_win, char_win1])
self.keybinding("window/minimize")
- self.assertThat(lambda: mah_win2.is_hidden, Eventually(Equals(True)))
+ self.assertThat(lambda: char_win2.is_hidden, Eventually(Equals(True)))
self.assertProperty(calc_win, is_focused=True)
- self.assertVisibleWindowStack([calc_win, mah_win1])
+ self.assertVisibleWindowStack([calc_win, char_win1])
- self.launcher_instance.click_launcher_icon(mahj_icon)
- self.assertProperty(mah_win1, is_focused=True)
- self.assertThat(lambda: mah_win2.is_hidden, Eventually(Equals(True)))
- self.assertVisibleWindowStack([mah_win1, calc_win])
+ self.launcher_instance.click_launcher_icon(char_icon)
+ self.assertProperty(char_win1, is_focused=True)
+ self.assertThat(lambda: char_win2.is_hidden, Eventually(Equals(True)))
+ self.assertVisibleWindowStack([char_win1, calc_win])
def test_clicking_icon_twice_initiates_spread(self):
"""This tests shows that when you click on a launcher icon twice,
when an application window is focused, the spread is initiated.
"""
- calc_win1 = self.start_app_window("Calculator")
- calc_win2 = self.start_app_window("Calculator")
- calc_app = calc_win1.application
+ char_win1 = self.start_app_window("Character Map")
+ char_win2 = self.start_app_window("Character Map")
+ char_app = char_win1.application
- self.assertVisibleWindowStack([calc_win2, calc_win1])
- self.assertProperty(calc_win2, is_focused=True)
+ self.assertVisibleWindowStack([char_win2, char_win1])
+ self.assertProperty(char_win2, is_focused=True)
- calc_icon = self.launcher.model.get_icon(desktop_id=calc_app.desktop_file)
+ char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file)
self.addCleanup(self.keybinding, "spread/cancel")
- self.launcher_instance.click_launcher_icon(calc_icon)
+ self.launcher_instance.click_launcher_icon(char_icon)
self.assertThat(self.window_manager.scale_active, Eventually(Equals(True)))
self.assertThat(self.window_manager.scale_active_for_group, Eventually(Equals(True)))
+ def test_while_in_scale_mode_the_dash_will_still_open(self):
+ """If scale is initiated through the laucher pressing super must close
+ scale and open the dash.
+ """
+ char_win1 = self.start_app_window("Character Map")
+ char_win2 = self.start_app_window("Character Map")
+ char_app = char_win1.application
+
+ self.assertVisibleWindowStack([char_win2, char_win1])
+ self.assertProperty(char_win2, is_focused=True)
+
+ char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file)
+ self.launcher_instance.click_launcher_icon(char_icon)
+ self.assertThat(self.window_manager.scale_active, Eventually(Equals(True)))
+
+ self.dash.ensure_visible()
+ self.addCleanup(self.dash.ensure_hidden)
+
+ self.assertThat(self.dash.visible, Eventually(Equals(True)))
+ self.assertThat(self.window_manager.scale_active, Eventually(Equals(False)))
+
def test_icon_shows_on_quick_application_reopen(self):
"""Icons must stay on launcher when an application is quickly closed/reopened."""
calc = self.start_app("Calculator")
@@ -146,7 +167,7 @@ class LauncherDragIconsBehavior(LauncherTestCase):
# the old fashioned way.
refresh_fn = lambda: self.launcher.model.get_children_by_type(
BamfLauncherIcon, desktop_id="gcalctool.desktop")
- self.assertThat(refresh_fn, Eventually(Equals(None)))
+ self.assertThat(refresh_fn, Eventually(Equals([])))
def test_can_drag_icon_below_bfb(self):
"""Application icons must be draggable to below the BFB."""
diff --git a/tests/autopilot/unity/tests/launcher/test_reveal.py b/tests/autopilot/unity/tests/launcher/test_reveal.py
index 00cad97a5..45976fa7b 100644
--- a/tests/autopilot/unity/tests/launcher/test_reveal.py
+++ b/tests/autopilot/unity/tests/launcher/test_reveal.py
@@ -73,6 +73,34 @@ class LauncherRevealTests(LauncherTestCase):
sleep(5)
self.assertThat(self.launcher_instance.is_showing, Equals(False))
+ def test_launcher_stays_open_after_spread(self):
+ """Clicking on the launcher to close an active spread must not hide the launcher."""
+ char_win1 = self.start_app_window("Character Map")
+ char_win2 = self.start_app_window("Character Map")
+ char_app = char_win1.application
+
+ char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file)
+
+ self.launcher_instance.click_launcher_icon(char_icon, move_mouse_after=False)
+ self.assertThat(self.window_manager.scale_active, Eventually(Equals(True)))
+ self.launcher_instance.click_launcher_icon(char_icon, move_mouse_after=False)
+
+ self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True)))
+ self.assertThat(self.window_manager.scale_active, Eventually(Equals(False)))
+
+ def test_launcher_stays_open_after_icon_click(self):
+ """Clicking on a launcher icon must not hide the launcher."""
+ char_win = self.start_app_window("Character Map")
+ char_app = char_win.application
+
+ char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file)
+ self.launcher_instance.click_launcher_icon(char_icon, move_mouse_after=False)
+
+ # Have to sleep to give the launcher time to hide (what the old behavior was)
+ sleep(5)
+
+ self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True)))
+
def test_new_icon_has_the_shortcut(self):
"""New icons should have an associated shortcut"""
if self.launcher.model.num_bamf_launcher_icons() >= 10:
diff --git a/tests/autopilot/unity/tests/test_dash.py b/tests/autopilot/unity/tests/test_dash.py
index 18190cb16..ab4c5b489 100644
--- a/tests/autopilot/unity/tests/test_dash.py
+++ b/tests/autopilot/unity/tests/test_dash.py
@@ -8,11 +8,10 @@
from __future__ import absolute_import
-from time import sleep
-
+from autopilot.emulators.clipboard import get_clipboard_contents
from autopilot.matchers import Eventually
-from gtk import Clipboard
-from testtools.matchers import Equals, NotEquals
+from testtools.matchers import Equals, NotEquals, GreaterThan
+from time import sleep
from unity.tests import UnityTestCase
@@ -51,6 +50,11 @@ class DashRevealTests(DashTestCase):
self.dash.reveal_file_lens()
self.assertThat(self.dash.active_lens, Eventually(Equals('files.lens')))
+ def test_video_lens_shortcut(self):
+ """Video lens must reveal when super+v is pressed."""
+ self.dash.reveal_video_lens()
+ self.assertThat(self.dash.active_lens, Eventually(Equals('video.lens')))
+
def test_command_lens_shortcut(self):
"""Run Command lens must reveat on alt+F2."""
self.dash.reveal_command_lens()
@@ -180,7 +184,7 @@ class DashKeyNavTests(DashTestCase):
current_focused_icon = lensbar.focused_lens_icon
- self.keyboard.press_and_release("Right");
+ self.keyboard.press_and_release("Right")
self.assertThat(lensbar.focused_lens_icon, Eventually(NotEquals(current_focused_icon)))
self.keyboard.press_and_release("Left")
@@ -192,17 +196,35 @@ class DashKeyNavTests(DashTestCase):
for i in range(self.dash.get_num_rows()):
self.keyboard.press_and_release("Down")
- self.keyboard.press_and_release("Right");
+ self.keyboard.press_and_release("Right")
lensbar = self.dash.view.get_lensbar()
focused_icon = lensbar.focused_lens_icon
- self.keyboard.press_and_release("Enter");
+ self.keyboard.press_and_release("Enter")
self.assertThat(lensbar.active_lens, Eventually(Equals(focused_icon)))
# lensbar should lose focus after activation.
- # TODO this should be a different test to make sure focus
- # returns to the correct place.
self.assertThat(lensbar.focused_lens_icon, Eventually(Equals("")))
+
+ def test_focus_returns_to_searchbar(self):
+ """This test makes sure that the focus is returned to the searchbar of the newly
+ activated lens."""
+ self.dash.ensure_visible()
+
+ for i in range(self.dash.get_num_rows()):
+ self.keyboard.press_and_release("Down")
+ self.keyboard.press_and_release("Right")
+ lensbar = self.dash.view.get_lensbar()
+ focused_icon = lensbar.focused_lens_icon
+ self.keyboard.press_and_release("Enter")
+
+ self.assertThat(lensbar.active_lens, Eventually(Equals(focused_icon)))
+ self.assertThat(lensbar.focused_lens_icon, Eventually(Equals("")))
+
+ # Now we make sure if the newly activated lens searchbar have the focus.
+ self.keyboard.type("HasFocus")
+
+ self.assertThat(self.dash.search_string, Eventually(Equals("HasFocus")))
def test_category_header_keynav(self):
""" Tests that a category header gets focus when 'down' is pressed after the
@@ -280,6 +302,34 @@ class DashKeyNavTests(DashTestCase):
category = lens.get_focused_category()
self.assertIsNot(category, None)
+ def test_bottom_up_keynav_with_filter_bar(self):
+ """This test makes sure that bottom-up key navigation works well
+ in the dash filter bar.
+ """
+ self.dash.reveal_application_lens()
+ lens = self.dash.get_current_lens()
+
+ filter_bar = lens.get_filterbar()
+ filter_bar.ensure_expanded()
+
+ # Tab to fist filter expander
+ self.keyboard.press_and_release('Tab')
+ self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(NotEquals(None)))
+ old_focused_filter = filter_bar.get_focused_filter()
+ old_focused_filter.ensure_expanded()
+
+ # Tab to the next filter expander
+ self.keyboard.press_and_release('Tab')
+ self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(NotEquals(None)))
+ new_focused_filter = filter_bar.get_focused_filter()
+ self.assertNotEqual(old_focused_filter, new_focused_filter)
+ new_focused_filter.ensure_expanded()
+
+ # Move the focus up.
+ self.keyboard.press_and_release("Up")
+ self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(Equals(None)))
+ self.assertThat(old_focused_filter.content_has_focus, Eventually(Equals(True)))
+
class DashClipboardTests(DashTestCase):
"""Test the Unity clipboard"""
@@ -305,8 +355,7 @@ class DashClipboardTests(DashTestCase):
self.keyboard.press_and_release("Ctrl+a")
self.keyboard.press_and_release("Ctrl+c")
- cb = Clipboard(selection="CLIPBOARD")
- self.assertThat(self.dash.search_string, Eventually(Equals(cb.wait_for_text())))
+ self.assertThat(get_clipboard_contents, Eventually(Equals("Copy")))
def test_ctrl_x(self):
""" This test if ctrl+x deletes all text and copys it """
@@ -319,8 +368,7 @@ class DashClipboardTests(DashTestCase):
self.keyboard.press_and_release("Ctrl+x")
self.assertThat(self.dash.search_string, Eventually(Equals("")))
- cb = Clipboard(selection="CLIPBOARD")
- self.assertEqual(cb.wait_for_text(), u'Cut')
+ self.assertThat(get_clipboard_contents, Eventually(Equals('Cut')))
def test_ctrl_c_v(self):
""" This test if ctrl+c and ctrl+v copies and pastes text"""
@@ -349,6 +397,23 @@ class DashClipboardTests(DashTestCase):
self.keyboard.press_and_release("Ctrl+v")
self.assertThat(self.dash.search_string, Eventually(Equals('CutPasteCutPaste')))
+
+ def test_middle_click_paste(self):
+ """Tests if Middle mouse button pastes into searchbar"""
+
+ self.start_app_window("Calculator", locale='C')
+
+ self.keyboard.type("ThirdButtonPaste")
+ self.keyboard.press_and_release("Ctrl+a")
+
+ self.dash.ensure_visible()
+
+ self.mouse.move(self.dash.searchbar.x + self.dash.searchbar.width / 2,
+ self.dash.searchbar.y + self.dash.searchbar.height / 2)
+
+ self.mouse.click(button=2)
+
+ self.assertThat(self.dash.search_string, Eventually(Equals('ThirdButtonPaste')))
class DashKeyboardFocusTests(DashTestCase):
@@ -497,8 +562,8 @@ class DashBorderTests(DashTestCase):
if (self.dash.view.form_factor != "desktop"):
self.skip("Not in desktop form-factor.")
- x = self.dash.view.x + self.dash.view.width + self.dash.view.right_border_width / 2;
- y = self.dash.view.y + self.dash.view.height / 2;
+ x = self.dash.view.x + self.dash.view.width + self.dash.view.right_border_width / 2
+ y = self.dash.view.y + self.dash.view.height / 2
self.mouse.move(x, y)
self.mouse.click()
@@ -512,8 +577,8 @@ class DashBorderTests(DashTestCase):
if (self.dash.view.form_factor != "desktop"):
self.skip("Not in desktop form-factor.")
- x = self.dash.view.x + self.dash.view.width / 2;
- y = self.dash.view.y + self.dash.view.height + self.dash.view.bottom_border_height / 2;
+ x = self.dash.view.x + self.dash.view.width / 2
+ y = self.dash.view.y + self.dash.view.height + self.dash.view.bottom_border_height / 2
self.mouse.move(x, y)
self.mouse.click()
@@ -543,3 +608,210 @@ class CategoryHeaderTests(DashTestCase):
self.mouse.click()
self.assertThat(category.is_expanded, Eventually(Equals(is_expanded)))
+
+class PreviewAppLensInvocationTests(DashTestCase):
+ """Tests that application lens previews can be opened and closed
+ """
+ def assertSearchText(self, text):
+ self.assertThat(self.dash.search_string, Eventually(Equals(text)))
+
+ def test_open_preview_close_preview(self):
+ """Right clicking on any result shall open a preview,
+ escaping shall close the preview
+ """
+ lens = self.dash.reveal_application_lens()
+ self.addCleanup(self.dash.ensure_hidden)
+
+ category = lens.get_category_by_name("Installed")
+ results = category.get_results()
+ # wait for a result
+ refresh_fn = lambda: len(results)
+ self.assertThat(refresh_fn, Eventually(GreaterThan(0)))
+
+ result = results[0]
+ # result.preview handles finding xy co-ords and right mouse-click
+ result.preview()
+ # revealing a preview may be very slow, not sure if Eventually handles that nicely
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(True)))
+
+ self.keyboard.press_and_release("Escape")
+
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(False)))
+
+ def test_preview_refocus_close(self):
+ """This tests that if the mouse is clicked on a preview element (Cover art for example),
+ the keyboard shortcut for closing ('Escape') still works correctly.
+ """
+ lens = self.dash.reveal_application_lens()
+ self.addCleanup(self.dash.ensure_hidden)
+
+ category = lens.get_category_by_name("Installed")
+ results = category.get_results()
+ # wait for a result
+ refresh_fn = lambda: len(results)
+ self.assertThat(refresh_fn, Eventually(GreaterThan(0)))
+
+ result = results[0]
+ # result.preview handles finding xy co-ords and right mouse-click
+ result.preview()
+ # revealing a preview may be very slow, not sure if Eventually handles that nicely
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(True)))
+
+ preview_container = self.dash.view.get_preview_container()
+ # wait for settle.
+ self.assertThat(preview_container.animating, Eventually(Equals(False)))
+ cover_art = preview_container.current_preview.cover_art
+
+ # click the cover-art (this will set focus)
+ tx = cover_art.x + (cover_art.width / 2)
+ ty = cover_art.y + (cover_art.height / 2)
+ self.mouse.move(tx, ty)
+ self.mouse.click()
+
+ self.keyboard.press_and_release("Escape")
+
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(False)))
+
+
+class PreviewFileLensInvocationTests(DashTestCase):
+ """Tests that file lens previews can be opened and closed
+ """
+ def assertSearchText(self, text):
+ self.assertThat(self.dash.search_string, Eventually(Equals(text)))
+
+ def test_open_preview_close_preview(self):
+ """Right clicking on any result shall open a preview,
+ escaping shall close the preview
+ """
+ lens = self.dash.reveal_file_lens()
+ self.addCleanup(self.dash.ensure_hidden)
+
+ category = lens.get_category_by_name("Folders")
+ results = category.get_results()
+ # wait for a result
+ refresh_fn = lambda: len(results)
+ self.assertThat(refresh_fn, Eventually(GreaterThan(0)))
+
+ result = results[0]
+ # result.preview handles finding xy co-ords and right mouse-click
+ result.preview()
+ # revealing a preview may be very slow, not sure if Eventually handles that nicely
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(True)))
+
+ self.keyboard.press_and_release("Escape")
+
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(False)))
+
+
+class PreviewNavigateTests(DashTestCase):
+ """Tests that mouse navigation works with previews."""
+
+ def setUp(self):
+ super(PreviewNavigateTests, self).setUp()
+
+ self.dash.reveal_application_lens()
+ self.addCleanup(self.dash.ensure_hidden)
+
+ lens = self.dash.get_current_lens()
+
+ results_category = lens.get_category_by_name("Installed")
+ results = results_category.get_results()
+ # wait for results (we need 4 results to perorm the multi-navigation tests)
+ refresh_fn = lambda: len(results)
+ self.assertThat(refresh_fn, Eventually(GreaterThan(4)))
+
+ result = results[2] # 2 so we can navigate left
+ result.preview()
+ self.assertThat(self.dash.view.preview_displaying, Eventually(Equals(True)))
+
+ self.preview_container = self.dash.view.get_preview_container()
+
+ def test_navigate_left(self):
+ """Tests that left navigation works with previews."""
+
+ # wait until preview has finished animating
+ self.assertThat(self.preview_container.animating, Eventually(Equals(False)))
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True)))
+
+ old_navigation_complete_count = self.preview_container.navigation_complete_count
+ old_relative_nav_index = self.preview_container.relative_nav_index
+
+ self.preview_container.navigate_left(1)
+
+ self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+1)))
+ self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index-1)))
+
+ # should be one more on the left
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True)))
+ # if we've navigated left, there should be at least one preview available on right.
+ self.assertThat(self.preview_container.navigate_right_enabled, Eventually(Equals(True)))
+
+ # Test close preview after navigate
+ self.keyboard.press_and_release("Escape")
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(False)))
+
+ def test_navigate_left_multi(self):
+ """Tests that multiple left navigation works with previews."""
+
+ # wait until preview has finished animating
+ self.assertThat(self.preview_container.animating, Eventually(Equals(False)))
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True)))
+
+ old_navigation_complete_count = self.preview_container.navigation_complete_count
+ old_relative_nav_index = self.preview_container.relative_nav_index
+
+ self.preview_container.navigate_left(2)
+
+ self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+2)))
+ self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index-2)))
+
+ # shouldnt be any previews on left.
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(False)))
+ # if we've navigated left, there should be at least one preview available on right.
+ self.assertThat(self.preview_container.navigate_right_enabled, Eventually(Equals(True)))
+
+
+ def test_navigate_right(self):
+ """Tests that right navigation works with previews."""
+
+ # wait until preview has finished animating
+ self.assertThat(self.preview_container.animating, Eventually(Equals(False)))
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True)))
+
+ old_navigation_complete_count = self.preview_container.navigation_complete_count
+ old_relative_nav_index = self.preview_container.relative_nav_index
+
+ self.preview_container.navigate_right(1)
+
+ self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+1)))
+ self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index+1)))
+
+ # should be at least one more on the left
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True)))
+ # if we've navigated right, there should be at least one preview available on left.
+ self.assertThat(self.preview_container.navigate_right_enabled, Eventually(Equals(True)))
+
+ # Test close preview after navigate
+ self.keyboard.press_and_release("Escape")
+ self.assertThat(self.dash.preview_displaying, Eventually(Equals(False)))
+
+ def test_navigate_right_multi(self):
+ """Tests that multiple right navigation works with previews."""
+
+ # wait until preview has finished animating
+ self.assertThat(self.preview_container.animating, Eventually(Equals(False)))
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True)))
+
+ old_navigation_complete_count = self.preview_container.navigation_complete_count
+ old_relative_nav_index = self.preview_container.relative_nav_index
+
+ self.preview_container.navigate_right(2)
+
+ self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+2)))
+ self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index+2)))
+
+ # if we've navigated right, there should be at least one preview available on left.
+ self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True)))
+
+
+
diff --git a/tests/autopilot/unity/tests/test_hud.py b/tests/autopilot/unity/tests/test_hud.py
index 9411184a0..0fbbf57cf 100644
--- a/tests/autopilot/unity/tests/test_hud.py
+++ b/tests/autopilot/unity/tests/test_hud.py
@@ -247,6 +247,20 @@ class HudBehaviorTests(HudTestsBase):
self.mouse.click()
self.assertThat(self.hud.visible, Eventually(Equals(False)))
+
+ def test_hud_closes_click_after_text_removed(self):
+ """Clicking outside of the hud after a search text has been entered and
+ then removed from the searchbox will make it close."""
+
+ self.hud.ensure_visible()
+ self.keyboard.type("Test")
+ self.keyboard.press_and_release("Escape")
+
+ (x,y,w,h) = self.hud.view.geometry
+ self.mouse.move(w/2, h+50)
+ self.mouse.click()
+
+ self.assertThat(self.hud.visible, Eventually(Equals(False)))
def test_alt_f4_close_hud(self):
"""Hud must close on alt+F4."""
@@ -262,7 +276,64 @@ class HudBehaviorTests(HudTestsBase):
self.hud.ensure_visible()
self.keyboard.press_and_release("Alt+F4")
self.assertThat(self.hud.visible, Eventually(Equals(False)))
+
+ def test_app_activate_on_enter(self):
+ """Hud must close after activating a search item with Enter."""
+ self.hud.ensure_visible()
+
+ self.keyboard.type("Device > System Settings")
+ self.assertThat(self.hud.search_string, Eventually(Equals("Device > System Settings")))
+
+ self.keyboard.press_and_release("Enter")
+
+ app_found = self.bamf.wait_until_application_is_running("gnome-control-center.desktop", 5)
+ self.assertTrue(app_found)
+ self.addCleanup(self.close_all_app, "System Settings")
+
+ self.assertThat(self.hud.visible, Eventually(Equals(False)))
+
+ def test_hud_closes_on_escape(self):
+ """Hud must close on escape after searchbox is cleared"""
+ self.hud.ensure_visible()
+
+ self.keyboard.type("ThisText")
+ self.keyboard.press_and_release("Escape")
+ self.keyboard.press_and_release("Escape")
+
+ self.assertThat(self.hud.visible, Eventually(Equals(False)))
+
+ def test_hud_closes_on_escape_shrunk(self):
+ """Hud must close when escape key is pressed"""
+ self.hud.ensure_visible()
+ self.keyboard.press_and_release("Escape")
+
+ self.assertThat(self.hud.visible, Eventually(Equals(False)))
+ def test_alt_arrow_keys_not_eaten(self):
+ """Tests that Alt+ArrowKey events are correctly passed to the
+ active window when Unity is not responding to them."""
+
+ self.start_app_window("Terminal")
+
+ #There's no easy way to read text from terminal, writing input
+ #to a text file and then reading from there works.
+ self.keyboard.type('echo "')
+
+ #Terminal is receiving input with Alt+Arrowkeys
+ self.keyboard.press("Alt")
+ self.keyboard.press_and_release("Up")
+ self.keyboard.press_and_release("Down")
+ self.keyboard.press_and_release("Right")
+ self.keyboard.press_and_release("Left")
+ self.keyboard.release("Alt")
+
+ self.keyboard.type('" > /tmp/ap_test_alt_keys')
+ self.addCleanup(remove, '/tmp/ap_test_alt_keys')
+ self.keyboard.press_and_release("Enter")
+
+ file_contents = open('/tmp/ap_test_alt_keys', 'r').read().strip()
+
+ self.assertThat(file_contents, Equals('ABCD'))
class HudLauncherInteractionsTests(HudTestsBase):
@@ -358,9 +429,9 @@ class HudLockedLauncherInteractionsTests(HudTestsBase):
for icon in self.launcher.model.get_launcher_icons_for_monitor(self.hud_monitor):
if isinstance(icon, HudLauncherIcon):
- self.assertFalse(icon.desaturated)
+ self.assertThat(icon.desaturated, Eventually(Equals(False)))
else:
- self.assertTrue(icon.desaturated)
+ self.assertThat(icon.desaturated, Eventually(Equals(True)))
def test_hud_launcher_icon_click_hides_hud(self):
"""Clicking the Hud Icon should hide the HUD"""
diff --git a/tests/autopilot/unity/tests/test_ibus.py b/tests/autopilot/unity/tests/test_ibus.py
index 35480b1cf..b64cc291e 100644
--- a/tests/autopilot/unity/tests/test_ibus.py
+++ b/tests/autopilot/unity/tests/test_ibus.py
@@ -18,6 +18,8 @@ from autopilot.emulators.ibus import (
from autopilot.matchers import Eventually
from autopilot.testcase import multiply_scenarios
from testtools.matchers import Equals, NotEquals
+from unity.emulators.dash import Dash
+from unity.emulators.hud import Hud
from unity.tests import UnityTestCase
@@ -27,9 +29,29 @@ class IBusTests(UnityTestCase):
def setUp(self):
super(IBusTests, self).setUp()
+ self.set_correct_ibus_trigger_keys()
- def tearDown(self):
- super(IBusTests, self).tearDown()
+ def set_correct_ibus_trigger_keys(self):
+ """Set the correct keys to trigger IBus.
+
+ This method configures the ibus trigger keys inside gconf, and also sets
+ self.activate_binding and self.activate_release_binding.
+
+ This method adds a cleanUp to reset the old keys once the test is done.
+
+ """
+ # get the existing keys:
+ trigger_hotkey_path = '/desktop/ibus/general/hotkey/trigger'
+ old_keys = self.get_gconf_option(trigger_hotkey_path)
+
+ self.activate_binding = 'Control+space'
+ activate_release_binding_option = 'Alt+Release+Control_L'
+ new_keys = [self.activate_binding, activate_release_binding_option]
+
+ if new_keys != old_keys:
+ self.set_gconf_option(trigger_hotkey_path, new_keys)
+ self.addCleanup(self.set_gconf_option, trigger_hotkey_path, old_keys)
+ self.activate_release_binding = 'Alt+Control_L'
@classmethod
def setUpClass(cls):
@@ -41,6 +63,10 @@ class IBusTests(UnityTestCase):
set_active_engines(cls._old_engines)
def activate_input_engine_or_skip(self, engine_name):
+ """Activate the input engine 'engine_name', or skip the test if the
+ engine name is not avaialble (probably because it's not been installed).
+
+ """
available_engines = get_available_input_engines()
if engine_name in available_engines:
if get_active_input_engines() != [engine_name]:
@@ -49,92 +75,93 @@ class IBusTests(UnityTestCase):
self.skip("This test requires the '%s' engine to be installed." % (engine_name))
def activate_ibus(self, widget):
- """Activate IBus, and wait till it's actived on 'widget'"""
+ """Activate IBus, and wait till it's actived on 'widget'."""
self.assertThat(widget.im_active, Equals(False))
- self.keyboard.press_and_release('Ctrl+Space', 0.05)
+ self.keyboard.press_and_release(self.activate_binding)
self.assertThat(widget.im_active, Eventually(Equals(True)))
def deactivate_ibus(self, widget):
- """Deactivate ibus, and wait till it's inactive on 'widget'"""
+ """Deactivate ibus, and wait till it's inactive on 'widget'."""
self.assertThat(widget.im_active, Equals(True))
- self.keyboard.press_and_release('Ctrl+Space', 0.05)
+ self.keyboard.press_and_release(self.activate_binding)
self.assertThat(widget.im_active, Eventually(Equals(False)))
- def do_dash_test_with_engine(self):
- self.dash.ensure_visible()
- self.addCleanup(self.dash.ensure_hidden)
- self.activate_ibus(self.dash.searchbar)
- self.keyboard.type(self.input)
- commit_key = getattr(self, 'commit_key', None)
- if commit_key:
- self.keyboard.press_and_release(commit_key)
- self.deactivate_ibus(self.dash.searchbar)
- self.assertThat(self.dash.search_string, Eventually(Equals(self.result)))
- def do_hud_test_with_engine(self):
- self.hud.ensure_visible()
- self.addCleanup(self.hud.ensure_hidden)
- self.activate_ibus(self.hud.searchbar)
+class IBusWidgetScenariodTests(IBusTests):
+ """A class that includes scenarios for the hud and dash widgets."""
+
+ scenarios = [
+ ('dash', {'widget': Dash()}),
+ ('hud', {'widget': Hud()})
+ ]
+
+ def do_ibus_test(self):
+ """Do the basic IBus test on self.widget using self.input and self.result."""
+ self.widget.ensure_visible()
+ self.addCleanup(self.widget.ensure_hidden)
+ self.activate_ibus(self.widget.searchbar)
self.keyboard.type(self.input)
commit_key = getattr(self, 'commit_key', None)
if commit_key:
self.keyboard.press_and_release(commit_key)
- self.deactivate_ibus(self.hud.searchbar)
- self.assertThat(self.hud.search_string, Eventually(Equals(self.result)))
+ self.deactivate_ibus(self.widget.searchbar)
+ self.assertThat(self.widget.search_string, Eventually(Equals(self.result)))
+
-class IBusTestsPinyin(IBusTests):
+class IBusTestsPinyin(IBusWidgetScenariodTests):
"""Tests for the Pinyin(Chinese) input engine."""
engine_name = "pinyin"
- scenarios = [
- ('basic', {'input': 'abc1', 'result': u'\u963f\u5e03\u4ece'}),
- ('photo', {'input': 'zhaopian ', 'result': u'\u7167\u7247'}),
- ('internet', {'input': 'hulianwang ', 'result': u'\u4e92\u8054\u7f51'}),
- ('disk', {'input': 'cipan ', 'result': u'\u78c1\u76d8'}),
- ('disk_management', {'input': 'cipan guanli ', 'result': u'\u78c1\u76d8\u7ba1\u7406'}),
- ]
+ scenarios = multiply_scenarios(
+ IBusWidgetScenariodTests.scenarios,
+ [
+ ('basic', {'input': 'abc1', 'result': u'\u963f\u5e03\u4ece'}),
+ ('photo', {'input': 'zhaopian ', 'result': u'\u7167\u7247'}),
+ ('internet', {'input': 'hulianwang ', 'result': u'\u4e92\u8054\u7f51'}),
+ ('disk', {'input': 'cipan ', 'result': u'\u78c1\u76d8'}),
+ ('disk_management', {'input': 'cipan guanli ', 'result': u'\u78c1\u76d8\u7ba1\u7406'}),
+ ]
+ )
def setUp(self):
super(IBusTestsPinyin, self).setUp()
self.activate_input_engine_or_skip(self.engine_name)
- def test_simple_input_dash(self):
- self.do_dash_test_with_engine()
-
- def test_simple_input_hud(self):
- self.do_hud_test_with_engine()
+ def test_pinyin(self):
+ self.do_ibus_test()
-class IBusTestsHangul(IBusTests):
+class IBusTestsHangul(IBusWidgetScenariodTests):
"""Tests for the Hangul(Korean) input engine."""
engine_name = "hangul"
- scenarios = [
- ('transmission', {'input': 'xmfostmaltus ', 'result': u'\ud2b8\ub79c\uc2a4\ubbf8\uc158 '}),
- ('social', {'input': 'httuf ', 'result': u'\uc18c\uc15c '}),
- ('document', {'input': 'anstj ', 'result': u'\ubb38\uc11c '}),
- ]
+ scenarios = multiply_scenarios(
+ IBusWidgetScenariodTests.scenarios,
+ [
+ ('transmission', {'input': 'xmfostmaltus ', 'result': u'\ud2b8\ub79c\uc2a4\ubbf8\uc158 '}),
+ ('social', {'input': 'httuf ', 'result': u'\uc18c\uc15c '}),
+ ('document', {'input': 'anstj ', 'result': u'\ubb38\uc11c '}),
+ ]
+ )
def setUp(self):
super(IBusTestsHangul, self).setUp()
self.activate_input_engine_or_skip(self.engine_name)
- def test_simple_input_dash(self):
- self.do_dash_test_with_engine()
-
- def test_simple_input_hud(self):
- self.do_hud_test_with_engine()
+ def test_hangul(self):
+ self.do_ibus_test()
-class IBusTestsAnthy(IBusTests):
+class IBusTestsAnthy(IBusWidgetScenariodTests):
"""Tests for the Anthy(Japanese) input engine."""
engine_name = "anthy"
scenarios = multiply_scenarios(
+ IBusWidgetScenariodTests.scenarios,
[
('system', {'input': 'shisutemu ', 'result': u'\u30b7\u30b9\u30c6\u30e0'}),
('game', {'input': 'ge-mu ', 'result': u'\u30b2\u30fc\u30e0'}),
@@ -150,11 +177,8 @@ class IBusTestsAnthy(IBusTests):
super(IBusTestsAnthy, self).setUp()
self.activate_input_engine_or_skip(self.engine_name)
- def test_simple_input_dash(self):
- self.do_dash_test_with_engine()
-
- def test_simple_input_hud(self):
- self.do_hud_test_with_engine()
+ def test_anthy(self):
+ self.do_ibus_test()
class IBusTestsPinyinIgnore(IBusTests):
@@ -194,6 +218,7 @@ class IBusTestsPinyinIgnore(IBusTests):
class IBusTestsAnthyIgnore(IBusTests):
"""Tests for ignoring key events while the Anthy input engine is active."""
+ scenarios = None
engine_name = "anthy"
def setUp(self):
@@ -224,3 +249,92 @@ class IBusTestsAnthyIgnore(IBusTests):
self.deactivate_ibus(self.hud.searchbar)
self.assertEqual(old_selected, new_selected)
+
+
+class IBusActivationTests(IBusTests):
+
+ """This class contains tests that make sure each IBus engine can activate
+ and deactivate correctly with various keystrokes.
+
+ """
+
+ scenarios = multiply_scenarios(
+ IBusWidgetScenariodTests.scenarios,
+ [ (e, {'engine_name': e}) for e in ('pinyin','anthy','hangul') ]
+ )
+
+ def setUp(self):
+ super(IBusActivationTests, self).setUp()
+ self.activate_input_engine_or_skip(self.engine_name)
+
+ def activate_ibus_on_release(self, widget):
+ """Activate IBus when keys have been released, and wait till it's actived
+ on 'widget'.
+
+ """
+ self.assertThat(widget.im_active, Equals(False))
+ self.keyboard.press_and_release(self.activate_release_binding)
+ self.assertThat(widget.im_active, Eventually(Equals(True)))
+
+ def deactivate_ibus_on_release(self, widget):
+ """Activate IBus when keys have been released, and wait till it's actived
+ on 'widget'.
+
+ """
+ self.assertThat(widget.im_active, Equals(True))
+ self.keyboard.press_and_release(self.activate_release_binding)
+ self.assertThat(widget.im_active, Eventually(Equals(False)))
+
+ def test_activate(self):
+ """Tests the ibus activation using the "key-down" keybinding."""
+ self.widget.ensure_visible()
+ self.addCleanup(self.widget.ensure_hidden)
+ self.assertThat(self.widget.searchbar.im_active, Equals(False))
+
+ self.keyboard.press(self.activate_binding)
+ self.addCleanup(self.keyboard.release, self.activate_binding)
+
+ self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(True)))
+ self.keyboard.release(self.activate_binding)
+
+ self.deactivate_ibus(self.widget.searchbar)
+
+ def test_deactivate(self):
+ """Tests the ibus deactivation using the "key-down" keybinding"""
+ self.widget.ensure_visible()
+ self.addCleanup(self.widget.ensure_hidden)
+ self.activate_ibus(self.widget.searchbar)
+
+ self.assertThat(self.widget.searchbar.im_active, Equals(True))
+ self.keyboard.press(self.activate_binding)
+ self.addCleanup(self.keyboard.release, self.activate_binding)
+ self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False)))
+ self.keyboard.release(self.activate_binding)
+ self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False)))
+
+ def test_activate_on_release(self):
+ """Tests the ibus activation using "key-up" keybinding"""
+ self.widget.ensure_visible()
+ self.addCleanup(self.widget.ensure_hidden)
+
+ self.assertThat(self.widget.searchbar.im_active, Equals(False))
+ self.keyboard.press(self.activate_release_binding)
+ self.addCleanup(self.keyboard.release, self.activate_release_binding)
+ self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False)))
+ self.keyboard.release(self.activate_release_binding)
+ self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(True)))
+
+ self.deactivate_ibus_on_release(self.widget.searchbar)
+
+ def test_deactivate_on_release(self):
+ """Tests the ibus deactivation using "key-up" keybinding"""
+ self.widget.ensure_visible()
+ self.addCleanup(self.widget.ensure_hidden)
+ self.activate_ibus_on_release(self.widget.searchbar)
+
+ self.assertThat(self.widget.searchbar.im_active, Equals(True))
+ self.keyboard.press(self.activate_release_binding)
+ self.addCleanup(self.keyboard.release, self.activate_release_binding)
+ self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(True)))
+ self.keyboard.release(self.activate_release_binding)
+ self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False)))
diff --git a/tests/autopilot/unity/tests/test_panel.py b/tests/autopilot/unity/tests/test_panel.py
index abbb77641..1d31f81be 100644
--- a/tests/autopilot/unity/tests/test_panel.py
+++ b/tests/autopilot/unity/tests/test_panel.py
@@ -54,9 +54,8 @@ class PanelTestsBase(UnityTestCase):
"""
self.close_all_app(app_name)
- app = self.start_app(app_name, locale="C")
-
- [app_win] = app.get_windows()
+ app_win = self.start_app_window(app_name, locale="C")
+ app = app_win.application
app_win.set_focus()
self.assertTrue(app.is_active)
@@ -113,7 +112,7 @@ class PanelTestsBase(UnityTestCase):
self.addCleanup(self.keyboard.press_and_release, "Escape")
self.assertThat(indicator.active, Eventually(Equals(True)))
- def assert_win_buttons_in_overlay_mode(self, overlay_mode):
+ def assertWinButtonsInOverlayMode(self, overlay_mode):
"""Assert that there are three panel window buttons and all of them are
in the specified overlay mode.
@@ -126,7 +125,7 @@ class PanelTestsBase(UnityTestCase):
for button in buttons:
self.assertThat(button.overlay_mode, Eventually(Equals(overlay_mode)))
- def assert_no_window_open_with_xid(self, x_id):
+ def assertNoWindowOpenWithXid(self, x_id):
"""Assert that Bamf doesn't know of any open windows with the given xid."""
# We can't check text_win.closed since we've just destroyed the window.
# Instead we make sure no window with it's x_id exists.
@@ -202,16 +201,24 @@ class PanelTitleTests(PanelTestsBase):
old_title = text_win.title
text_win.set_focus()
- self.keyboard.type("Unity rocks!")
- self.keyboard.press_and_release("Ctrl+S")
- sleep(.25)
- self.keyboard.type("/tmp/autopilot-awesome-test.txt")
- self.keyboard.press_and_release("Return")
- self.addCleanup(os.remove, "/tmp/autopilot-awesome-test.txt")
+ self.keyboard.press_and_release("Ctrl+n")
self.assertThat(lambda: text_win.title, Eventually(NotEquals(old_title)))
self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
+ def test_panel_title_doesnt_change_with_switcher(self):
+ """Switching between apps must not change the Panels title."""
+ calc_win = self.open_new_application_window("Calculator")
+ text_win = self.open_new_application_window("Text Editor")
+ current_title = self.panel.title
+
+ self.switcher.initiate()
+ self.addCleanup(self.switcher.terminate)
+ self.switcher.next_icon()
+
+ self.assertThat(self.panel.title,
+ Eventually(Equals(current_title)))
+
class PanelWindowButtonsTests(PanelTestsBase):
@@ -225,7 +232,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
def test_window_buttons_dont_show_on_empty_desktop(self):
"""Tests that the window buttons are not shown on clean desktop."""
- # THis initially used Show Desktop mode, but it's very buggy from within
+ # This initially used Show Desktop mode, but it's very buggy from within
# autopilot. We assume that workspace 2 is empty (which is safe for the
# jenkins runs at least.)
initial_workspace = self.workspace.current_workspace
@@ -272,7 +279,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.panel.move_mouse_over_window_buttons()
self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
- self.assert_win_buttons_in_overlay_mode(False)
+ self.assertWinButtonsInOverlayMode(False)
def test_window_buttons_show_with_dash(self):
"""Window buttons must be shown when the dash is open."""
@@ -280,7 +287,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.addCleanup(self.dash.ensure_hidden)
self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
- self.assert_win_buttons_in_overlay_mode(True)
+ self.assertWinButtonsInOverlayMode(True)
def test_window_buttons_show_with_hud(self):
"""Window buttons must be shown when the HUD is open."""
@@ -288,7 +295,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.addCleanup(self.hud.ensure_hidden)
self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
- self.assert_win_buttons_in_overlay_mode(True)
+ self.assertWinButtonsInOverlayMode(True)
def test_window_buttons_update_visual_state(self):
"""Window button must update its state in response to mouse events."""
@@ -310,19 +317,9 @@ class PanelWindowButtonsTests(PanelTestsBase):
their area.
"""
self.hud.ensure_visible()
- button = self.panel.window_buttons.close
-
- # FIXME: THere's a bug in unity that prevents us from doing:
- # self.addCleanup(self.hud.ensure_hidden)
- # SO we do this instead. The bug is:
- #
- # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
- #
- # Once that's fixed the next two lines can be removed, and the one above
- # added instead.
- self.addCleanup(self.assertThat, self.hud.visible, Eventually(Equals(False)))
- self.addCleanup(button.mouse_click)
+ self.addCleanup(self.hud.ensure_hidden)
+ button = self.panel.window_buttons.close
button.mouse_move_to()
self.mouse.press()
self.assertThat(button.visual_state, Eventually(Equals("pressed")))
@@ -340,7 +337,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
win_xid = text_win.x_id
self.panel.window_buttons.close.mouse_click()
- self.assert_no_window_open_with_xid(win_xid)
+ self.assertNoWindowOpenWithXid(win_xid)
def test_window_buttons_close_follows_fitts_law(self):
"""Tests that the 'Close' button is activated when clicking at 0,0.
@@ -357,7 +354,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.mouse.move(screen_x, screen_y)
self.mouse.click()
- self.assert_no_window_open_with_xid(win_xid)
+ self.assertNoWindowOpenWithXid(win_xid)
def test_window_buttons_minimize_button_works_for_window(self):
"""Tests that the window button 'Minimize' actually minimizes a window."""
@@ -367,7 +364,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.panel.window_buttons.minimize.mouse_click()
- self.assertThat(lambda: text_win.is_hidden, Eventually(Equals(True)))
+ self.assertProperty(text_win, is_hidden=True)
def test_window_buttons_minimize_follows_fitts_law(self):
"""Tests that the 'Minimize' button is conform to Fitts's Law.
@@ -385,7 +382,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.mouse.move(target_x, target_y)
self.mouse.click()
- self.assertThat(lambda: text_win.is_hidden, Eventually(Equals(True)))
+ self.assertProperty(text_win, is_hidden=True)
def test_window_buttons_unmaximize_button_works_for_window(self):
"""Tests that the window button 'Unmaximize' actually unmaximizes a window."""
@@ -415,7 +412,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
sleep(1)
self.mouse.click()
- self.assertThat(lambda: text_win.is_maximized, Eventually(Equals(False)))
+ self.assertProperty(text_win, is_maximized=False)
def test_window_buttons_close_button_works_for_hud(self):
"""Tests that the window 'Close' actually closes the HUD."""
@@ -435,13 +432,8 @@ class PanelWindowButtonsTests(PanelTestsBase):
def test_minimize_button_does_nothing_for_hud(self):
"""Minimize button must not affect the Hud."""
self.hud.ensure_visible()
- # FIXME: When this bug is fixed:
- #
- # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
- #
- # We can replace the following line with:
- # self.addCleanup(self.hud.ensure_hidden)
- self.addCleanup(self.panel.window_buttons.close.mouse_click)
+ self.addCleanup(self.hud.ensure_hidden)
+
self.panel.window_buttons.minimize.mouse_click()
self.assertThat(self.hud.visible, Eventually(Equals(True)))
@@ -456,13 +448,8 @@ class PanelWindowButtonsTests(PanelTestsBase):
def test_maximize_button_does_nothing_for_hud(self):
"""Maximize button must not affect the Hud."""
self.hud.ensure_visible()
- # FIXME: When this bug is fixed:
- #
- # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
- #
- # We can replace the following line with:
- # self.addCleanup(self.hud.ensure_hidden)
- self.addCleanup(self.panel.window_buttons.close.mouse_click)
+ self.addCleanup(self.hud.ensure_hidden)
+
self.panel.window_buttons.maximize.mouse_click()
self.assertThat(self.hud.visible, Eventually(Equals(True)))
@@ -475,13 +462,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
"""
inital_form_factor = self.dash.view.form_factor
self.hud.ensure_visible()
- # FIXME: When this bug is fixed:
- #
- # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
- #
- # We can replace the following line with:
- # self.addCleanup(self.hud.ensure_hidden)
- self.addCleanup(self.panel.window_buttons.close.mouse_click)
+ self.addCleanup(self.hud.ensure_hidden)
self.panel.window_buttons.maximize.mouse_click()
# long sleep here to make sure that any change that might happen will
@@ -595,7 +576,7 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.move_window_to_panel_monitor(target_win, restore_position=False)
self.keybinding("window/maximize")
- self.assertThat(lambda: target_win.is_maximized, Eventually(Equals(True)))
+ self.assertProperty(target_win, is_maximized=True)
self.assertThat(self.panel.window_buttons.close.enabled, Eventually(Equals(True)))
self.assertThat(self.panel.window_buttons.minimize.enabled, Eventually(Equals(False)))
@@ -647,6 +628,16 @@ class PanelWindowButtonsTests(PanelTestsBase):
self.keyboard.type("World")
self.assertThat(self.hud.search_string, Eventually(Equals("HelloWorld")))
+
+ def test_double_click_unmaximize_window(self):
+ """Double clicking the grab area must unmaximize a maximized window."""
+ gedit_win = self.open_new_application_window("Text Editor", maximized=True)
+
+ self.panel.move_mouse_over_grab_area()
+ self.mouse.click()
+ self.mouse.click()
+
+ self.assertThat(self.panel.title, Eventually(Equals(gedit_win.application.name)))
class PanelHoverTests(PanelTestsBase):
@@ -821,7 +812,10 @@ class PanelMenuTests(PanelTestsBase):
self.patch_environment("UBUNTU_MENUPROXY", "")
calc_win = self.open_new_application_window("Calculator")
- self.assertThat(lambda: len(self.panel.menus.get_entries()), Eventually(Equals(0)))
+ self.assertThat(
+ lambda: len(self.panel.menus.get_entries()),
+ Eventually(Equals(0)),
+ "Current panel entries are: %r" % self.panel.menus.get_entries())
self.panel.move_mouse_over_grab_area()
self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name)))
@@ -836,10 +830,10 @@ class PanelMenuTests(PanelTestsBase):
def test_menus_dont_show_if_a_new_application_window_is_opened(self):
"""This tests the menu discovery feature on new window for a know application."""
- self.open_new_application_window("Calculator")
+ self.open_new_application_window("Character Map")
self.sleep_menu_settle_period()
- self.start_app("Calculator")
+ self.start_app("Character Map")
sleep(self.panel.menus.fadein_duration / 1000.0)
# Not using Eventually here since this is time-critical. Need to work
# out a better way to do this.
@@ -906,10 +900,17 @@ class PanelIndicatorEntryTests(PanelTestsBase):
scenarios = _make_monitor_scenarios()
- def test_menu_opens_on_click(self):
- """Tests that clicking on a menu entry, opens a menu."""
+ def open_app_and_get_menu_entry(self):
+ """Open the test app and wait for the menu entry to appear."""
self.open_new_application_window("Calculator")
+ refresh_fn = lambda: len(self.panel.menus.get_entries())
+ self.assertThat(refresh_fn, Eventually(GreaterThan(0)))
menu_entry = self.panel.menus.get_entries()[0]
+ return menu_entry
+
+ def test_menu_opens_on_click(self):
+ """Tests that clicking on a menu entry, opens a menu."""
+ menu_entry = self.open_app_and_get_menu_entry()
self.mouse_open_indicator(menu_entry)
self.assertThat(menu_entry.active, Eventually(Equals(True)))
@@ -918,8 +919,7 @@ class PanelIndicatorEntryTests(PanelTestsBase):
def test_menu_opens_closes_on_click(self):
"""Clicking on an open menu entru must close it again."""
- self.open_new_application_window("Calculator")
- menu_entry = self.panel.menus.get_entries()[0]
+ menu_entry = self.open_app_and_get_menu_entry()
self.mouse_open_indicator(menu_entry)
# This assert is for timing purposes only:
@@ -932,8 +932,7 @@ class PanelIndicatorEntryTests(PanelTestsBase):
def test_menu_closes_on_click_outside(self):
"""Clicking outside an open menu must close it."""
- self.open_new_application_window("Calculator")
- menu_entry = self.panel.menus.get_entries()[0]
+ menu_entry = self.open_app_and_get_menu_entry()
self.mouse_open_indicator(menu_entry)
# This assert is for timing purposes only:
@@ -973,7 +972,7 @@ class PanelKeyNavigationTests(PanelTestsBase):
self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id)))
self.keybinding("panel/open_first_menu")
- self.assertThat(self.panel.get_active_indicator(), Eventually(Equals(None)))
+ self.assertThat(self.panel.get_active_indicator, Eventually(Equals(None)))
def test_panel_menu_accelerators_work(self):
"""Pressing a valid menu accelerator must open the correct menu item."""
@@ -1050,33 +1049,33 @@ class PanelGrabAreaTests(PanelTestsBase):
self.panel.move_mouse_below_the_panel()
self.mouse.release()
- self.assertThat(lambda: text_win.is_maximized, Eventually(Equals(False)))
+ self.assertProperty(text_win, is_maximized=False)
def test_focus_the_maximized_window_works(self):
"""Clicking on the grab area must put a maximized window in focus."""
text_win = self.open_new_application_window("Text Editor", maximized=True)
calc_win = self.open_new_application_window("Calculator")
- self.assertThat(lambda: text_win.is_focused, Eventually(Equals(False)))
- self.assertThat(lambda: calc_win.is_focused, Eventually(Equals(True)))
+ self.assertProperty(text_win, is_focused=False)
+ self.assertProperty(calc_win, is_focused=True)
self.move_mouse_over_grab_area()
self.mouse.click()
- self.assertThat(lambda: text_win.is_focused, Eventually(Equals(True)))
+ self.assertProperty(text_win, is_focused=True)
def test_lower_the_maximized_window_works(self):
"""Middle-clicking on the panel grab area must lower a maximized window."""
calc_win = self.open_new_application_window("Calculator")
text_win = self.open_new_application_window("Text Editor", maximized=True)
- self.assertThat(lambda: text_win.is_focused, Eventually(Equals(True)))
- self.assertThat(lambda: calc_win.is_focused, Eventually(Equals(False)))
+ self.assertProperty(text_win, is_focused=True)
+ self.assertProperty(calc_win, is_focused=False)
self.move_mouse_over_grab_area()
self.mouse.click(2)
- self.assertThat(lambda: calc_win.is_focused, Eventually(Equals(True)))
+ self.assertProperty(calc_win, is_focused=True)
def test_panels_dont_steal_keynav_foucs_from_hud(self):
"""On a mouse click event on the panel you must still be able to type into the Hud."""
diff --git a/tests/autopilot/unity/tests/test_quicklist.py b/tests/autopilot/unity/tests/test_quicklist.py
index d9cfe6647..8aa4a3ad2 100644
--- a/tests/autopilot/unity/tests/test_quicklist.py
+++ b/tests/autopilot/unity/tests/test_quicklist.py
@@ -72,14 +72,14 @@ class QuicklistActionTests(UnityTestCase):
Then we activate the Calculator quicklist item.
Then we actiavte the Mahjongg launcher icon.
"""
- mah_win1 = self.start_app_window("Mahjongg")
+ char_win1 = self.start_app_window("Character Map")
calc_win = self.start_app_window("Calculator")
- mah_win2 = self.start_app_window("Mahjongg")
+ char_win2 = self.start_app_window("Character Map")
- self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+ self.assertVisibleWindowStack([char_win2, calc_win, char_win1])
- mahj_icon = self.launcher.model.get_icon(
- desktop_id=mah_win1.application.desktop_file)
+ char_icon = self.launcher.model.get_icon(
+ desktop_id=char_win1.application.desktop_file)
calc_icon = self.launcher.model.get_icon(
desktop_id=calc_win.application.desktop_file)
@@ -87,29 +87,29 @@ class QuicklistActionTests(UnityTestCase):
calc_ql.get_quicklist_application_item(calc_win.application.name).mouse_click()
self.assertProperty(calc_win, is_focused=True)
- self.assertVisibleWindowStack([calc_win, mah_win2, mah_win1])
+ self.assertVisibleWindowStack([calc_win, char_win2, char_win1])
- mahj_ql = self.open_quicklist_for_icon(mahj_icon)
- mahj_ql.get_quicklist_application_item(mah_win1.application.name).mouse_click()
+ char_ql = self.open_quicklist_for_icon(char_icon)
+ char_ql.get_quicklist_application_item(char_win1.application.name).mouse_click()
- self.assertProperty(mah_win2, is_focused=True)
- self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+ self.assertProperty(char_win2, is_focused=True)
+ self.assertVisibleWindowStack([char_win2, calc_win, char_win1])
def test_quicklist_application_item_initiate_spread(self):
"""This tests shows that when you activate a quicklist application item
when an application window is focused, the spread is initiated.
"""
- calc_win1 = self.start_app_window("Calculator")
- calc_win2 = self.start_app_window("Calculator")
- calc_app = calc_win1.application
+ char_win1 = self.start_app_window("Character Map")
+ char_win2 = self.start_app_window("Character Map")
+ char_app = char_win1.application
- self.assertVisibleWindowStack([calc_win2, calc_win1])
- self.assertProperty(calc_win2, is_focused=True)
+ self.assertVisibleWindowStack([char_win2, char_win1])
+ self.assertProperty(char_win2, is_focused=True)
- calc_icon = self.launcher.model.get_icon(desktop_id=calc_app.desktop_file)
+ char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file)
- calc_ql = self.open_quicklist_for_icon(calc_icon)
- app_item = calc_ql.get_quicklist_application_item(calc_app.name)
+ char_ql = self.open_quicklist_for_icon(char_icon)
+ app_item = char_ql.get_quicklist_application_item(char_app.name)
self.addCleanup(self.keybinding, "spread/cancel")
app_item.mouse_click()
@@ -155,6 +155,44 @@ class QuicklistActionTests(UnityTestCase):
self.addCleanup(self.dash.ensure_hidden)
self.assertThat(self.dash.visible, Eventually(Equals(True)))
+ def test_right_click_opens_quicklist_if_already_open(self):
+ """A right click to another icon in the launcher must
+ close the current open quicklist and open the other
+ icons quicklist.
+ lp:890991
+ """
+
+ calc_win = self.start_app_window("Calculator")
+ mahj_win = self.start_app_window("Mahjongg")
+
+ calc_icon = self.launcher.model.get_icon(
+ desktop_id=calc_win.application.desktop_file)
+ mahj_icon = self.launcher.model.get_icon(
+ desktop_id=mahj_win.application.desktop_file)
+
+ calc_ql = self.open_quicklist_for_icon(calc_icon)
+ self.assertThat(calc_ql.active, Eventually(Equals(True)))
+
+ mahj_ql = self.open_quicklist_for_icon(mahj_icon)
+ self.assertThat(mahj_ql.active, Eventually(Equals(True)))
+ self.assertThat(calc_ql.active, Eventually(Equals(False)))
+
+ def test_right_clicking_same_icon_doesnt_reopen_ql(self):
+ """A right click to the same icon in the launcher must
+ not re-open the quicklist if already open. It must hide.
+ """
+
+ calc_win = self.start_app_window("Calculator")
+
+ calc_icon = self.launcher.model.get_icon(
+ desktop_id=calc_win.application.desktop_file)
+
+ calc_ql = self.open_quicklist_for_icon(calc_icon)
+ self.assertThat(calc_ql.active, Eventually(Equals(True)))
+
+ calc_ql = self.open_quicklist_for_icon(calc_icon)
+ self.assertThat(calc_ql.active, Eventually(Equals(False)))
+
class QuicklistKeyNavigationTests(UnityTestCase):
"""Tests for the quicklist key navigation."""
@@ -343,3 +381,23 @@ class QuicklistKeyNavigationTests(UnityTestCase):
mouse_item = self.quicklist.selectable_items[-2]
mouse_item.mouse_move_to()
self.assertCorrectItemSelected(mouse_item)
+
+ def test_moving_mouse_during_grab_select_correct_menuitem(self):
+ """Test that moving the mouse during grabbing selects the
+ correct menu item. See bug #1027955.
+ """
+ self.open_quicklist_with_mouse()
+ mouse_item = self.quicklist.selectable_items[0]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+
+ # Dragging the mouse horizontally doesn't change the selection
+ self.mouse.press()
+ self.addCleanup(self.mouse.release)
+ self.mouse.move(mouse_item.x + mouse_item.width - 10, mouse_item.y + mouse_item.height / 2)
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
+
+ # Moving the mouse down selects the next item
+ mouse_item = self.quicklist.selectable_items[1]
+ mouse_item.mouse_move_to()
+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
diff --git a/tests/autopilot/unity/tests/test_shortcut_hint.py b/tests/autopilot/unity/tests/test_shortcut_hint.py
index 63b4eaf1e..5af6f883d 100644
--- a/tests/autopilot/unity/tests/test_shortcut_hint.py
+++ b/tests/autopilot/unity/tests/test_shortcut_hint.py
@@ -32,11 +32,11 @@ class BaseShortcutHintTests(UnityTestCase):
def skip_if_monitor_too_small(self):
monitor = self.screen_geo.get_primary_monitor()
- monitor_geo = self.screen_geo.get_monitor_geometry(monitor);
- monitor_w = monitor_geo[2];
- monitor_h = monitor_geo[3];
- launcher_width = self.launcher.get_launcher_for_monitor(monitor).geometry[2];
- panel_height = 24 # TODO get it from panel
+ monitor_geo = self.screen_geo.get_monitor_geometry(monitor)
+ monitor_w = monitor_geo[2]
+ monitor_h = monitor_geo[3]
+ launcher_width = self.launcher.get_launcher_for_monitor(monitor).geometry[2]
+ panel_height = self.panels.get_panel_for_monitor(monitor).geometry[3]
if ((monitor_w - launcher_width) <= self.DEFAULT_WIDTH or
(monitor_h - panel_height) <= self.DEFAULT_HEIGHT):
diff --git a/tests/autopilot/unity/tests/test_showdesktop.py b/tests/autopilot/unity/tests/test_showdesktop.py
index e2f87faed..6efc9d972 100644
--- a/tests/autopilot/unity/tests/test_showdesktop.py
+++ b/tests/autopilot/unity/tests/test_showdesktop.py
@@ -8,11 +8,8 @@
from __future__ import absolute_import
-from autopilot.matchers import Eventually
-from testtools.matchers import NotEquals
from time import sleep
-from unity.emulators.icons import DesktopLauncherIcon
from unity.tests import UnityTestCase
@@ -65,13 +62,13 @@ class ShowDesktopTests(UnityTestCase):
def test_unhide_single_app(self):
"""Un-hide a single app from launcher after hiding all apps."""
- test_windows = self.launch_test_apps()
+ charmap, calc = self.launch_test_apps()
# show desktop, verify all windows are hidden:
self.window_manager.enter_show_desktop()
self.addCleanup(self.window_manager.leave_show_desktop)
- for win in test_windows:
+ for win in (charmap, calc):
self.assertProperty(win, is_valid=True)
self.assertProperty(win, is_hidden=True)
@@ -88,7 +85,7 @@ class ShowDesktopTests(UnityTestCase):
# hide desktop - now all windows should be visible:
self.window_manager.leave_show_desktop()
- for win in test_windows:
+ for win in (charmap, calc):
self.assertProperty(win, is_hidden=False)
def test_showdesktop_switcher(self):
diff --git a/tests/autopilot/unity/tests/test_switcher.py b/tests/autopilot/unity/tests/test_switcher.py
index f3a301959..9e7639b8e 100644
--- a/tests/autopilot/unity/tests/test_switcher.py
+++ b/tests/autopilot/unity/tests/test_switcher.py
@@ -9,6 +9,7 @@
from __future__ import absolute_import
from autopilot.matchers import Eventually
+from autopilot.testcase import multiply_scenarios
import logging
from testtools.matchers import Equals, Contains, Not
from time import sleep
@@ -19,6 +20,22 @@ from unity.tests import UnityTestCase
logger = logging.getLogger(__name__)
class SwitcherTestCase(UnityTestCase):
+
+ scenarios = [
+ ('show_desktop_icon_true', {'show_desktop_option': True}),
+ ('show_desktop_icon_false', {'show_desktop_option': False}),
+ ]
+
+ def setUp(self):
+ super(SwitcherTestCase, self).setUp()
+ self.set_show_desktop(self.show_desktop_option)
+
+ def set_show_desktop(self, state):
+ if type(state) is not bool:
+ raise TypeError("'state' must be boolean, not %r" % type(state))
+ self.set_unity_option("disable_show_desktop", state)
+ self.assertThat(self.switcher.controller.show_desktop_disabled, Eventually(Equals(state)))
+
def set_timeout_setting(self, state):
if type(state) is not bool:
raise TypeError("'state' must be boolean, not %r" % type(state))
@@ -29,9 +46,9 @@ class SwitcherTestCase(UnityTestCase):
"""Start some applications, returning their windows.
If no applications are specified, the following will be started:
- * Character Map
- * Calculator
* Calculator
+ * Character Map
+ * Character Map
Windows are always started in the order that they are specified (which
means the last specified application will *probably* be at the top of the
@@ -40,7 +57,7 @@ class SwitcherTestCase(UnityTestCase):
"""
if len(args) == 0:
- args = ('Character Map', 'Calculator', 'Calculator')
+ args = ('Calculator', 'Character Map', 'Character Map')
windows = []
for app in args:
windows.append(self.start_app_window(app))
@@ -134,6 +151,8 @@ class SwitcherTests(SwitcherTestCase):
open the switcher.
"""
+ self.start_app("Character Map")
+
self.keybinding_hold("switcher/reveal_normal")
self.addCleanup(self.keybinding_release, "switcher/reveal_normal")
self.assertThat(self.switcher.visible, Eventually(Equals(False)))
@@ -144,6 +163,8 @@ class SwitcherTests(SwitcherTestCase):
def test_switcher_cancel(self):
"""Pressing the switcher cancel keystroke must cancel the switcher."""
+ self.start_app("Character Map")
+
self.switcher.initiate()
self.addCleanup(self.switcher.terminate)
@@ -153,6 +174,8 @@ class SwitcherTests(SwitcherTestCase):
def test_lazy_switcher_cancel(self):
"""Must be able to cancel the switcher after a 'lazy' initiation."""
+ self.start_app("Character Map")
+
self.keybinding_hold("switcher/reveal_normal")
self.addCleanup(self.keybinding_release, "switcher/reveal_normal")
self.assertThat(self.switcher.visible, Eventually(Equals(False)))
@@ -208,24 +231,25 @@ class SwitcherWindowsManagementTests(SwitcherTestCase):
Then we close the currently focused window.
"""
- mah_win1, calc_win, mah_win2 = self.start_applications("Mahjongg", "Calculator", "Mahjongg")
- self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+ char_win1, calc_win, char_win2 = self.start_applications("Character Map", "Calculator", "Character Map")
+ self.assertVisibleWindowStack([char_win2, calc_win, char_win1])
self.keybinding("switcher/reveal_normal")
self.assertProperty(calc_win, is_focused=True)
- self.assertVisibleWindowStack([calc_win, mah_win2, mah_win1])
+ self.assertVisibleWindowStack([calc_win, char_win2, char_win1])
self.keybinding("switcher/reveal_normal")
- self.assertProperty(mah_win2, is_focused=True)
- self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
+ self.assertProperty(char_win2, is_focused=True)
+ self.assertVisibleWindowStack([char_win2, calc_win, char_win1])
self.keybinding("window/close")
self.assertProperty(calc_win, is_focused=True)
- self.assertVisibleWindowStack([calc_win, mah_win1])
+ self.assertVisibleWindowStack([calc_win, char_win1])
class SwitcherDetailsTests(SwitcherTestCase):
"""Test the details mode for the switcher."""
+
def setUp(self):
super(SwitcherDetailsTests, self).setUp()
self.set_timeout_setting(True)
@@ -271,10 +295,12 @@ class SwitcherDetailsModeTests(SwitcherTestCase):
"""
- scenarios = [
- ('initiate_with_grave', {'initiate_keycode': '`'}),
- ('initiate_with_down', {'initiate_keycode': 'Down'}),
- ]
+ scenarios = multiply_scenarios(SwitcherTestCase.scenarios,
+ [
+ ('initiate_with_grave', {'initiate_keycode': '`'}),
+ ('initiate_with_down', {'initiate_keycode': 'Down'}),
+ ]
+ )
def test_can_start_details_mode(self):
"""Must be able to switch to details mode using selected scenario keycode.
@@ -308,6 +334,22 @@ class SwitcherDetailsModeTests(SwitcherTestCase):
self.switcher.next_icon()
self.assertThat(self.switcher.selection_index, Eventually(Equals(0)))
+ def test_detail_mode_selects_last_active_window(self):
+ """The active selection in detail mode must be the last focused window.
+ If it was the currently active application type.
+ """
+ char_win1, char_win2 = self.start_applications("Character Map", "Character Map")
+ self.assertVisibleWindowStack([char_win2, char_win1])
+
+ self.switcher.initiate()
+ while self.switcher.current_icon.tooltip_text != char_win2.application.name:
+ self.switcher.next_icon()
+ self.keyboard.press_and_release(self.initiate_keycode)
+ sleep(0.5)
+ self.switcher.select()
+
+ self.assertProperty(char_win1, is_focused=True)
+
class SwitcherWorkspaceTests(SwitcherTestCase):
"""Test Switcher behavior with respect to multiple workspaces."""
@@ -339,7 +381,6 @@ class SwitcherWorkspaceTests(SwitcherTestCase):
self.workspace.switch_to(2)
char_map = self.start_app("Character Map")
-
self.switcher.initiate(SwitcherMode.ALL)
self.addCleanup(self.switcher.terminate)
@@ -361,18 +402,34 @@ class SwitcherWorkspaceTests(SwitcherTestCase):
self.set_unity_option("alt_tab_timeout", False)
self.workspace.switch_to(1)
- self.start_app("Mahjongg")
+ self.start_app("Character Map")
self.workspace.switch_to(3)
- mah_win2 = self.start_app_window("Mahjongg")
+ char_win2 = self.start_app_window("Character Map")
self.keybinding("window/minimize")
- self.assertProperty(mah_win2, is_hidden=True)
+ self.assertProperty(char_win2, is_hidden=True)
self.start_app("Calculator")
self.switcher.initiate()
- while self.switcher.current_icon.tooltip_text != mah_win2.application.name:
+ while self.switcher.current_icon.tooltip_text != char_win2.application.name:
self.switcher.next_icon()
self.switcher.select()
- self.assertProperty(mah_win2, is_hidden=False)
+ self.assertProperty(char_win2, is_hidden=False)
+
+ def test_switcher_is_disabled_when_wall_plugin_active(self):
+ """The switcher must not open when the wall plugin is active using ctrl+alt+<direction>."""
+
+ initial_workspace = self.workspace.current_workspace
+ self.addCleanup(self.workspace.switch_to, initial_workspace)
+
+ self.workspace.switch_to(0)
+ sleep(1)
+ self.keyboard.press("Ctrl+Alt+Right")
+ self.addCleanup(self.keyboard.release, "Ctrl+Alt+Right")
+ sleep(1)
+ self.keybinding_hold_part_then_tap("switcher/reveal_normal")
+ self.addCleanup(self.switcher.terminate)
+
+ self.assertThat(self.switcher.visible, Eventually(Equals(False)))
diff --git a/tests/data/no-icon.desktop b/tests/data/no-icon.desktop
new file mode 100644
index 000000000..4f2902fe2
--- /dev/null
+++ b/tests/data/no-icon.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Name=Default
+Comment=Interactive viewer for a Default icon!
+Exec=gedit
+Terminal=false
+Type=Application
+Categories=GTK;Science;Graphics;
diff --git a/tests/gmockvolume.c b/tests/gmockvolume.c
new file mode 100644
index 000000000..5ee2d23a1
--- /dev/null
+++ b/tests/gmockvolume.c
@@ -0,0 +1,176 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include "gmockvolume.h"
+
+static void g_mock_volume_volume_iface_init (GVolumeIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GMockVolume, g_mock_volume, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME,
+ g_mock_volume_volume_iface_init))
+
+static void
+g_mock_volume_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (g_mock_volume_parent_class)->finalize (object);
+}
+
+static void
+g_mock_volume_class_init (GMockVolumeClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = g_mock_volume_finalize;
+}
+
+static void
+g_mock_volume_init (GMockVolume *mock_volume)
+{
+}
+
+GMockVolume *
+g_mock_volume_new ()
+{
+ GMockVolume *volume;
+
+ volume = g_object_new (G_TYPE_MOCK_VOLUME, NULL);
+
+ return volume;
+}
+
+static char *
+g_mock_volume_get_name (GVolume *volume)
+{
+ return g_strdup ("");
+}
+
+static GIcon *
+g_mock_volume_get_icon (GVolume *volume)
+{
+ return g_icon_new_for_string("", NULL);
+}
+
+static char *
+g_mock_volume_get_uuid (GVolume *volume)
+{
+ return NULL;
+}
+
+static GDrive *
+g_mock_volume_get_drive (GVolume *volume)
+{
+ return NULL;
+}
+
+static GMount *
+g_mock_volume_get_mount (GVolume *volume)
+{
+ return NULL;
+}
+
+static gboolean
+g_mock_volume_can_mount (GVolume *volume)
+{
+ return TRUE;
+}
+
+static gboolean
+g_mock_volume_can_eject (GVolume *volume)
+{
+ return FALSE;
+}
+
+static gboolean
+g_mock_volume_should_automount (GVolume *volume)
+{
+ return TRUE;
+}
+
+static void
+g_mock_volume_mount (GVolume *volume,
+ GMountMountFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+}
+
+static gboolean
+g_mock_volume_mount_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+g_mock_volume_eject (GVolume *volume,
+ GMountUnmountFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+}
+
+static gboolean
+g_mock_volume_eject_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error)
+{
+ return TRUE;
+}
+
+static gchar *
+g_mock_volume_get_identifier (GVolume *volume,
+ const gchar *kind)
+{
+ return NULL;
+}
+
+static gchar **
+g_mock_volume_enumerate_identifiers (GVolume *volume)
+{
+ return NULL;
+}
+
+static void
+g_mock_volume_volume_iface_init (GVolumeIface *iface)
+{
+ iface->get_name = g_mock_volume_get_name;
+ iface->get_icon = g_mock_volume_get_icon;
+ iface->get_uuid = g_mock_volume_get_uuid;
+ iface->get_drive = g_mock_volume_get_drive;
+ iface->get_mount = g_mock_volume_get_mount;
+ iface->can_mount = g_mock_volume_can_mount;
+ iface->can_eject = g_mock_volume_can_eject;
+ iface->should_automount = g_mock_volume_should_automount;
+ iface->mount_fn = g_mock_volume_mount;
+ iface->mount_finish = g_mock_volume_mount_finish;
+ iface->eject = g_mock_volume_eject;
+ iface->eject_finish = g_mock_volume_eject_finish;
+ iface->get_identifier = g_mock_volume_get_identifier;
+ iface->enumerate_identifiers = g_mock_volume_enumerate_identifiers;
+}
+
diff --git a/tests/gmockvolume.h b/tests/gmockvolume.h
new file mode 100644
index 000000000..0c9ee118a
--- /dev/null
+++ b/tests/gmockvolume.h
@@ -0,0 +1,53 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ *
+ */
+
+#ifndef UNITYSHELL_G_MOCK_VOLUME_H
+#define UNITYSHELL_G_MOCK_VOLUME_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_MOCK_VOLUME (g_mock_volume_get_type ())
+#define G_MOCK_VOLUME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_MOCK_VOLUME, GMockVolume))
+#define G_MOCK_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_MOCK_VOLUME, GMockVolumeClass))
+#define G_IS_MOCK_VOLUME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_MOCK_VOLUME))
+#define G_IS_MOCK_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_MOCK_VOLUME))
+
+typedef struct _GMockVolume GMockVolume;
+typedef struct _GMockVolumeClass GMockVolumeClass;
+
+struct _GMockVolume {
+ GObject parent;
+};
+
+struct _GMockVolumeClass {
+ GObjectClass parent_class;
+};
+
+GType g_mock_volume_get_type (void) G_GNUC_CONST;
+GMockVolume * g_mock_volume_new ();
+
+G_END_DECLS
+
+#endif // UNITYSHELL_G_MOCK_VOLUME_H
+
diff --git a/tests/test-gesture-engine/CMakeLists.txt b/tests/test-gesture-engine/CMakeLists.txt
deleted file mode 100644
index 49596e152..000000000
--- a/tests/test-gesture-engine/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-if (GTEST_SRC_DIR)
- set(UNITY_SRC ${CMAKE_SOURCE_DIR}/plugins/unityshell/src)
-
- add_custom_command(OUTPUT GestureEngine.cpp GestureEngine.h UBusMessages.h
- COMMAND cp ${UNITY_SRC}/GestureEngine.cpp ${UNITY_SRC}/GestureEngine.h ${CMAKE_SOURCE_DIR}/unity-shared//UBusMessages.h ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script ${UNITY_SRC}/GestureEngine.cpp > ${CMAKE_CURRENT_BINARY_DIR}/GestureEngine.cpp
- COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script ${UNITY_SRC}/GestureEngine.h > ${CMAKE_CURRENT_BINARY_DIR}/GestureEngine.h
- DEPENDS ${UNITY_SRC}/GestureEngine.cpp ${UNITY_SRC}/GestureEngine.h ${CMAKE_SOURCE_DIR}/unity-shared/UBusMessages.h
- COMMENT "Copying GestureEngine source.")
-
- # 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_GESTURE_ENGINE_DEPS REQUIRED QUIET "${UNITY_PLUGIN_DEPS}")
- set(TEST_GESTURE_ENGINE_CFLAGS
- "-g"
- "-I${CMAKE_CURRENT_SOURCE_DIR}"
- "-I${CMAKE_CURRENT_BINARY_DIR}"
- ${TEST_GESTURE_ENGINE_DEPS_CFLAGS}
- )
- add_definitions(${TEST_GESTURE_ENGINE_CFLAGS})
-
- pkg_check_modules (COMPIZ REQUIRED QUIET compiz)
- link_directories (${COMPIZ_LIBDIR})
-
- add_executable(test-gesture-engine
- test_gesture_engine.cpp
- X11_mock.cpp
- GestureEngine.cpp
- PluginAdapterMock.cpp
- GeisAdapterMock.cpp
- ubus-server-mock.cpp
- )
- target_link_libraries(test-gesture-engine gtest ${TEST_GESTURE_ENGINE_DEPS_LIBRARIES} -lcompiz_core)
- add_test(UnityGTestGestureEngine test-gesture-engine)
- add_dependencies(test-gesture-engine gtest unity-core-${UNITY_API_VERSION})
-
- add_custom_target (check-gesture-engine COMMAND ./test-gesture-engine DEPENDS test-gesture-engine)
-endif (GTEST_SRC_DIR)
diff --git a/tests/test-gesture-engine/GeisAdapterMock.cpp b/tests/test-gesture-engine/GeisAdapterMock.cpp
deleted file mode 100644
index 2d4355a21..000000000
--- a/tests/test-gesture-engine/GeisAdapterMock.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 "GeisAdapterMock.h"
-
-GeisAdapterMock *GeisAdapterMock::_default = nullptr;
-
-GeisAdapterMock& GeisAdapterMock::Instance() {
- if (!_default)
- {
- _default = new GeisAdapterMock;
- }
- return *_default;
-}
diff --git a/tests/test-gesture-engine/GeisAdapterMock.h b/tests/test-gesture-engine/GeisAdapterMock.h
deleted file mode 100644
index c4237a0a8..000000000
--- a/tests/test-gesture-engine/GeisAdapterMock.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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 GEISADAPTER_MOCK_H
-#define GEISADAPTER_MOCK_H
-
-#include <sigc++/sigc++.h>
-#include <X11/Xlib.h>
-
-class GeisAdapterMock : public sigc::trackable
-{
-public:
- static GeisAdapterMock& Instance();
-
- ~GeisAdapterMock() {}
-
- typedef struct _GeisTapData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- int tap_length_ms;
- float position_x;
- float position_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisTapData;
-
- typedef struct _GeisDragData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float delta_x;
- float delta_y;
- float velocity_x;
- float velocity_y;
- float position_x;
- float position_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisDragData;
-
- typedef struct _GeisRotateData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float angle;
- float angle_delta;
- float angle_velocity;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisRotateData;
-
- typedef struct _GeisPinchData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float radius;
- float radius_delta;
- float radius_velocity;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisPinchData;
-
- typedef struct _GeisTouchData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisTouchData;
-
- sigc::signal<void, GeisTapData*> tap;
-
- sigc::signal<void, GeisDragData*> drag_start;
- sigc::signal<void, GeisDragData*> drag_update;
- sigc::signal<void, GeisDragData*> drag_finish;
-
- sigc::signal<void, GeisRotateData*> rotate_start;
- sigc::signal<void, GeisRotateData*> rotate_update;
- sigc::signal<void, GeisRotateData*> rotate_finish;
-
- sigc::signal<void, GeisPinchData*> pinch_start;
- sigc::signal<void, GeisPinchData*> pinch_update;
- sigc::signal<void, GeisPinchData*> pinch_finish;
-
- sigc::signal<void, GeisTouchData*> touch_start;
- sigc::signal<void, GeisTouchData*> touch_update;
- sigc::signal<void, GeisTouchData*> touch_finish;
-
-private:
- GeisAdapterMock() {}
-
- static GeisAdapterMock* _default;
-
-};
-#endif
diff --git a/tests/test-gesture-engine/test_gesture_engine.cpp b/tests/test-gesture-engine/test_gesture_engine.cpp
deleted file mode 100644
index 1c009bd55..000000000
--- a/tests/test-gesture-engine/test_gesture_engine.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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 "GestureEngine.h"
-
-CompScreenMock concrete_screen_mock;
-CompScreenMock *screen_mock = &concrete_screen_mock;
-int pointerX_mock = 0;
-int pointerY_mock = 0;
-
-class GestureEngineTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- screen_mock->_width = 1280;
- screen_mock->_height = 1024;
-
- GenerateWindows();
- }
-
- void PerformPinch(GestureEngine &gesture_engine, float peak_radius) {
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- GeisAdapterMock::GeisTouchData touch_data;
- touch_data.id = 1;
- touch_data.touches = 3;
- touch_data.window = 123;
- touch_data.focus_x = 100; /* hits the middle window */
- touch_data.focus_y = 100;
- gesture_engine.OnTouchStart(&touch_data);
-
- GeisAdapterMock::GeisPinchData pinch_data;
- pinch_data.id = 1;
- pinch_data.touches = 3;
- pinch_data.window = 123;
- pinch_data.focus_x = 100; /* hits the middle window */
- pinch_data.focus_y = 100;
- pinch_data.radius = 1.0;
- gesture_engine.OnPinchStart(&pinch_data);
-
- touch_data.focus_x += 10;
- touch_data.focus_y += 20;
- gesture_engine.OnTouchUpdate(&touch_data);
-
- pinch_data.focus_x += 10;
- pinch_data.focus_y += 20;
- pinch_data.radius = peak_radius;
- gesture_engine.OnPinchUpdate(&pinch_data);
-
- gesture_engine.OnTouchFinish(&touch_data);
- gesture_engine.OnPinchFinish(&pinch_data);
- }
-
- 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 CompWindowMock;
- /* x, y, width, height, border */
- window->_geometry.set(0, 0, screen_mock->width(), screen_mock->height(), 0);
- window->_serverGeometry = window->_geometry;
- window->_actions = 0;
- window->_state = 0;
- screen_mock->_client_list_stacking.push_back(window);
-
- /* middle window */
- window = new CompWindowMock;
- window->_geometry.set(10, 10, 400, 400, 0);
- window->_serverGeometry = window->_geometry;
- window->_actions = CompWindowActionMoveMask;
- window->_state = 0;
- screen_mock->_client_list_stacking.push_back(window);
-
- /* top-level window */
- window = new CompWindowMock;
- window->_geometry.set(500, 500, 410, 410, 0);
- window->_serverGeometry = 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());
- }
-};
-
-TEST_F(GestureEngineTest, ThreeFingersDragMovesWindow)
-{
- GestureEngine gestureEngine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- GeisAdapterMock::GeisTouchData touch_data;
- touch_data.id = 1;
- touch_data.touches = 3;
- touch_data.window = 123;
- touch_data.focus_x = 100; /* hits the middle window */
- touch_data.focus_y = 100;
- gestureEngine.OnTouchStart(&touch_data);
-
- GeisAdapterMock::GeisDragData drag_data;
- drag_data.id = 1;
- drag_data.touches = 3;
- drag_data.window = 123;
- drag_data.focus_x = 100; /* hits the middle window */
- drag_data.focus_y = 100;
- gestureEngine.OnDragStart(&drag_data);
-
- ASSERT_FALSE(middle_window->_moved);
-
- touch_data.focus_x += 10;
- touch_data.focus_y += 20;
- gestureEngine.OnTouchUpdate(&touch_data);
-
- drag_data.delta_x = 10;
- drag_data.delta_y = 20;
- drag_data.focus_x += drag_data.delta_x;
- drag_data.focus_y += drag_data.delta_x;
- gestureEngine.OnDragUpdate(&drag_data);
-
- ASSERT_TRUE(middle_window->_moved);
- ASSERT_EQ(drag_data.delta_x, middle_window->_movement_x);
- ASSERT_EQ(drag_data.delta_y, middle_window->_movement_y);
-}
-
-TEST_F(GestureEngineTest, ThreeFingersDragDoesntMoveStaticWindow)
-{
- GestureEngine gestureEngine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- /* can't be moved */
- middle_window->_actions = 0;
-
- GeisAdapterMock::GeisTouchData touch_data;
- touch_data.id = 1;
- touch_data.touches = 3;
- touch_data.window = 123;
- touch_data.focus_x = 100; /* hits the middle window */
- touch_data.focus_y = 100;
- gestureEngine.OnTouchStart(&touch_data);
-
- GeisAdapterMock::GeisDragData drag_data;
- drag_data.id = 1;
- drag_data.touches = 3;
- drag_data.window = 123;
- drag_data.focus_x = 100; /* hits the middle window */
- drag_data.focus_y = 100;
- gestureEngine.OnDragStart(&drag_data);
-
- ASSERT_FALSE(middle_window->_moved);
-
- touch_data.focus_x += 10;
- touch_data.focus_y += 20;
- gestureEngine.OnTouchUpdate(&touch_data);
-
- drag_data.delta_x = 10;
- drag_data.delta_y = 20;
- drag_data.focus_x += drag_data.delta_x;
- drag_data.focus_y += drag_data.delta_x;
- gestureEngine.OnDragUpdate(&drag_data);
-
- ASSERT_FALSE(middle_window->_moved);
-}
-
-TEST_F(GestureEngineTest, ThreeFingersPinchMaximizesWindow)
-{
- GestureEngine gesture_engine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- PerformPinch(gesture_engine, 2.0);
-
- ASSERT_EQ(1, middle_window->_maximize_count);
- ASSERT_EQ(MAXIMIZE_STATE, middle_window->_maximize_state);
-}
-
-TEST_F(GestureEngineTest, ThreeFingersPinchRestoresWindow)
-{
- GestureEngine gesture_engine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- PerformPinch(gesture_engine, 0.3);
-
- ASSERT_EQ(1, middle_window->_maximize_count);
- ASSERT_EQ(0, middle_window->_maximize_state);
-}
-
-TEST_F(GestureEngineTest, MinimalThreeFingersPinchDoesNothing)
-{
- GestureEngine gesture_engine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- PerformPinch(gesture_engine, 1.1);
-
- ASSERT_EQ(0, middle_window->_maximize_count);
-}
-
-/* Regression test for lp:979418, where the grab is not removed if the gesture
- * id is 0. */
-TEST_F(GestureEngineTest, DragGrabCheck)
-{
- screen_mock->_grab_count = 0;
-
- GestureEngine gesture_engine(screen_mock);
-
- GeisAdapterMock::GeisDragData drag_data;
- drag_data.id = 0;
- drag_data.touches = 3;
- drag_data.window = 123;
- drag_data.focus_x = 100; /* hits the middle window */
- drag_data.focus_y = 100;
- gesture_engine.OnDragStart(&drag_data);
-
- gesture_engine.OnDragFinish(&drag_data);
-
- ASSERT_EQ(0, screen_mock->_grab_count);
-}
-
-int main(int argc, char** argv)
-{
- ::testing::InitGoogleTest(&argc, argv);
-
- int ret = RUN_ALL_TESTS();
-
- return ret;
-}
diff --git a/tests/test-gestures/CMakeLists.txt b/tests/test-gestures/CMakeLists.txt
new file mode 100644
index 000000000..00ef9e450
--- /dev/null
+++ b/tests/test-gestures/CMakeLists.txt
@@ -0,0 +1,94 @@
+if (GTEST_SRC_DIR)
+ set(UNITY_SRC ${CMAKE_SOURCE_DIR}/plugins/unityshell/src)
+
+ add_custom_command(OUTPUT CompoundGestureRecognizer.cpp
+ CompoundGestureRecognizer.h
+ GesturalWindowSwitcher.cpp
+ GesturalWindowSwitcher.h
+ UnityGestureBroker.cpp
+ UnityGestureBroker.h
+ UBusMessages.h
+ WindowGestureTarget.h
+ WindowGestureTarget.cpp
+
+ COMMAND cp ${UNITY_SRC}/CompoundGestureRecognizer.cpp
+ ${UNITY_SRC}/CompoundGestureRecognizer.h
+ ${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
+
+ COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_switcher
+ ${UNITY_SRC}/GesturalWindowSwitcher.cpp >
+ ${CMAKE_CURRENT_BINARY_DIR}/GesturalWindowSwitcher.cpp
+
+ COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_switcher
+ ${UNITY_SRC}/GesturalWindowSwitcher.h >
+ ${CMAKE_CURRENT_BINARY_DIR}/GesturalWindowSwitcher.h
+
+ DEPENDS ${UNITY_SRC}/CompoundGestureRecognizer.cpp
+ ${UNITY_SRC}/CompoundGestureRecognizer.h
+ ${UNITY_SRC}/GesturalWindowSwitcher.cpp
+ ${UNITY_SRC}/GesturalWindowSwitcher.h
+ ${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
+ CompoundGestureRecognizer.cpp
+ CompoundGestureRecognizer.h
+ GesturalWindowSwitcher.cpp
+ GesturalWindowSwitcher.h
+ test_compound_gesture_recognizer.cpp
+ test_gestural_window_switcher.cpp
+ 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/GesturalWindowSwitcherMock.h b/tests/test-gestures/GesturalWindowSwitcherMock.h
new file mode 100644
index 000000000..b21a2f7b6
--- /dev/null
+++ b/tests/test-gestures/GesturalWindowSwitcherMock.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
+ */
+
+#ifndef GESTURAL_WINDOW_SWITCHER_MOCK_H
+#define GESTURAL_WINDOW_SWITCHER_MOCK_H
+
+#include <Nux/Gesture.h>
+
+namespace unity
+{
+
+class GesturalWindowSwitcherMock : public nux::GestureTarget
+{
+ public:
+ GesturalWindowSwitcherMock() {}
+
+ virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event)
+ {
+ return nux::GestureDeliveryRequest::NONE;
+ }
+};
+typedef std::shared_ptr<GesturalWindowSwitcherMock> ShPtGesturalWindowSwitcherMock;
+
+} //namespace unity
+#endif // GESTURAL_WINDOW_SWITCHER_MOCK_H
diff --git a/tests/test-gestures/NuxMock.h b/tests/test-gestures/NuxMock.h
new file mode 100644
index 000000000..4ae586655
--- /dev/null
+++ b/tests/test-gestures/NuxMock.h
@@ -0,0 +1,27 @@
+#ifndef NUX_MOCK_H
+#define NUX_MOCK_H
+
+#include <Nux/Nux.h>
+
+namespace nux
+{
+
+class InputAreaMock : public Object
+{
+ public:
+ void GestureEvent(const GestureEvent &event)
+ {
+ }
+};
+
+class ViewMock : public InputAreaMock
+{
+ public:
+ sigc::signal<void, int, int, unsigned long, unsigned long> mouse_down;
+ sigc::signal<void, int, int, unsigned long, unsigned long> mouse_up;
+ sigc::signal<void, int, int, int, int, unsigned long, unsigned long> mouse_drag;
+};
+
+} // namespace nux
+
+#endif // NUX_MOCK_H
diff --git a/tests/test-gesture-engine/PluginAdapterMock.cpp b/tests/test-gestures/PluginAdapterMock.cpp
index a71af2421..a71af2421 100644
--- a/tests/test-gesture-engine/PluginAdapterMock.cpp
+++ b/tests/test-gestures/PluginAdapterMock.cpp
diff --git a/tests/test-gesture-engine/PluginAdapterMock.h b/tests/test-gestures/PluginAdapterMock.h
index 2b111a68b..2b111a68b 100644
--- a/tests/test-gesture-engine/PluginAdapterMock.h
+++ b/tests/test-gestures/PluginAdapterMock.h
diff --git a/tests/test-gestures/SwitcherControllerMock.h b/tests/test-gestures/SwitcherControllerMock.h
new file mode 100644
index 000000000..9c14a8ee7
--- /dev/null
+++ b/tests/test-gestures/SwitcherControllerMock.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
+ */
+
+#ifndef SWITCHER_CONTROLLER_MOCK_H
+#define SWITCHER_CONTROLLER_MOCK_H
+
+#include "NuxMock.h"
+
+namespace unity {
+namespace switcher {
+
+class SwitcherViewMock : public nux::ViewMock
+{
+public:
+ int IconIndexAt(int x, int y)
+ {
+ return x*y;
+ }
+};
+
+class ControllerMock
+{
+public:
+ ControllerMock()
+ {
+ Reset();
+ }
+
+ void Reset()
+ {
+ is_visible_ = false;
+ prev_count_ = 0;
+ next_count_ = 0;
+ index_selected_ = -1;
+ }
+
+ typedef std::shared_ptr<ControllerMock> Ptr;
+
+ sigc::signal<void> view_built;
+
+ void Next()
+ {
+ ++next_count_;
+ }
+
+ void Prev()
+ {
+ ++prev_count_;
+ }
+
+ void Select(int index)
+ {
+ index_selected_ = index;
+ }
+
+ bool Visible()
+ {
+ return is_visible_;
+ }
+
+ void Hide()
+ {
+ is_visible_ = false;
+ }
+
+ SwitcherViewMock *GetView()
+ {
+ return &view_;
+ }
+
+ bool is_visible_;
+ SwitcherViewMock view_;
+ int prev_count_;
+ int next_count_;
+ int index_selected_;
+};
+
+} // namespace switcher
+} // namespace unity
+
+
+#endif // SWITCHER_CONTROLLER_MOCK_H
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-gesture-engine/X11_mock.cpp b/tests/test-gestures/X11_mock.cpp
index 5560aa9ac..5560aa9ac 100644
--- a/tests/test-gesture-engine/X11_mock.cpp
+++ b/tests/test-gestures/X11_mock.cpp
diff --git a/tests/test-gesture-engine/X11_mock.h b/tests/test-gestures/X11_mock.h
index f98e028be..f98e028be 100644
--- a/tests/test-gesture-engine/X11_mock.h
+++ b/tests/test-gestures/X11_mock.h
diff --git a/tests/test-gesture-engine/compiz_mock/core/core.h b/tests/test-gestures/compiz_mock/core/core.h
index f1c358fbf..f1c358fbf 100644
--- a/tests/test-gesture-engine/compiz_mock/core/core.h
+++ b/tests/test-gestures/compiz_mock/core/core.h
diff --git a/tests/test-gesture-engine/compiz_mock/core/screen.h b/tests/test-gestures/compiz_mock/core/screen.h
index 38795db15..225d41c65 100644
--- a/tests/test-gesture-engine/compiz_mock/core/screen.h
+++ b/tests/test-gestures/compiz_mock/core/screen.h
@@ -31,41 +31,42 @@ typedef std::vector<CompWindowMock*> CompWindowMockVector;
class CompScreenMock {
public:
- CompScreenMock() : _grab_count(0) {}
+ CompScreenMock() : grab_count_(0), next_grab_handle_(1) {}
typedef int GrabHandle;
- int width() const {return _width;}
- int height() const {return _height;}
+ int width() const {return width_;}
+ int height() const {return height_;}
- Display *dpy() {return _dpy;}
+ Display *dpy() {return dpy_;}
const CompWindowMockVector & clientList(bool stackingOrder = true) {
if (stackingOrder)
- return _client_list_stacking;
+ return client_list_stacking_;
else
- return _client_list;
+ return client_list_;
}
- Window root() {return _root;}
+ Window root() {return root_;}
GrabHandle pushGrab(Cursor cursor, const char *name) {
- _grab_count++;
- return 0;
+ grab_count_++;
+ return next_grab_handle_++;
}
void removeGrab(GrabHandle handle, CompPoint *restorePointer) {
- _grab_count--;
+ 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 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;
diff --git a/tests/test-gestures/compiz_mock/core/timer.h b/tests/test-gestures/compiz_mock/core/timer.h
new file mode 100644
index 000000000..2452da7dc
--- /dev/null
+++ b/tests/test-gestures/compiz_mock/core/timer.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_TIMER_MOCK_H
+#define COMPIZ_TIMER_MOCK_H
+
+#include <boost/function.hpp>
+
+class CompTimerMock
+{
+ public:
+ typedef boost::function<bool ()> CallBack;
+
+ CompTimerMock()
+ {
+ is_running = false;
+ callback = NULL;
+
+ // OBS: no support for more than one simultaneous timer
+ instance = this;
+ }
+
+ virtual ~CompTimerMock()
+ {
+ instance = nullptr;
+ }
+
+ void setCallback (CallBack callback)
+ {
+ this->callback = callback;
+ }
+
+ void setTimes(unsigned int min, unsigned int max = 0)
+ {
+ }
+
+ void start()
+ {
+ is_running = true;
+ }
+
+ void stop()
+ {
+ is_running = false;
+ }
+
+ void ForceTimeout()
+ {
+ if (is_running && callback)
+ {
+ callback();
+ is_running = false;
+ }
+ }
+
+ CallBack callback;
+ bool is_running;
+
+ static CompTimerMock *instance;
+};
+
+#endif // COMPIZ_TIMER_MOCK_H
diff --git a/tests/test-gesture-engine/compiz_mock/core/window.h b/tests/test-gestures/compiz_mock/core/window.h
index d65524b7d..f5e930107 100644
--- a/tests/test-gesture-engine/compiz_mock/core/window.h
+++ b/tests/test-gestures/compiz_mock/core/window.h
@@ -24,46 +24,56 @@
/* The real CompWindow */
#include <core/window.h>
-class CompWindowMock {
+class CompWindowMock
+{
public:
- CompWindowMock() : _moved(false), _maximize_count(0), _maximize_state(0) {}
+ 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 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;
+ void move(int dx, int dy, bool immediate = true)
+ {
+ moved_ = true;
+ movement_x_ = dx;
+ movement_y_ = dy;
}
- unsigned int actions () {return _actions;}
+ unsigned int actions () {return actions_;}
- void maximize(int state) {++_maximize_count; _maximize_state = state;}
+ 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;}
+ 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 _serverGeometry;}
+ 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_;
- unsigned int _actions;
- unsigned int _state;
- compiz::window::Geometry _serverGeometry;
- compiz::window::Geometry _geometry;
+ int maximize_count_;
+ int maximize_state_;
- bool _moved;
- int _movement_x;
- int _movement_y;
+ int id_;
- int _maximize_count;
- int _maximize_state;
+ 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..626f8f244
--- /dev/null
+++ b/tests/test-gestures/sed_script_broker
@@ -0,0 +1,12 @@
+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
+s|GesturalWindowSwitcher|GesturalWindowSwitcherMock|g
diff --git a/tests/test-gesture-engine/sed_script b/tests/test-gestures/sed_script_gesture
index 94fb691f6..c2e3ffa48 100644
--- a/tests/test-gesture-engine/sed_script
+++ b/tests/test-gestures/sed_script_gesture
@@ -9,6 +9,10 @@ s|\<XSync\>|XSyncMock|g
s|\<XWarpPointer\>|XWarpPointerMock|g
s|\<XFreeCursor\>|XFreeCursorMock|g
s|\<XCreateFontCursor\>|XCreateFontCursorMock|g
-s|\<GeisAdapter\>|GeisAdapterMock|g
-s|\<PluginAdapter\>|PluginAdapterMock|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/sed_script_switcher b/tests/test-gestures/sed_script_switcher
new file mode 100644
index 000000000..8deb1b585
--- /dev/null
+++ b/tests/test-gestures/sed_script_switcher
@@ -0,0 +1,25 @@
+s|<core/core.h>|<compiz_mock/core/core.h>|
+s|<core/timer.h>|<compiz_mock/core/timer.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
+s|\<CompTimer\>|CompTimerMock|g
+s|\<LauncherController\>|LauncherControllerMock|g
+s|\<SwitcherController\>|SwitcherControllerMock|g
+s|\<switcher\:\:Controller\>|switcher\:\:ControllerMock|g
+s|\<launcher\:\:Controller\>|launcher\:\:ControllerMock|g
+s|\<SwitcherView\>|SwitcherViewMock|g
diff --git a/tests/test-gestures/test_compound_gesture_recognizer.cpp b/tests/test-gestures/test_compound_gesture_recognizer.cpp
new file mode 100644
index 000000000..56e83a86f
--- /dev/null
+++ b/tests/test-gestures/test_compound_gesture_recognizer.cpp
@@ -0,0 +1,189 @@
+/*
+ * This file is part of Unity
+ *
+ * Copyright (C) 2012 - Canonical Ltd.
+ *
+ * Unity 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.
+ *
+ * Unity 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
+ */
+
+#include <gtest/gtest.h>
+#include "CompoundGestureRecognizer.h"
+#include "FakeGestureEvent.h"
+
+using namespace unity;
+
+class CompoundGestureRecognizerTest : public ::testing::Test
+{
+ public:
+ CompoundGestureRecognizerTest()
+ {
+ fake_event.gesture_id = 0;
+ fake_event.timestamp = 12345; // some arbitrary, big value
+ }
+
+ RecognitionResult PerformTap()
+ {
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id += 1;
+ fake_event.gesture_classes = nux::TOUCH_GESTURE;
+ if (gesture_recognizer.GestureEvent(fake_event.ToGestureEvent())
+ != RecognitionResult::NONE)
+ ADD_FAILURE();
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.timestamp += 0.2 * CompoundGestureRecognizer::MAX_TAP_TIME;
+ if (gesture_recognizer.GestureEvent(fake_event.ToGestureEvent())
+ != RecognitionResult::NONE)
+ ADD_FAILURE();
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TAP_TIME;
+ return gesture_recognizer.GestureEvent(fake_event.ToGestureEvent());
+ }
+
+
+ CompoundGestureRecognizer gesture_recognizer;
+ nux::FakeGestureEvent fake_event;
+};
+
+TEST_F(CompoundGestureRecognizerTest, DoubleTap)
+{
+ // First tap
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ // Second tap
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::DOUBLE_TAP_RECOGNIZED, PerformTap());
+}
+
+/*
+ If too much time passes between two consecutive taps,
+ it's not considered a double tap
+ */
+TEST_F(CompoundGestureRecognizerTest, Tap_BigInterval_Tap)
+{
+ // First tap
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ // Second tap
+ fake_event.timestamp += 2 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+}
+
+TEST_F(CompoundGestureRecognizerTest, Tap_BigInterval_DoubleTap)
+{
+ // First tap
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ // Second tap
+ fake_event.timestamp += 2 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ // Third tap
+ fake_event.timestamp += 0.5 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::DOUBLE_TAP_RECOGNIZED, PerformTap());
+}
+
+TEST_F(CompoundGestureRecognizerTest, TapAndDrag)
+{
+ // First tap
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ // Drag
+
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 1;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.gesture_classes = nux::TOUCH_GESTURE | nux::DRAG_GESTURE;
+ fake_event.timestamp += 0.2 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TAP_TIME;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+}
+
+TEST_F(CompoundGestureRecognizerTest, TapAndHold)
+{
+ // Tap
+
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ // Hold
+
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 1;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.timestamp += 0.2 * CompoundGestureRecognizer::MAX_TAP_TIME;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.timestamp += 1.0 * CompoundGestureRecognizer::HOLD_TIME;
+ ASSERT_EQ(RecognitionResult::TAP_AND_HOLD_RECOGNIZED,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.3 * CompoundGestureRecognizer::HOLD_TIME;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+}
+
+TEST_F(CompoundGestureRecognizerTest, Tap_ShortHold_DoubleTap)
+{
+ // Tap
+
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ // Short hold
+ // Too long for a tap and too short for a hold.
+
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 1;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.timestamp += (CompoundGestureRecognizer::MAX_TAP_TIME +
+ CompoundGestureRecognizer::HOLD_TIME) / 2;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 1;
+ ASSERT_EQ(RecognitionResult::NONE,
+ gesture_recognizer.GestureEvent(fake_event.ToGestureEvent()));
+
+ // Verify that the state machine went back to its initial state
+ // by checking that a subsequent double tap gets recognized normally
+
+ fake_event.timestamp += 0.5 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::NONE, PerformTap());
+
+ fake_event.timestamp += 0.5 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ ASSERT_EQ(RecognitionResult::DOUBLE_TAP_RECOGNIZED, PerformTap());
+}
diff --git a/tests/test-gestures/test_gestural_window_switcher.cpp b/tests/test-gestures/test_gestural_window_switcher.cpp
new file mode 100644
index 000000000..be0586992
--- /dev/null
+++ b/tests/test-gestures/test_gestural_window_switcher.cpp
@@ -0,0 +1,323 @@
+/*
+ * This file is part of Unity
+ *
+ * Copyright (C) 2012 - Canonical Ltd.
+ *
+ * Unity 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.
+ *
+ * Unity 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
+ */
+
+#include <gtest/gtest.h>
+#include "GesturalWindowSwitcher.h"
+#include "FakeGestureEvent.h"
+#include "unityshell_mock.h"
+#include "compiz_mock/core/timer.h"
+
+using namespace unity;
+
+class GesturalWindowSwitcherTest: public ::testing::Test
+{
+ public:
+ virtual void SetUp()
+ {
+ unity_screen = unity::UnityScreenMock::get(screen_mock);
+ unity_screen->Reset();
+
+ fake_event.gesture_id = 0;
+ fake_event.timestamp = 12345; // some arbitrary, big value
+
+ unity_screen->switcher_controller()->view_built.emit();
+ }
+
+ void PerformTap()
+ {
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id += 1;
+ fake_event.gesture_classes = nux::TOUCH_GESTURE;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.timestamp += 0.2 * CompoundGestureRecognizer::MAX_TAP_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TAP_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+ }
+
+ void PerformTapAndHold()
+ {
+ PerformTap();
+
+ // Hold
+
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id += 1;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.timestamp += 0.2 * CompoundGestureRecognizer::MAX_TAP_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.timestamp += 1.0 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+ }
+
+ GesturalWindowSwitcher gestural_switcher;
+ nux::FakeGestureEvent fake_event;
+ unity::UnityScreenMock *unity_screen;
+};
+
+TEST_F(GesturalWindowSwitcherTest, DoubleTapSwitchesWindow)
+{
+ PerformTap();
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::MAX_TIME_BETWEEN_GESTURES;
+ PerformTap();
+
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // simulate that enough time has passed
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_FALSE(unity_screen->switcher_controller()->is_visible_);
+}
+
+TEST_F(GesturalWindowSwitcherTest, TapAndHoldShowsSwitcher)
+{
+ PerformTapAndHold();
+
+ // switcher should show up
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // simulate that enough idle time has passed
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ // nothing should change
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // lift fingers. End hold.
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // nothing should change
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // simulate that enough idle time has passed
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ // switcher should finally be closed
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_FALSE(unity_screen->switcher_controller()->is_visible_);
+}
+
+TEST_F(GesturalWindowSwitcherTest, TapAndHoldAndDragSelectsNextWindow)
+{
+ PerformTapAndHold();
+
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // Drag far enough to the right.
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.gesture_classes = nux::TOUCH_GESTURE | nux::DRAG_GESTURE;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ fake_event.delta.x = 0.6 * GesturalWindowSwitcher::DRAG_DELTA_FOR_CHANGING_SELECTION;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ fake_event.delta.x = 0.6 * GesturalWindowSwitcher::DRAG_DELTA_FOR_CHANGING_SELECTION;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // Selection should have jumped to the next window
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // Drag far enough to the left.
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ fake_event.delta.x = -0.6 * GesturalWindowSwitcher::DRAG_DELTA_FOR_CHANGING_SELECTION;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ fake_event.delta.x = -0.6 * GesturalWindowSwitcher::DRAG_DELTA_FOR_CHANGING_SELECTION;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // Selection should have jumped to the previous window
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // End gesture
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // Switcher should have been closed at once
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_FALSE(unity_screen->switcher_controller()->is_visible_);
+}
+
+TEST_F(GesturalWindowSwitcherTest, NewDragAfterTapAndHoldSelectsNextWindow)
+{
+ PerformTapAndHold();
+
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // End hold gesture
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // Start a new gesture and drag far enough to the right.
+
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id += 1;
+ fake_event.gesture_classes = nux::TOUCH_GESTURE;
+ fake_event.timestamp += 0.6 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.gesture_classes |= nux::DRAG_GESTURE;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ fake_event.delta.x = 0.6 * GesturalWindowSwitcher::DRAG_DELTA_FOR_CHANGING_SELECTION;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ fake_event.delta.x = 0.6 * GesturalWindowSwitcher::DRAG_DELTA_FOR_CHANGING_SELECTION;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // switcher should have been closed
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_FALSE(unity_screen->switcher_controller()->is_visible_);
+}
+
+TEST_F(GesturalWindowSwitcherTest, ClickAfterTapAndHoldSelectsWindow)
+{
+ PerformTapAndHold();
+
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // lift fingers. End hold.
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // click on position (12, 23)
+ unity_screen->switcher_controller()->view_.mouse_down.emit(12, 23, 0, 0);
+ unity_screen->switcher_controller()->view_.mouse_up.emit(12, 23, 0, 0);
+
+ // Should have selected the icon index corresponding to the
+ // position clicked.
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+ ASSERT_EQ(12*23, unity_screen->switcher_controller()->index_selected_);
+
+ // simulate that enough time has passed
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ ASSERT_FALSE(unity_screen->switcher_controller()->is_visible_);
+}
+
+TEST_F(GesturalWindowSwitcherTest, MouseDragAfterTapAndHoldSelectsNextWindow)
+{
+ unity::switcher::SwitcherViewMock &switcher_view =
+ unity_screen->switcher_controller()->view_;
+ int drag_delta = GesturalWindowSwitcher::DRAG_DELTA_FOR_CHANGING_SELECTION * 1.5f;
+
+ PerformTapAndHold();
+
+ if (CompTimerMock::instance)
+ CompTimerMock::instance->ForceTimeout();
+
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_TRUE(unity_screen->switcher_controller()->is_visible_);
+
+ // lift fingers. End hold.
+ fake_event.type = nux::EVENT_GESTURE_END;
+ fake_event.timestamp += 0.1 * CompoundGestureRecognizer::HOLD_TIME;
+ gestural_switcher.GestureEvent(fake_event.ToGestureEvent());
+
+ // drag right far enough to trigger the selection of the next item
+ switcher_view.mouse_down.emit(12, 23, 0, 0);
+ switcher_view.mouse_drag.emit(12 + drag_delta, 23, drag_delta, 0, 0, 0);
+ switcher_view.mouse_up.emit(12 + drag_delta, 23, 0, 0);
+
+ // Should selected the next icon and close the switcher right away
+ ASSERT_EQ(1, unity_screen->SetUpAndShowSwitcher_count_);
+ ASSERT_EQ(1, unity_screen->switcher_controller()->next_count_);
+ ASSERT_EQ(0, unity_screen->switcher_controller()->prev_count_);
+ ASSERT_FALSE(unity_screen->switcher_controller()->is_visible_);
+ ASSERT_EQ(-1, unity_screen->switcher_controller()->index_selected_);
+}
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..1d99b8a25
--- /dev/null
+++ b/tests/test-gestures/test_gestures_main.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 <compiz_mock/core/timer.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;
+
+CompTimerMock *CompTimerMock::instance = nullptr;
+
+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-gesture-engine/ubus-server-mock.cpp b/tests/test-gestures/ubus-server-mock.cpp
index 8305aedff..8305aedff 100644
--- a/tests/test-gesture-engine/ubus-server-mock.cpp
+++ b/tests/test-gestures/ubus-server-mock.cpp
diff --git a/tests/test-gesture-engine/ubus-server-mock.h b/tests/test-gestures/ubus-server-mock.h
index 21a642253..21a642253 100644
--- a/tests/test-gesture-engine/ubus-server-mock.h
+++ b/tests/test-gestures/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..36a34c667
--- /dev/null
+++ b/tests/test-gestures/unityshell_mock.h
@@ -0,0 +1,68 @@
+#ifndef UNITYSHELL_MOCK_H
+#define UNITYSHELL_MOCK_H
+
+#include <compiz_mock/core/core.h>
+#include <sigc++/sigc++.h>
+#include <NuxMock.h>
+
+#include "SwitcherControllerMock.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()
+ {
+ switcher_controller_ = std::make_shared<switcher::ControllerMock>();
+ Reset();
+ }
+
+ void Reset()
+ {
+ SetUpAndShowSwitcher_count_ = 0;
+ switcher_controller_->Reset();
+ }
+
+ virtual ~UnityScreenMock()
+ {
+ }
+
+ static UnityScreenMock *get(CompScreenMock *screen)
+ {
+ return static_cast<UnityScreenMock*>(screen);
+
+ }
+
+ void SetUpAndShowSwitcher()
+ {
+ ++SetUpAndShowSwitcher_count_;
+ switcher_controller_->is_visible_ = true;
+ }
+
+ switcher::ControllerMock::Ptr switcher_controller()
+ {
+ return switcher_controller_;
+ }
+
+ switcher::ControllerMock::Ptr switcher_controller_;
+ int SetUpAndShowSwitcher_count_;
+};
+
+} // namespace unity
+
+#endif // UNITYSHELL_MOCK_H
diff --git a/tests/test_bamflaunchericon.cpp b/tests/test_bamflaunchericon.cpp
index 9719e9a5f..874407b75 100644
--- a/tests/test_bamflaunchericon.cpp
+++ b/tests/test_bamflaunchericon.cpp
@@ -15,6 +15,8 @@
* <http://www.gnu.org/licenses/>
*
* Authored by: Andrea Azzarone <azzarone@gmail.com>
+ * Brandon Schaefer <brandon.schaefer@canonical.com>
+ * Marco Trevisan <marco.trevisan@canonical.com>
*/
#include <config.h>
@@ -23,33 +25,40 @@
#include <UnityCore/GLibWrapper.h>
#include "BamfLauncherIcon.h"
+
using namespace unity;
namespace
{
+const std::string USC_DESKTOP = BUILDDIR"/tests/data/ubuntu-software-center.desktop";
+const std::string NO_ICON_DESKTOP = BUILDDIR"/tests/data/no-icon.desktop";
+
class TestBamfLauncherIcon : public testing::Test
{
public:
virtual void SetUp()
{
+ BamfApplication* bamf_app;
bamf_matcher = bamf_matcher_get_default();
- bamf_app = bamf_matcher_get_application_for_desktop_file(bamf_matcher,
- BUILDDIR"/tests/data/ubuntu-software-center.desktop",
- TRUE);
+ bamf_app = bamf_matcher_get_application_for_desktop_file(bamf_matcher, USC_DESKTOP.c_str(), TRUE);
usc_icon = new launcher::BamfLauncherIcon(bamf_app);
+ ASSERT_EQ(usc_icon->DesktopFile(), USC_DESKTOP);
- }
+ bamf_app = bamf_matcher_get_application_for_desktop_file(bamf_matcher, NO_ICON_DESKTOP.c_str(), TRUE);
+ empty_icon = new launcher::BamfLauncherIcon(bamf_app);
+ ASSERT_EQ(empty_icon->DesktopFile(), NO_ICON_DESKTOP);
- virtual void TearDown()
- {
+ bamf_app = static_cast<BamfApplication*>(g_object_new(BAMF_TYPE_APPLICATION, nullptr));
+ empty_app = new launcher::BamfLauncherIcon(bamf_app);
+ ASSERT_TRUE(empty_app->DesktopFile().empty());
}
glib::Object<BamfMatcher> bamf_matcher;
- BamfApplication* bamf_app;
nux::ObjectPtr<launcher::BamfLauncherIcon> usc_icon;
-
+ nux::ObjectPtr<launcher::BamfLauncherIcon> empty_icon;
+ nux::ObjectPtr<launcher::BamfLauncherIcon> empty_app;
};
TEST_F(TestBamfLauncherIcon, TestCustomBackgroundColor)
@@ -62,4 +71,11 @@ TEST_F(TestBamfLauncherIcon, TestCustomBackgroundColor)
EXPECT_EQ(color.alpha, 0xff / 255.0f);
}
+TEST_F(TestBamfLauncherIcon, TestDefaultIcon)
+{
+ EXPECT_EQ(usc_icon->icon_name.Get(), "softwarecenter");
+ EXPECT_EQ(empty_icon->icon_name.Get(), "application-default-icon");
+ EXPECT_EQ(empty_app->icon_name.Get(), "application-default-icon");
+}
+
}
diff --git a/tests/test_bfb_launcher_icon.cpp b/tests/test_bfb_launcher_icon.cpp
new file mode 100644
index 000000000..bcc6c5f54
--- /dev/null
+++ b/tests/test_bfb_launcher_icon.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
+ */
+
+#include <gmock/gmock.h>
+
+#include "BFBLauncherIcon.h"
+
+using namespace unity;
+using namespace unity::launcher;
+
+namespace
+{
+
+class MockBFBLauncherIcon : public BFBLauncherIcon
+{
+public:
+ MockBFBLauncherIcon()
+ : BFBLauncherIcon(LauncherHideMode::LAUNCHER_HIDE_NEVER)
+ {}
+
+ AbstractLauncherIcon::MenuItemsVector GetMenus()
+ {
+ return BFBLauncherIcon::GetMenus();
+ }
+};
+
+TEST(TestBFBLauncherIcon, OverlayMenus)
+{
+ MockBFBLauncherIcon bfb;
+
+ for (auto menu_item : bfb.GetMenus())
+ {
+ bool overlay_item = dbusmenu_menuitem_property_get_bool(menu_item, QuicklistMenuItem::OVERLAY_MENU_ITEM_PROPERTY);
+ ASSERT_TRUE(overlay_item);
+ }
+}
+
+}
diff --git a/tests/test_device_launcher_section.cpp b/tests/test_device_launcher_section.cpp
new file mode 100644
index 000000000..b00bbfc72
--- /dev/null
+++ b/tests/test_device_launcher_section.cpp
@@ -0,0 +1,111 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ *
+ */
+
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include "DeviceLauncherSection.h"
+#include "AbstractVolumeMonitorWrapper.h"
+using namespace unity;
+using namespace unity::launcher;
+
+#include "gmockvolume.h"
+#include "test_utils.h"
+
+namespace
+{
+
+class EventListener
+{
+public:
+ EventListener()
+ : icon_added(false)
+ {}
+
+ void OnIconAdded(AbstractLauncherIcon::Ptr icon)
+ {
+ icon_added = true;
+ }
+
+ bool icon_added;
+};
+
+class MockVolumeMonitorWrapper : public AbstractVolumeMonitorWrapper
+{
+public:
+ typedef std::shared_ptr<MockVolumeMonitorWrapper> Ptr;
+
+ MockVolumeMonitorWrapper()
+ : volume1(G_VOLUME(g_mock_volume_new()))
+ , volume2(G_VOLUME(g_mock_volume_new()))
+ {
+ }
+
+ VolumeList GetVolumes()
+ {
+ VolumeList ret;
+
+ ret.push_back(volume1);
+ ret.push_back(volume2);
+
+ return ret;
+ }
+
+ glib::Object<GVolume> volume1;
+ glib::Object<GVolume> volume2;
+};
+
+class TestDeviceLauncherSection : public Test
+{
+public:
+ TestDeviceLauncherSection()
+ : monitor_(new MockVolumeMonitorWrapper)
+ , section_(monitor_)
+ {}
+
+ void SetUp()
+ {
+ // Make sure PopulateEntries is called.
+ Utils::WaitForTimeoutMSec(1500);
+ }
+
+ MockVolumeMonitorWrapper::Ptr monitor_;
+ DeviceLauncherSection section_;
+};
+
+
+TEST_F(TestDeviceLauncherSection, TestNoDuplicates)
+{
+ std::shared_ptr<EventListener> listener(new EventListener);
+ section_.IconAdded.connect(sigc::mem_fun(*listener, &EventListener::OnIconAdded));
+
+ // Emit the signal volume_added for each volume.
+ monitor_->volume_added.emit(monitor_->volume1);
+ monitor_->volume_added.emit(monitor_->volume2);
+
+ Utils::WaitForTimeoutMSec(500);
+
+ EXPECT_EQ(listener->icon_added, false);
+}
+
+}
+
diff --git a/tests/test_edge_barrier_controller.cpp b/tests/test_edge_barrier_controller.cpp
new file mode 100644
index 000000000..f00ac2bf1
--- /dev/null
+++ b/tests/test_edge_barrier_controller.cpp
@@ -0,0 +1,272 @@
+/*
+ * 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: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
+ *
+ */
+
+#include <gmock/gmock.h>
+#include "test_utils.h"
+#include "test_uscreen_mock.h"
+
+#include "EdgeBarrierController.h"
+
+using namespace unity;
+using namespace unity::ui;
+using namespace testing;
+
+namespace
+{
+
+class MockPointerBarrier : public PointerBarrierWrapper
+{
+public:
+ MockPointerBarrier(int monitor = 0, bool released_ = false)
+ {
+ index = monitor;
+ x1 = 1;
+ released = released_;
+ }
+
+ MOCK_METHOD0(ConstructBarrier, void());
+ MOCK_METHOD0(DestroyBarrier, void());
+ MOCK_METHOD1(ReleaseBarrier, void(int));
+};
+
+class MockEdgeBarrierController : public EdgeBarrierController
+{
+public:
+ void ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
+ {
+ EdgeBarrierController::ProcessBarrierEvent(owner, event);
+ }
+
+ EdgeBarrierSubscriber* GetSubscriber(unsigned int monitor)
+ {
+ return EdgeBarrierController::GetSubscriber(monitor);
+ }
+};
+
+class TestBarrierSubscriber : public EdgeBarrierSubscriber
+{
+public:
+ TestBarrierSubscriber(bool handles = false)
+ : handles_(handles)
+ {}
+
+ bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
+ {
+ return handles_;
+ }
+
+ bool handles_;
+};
+
+class TestEdgeBarrierController : public Test
+{
+public:
+ virtual void SetUp()
+ {
+ bc.options = std::make_shared<launcher::Options>();
+ bc.options()->edge_resist = true;
+ bc.options()->edge_passed_disabled_ms = 150;
+
+ uscreen.SetupFakeMultiMonitor();
+
+ for (int i = 0; i < max_num_monitors; ++i)
+ {
+ // By default we assume that no subscriber handles the events!!!
+ bc.Subscribe(&subscribers_[i], i);
+ }
+ }
+
+ BarrierEvent::Ptr MakeBarrierEvent(int id, bool breaker)
+ {
+ int velocity = breaker ? std::numeric_limits<int>::max() : bc.options()->edge_overcome_pressure() - 1;
+ return std::make_shared<BarrierEvent>(0, 1, velocity, id);
+ }
+
+ TestBarrierSubscriber subscribers_[max_num_monitors];
+ MockUScreen uscreen;
+ MockEdgeBarrierController bc;
+};
+
+TEST_F(TestEdgeBarrierController, Construction)
+{
+ EXPECT_TRUE(bc.sticky_edges);
+
+ for (int i = 0; i < max_num_monitors; ++i)
+ ASSERT_EQ(bc.GetSubscriber(i), &subscribers_[i]);
+}
+
+TEST_F(TestEdgeBarrierController, Unsubscribe)
+{
+ for (int i = 0; i < max_num_monitors; ++i)
+ {
+ bc.Unsubscribe(&subscribers_[i], i);
+ ASSERT_EQ(bc.GetSubscriber(i), nullptr);
+ }
+}
+
+TEST_F(TestEdgeBarrierController, UnsubscribeInvalid)
+{
+ bc.Unsubscribe(&subscribers_[2], 1);
+ ASSERT_EQ(bc.GetSubscriber(2), &subscribers_[2]);
+}
+
+TEST_F(TestEdgeBarrierController, SubscriberReplace)
+{
+ TestBarrierSubscriber handling_subscriber(true);
+ bc.Subscribe(&handling_subscriber, 0);
+ EXPECT_EQ(bc.GetSubscriber(0), &handling_subscriber);
+}
+
+TEST_F(TestEdgeBarrierController, ProcessHandledEvent)
+{
+ int monitor = 0;
+
+ TestBarrierSubscriber handling_subscriber(true);
+ bc.Subscribe(&handling_subscriber, monitor);
+
+ MockPointerBarrier owner(monitor);
+ auto breaking_barrier_event = MakeBarrierEvent(0, true);
+
+ EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0);
+ bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
+}
+
+TEST_F(TestEdgeBarrierController, ProcessHandledEventOnReleasedBarrier)
+{
+ int monitor = max_num_monitors-1;
+
+ TestBarrierSubscriber handling_subscriber(true);
+ bc.Subscribe(&handling_subscriber, monitor);
+
+ MockPointerBarrier owner(monitor, true);
+ auto breaking_barrier_event = MakeBarrierEvent(0, true);
+
+ EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0);
+ bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
+}
+
+TEST_F(TestEdgeBarrierController, ProcessUnHandledEventBreakingBarrier)
+{
+ int monitor = 1;
+
+ MockPointerBarrier owner(monitor);
+ int breaking_id = 12345;
+ auto breaking_barrier_event = MakeBarrierEvent(breaking_id, true);
+
+ EXPECT_CALL(owner, ReleaseBarrier(breaking_id));
+ bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
+}
+
+TEST_F(TestEdgeBarrierController, ProcessUnHandledEventBreakingBarrierOnMaxMonitor)
+{
+ int monitor = max_num_monitors;
+
+ MockPointerBarrier owner(monitor);
+ auto breaking_barrier_event = MakeBarrierEvent(0, true);
+
+ // This was leading to a crash, see bug #1020075
+ // you can reproduce this repeating this test multiple times using the
+ // --gtest_repeat=X command line
+ EXPECT_CALL(owner, ReleaseBarrier(_));
+ bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
+}
+
+TEST_F(TestEdgeBarrierController, ProcessUnHandledEventNotBreakingBarrier)
+{
+ int monitor = 2;
+
+ MockPointerBarrier owner(monitor);
+ int not_breaking_id = 54321;
+ auto not_breaking_barrier_event = MakeBarrierEvent(not_breaking_id, false);
+
+ EXPECT_CALL(owner, ReleaseBarrier(not_breaking_id)).Times(0);
+ bc.ProcessBarrierEvent(&owner, not_breaking_barrier_event);
+}
+
+TEST_F(TestEdgeBarrierController, ProcessUnHandledEventOnReleasedBarrier)
+{
+ int monitor = 2;
+
+ MockPointerBarrier owner(monitor, true);
+ int not_breaking_id = 345678;
+ auto not_breaking_barrier_event = MakeBarrierEvent(not_breaking_id, false);
+
+ EXPECT_CALL(owner, ReleaseBarrier(not_breaking_id));
+ bc.ProcessBarrierEvent(&owner, not_breaking_barrier_event);
+}
+
+TEST_F(TestEdgeBarrierController, BreakingEdgeTemporaryReleasesBarrier)
+{
+ MockPointerBarrier owner;
+
+ EXPECT_CALL(owner, ReleaseBarrier(1));
+ bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(1, true));
+ ASSERT_TRUE(owner.released());
+
+ Utils::WaitForTimeoutMSec(bc.options()->edge_passed_disabled_ms);
+ EXPECT_FALSE(owner.released());
+}
+
+TEST_F(TestEdgeBarrierController, BreakingEdgeTemporaryReleasesBarrierForNotHandledEvents)
+{
+ MockPointerBarrier owner;
+ int monitor = 0;
+ subscribers_[monitor].handles_ = false;
+
+ EXPECT_CALL(owner, ReleaseBarrier(5));
+ bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true));
+ ASSERT_TRUE(owner.released());
+
+ subscribers_[monitor].handles_ = false;
+ EXPECT_CALL(owner, ReleaseBarrier(6));
+ bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(6, false));
+}
+
+TEST_F(TestEdgeBarrierController, BreakingEdgeDontReleasesBarrierForHandledEvents)
+{
+ MockPointerBarrier owner;
+ int monitor = 0;
+ subscribers_[monitor].handles_ = false;
+
+ EXPECT_CALL(owner, ReleaseBarrier(5));
+ bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true));
+ ASSERT_TRUE(owner.released());
+
+ subscribers_[monitor].handles_ = true;
+ EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0);
+ bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(6, true));
+}
+
+TEST_F(TestEdgeBarrierController, StickyEdgePropertyProxiesLauncherOption)
+{
+ bc.options()->edge_resist = false;
+ EXPECT_FALSE(bc.sticky_edges());
+
+ bc.options()->edge_resist = true;
+ EXPECT_TRUE(bc.sticky_edges());
+
+ bc.sticky_edges = false;
+ EXPECT_FALSE(bc.options()->edge_resist());
+
+ bc.sticky_edges = true;
+ EXPECT_TRUE(bc.options()->edge_resist());
+}
+
+}
diff --git a/tests/test_favorite_store_gsettings.cpp b/tests/test_favorite_store_gsettings.cpp
index 8609d9379..245fcd001 100644
--- a/tests/test_favorite_store_gsettings.cpp
+++ b/tests/test_favorite_store_gsettings.cpp
@@ -41,10 +41,9 @@ using testing::Eq;
namespace {
// Constant
+const gchar* SETTINGS_NAME = "com.canonical.Unity.Launcher";
+const gchar* SETTINGS_KEY = "favorites";
const gchar* SCHEMA_DIRECTORY = BUILDDIR"/settings";
-const gchar* BASE_STORE_FILE = BUILDDIR"/settings/test-favorite-store-gsettings.store";
-const gchar* BASE_STORE_CONTENTS = "[desktop/unity/launcher]\n" \
- "favorites=['%s', '%s', '%s']";
const char* base_store_favs[] = { BUILDDIR"/tests/data/ubuntuone-installer.desktop",
BUILDDIR"/tests/data/ubuntu-software-center.desktop",
@@ -76,41 +75,33 @@ bool ends_with(std::string const& value, std::string const& suffix)
class TestFavoriteStoreGSettings : public testing::Test
{
public:
- glib::Object<GSettingsBackend> backend;
- std::unique_ptr<internal::FavoriteStoreGSettings> setting_singleton_instance;
+ std::unique_ptr<internal::FavoriteStoreGSettings> favorite_store;
+ glib::Object<GSettings> gsettings_client;
virtual void SetUp()
{
// set the data directory so gsettings can find the schema
- g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIRECTORY, false);
+ g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIRECTORY, true);
+ g_setenv("GSETTINGS_BACKEND", "memory", true);
- glib::Error error;
- glib::String contents(g_strdup_printf(BASE_STORE_CONTENTS,
- base_store_favs[0],
- base_store_favs[1],
- base_store_favs[2]
- ));
+ favorite_store.reset(new internal::FavoriteStoreGSettings());
- g_file_set_contents(BASE_STORE_FILE,
- contents.Value(),
- -1,
- error.AsOutParam());
-
- ASSERT_FALSE(error);
-
- backend = g_keyfile_settings_backend_new(BASE_STORE_FILE, "/", "root");
- setting_singleton_instance.reset(new internal::FavoriteStoreGSettings(backend.RawPtr()));
+ // Setting the test values
+ gsettings_client = g_settings_new(SETTINGS_NAME);
+ g_settings_set_strv(gsettings_client, SETTINGS_KEY, base_store_favs);
}
virtual void TearDown()
{
+ g_setenv("GSETTINGS_SCHEMA_DIR", "", true);
+ g_setenv("GSETTINGS_BACKEND", "", true);
}
-
};
TEST_F(TestFavoriteStoreGSettings, TestAllocation)
{
- EXPECT_TRUE(G_IS_SETTINGS_BACKEND(backend.RawPtr()));
+ FavoriteStore &settings = FavoriteStore::Instance();
+ EXPECT_EQ(&settings, favorite_store.get());
}
TEST_F(TestFavoriteStoreGSettings, TestGetFavorites)
@@ -245,9 +236,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalFirst)
favs.push_back(base_store_favs[0]);
favs.push_back(base_store_favs[1]);
favs.push_back(base_store_favs[2]);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
ASSERT_TRUE(signal_received);
EXPECT_EQ(position, base_store_favs[0]);
@@ -273,9 +262,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalMiddle)
favs.push_back(base_store_favs[1]);
favs.push_back(other_desktop);
favs.push_back(base_store_favs[2]);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
ASSERT_TRUE(signal_received);
EXPECT_EQ(position, base_store_favs[1]);
@@ -301,9 +288,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalEnd)
favs.push_back(base_store_favs[1]);
favs.push_back(base_store_favs[2]);
favs.push_back(other_desktop);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
ASSERT_TRUE(signal_received);
EXPECT_EQ(position, base_store_favs[2]);
@@ -326,9 +311,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteAddedSignalEmpty)
FavoriteList favs;
favs.push_back(other_desktop);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
ASSERT_TRUE(signal_received);
EXPECT_EQ(position, "");
@@ -350,9 +333,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteRemoved)
FavoriteList favs;
favs.push_back(base_store_favs[0]);
favs.push_back(base_store_favs[2]);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
ASSERT_TRUE(signal_received);
EXPECT_EQ(path_removed, base_store_favs[1]);
@@ -372,9 +353,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteReordered)
favs.push_back(base_store_favs[0]);
favs.push_back(base_store_favs[2]);
favs.push_back(base_store_favs[1]);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
ASSERT_TRUE(signal_received);
@@ -382,9 +361,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteReordered)
favs.push_back(base_store_favs[0]);
favs.push_back(base_store_favs[2]);
favs.push_back(base_store_favs[1]);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
ASSERT_FALSE(signal_received);
}
@@ -415,9 +392,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed1)
favs.push_back(base_store_favs[0]);
favs.push_back(base_store_favs[1]);
favs.push_back(other_desktop);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
EXPECT_TRUE(added_received);
EXPECT_TRUE(removed_received);
@@ -450,9 +425,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed2)
favs.push_back(base_store_favs[1]);
favs.push_back(other_desktop);
favs.push_back(base_store_favs[0]);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
EXPECT_TRUE(added_received);
EXPECT_TRUE(removed_received);
@@ -484,9 +457,7 @@ TEST_F(TestFavoriteStoreGSettings, TestFavoriteSignalsMixed3)
FavoriteList favs;
favs.push_back(base_store_favs[1]);
favs.push_back(base_store_favs[0]);
- setting_singleton_instance->SaveFavorites(favs, false);
-
- sleep(1);
+ favorite_store->SaveFavorites(favs, false);
EXPECT_FALSE(added_received);
EXPECT_TRUE(removed_received);
diff --git a/tests/test_filesystem_lenses.cpp b/tests/test_filesystem_lenses.cpp
index aef7c2164..49d7226e3 100644
--- a/tests/test_filesystem_lenses.cpp
+++ b/tests/test_filesystem_lenses.cpp
@@ -31,12 +31,7 @@ void WaitForResult(bool& result)
void WaitForLensesToLoad(FilesystemLenses& lenses)
{
bool result = false;
-
- auto lenses_loaded_cb = [&result]()
- {
- result = true;
- };
- lenses.lenses_loaded.connect(sigc::slot<void>(lenses_loaded_cb));
+ lenses.lenses_loaded.connect([&result] {result = true;});
WaitForResult(result);
EXPECT_TRUE(result);
@@ -61,12 +56,7 @@ TEST(TestFilesystemLenses, TestLensesAdded)
LensDirectoryReader::Ptr test_reader(new LensDirectoryReader(TESTDATADIR"/lenses"));
FilesystemLenses lenses(test_reader);
unsigned int n_lenses = 0;
-
- auto lens_added_cb = [&n_lenses](Lens::Ptr & p)
- {
- n_lenses++;
- };
- lenses.lens_added.connect(sigc::slot<void, Lens::Ptr&>(lens_added_cb));
+ lenses.lens_added.connect([&n_lenses](Lens::Ptr & p) { ++n_lenses; });
WaitForLensesToLoad(lenses);
EXPECT_EQ(n_lenses, (unsigned int)3);
diff --git a/tests/test_glib_signals.cpp b/tests/test_glib_signals.cpp
index e3f0fa34c..7a45821ac 100644
--- a/tests/test_glib_signals.cpp
+++ b/tests/test_glib_signals.cpp
@@ -1,4 +1,5 @@
#include <UnityCore/GLibSignal.h>
+#include <sigc++/sigc++.h>
#include <gtest/gtest.h>
#include "test_glib_signals_utils.h"
@@ -274,6 +275,22 @@ TEST_F(TestGLibSignals, TestCleanDestruction)
signal.Connect(test_signals_, "signal0",
sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
g_object_unref(test_signals_);
+ EXPECT_EQ(signal.object(), nullptr);
+}
+
+TEST_F(TestGLibSignals, TestConnectReplacePreviousConnection)
+{
+ Signal<void, TestSignals*> signal;
+ signal.Connect(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+
+ unsigned signal0_num_cb = 0;
+ signal.Connect(test_signals_, "signal0", [&] (TestSignals*) {++signal0_num_cb;});
+
+ g_signal_emit_by_name(test_signals_, "signal0");
+
+ EXPECT_FALSE(signal0_received_);
+ EXPECT_EQ(signal0_num_cb, 1);
}
TEST_F(TestGLibSignals, TestManagerConstruction)
@@ -403,4 +420,26 @@ TEST_F(TestGLibSignals, TestManagerObjectDisconnection)
EXPECT_FALSE(signal1_received_);
}
+TEST_F(TestGLibSignals, TestManagerUnreffingObjectDeletesConnections)
+{
+ MockSignalManager manager;
+
+ manager.Add<void, TestSignals*>(test_signals_, "signal0",
+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback));
+ manager.Add<void, TestSignals*, const char*>(test_signals_, "signal1",
+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback));
+ manager.Add<void, TestSignals*, const char*, int>(test_signals_, "signal2",
+ sigc::mem_fun(this, &TestGLibSignals::Signal2Callback));
+ manager.Add<void, TestSignals*, const char*, int, float>(test_signals_, "signal3",
+ sigc::mem_fun(this, &TestGLibSignals::Signal3Callback));
+ manager.Add<void, TestSignals*, const char*, int, float, double>(test_signals_, "signal4",
+ sigc::mem_fun(this, &TestGLibSignals::Signal4Callback));
+ manager.Add<void, TestSignals*, const char*, int, float, double, gboolean>(test_signals_, "signal5",
+ sigc::mem_fun(this, &TestGLibSignals::Signal5Callback));
+ manager.Add<gboolean, TestSignals*, const char*, int, float, double, gboolean, char>(test_signals_, "signal6", sigc::mem_fun(this, &TestGLibSignals::Signal6Callback));
+
+ g_object_unref(test_signals_);
+ EXPECT_TRUE(manager.GetConnections().empty());
+}
+
}
diff --git a/tests/test_home_lens.cpp b/tests/test_home_lens.cpp
index 069175ab5..9e5105850 100644
--- a/tests/test_home_lens.cpp
+++ b/tests/test_home_lens.cpp
@@ -63,6 +63,7 @@ public:
ModelType::LOCAL)
{
search_in_global(true);
+ connected.SetGetterFunction(sigc::mem_fun(this, &StaticTestLens::force_connected));
DeeModel* cats = categories()->model();
DeeModel* results = global_results()->model();
@@ -88,6 +89,11 @@ public:
virtual ~StaticTestLens() {}
+ bool force_connected()
+ {
+ return true;
+ }
+
virtual void DoGlobalSearch(string const& search_string)
{
DeeModel* model = global_results()->model();
@@ -258,9 +264,10 @@ TEST(TestHomeLens, TestTwoStaticLenses)
EXPECT_EQ(home_lens_.GetLensAtIndex(1)->id(), "second.lens");
}
-TEST(TestHomeLens, TestCategoryMerging)
+TEST(TestHomeLens, TestCategoryMergingDisplayName)
{
- HomeLens home_lens_("name", "description", "searchhint");
+ HomeLens home_lens_("name", "description", "searchhint",
+ HomeLens::MergeMode::DISPLAY_NAME);
TwoStaticTestLenses lenses_;
DeeModel* cats = home_lens_.categories()->model();
DeeModelIter* iter;
@@ -292,6 +299,27 @@ TEST(TestHomeLens, TestCategoryMerging)
EXPECT_EQ("cat1+second.lens", string(dee_model_get_string(cats, iter, NAME_COLUMN)));
}
+TEST(TestHomeLens, TestCategoryMergingPerLens)
+{
+ HomeLens home_lens_("name", "description", "searchhint",
+ HomeLens::MergeMode::OWNER_LENS);
+ TwoStaticTestLenses lenses_;
+ DeeModel* cats = home_lens_.categories()->model();
+ DeeModelIter* iter;
+ const unsigned int NAME_COLUMN = 0;
+
+ home_lens_.AddLenses(lenses_);
+
+ EXPECT_EQ(dee_model_get_n_rows(cats), 2); // just two lenses
+
+ /* Validate the merged categories */
+ iter = dee_model_get_iter_at_row(cats, 0);
+ EXPECT_EQ("First Lens", string(dee_model_get_string(cats, iter, NAME_COLUMN)));
+
+ iter = dee_model_get_iter_at_row(cats, 1);
+ EXPECT_EQ("Second Lens", string(dee_model_get_string(cats, iter, NAME_COLUMN)));
+}
+
// It's not that we must not support filters. It is just not implemented yet.
// But we actively test against it to make sure we don't end up with broken
// filters in the UI. When/if we land support for filters on the home screen
@@ -307,7 +335,8 @@ TEST(TestHomeLens, TestIgnoreFilters)
TEST(TestHomeLens, TestOneSearch)
{
- HomeLens home_lens_("name", "description", "searchhint");
+ HomeLens home_lens_("name", "description", "searchhint",
+ HomeLens::MergeMode::DISPLAY_NAME);
TwoStaticTestLenses lenses_;
DeeModel* results = home_lens_.results()->model();
DeeModel* cats = home_lens_.categories()->model();
diff --git a/tests/test_icon_loader.cpp b/tests/test_icon_loader.cpp
index a97d0a117..f717bf585 100644
--- a/tests/test_icon_loader.cpp
+++ b/tests/test_icon_loader.cpp
@@ -18,6 +18,7 @@
*/
#include <gmock/gmock.h>
+#include <sigc++/sigc++.h>
#include "IconLoader.h"
@@ -42,7 +43,7 @@ gboolean TimeoutReached (gpointer data)
struct LoadResult
{
- GdkPixbuf *pixbuf;
+ glib::Object<GdkPixbuf> pixbuf;
bool got_callback;
LoadResult() : pixbuf(NULL), got_callback(false) {}
@@ -85,6 +86,28 @@ TEST(TestIconLoader, TestGetOneIcon)
g_source_remove (tid);
}
+TEST(TestIconLoader, TestGetAnnotatedIcon)
+{
+ LoadResult load_result;
+ IconLoader& icon_loader = IconLoader::GetDefault();
+ volatile bool timeout_reached = false;
+
+
+ icon_loader.LoadFromGIconString(". UnityProtocolAnnotatedIcon %7B'base-icon':%20%3C'gedit-icon'%3E,%20'ribbon':%20%3C'foo'%3E%7D", 48, sigc::mem_fun(load_result,
+ &LoadResult::IconLoaded));
+
+ guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached && !load_result.got_callback)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ }
+
+ EXPECT_TRUE(load_result.got_callback);
+ EXPECT_TRUE(IsValidPixbuf(load_result.pixbuf));
+
+ g_source_remove (tid);
+}
+
TEST(TestIconLoader, TestGetOneIconManyTimes)
{
std::vector<LoadResult> results;
diff --git a/tests/test_launcher.cpp b/tests/test_launcher.cpp
new file mode 100644
index 000000000..b6f6e22ad
--- /dev/null
+++ b/tests/test_launcher.cpp
@@ -0,0 +1,158 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#include <list>
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include <Nux/Nux.h>
+#include <Nux/BaseWindow.h>
+
+#include "launcher/DNDCollectionWindow.h"
+#include "launcher/MockLauncherIcon.h"
+#include "launcher/Launcher.h"
+#include "unity-shared/PanelStyle.h"
+#include "unity-shared/UnitySettings.h"
+#include "test_utils.h"
+using namespace unity;
+
+namespace unity
+{
+namespace launcher
+{
+namespace
+{
+
+const int STARTING_ANIMATION_DURATION = 150;
+
+class MockMockLauncherIcon : public launcher::MockLauncherIcon
+{
+public:
+ typedef nux::ObjectPtr<MockMockLauncherIcon> Ptr;
+
+ MOCK_METHOD1(ShouldHighlightOnDrag, bool(DndData const&));
+};
+
+}
+
+class TestLauncher : public Test
+{
+public:
+ TestLauncher()
+ : parent_window_(new nux::BaseWindow("TestLauncherWindow"))
+ , dnd_collection_window_(new DNDCollectionWindow)
+ , model_(new LauncherModel)
+ , options_(new Options)
+ , launcher_(new Launcher(parent_window_, dnd_collection_window_))
+ {
+ launcher_->options = options_;
+ launcher_->SetModel(model_);
+ }
+
+ float IconBackgroundIntensity(AbstractLauncherIcon::Ptr icon, timespec const& current) const
+ {
+ return launcher_->IconBackgroundIntensity(icon, current);
+ }
+
+ nux::BaseWindow* parent_window_;
+ nux::ObjectPtr<DNDCollectionWindow> dnd_collection_window_;
+ Settings settings;
+ panel::Style panel_style;
+ LauncherModel::Ptr model_;
+ Options::Ptr options_;
+ nux::ObjectPtr<Launcher> launcher_;
+};
+
+TEST_F(TestLauncher, TestQuirksDuringDnd)
+{
+ MockMockLauncherIcon::Ptr first(new MockMockLauncherIcon);
+ model_->AddIcon(first);
+
+ MockMockLauncherIcon::Ptr second(new MockMockLauncherIcon);
+ model_->AddIcon(second);
+
+ MockMockLauncherIcon::Ptr third(new MockMockLauncherIcon);
+ model_->AddIcon(third);
+
+ EXPECT_CALL(*first, ShouldHighlightOnDrag(_))
+ .WillRepeatedly(Return(true));
+
+ EXPECT_CALL(*second, ShouldHighlightOnDrag(_))
+ .WillRepeatedly(Return(true));
+
+ EXPECT_CALL(*third, ShouldHighlightOnDrag(_))
+ .WillRepeatedly(Return(false));
+
+ std::list<char*> uris;
+ dnd_collection_window_->collected.emit(uris);
+
+ Utils::WaitForTimeout(1);
+
+ EXPECT_FALSE(first->GetQuirk(launcher::AbstractLauncherIcon::Quirk::DESAT));
+ EXPECT_FALSE(second->GetQuirk(launcher::AbstractLauncherIcon::Quirk::DESAT));
+ EXPECT_TRUE(third->GetQuirk(launcher::AbstractLauncherIcon::Quirk::DESAT));
+}
+
+TEST_F(TestLauncher, TestMouseWheelScroll)
+{
+ int initial_scroll_delta;
+
+ launcher_->SetHover(true);
+ initial_scroll_delta = launcher_->GetDragDelta();
+
+ // scroll down
+ launcher_->RecvMouseWheel(0,0,20,0,0);
+ EXPECT_EQ((launcher_->GetDragDelta() - initial_scroll_delta), 25);
+
+ // scroll up
+ launcher_->RecvMouseWheel(0,0,-20,0,0);
+ EXPECT_EQ(launcher_->GetDragDelta(), initial_scroll_delta);
+
+ launcher_->SetHover(false);
+}
+
+TEST_F(TestLauncher, TestIconBackgroundIntensity)
+{
+ MockMockLauncherIcon::Ptr first(new MockMockLauncherIcon);
+ model_->AddIcon(first);
+
+ MockMockLauncherIcon::Ptr second(new MockMockLauncherIcon);
+ model_->AddIcon(second);
+
+ MockMockLauncherIcon::Ptr third(new MockMockLauncherIcon);
+ model_->AddIcon(third);
+
+ options_->backlight_mode = BACKLIGHT_NORMAL;
+ options_->launch_animation = LAUNCH_ANIMATION_PULSE;
+
+ first->SetQuirk(AbstractLauncherIcon::Quirk::RUNNING, true);
+ second->SetQuirk(AbstractLauncherIcon::Quirk::RUNNING, true);
+ third->SetQuirk(AbstractLauncherIcon::Quirk::RUNNING, false);
+
+ Utils::WaitForTimeoutMSec(STARTING_ANIMATION_DURATION);
+ timespec current;
+ clock_gettime(CLOCK_MONOTONIC, &current);
+
+ EXPECT_THAT(IconBackgroundIntensity(first, current), Gt(0.0f));
+ EXPECT_THAT(IconBackgroundIntensity(second, current), Gt(0.0f));
+ EXPECT_EQ(IconBackgroundIntensity(third, current), 0.0f);
+}
+
+}
+}
diff --git a/tests/test_launcher_controller.cpp b/tests/test_launcher_controller.cpp
new file mode 100644
index 000000000..16fbbf5ee
--- /dev/null
+++ b/tests/test_launcher_controller.cpp
@@ -0,0 +1,233 @@
+/*
+ * 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: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
+ */
+
+#include <gmock/gmock.h>
+#include "test_uscreen_mock.h"
+
+#include "FavoriteStore.h"
+#include "LauncherController.h"
+#include "LauncherControllerPrivate.h"
+#include "PanelStyle.h"
+#include "UnitySettings.h"
+
+using namespace unity::launcher;
+using namespace testing;
+
+namespace unity
+{
+
+class MockFavoriteStore : public FavoriteStore
+{
+public:
+ FavoriteList const& GetFavorites()
+ {
+ return fav_list_;
+ };
+
+ void AddFavorite(std::string const& desktop_path, int position) {};
+ void RemoveFavorite(std::string const& desktop_path) {};
+ void MoveFavorite(std::string const& desktop_path, int position) {};
+ void SetFavorites(FavoriteList const& desktop_paths) {};
+
+private:
+ FavoriteList fav_list_;
+};
+
+class MockBamfLauncherIcon : public BamfLauncherIcon
+{
+public:
+ //typedef nux::ObjectPtr<MockMockLauncherIcon> Ptr;
+ MockBamfLauncherIcon(BamfApplication* app)
+ : BamfLauncherIcon(app) {}
+
+ MOCK_METHOD0(UnStick, void());
+ MOCK_METHOD0(Quit, void());
+};
+
+namespace launcher
+{
+class TestLauncherController : public testing::Test
+{
+public:
+ TestLauncherController()
+ : lc(nux::GetGraphicsDisplay()->GetX11Display())
+ {}
+
+ virtual void SetUp()
+ {
+ lc.options = std::make_shared<Options>();
+ lc.multiple_launchers = true;
+ }
+
+protected:
+ ui::EdgeBarrierController &GetBarrierController()
+ {
+ return lc.pimpl->edge_barriers_;
+ }
+
+ LauncherModel::Ptr GetLauncherModel()
+ {
+ return lc.pimpl->model_;
+ }
+
+ MockUScreen uscreen;
+ Settings settings;
+ panel::Style panel_style;
+ MockFavoriteStore favorite_store;
+ Controller lc;
+};
+}
+
+TEST_F(TestLauncherController, Construction)
+{
+ EXPECT_NE(lc.options(), nullptr);
+ EXPECT_TRUE(lc.multiple_launchers());
+}
+
+TEST_F(TestLauncherController, MultimonitorMultipleLaunchers)
+{
+ lc.multiple_launchers = true;
+ uscreen.SetupFakeMultiMonitor();
+
+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
+
+ for (int i = 0; i < max_num_monitors; ++i)
+ {
+ EXPECT_EQ(lc.launchers()[i]->monitor(), i);
+ }
+}
+
+TEST_F(TestLauncherController, MultimonitorSingleLauncher)
+{
+ lc.multiple_launchers = false;
+ uscreen.SetupFakeMultiMonitor(0, false);
+
+ for (int i = 0; i < max_num_monitors; ++i)
+ {
+ uscreen.SetPrimary(i);
+ ASSERT_EQ(lc.launchers().size(), 1);
+ EXPECT_EQ(lc.launcher().monitor(), i);
+ }
+}
+
+TEST_F(TestLauncherController, MultimonitorSwitchToMultipleLaunchers)
+{
+ lc.multiple_launchers = false;
+ uscreen.SetupFakeMultiMonitor();
+
+ ASSERT_EQ(lc.launchers().size(), 1);
+
+ lc.multiple_launchers = true;
+ EXPECT_EQ(lc.launchers().size(), max_num_monitors);
+}
+
+TEST_F(TestLauncherController, MultimonitorSwitchToSingleLauncher)
+{
+ lc.multiple_launchers = true;
+ int primary = 3;
+ uscreen.SetupFakeMultiMonitor(primary);
+
+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
+
+ lc.multiple_launchers = false;
+ EXPECT_EQ(lc.launchers().size(), 1);
+ EXPECT_EQ(lc.launcher().monitor(), primary);
+}
+
+TEST_F(TestLauncherController, MultimonitorSwitchToSingleMonitor)
+{
+ uscreen.SetupFakeMultiMonitor();
+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
+
+ uscreen.Reset();
+ EXPECT_EQ(lc.launchers().size(), 1);
+ EXPECT_EQ(lc.launcher().monitor(), 0);
+}
+
+TEST_F(TestLauncherController, MultimonitorRemoveMiddleMonitor)
+{
+ uscreen.SetupFakeMultiMonitor();
+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
+
+ std::vector<nux::Geometry> &monitors = uscreen.GetMonitors();
+ monitors.erase(monitors.begin() + monitors.size()/2);
+ uscreen.changed.emit(uscreen.GetPrimaryMonitor(), uscreen.GetMonitors());
+ ASSERT_EQ(lc.launchers().size(), max_num_monitors - 1);
+
+ for (int i = 0; i < max_num_monitors - 1; ++i)
+ EXPECT_EQ(lc.launchers()[i]->monitor(), i);
+}
+
+TEST_F(TestLauncherController, SingleMonitorSwitchToMultimonitor)
+{
+ ASSERT_EQ(lc.launchers().size(), 1);
+
+ uscreen.SetupFakeMultiMonitor();
+
+ EXPECT_EQ(lc.launchers().size(), max_num_monitors);
+}
+
+TEST_F(TestLauncherController, MultiMonitorEdgeBarrierSubscriptions)
+{
+ uscreen.SetupFakeMultiMonitor();
+
+ for (int i = 0; i < max_num_monitors; ++i)
+ ASSERT_EQ(GetBarrierController().GetSubscriber(i), lc.launchers()[i].GetPointer());
+}
+
+TEST_F(TestLauncherController, SingleMonitorEdgeBarrierSubscriptionsUpdates)
+{
+ lc.multiple_launchers = false;
+ uscreen.SetupFakeMultiMonitor(0, false);
+
+ for (int i = 0; i < max_num_monitors; ++i)
+ {
+ uscreen.SetPrimary(i);
+
+ for (int j = 0; j < max_num_monitors; ++j)
+ {
+ if (j == i)
+ {
+ ASSERT_EQ(GetBarrierController().GetSubscriber(j), &lc.launcher());
+ }
+ else
+ {
+ ASSERT_EQ(GetBarrierController().GetSubscriber(j), nullptr);
+ }
+ }
+ }
+}
+
+TEST_F(TestLauncherController, OnlyUnstickIconOnFavoriteRemoval)
+{
+ const std::string USC_DESKTOP = BUILDDIR"/tests/data/ubuntu-software-center.desktop";
+
+ glib::Object<BamfMatcher> matcher(bamf_matcher_get_default());
+
+ auto bamf_app = bamf_matcher_get_application_for_desktop_file(matcher, USC_DESKTOP.c_str(), TRUE);
+ MockBamfLauncherIcon *bamf_icon = new MockBamfLauncherIcon(bamf_app);
+ GetLauncherModel()->AddIcon(AbstractLauncherIcon::Ptr(bamf_icon));
+
+ EXPECT_CALL(*bamf_icon, UnStick());
+ EXPECT_CALL(*bamf_icon, Quit()).Times(0);
+
+ favorite_store.favorite_removed.emit(USC_DESKTOP);
+}
+
+}
diff --git a/tests/test_lens.cpp b/tests/test_lens.cpp
index 0c222f512..c0c2f678b 100644
--- a/tests/test_lens.cpp
+++ b/tests/test_lens.cpp
@@ -6,7 +6,9 @@
#include <UnityCore/GLibWrapper.h>
#include <UnityCore/Lens.h>
#include <UnityCore/MultiRangeFilter.h>
-#include <UnityCore/MusicPreviews.h>
+#include <UnityCore/Preview.h>
+#include <UnityCore/MoviePreview.h>
+#include <UnityCore/Variant.h>
#include <UnityCore/RadioOptionFilter.h>
#include <UnityCore/RatingsFilter.h>
@@ -52,7 +54,7 @@ public:
void WaitForConnected()
{
bool timeout_reached = false;
- guint32 timeout_id = Utils::ScheduleTimeout(&timeout_reached);
+ guint32 timeout_id = Utils::ScheduleTimeout(&timeout_reached, 2000);
while (!lens_->connected && !timeout_reached)
{
@@ -68,7 +70,7 @@ public:
void WaitForModel(Model<Adaptor>* model, unsigned int n_rows)
{
bool timeout_reached = false;
- guint32 timeout_id = Utils::ScheduleTimeout(&timeout_reached);
+ guint32 timeout_id = Utils::ScheduleTimeout(&timeout_reached, 2000);
while (model->count != n_rows && !timeout_reached)
{
@@ -190,7 +192,7 @@ TEST_F(TestLens, TestGlobalSearch)
TEST_F(TestLens, TestActivation)
{
std::string uri = PopulateAndGetFirstResultURI();
-
+
bool activated = false;
auto activated_cb = [&activated, &uri] (std::string const& uri_,
HandledType handled,
@@ -201,45 +203,101 @@ TEST_F(TestLens, TestActivation)
EXPECT_EQ(hints.size(), 0);
activated = true;
};
- lens_->activated.connect(sigc::slot<void, std::string const&, HandledType,Lens::Hints const&>(activated_cb));
-
+ lens_->activated.connect(activated_cb);
+
lens_->Activate(uri);
Utils::WaitUntil(activated);
}
TEST_F(TestLens, TestPreview)
{
- // FIXME: fix up when unity-core supports current preview protocol
- /*
std::string uri = PopulateAndGetFirstResultURI();
bool previewed = false;
auto preview_cb = [&previewed, &uri] (std::string const& uri_,
- Preview::Ptr preview)
+ Preview::Ptr const& preview)
{
EXPECT_EQ(uri, uri_);
- EXPECT_EQ(preview->renderer_name, "preview-generic");
-
- TrackPreview::Ptr track_preview = std::static_pointer_cast<TrackPreview>(preview);
- EXPECT_EQ(track_preview->number, (unsigned int)1);
- EXPECT_EQ(track_preview->title, "Animus Vox");
- EXPECT_EQ(track_preview->artist, "The Glitch Mob");
- EXPECT_EQ(track_preview->album, "Drink The Sea");
- EXPECT_EQ(track_preview->length, (unsigned int)404);
- EXPECT_EQ(track_preview->album_cover, "file://music/the/track");
- EXPECT_EQ(track_preview->primary_action_name, "Play");
- EXPECT_EQ(track_preview->primary_action_icon_hint, "");
- EXPECT_EQ(track_preview->primary_action_uri, "play://music/the/track");
- EXPECT_EQ(track_preview->play_action_uri, "preview://music/the/track");
- EXPECT_EQ(track_preview->pause_action_uri, "pause://music/the/track");
- EXPECT_EQ(track_preview->genres.size(), (unsigned int)1);
+ EXPECT_EQ(preview->renderer_name, "preview-movie");
+
+ auto movie_preview = std::dynamic_pointer_cast<MoviePreview>(preview);
+ EXPECT_EQ(movie_preview->title, "A movie");
+ EXPECT_EQ(movie_preview->subtitle, "With subtitle");
+ EXPECT_EQ(movie_preview->description, "And description");
+
previewed = true;
};
- lens_->preview_ready.connect(sigc::slot<void, std::string const&, Preview::Ptr>(preview_cb));
+
+ lens_->preview_ready.connect(preview_cb);
lens_->Preview(uri);
Utils::WaitUntil(previewed);
- */
+}
+
+TEST_F(TestLens, TestPreviewAction)
+{
+ std::string uri = PopulateAndGetFirstResultURI();
+ bool previewed = false;
+ Preview::Ptr preview;
+
+ auto preview_cb = [&previewed, &uri, &preview]
+ (std::string const& uri_,
+ Preview::Ptr const& preview_)
+ {
+ EXPECT_EQ(uri, uri_);
+ EXPECT_EQ(preview_->renderer_name, "preview-movie");
+
+ preview = preview_;
+ previewed = true;
+ };
+
+ lens_->preview_ready.connect(preview_cb);
+ lens_->Preview(uri);
+
+ Utils::WaitUntil(previewed);
+
+ bool action_executed = false;
+ auto activated_cb = [&action_executed] (std::string const& uri,
+ HandledType handled_type,
+ Lens::Hints const& hints)
+ {
+ EXPECT_EQ(handled_type, HandledType::SHOW_DASH);
+ action_executed = true;
+ };
+
+ lens_->activated.connect(activated_cb);
+ EXPECT_GT(preview->GetActions().size(), (unsigned)0);
+ auto action = preview->GetActions()[0];
+ preview->PerformAction(action->id);
+
+ Utils::WaitUntil(action_executed);
+}
+
+TEST_F(TestLens, TestEmitClosedSignal)
+{
+ std::string uri = PopulateAndGetFirstResultURI();
+ bool previewed = false;
+ MoviePreview::Ptr movie_preview;
+
+ auto preview_cb = [&previewed, &uri, &movie_preview]
+ (std::string const& uri_,
+ Preview::Ptr const& preview)
+ {
+ EXPECT_EQ(uri, uri_);
+ EXPECT_EQ(preview->renderer_name, "preview-movie");
+
+ movie_preview = std::dynamic_pointer_cast<MoviePreview>(preview);
+
+ //there isn't anything we can really test here - other than it's not crashing here
+ movie_preview->EmitClosed();
+
+ previewed = true;
+ };
+
+ lens_->preview_ready.connect(preview_cb);
+ lens_->Preview(uri);
+
+ Utils::WaitUntil(previewed);
}
TEST_F(TestLens, TestFilterSync)
diff --git a/tests/test_model_iterator.cpp b/tests/test_model_iterator.cpp
new file mode 100644
index 000000000..1d90551f9
--- /dev/null
+++ b/tests/test_model_iterator.cpp
@@ -0,0 +1,126 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Michal Hruby <michal.hruby@canonical.com>
+ */
+
+#include <list>
+#include <algorithm>
+#include <gmock/gmock.h>
+#include <UnityCore/GLibWrapper.h>
+#include <UnityCore/Results.h>
+#include <UnityCore/ResultIterator.h>
+
+#include <dee.h>
+
+using namespace std;
+using namespace testing;
+using namespace unity;
+using namespace unity::glib;
+using namespace unity::dash;
+
+namespace
+{
+
+class TestResultIterator : public ::testing::Test
+{
+public:
+ TestResultIterator()
+ : results(new Results(ModelType::LOCAL))
+ {
+ dee_model_set_schema (results->model(),
+ "s", "s", "u", "s", "s", "s", "s", NULL);
+ }
+
+ void AddResult(std::string const& uri, std::string const& name)
+ {
+ dee_model_append(results->model(),
+ uri.c_str(), // uri
+ "icon", // icon-hint
+ 0, // category
+ "text/plain", // mimetype
+ name.c_str(), // display name
+ "", // comment
+ uri.c_str()); // dnd-uri
+ }
+
+ Results::Ptr results;
+};
+
+TEST_F(TestResultIterator, TestNullModel)
+{
+ Object<DeeModel> model;
+ ResultIterator it(model);
+
+ EXPECT_TRUE(it.IsLast());
+ // first could be undefined, but let's make sure the behaviour doesn't change
+ EXPECT_TRUE(it.IsFirst());
+}
+
+TEST_F(TestResultIterator, TestEmpty)
+{
+ ResultIterator it(results->model());
+
+ EXPECT_TRUE(it.IsLast());
+ // first could be undefined, but let's make sure the behaviour doesn't change
+ EXPECT_TRUE(it.IsFirst());
+}
+
+TEST_F(TestResultIterator, TestNonEmpty)
+{
+ AddResult("mailto:nospam@example.org", "Email");
+
+ ResultIterator it(results->model());
+
+ EXPECT_TRUE(it.IsFirst());
+ EXPECT_FALSE(it.IsLast());
+}
+
+TEST_F(TestResultIterator, TestCopy)
+{
+ AddResult("mailto:nospam@example.org", "Email");
+
+ ResultIterator one(results->model());
+ ResultIterator two(one);
+
+ EXPECT_EQ(one, two);
+
+ ResultIterator const& original = two++;
+ EXPECT_EQ(original, one);
+ EXPECT_NE(one, two);
+}
+
+TEST_F(TestResultIterator, TestIncrement)
+{
+ AddResult("file:///foo.txt", "Result #1");
+ AddResult("file:///qoo.txt", "Result #2");
+
+ ResultIterator it(results->model());
+
+ EXPECT_EQ((*it).uri, "file:///foo.txt");
+ EXPECT_EQ((*it).name, "Result #1");
+
+ it++;
+ EXPECT_EQ((*it).uri, "file:///qoo.txt");
+ EXPECT_EQ((*it).name, "Result #2");
+
+ it++;
+ EXPECT_TRUE(it.IsLast());
+ EXPECT_FALSE(it.IsFirst());
+}
+
+
+} // Namespace
diff --git a/tests/test_panel_style.cpp b/tests/test_panel_style.cpp
new file mode 100644
index 000000000..3e795c3d4
--- /dev/null
+++ b/tests/test_panel_style.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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: Andrea Azzarone <andrea.azzarone@canonical.com>
+ *
+ */
+
+#include <config.h>
+
+#include <gio/gio.h>
+#include <gtest/gtest.h>
+
+#include "unity-shared/PanelStyle.h"
+#include "unity-shared/UnitySettings.h"
+
+using namespace unity;
+using namespace testing;
+
+namespace
+{
+
+const std::string TITLEBAR_FONT = "Ubuntu Bold 11";
+
+class TestPanelStyle : public Test
+{
+public:
+ glib::Object<GSettings> gsettings;
+ Settings unity_settings;
+ std::unique_ptr<panel::Style> panel_style_instance;
+
+ /* override */ void SetUp()
+ {
+ g_setenv("GSETTINGS_BACKEND", "memory", TRUE);
+
+ gsettings = g_settings_new("org.gnome.desktop.wm.preferences");
+ g_settings_set_string(gsettings, "titlebar-font", TITLEBAR_FONT.c_str());
+
+ panel_style_instance.reset(new panel::Style());
+ }
+
+ /* override */ void TearDown()
+ {
+ g_setenv("GSETTINGS_BACKEND", "", TRUE);
+ }
+};
+
+TEST_F(TestPanelStyle, TestGetFontDescription)
+{
+ ASSERT_EQ(panel_style_instance->GetFontDescription(panel::PanelItem::TITLE), TITLEBAR_FONT);
+}
+
+TEST_F(TestPanelStyle, TestChangedSignal)
+{
+ bool signal_received = false;
+
+ panel_style_instance->changed.connect([&](){
+ signal_received = true;
+ });
+
+ g_settings_set_string(gsettings, "titlebar-font", "Ubuntu Italic 11");
+
+ sleep(1);
+
+ ASSERT_TRUE(signal_received);
+ ASSERT_EQ(panel_style_instance->GetFontDescription(panel::PanelItem::TITLE), "Ubuntu Italic 11");
+}
+
+}
diff --git a/tests/test_pointer_barrier.cpp b/tests/test_pointer_barrier.cpp
new file mode 100644
index 000000000..5c07e0d4b
--- /dev/null
+++ b/tests/test_pointer_barrier.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <limits>
+
+#include "test_utils.h"
+#include "PointerBarrier.h"
+
+using namespace unity::ui;
+
+namespace
+{
+
+class MockPointerBarrier : public PointerBarrierWrapper
+{
+public:
+ bool HandleEvent(XEvent ev) { return PointerBarrierWrapper::HandleEvent(ev); }
+};
+
+TEST(TestPointerBarrier, Construction)
+{
+ PointerBarrierWrapper pb;
+
+ EXPECT_EQ(pb.active, false);
+ EXPECT_EQ(pb.released, false);
+ EXPECT_EQ(pb.smoothing, 75);
+ EXPECT_EQ(pb.max_velocity_multiplier, 1.0f);
+ EXPECT_EQ(pb.direction, BOTH);
+}
+
+TEST(TestPointerBarrier, EventConstruction)
+{
+ BarrierEvent bev(1, 2, 3, 4);
+ EXPECT_EQ(bev.x, 1);
+ EXPECT_EQ(bev.y, 2);
+ EXPECT_EQ(bev.velocity, 3);
+ EXPECT_EQ(bev.event_id, 4);
+}
+
+TEST(TestPointerBarrier, HandleInvalidEvents)
+{
+ MockPointerBarrier pb;
+ XFixesBarrierNotifyEvent ev;
+ auto xev = reinterpret_cast<XEvent*>(&ev);
+
+ ev.type = XFixesBarrierNotify + 1;
+ EXPECT_FALSE(pb.HandleEvent(*xev));
+
+ ev.type = XFixesBarrierNotify;
+ ev.subtype = XFixesBarrierHitNotify + 1;
+ ev.barrier = 1;
+ EXPECT_FALSE(pb.HandleEvent(*xev));
+
+ ev.barrier = 0;
+ EXPECT_TRUE(pb.HandleEvent(*xev));
+}
+
+TEST(TestPointerBarrier, HandleHitNotifyEvents)
+{
+ MockPointerBarrier pb;
+ XFixesBarrierNotifyEvent ev;
+ auto xev = reinterpret_cast<XEvent*>(&ev);
+
+ ev.type = XFixesBarrierNotify;
+ ev.subtype = XFixesBarrierHitNotify;
+ ev.barrier = 0;
+ ev.event_id = 0xdeadbeef;
+ ev.x = 555;
+ ev.y = 333;
+ ev.velocity = std::numeric_limits<int>::max();
+
+ bool got_event = false;
+
+ pb.barrier_event.connect([&] (PointerBarrierWrapper* pbw, BarrierEvent::Ptr bev) {
+ got_event = true;
+
+ EXPECT_EQ(pbw, &pb);
+ EXPECT_EQ(bev->x, ev.x);
+ EXPECT_EQ(bev->y, ev.y);
+ EXPECT_EQ(bev->velocity, 600 * pb.max_velocity_multiplier);
+ EXPECT_EQ(bev->event_id, ev.event_id);
+ });
+
+ EXPECT_TRUE(pb.HandleEvent(*xev));
+ EXPECT_FALSE(got_event);
+
+ Utils::WaitForTimeoutMSec(pb.smoothing());
+
+ EXPECT_TRUE(got_event);
+}
+
+TEST(TestPointerBarrier, HandleHitNotifyReleasedEvents)
+{
+ MockPointerBarrier pb;
+ XFixesBarrierNotifyEvent ev;
+ auto xev = reinterpret_cast<XEvent*>(&ev);
+
+ ev.type = XFixesBarrierNotify;
+ ev.subtype = XFixesBarrierHitNotify;
+ ev.barrier = 0;
+ ev.event_id = 0xabba;
+ ev.x = 3333;
+ ev.y = 5555;
+ ev.velocity = std::numeric_limits<int>::max();
+
+ bool got_event = false;
+
+ pb.barrier_event.connect([&] (PointerBarrierWrapper* pbw, BarrierEvent::Ptr bev) {
+ got_event = true;
+
+ EXPECT_EQ(pbw, &pb);
+ EXPECT_EQ(bev->x, ev.x);
+ EXPECT_EQ(bev->y, ev.y);
+ EXPECT_EQ(bev->velocity, ev.velocity);
+ EXPECT_EQ(bev->event_id, ev.event_id);
+ });
+
+ pb.released = true;
+ EXPECT_TRUE(pb.HandleEvent(*xev));
+ EXPECT_TRUE(got_event);
+}
+
+}
diff --git a/tests/test_previews.cpp b/tests/test_previews.cpp
new file mode 100644
index 000000000..a688c7727
--- /dev/null
+++ b/tests/test_previews.cpp
@@ -0,0 +1,266 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2011 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
+ */
+
+#include <list>
+#include <algorithm>
+#include <gmock/gmock.h>
+#include <gio/gio.h>
+#include <UnityCore/Variant.h>
+#include <UnityCore/Preview.h>
+#include <UnityCore/ApplicationPreview.h>
+#include <UnityCore/MoviePreview.h>
+#include <UnityCore/MusicPreview.h>
+#include <UnityCore/SeriesPreview.h>
+#include <unity-protocol.h>
+
+using namespace std;
+using namespace testing;
+using namespace unity;
+using namespace unity::glib;
+using namespace unity::dash;
+
+namespace
+{
+
+bool IsVariant(Variant const& variant)
+{
+ return g_variant_get_type_string(variant) != NULL;
+}
+
+TEST(TestPreviews, DeserializeGeneric)
+{
+ Object<GIcon> icon(g_icon_new_for_string("accessories", NULL));
+ Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_generic_preview_new()));
+ unity_protocol_preview_set_title(proto_obj, "Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Description");
+ unity_protocol_preview_set_image(proto_obj, icon);
+ unity_protocol_preview_set_image_source_uri(proto_obj, "Source");
+
+ Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())),
+ glib::StealRef());
+ EXPECT_TRUE(IsVariant(v));
+
+ Preview::Ptr preview = Preview::PreviewForVariant(v);
+ EXPECT_TRUE(preview != nullptr);
+
+ EXPECT_EQ(preview->renderer_name, "preview-generic");
+ EXPECT_EQ(preview->title, "Title");
+ EXPECT_EQ(preview->subtitle, "Subtitle");
+ EXPECT_EQ(preview->description, "Description");
+ EXPECT_EQ(preview->image_source_uri, "Source");
+ EXPECT_TRUE(g_icon_equal(preview->image(), icon) != FALSE);
+}
+
+TEST(TestPreviews, DeserializeGenericWithMeta)
+{
+ Object<GIcon> icon(g_icon_new_for_string("accessories", NULL));
+ Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_generic_preview_new()));
+ unity_protocol_preview_set_title(proto_obj, "Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Description");
+ unity_protocol_preview_set_image(proto_obj, icon);
+ unity_protocol_preview_set_image_source_uri(proto_obj, "Source");
+ unity_protocol_preview_add_action(proto_obj, "action1", "Action #1", NULL, 0);
+ unity_protocol_preview_add_action(proto_obj, "action2", "Action #2", NULL, 0);
+ unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("i", 34));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint"));
+
+ Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())),
+ glib::StealRef());
+ EXPECT_TRUE(IsVariant(v));
+
+ Preview::Ptr preview = Preview::PreviewForVariant(v);
+ EXPECT_TRUE(preview != nullptr);
+
+ EXPECT_EQ(preview->renderer_name, "preview-generic");
+ EXPECT_EQ(preview->title, "Title");
+ EXPECT_EQ(preview->subtitle, "Subtitle");
+ EXPECT_EQ(preview->description, "Description");
+ EXPECT_TRUE(g_icon_equal(preview->image(), icon) != FALSE);
+ EXPECT_EQ(preview->image_source_uri, "Source");
+
+ auto actions = preview->GetActions();
+ auto info_hints = preview->GetInfoHints();
+
+ EXPECT_EQ(actions.size(), 2);
+
+ auto action1 = actions[0];
+ EXPECT_EQ(action1->id, "action1");
+ EXPECT_EQ(action1->display_name, "Action #1");
+ EXPECT_EQ(action1->icon_hint, "");
+ EXPECT_EQ(action1->layout_hint, 0);
+
+ auto action2 = actions[1];
+ EXPECT_EQ(action2->id, "action2");
+ EXPECT_EQ(action2->display_name, "Action #2");
+ EXPECT_EQ(action2->icon_hint, "");
+
+ EXPECT_EQ(info_hints.size(), 2);
+ auto hint1 = info_hints[0];
+ EXPECT_EQ(hint1->id, "hint1");
+ EXPECT_EQ(hint1->display_name, "Hint 1");
+ EXPECT_EQ(hint1->icon_hint, "");
+ EXPECT_EQ(hint1->value.GetInt(), 34);
+ auto hint2 = info_hints[1];
+ EXPECT_EQ(hint2->id, "hint2");
+ EXPECT_EQ(hint2->display_name, "Hint 2");
+ EXPECT_EQ(hint2->icon_hint, "");
+ EXPECT_EQ(hint2->value.GetString(), "string hint");
+}
+
+TEST(TestPreviews, DeserializeApplication)
+{
+ Object<GIcon> icon(g_icon_new_for_string("application", NULL));
+ Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_application_preview_new()));
+ unity_protocol_preview_set_title(proto_obj, "Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Description");
+ unity_protocol_preview_set_image(proto_obj, icon);
+ auto app_proto_obj = glib::object_cast<UnityProtocolApplicationPreview>(proto_obj);
+ unity_protocol_application_preview_set_last_update(app_proto_obj, "2012/06/13");
+ unity_protocol_application_preview_set_copyright(app_proto_obj, "(c) Canonical");
+ unity_protocol_application_preview_set_license(app_proto_obj, "GPLv3");
+ unity_protocol_application_preview_set_app_icon(app_proto_obj, icon);
+ unity_protocol_application_preview_set_rating(app_proto_obj, 4.0);
+ unity_protocol_application_preview_set_num_ratings(app_proto_obj, 12);
+
+ Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())),
+ glib::StealRef());
+ EXPECT_TRUE(IsVariant(v));
+
+ Preview::Ptr base_preview = Preview::PreviewForVariant(v);
+ ApplicationPreview::Ptr preview = std::dynamic_pointer_cast<ApplicationPreview>(base_preview);
+ EXPECT_TRUE(preview != nullptr);
+
+ EXPECT_EQ(preview->renderer_name, "preview-application");
+ EXPECT_EQ(preview->title, "Title");
+ EXPECT_EQ(preview->subtitle, "Subtitle");
+ EXPECT_EQ(preview->description, "Description");
+ EXPECT_TRUE(g_icon_equal(preview->image(), icon) != FALSE);
+ EXPECT_EQ(preview->last_update, "2012/06/13");
+ EXPECT_EQ(preview->copyright, "(c) Canonical");
+ EXPECT_EQ(preview->license, "GPLv3");
+ EXPECT_TRUE(g_icon_equal(preview->app_icon(), icon) != FALSE);
+ EXPECT_EQ(preview->rating, 4.0);
+ EXPECT_EQ(preview->num_ratings, static_cast<unsigned>(12));
+}
+
+TEST(TestPreviews, DeserializeMovie)
+{
+ Object<GIcon> icon(g_icon_new_for_string("movie", NULL));
+ Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_movie_preview_new()));
+ unity_protocol_preview_set_title(proto_obj, "Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Description");
+ unity_protocol_preview_set_image(proto_obj, icon);
+ auto movie_proto_obj = glib::object_cast<UnityProtocolMoviePreview>(proto_obj);
+ unity_protocol_movie_preview_set_year(movie_proto_obj, "2012");
+ unity_protocol_movie_preview_set_rating(movie_proto_obj, 4.0);
+ unity_protocol_movie_preview_set_num_ratings(movie_proto_obj, 12);
+
+ Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())),
+ glib::StealRef());
+ EXPECT_TRUE(IsVariant(v));
+
+ Preview::Ptr base_preview = Preview::PreviewForVariant(v);
+ MoviePreview::Ptr preview = std::dynamic_pointer_cast<MoviePreview>(base_preview);
+ EXPECT_TRUE(preview != nullptr);
+
+ EXPECT_EQ(preview->renderer_name, "preview-movie");
+ EXPECT_EQ(preview->title, "Title");
+ EXPECT_EQ(preview->subtitle, "Subtitle");
+ EXPECT_EQ(preview->description, "Description");
+ EXPECT_TRUE(g_icon_equal(preview->image(), icon) != FALSE);
+ EXPECT_EQ(preview->year, "2012");
+ EXPECT_EQ(preview->rating, 4.0);
+ EXPECT_EQ(preview->num_ratings, static_cast<unsigned int>(12));
+}
+
+TEST(TestPreviews, DeserializeMusic)
+{
+ Object<GIcon> icon(g_icon_new_for_string("music", NULL));
+ Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_music_preview_new()));
+ unity_protocol_preview_set_title(proto_obj, "Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Description");
+ unity_protocol_preview_set_image(proto_obj, icon);
+ auto music_proto_obj = glib::object_cast<UnityProtocolMusicPreview>(proto_obj);
+
+ Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())),
+ glib::StealRef());
+ EXPECT_TRUE(IsVariant(v));
+
+ Preview::Ptr base_preview = Preview::PreviewForVariant(v);
+ MusicPreview::Ptr preview = std::dynamic_pointer_cast<MusicPreview>(base_preview);
+ EXPECT_TRUE(preview != nullptr);
+
+ EXPECT_EQ(preview->renderer_name, "preview-music");
+ EXPECT_EQ(preview->title, "Title");
+ EXPECT_EQ(preview->subtitle, "Subtitle");
+ EXPECT_EQ(preview->description, "Description");
+ EXPECT_TRUE(g_icon_equal(preview->image(), icon) != FALSE);
+}
+
+TEST(TestPreviews, DeserializeSeries)
+{
+ Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_series_preview_new()));
+ auto series_proto_obj = glib::object_cast<UnityProtocolSeriesPreview>(proto_obj);
+ unity_protocol_series_preview_add_series_item(
+ series_proto_obj, "#1", "scheme://path/0", NULL);
+ unity_protocol_series_preview_add_series_item(
+ series_proto_obj, "#2", "scheme://path/1", NULL);
+ unity_protocol_series_preview_set_selected_item(series_proto_obj, 1);
+
+ Object<GIcon> icon(g_icon_new_for_string("accessories", NULL));
+ Object<UnityProtocolPreview> child_proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_generic_preview_new()));
+ unity_protocol_preview_set_title(child_proto_obj, "Title");
+ unity_protocol_preview_set_subtitle(child_proto_obj, "Subtitle");
+ unity_protocol_preview_set_description(child_proto_obj, "Description");
+ unity_protocol_preview_set_image(child_proto_obj, icon);
+
+ unity_protocol_series_preview_set_child_preview(series_proto_obj,
+ child_proto_obj);
+
+ Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())),
+ glib::StealRef());
+ EXPECT_TRUE(IsVariant(v));
+
+ Preview::Ptr base_preview = Preview::PreviewForVariant(v);
+ SeriesPreview::Ptr preview = std::dynamic_pointer_cast<SeriesPreview>(base_preview);
+ EXPECT_TRUE(preview != nullptr);
+
+ EXPECT_EQ(preview->renderer_name, "preview-series");
+
+ auto items = preview->GetItems();
+ EXPECT_EQ(items.size(), 2);
+
+ auto item1 = preview->GetItems()[1];
+ EXPECT_EQ(item1->uri, "scheme://path/1");
+ EXPECT_EQ(item1->title, "#2");
+
+ auto child_preview = preview->GetChildPreview();
+ EXPECT_EQ(child_preview->renderer_name, "preview-generic");
+ EXPECT_EQ(child_preview->title, "Title");
+ EXPECT_EQ(child_preview->subtitle, "Subtitle");
+ EXPECT_EQ(child_preview->description, "Description");
+ EXPECT_TRUE(g_icon_equal(child_preview->image(), icon) != FALSE);
+}
+
+} // Namespace
diff --git a/tests/test_previews_application.cpp b/tests/test_previews_application.cpp
new file mode 100644
index 000000000..e5a3adcc1
--- /dev/null
+++ b/tests/test_previews_application.cpp
@@ -0,0 +1,124 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#include <list>
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include <Nux/Nux.h>
+#include <Nux/BaseWindow.h>
+#include <unity-shared/StaticCairoText.h>
+#include <unity-shared/DashStyle.h>
+#include <unity-shared/PreviewStyle.h>
+#include <unity-shared/ThumbnailGenerator.h>
+#include "unity-shared/UnitySettings.h"
+
+#include <unity-protocol.h>
+#include "UnityCore/ApplicationPreview.h"
+#include "dash/previews/ApplicationPreview.h"
+#include "dash/previews/PreviewInfoHintWidget.h"
+#include "dash/previews/PreviewRatingsWidget.h"
+#include "test_utils.h"
+using namespace unity;
+using namespace unity::dash;
+
+namespace
+{
+
+class MockApplicationPreview : public previews::ApplicationPreview
+{
+public:
+ typedef nux::ObjectPtr<MockApplicationPreview> Ptr;
+
+ MockApplicationPreview(dash::Preview::Ptr preview_model)
+ : ApplicationPreview(preview_model)
+ {}
+
+ using ApplicationPreview::title_;
+ using ApplicationPreview::subtitle_;
+ using ApplicationPreview::license_;
+ using ApplicationPreview::last_update_;
+ using ApplicationPreview::copywrite_;
+ using ApplicationPreview::description_;
+ using ApplicationPreview::action_buttons_;
+ using ApplicationPreview::preview_info_hints_;
+ using ApplicationPreview::app_rating_;
+};
+
+class TestPreviewApplication : public Test
+{
+public:
+ TestPreviewApplication()
+ : parent_window_(new nux::BaseWindow("TestPreviewApplication"))
+ {
+ glib::Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_application_preview_new()));
+
+ unity_protocol_application_preview_set_app_icon(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), g_icon_new_for_string("/home/nick/SkypeIcon.png", NULL));
+ unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "License");
+ unity_protocol_application_preview_set_copyright(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "Copywrite");
+ unity_protocol_application_preview_set_last_update(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "11th Apr 2012");
+ unity_protocol_application_preview_set_rating(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), 0.8);
+ unity_protocol_application_preview_set_num_ratings(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), 12);
+
+ unity_protocol_preview_set_image_source_uri(proto_obj, "http://ia.media-imdb.com/images/M/MV5BMTM3NDM5MzY5Ml5BMl5BanBnXkFtZTcwNjExMDUwOA@@._V1._SY317_.jpg");
+ unity_protocol_preview_set_title(proto_obj, "Application Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Application Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Application Desctiption");
+ unity_protocol_preview_add_action(proto_obj, "action1", "Action 1", NULL, 0);
+ unity_protocol_preview_add_action(proto_obj, "action2", "Action 2", NULL, 0);
+ unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("s", "string hint 1"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint 2"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint3", "Hint 3", NULL, g_variant_new("i", 12));
+
+ glib::Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())), glib::StealRef());
+ preview_model_ = dash::Preview::PreviewForVariant(v);
+ }
+
+ nux::BaseWindow* parent_window_;
+ dash::Preview::Ptr preview_model_;
+
+ unity::Settings settings;
+ previews::Style panel_style;
+ dash::Style dash_style;
+ ThumbnailGenerator thumbnail_generator;
+};
+
+TEST_F(TestPreviewApplication, TestCreate)
+{
+ previews::Preview::Ptr preview_view = previews::Preview::PreviewForModel(preview_model_);
+
+ EXPECT_TRUE(dynamic_cast<previews::ApplicationPreview*>(preview_view.GetPointer()) != NULL);
+}
+
+TEST_F(TestPreviewApplication, TestUIValues)
+{
+ MockApplicationPreview::Ptr preview_view(new MockApplicationPreview(preview_model_));
+
+ EXPECT_EQ(preview_view->title_->GetText(), "Application Title");
+ EXPECT_EQ(preview_view->subtitle_->GetText(), "Application Subtitle");
+ EXPECT_EQ(preview_view->description_->GetText(), "Application Desctiption");
+ EXPECT_EQ(preview_view->license_->GetText(), "License");
+ //EXPECT_EQ(preview_view->last_update_->GetText(), "Last Updated 11th Apr 2012"); // Not 100% sure this will work with translations.
+ EXPECT_EQ(preview_view->copywrite_->GetText(), "Copywrite");
+
+ EXPECT_EQ(preview_view->app_rating_->GetRating(), 0.8f);
+ EXPECT_EQ(preview_view->action_buttons_.size(), 2);
+}
+
+}
diff --git a/tests/test_previews_generic.cpp b/tests/test_previews_generic.cpp
new file mode 100644
index 000000000..a803afa9c
--- /dev/null
+++ b/tests/test_previews_generic.cpp
@@ -0,0 +1,107 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#include <list>
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include <Nux/Nux.h>
+#include <Nux/BaseWindow.h>
+#include <unity-shared/StaticCairoText.h>
+#include <unity-shared/DashStyle.h>
+#include <unity-shared/PreviewStyle.h>
+#include <unity-shared/ThumbnailGenerator.h>
+#include "unity-shared/UnitySettings.h"
+
+#include <unity-protocol.h>
+#include "UnityCore/GenericPreview.h"
+#include "dash/previews/GenericPreview.h"
+#include "test_utils.h"
+using namespace unity;
+using namespace unity::dash;
+
+namespace
+{
+
+class MockGenericPreview : public previews::GenericPreview
+{
+public:
+ typedef nux::ObjectPtr<MockGenericPreview> Ptr;
+
+ MockGenericPreview(dash::Preview::Ptr preview_model)
+ : GenericPreview(preview_model)
+ {}
+
+ using GenericPreview::title_;
+ using GenericPreview::subtitle_;
+ using GenericPreview::description_;
+ using GenericPreview::action_buttons_;
+ using GenericPreview::preview_info_hints_;
+};
+
+class TestPreviewGeneric : public Test
+{
+public:
+ TestPreviewGeneric()
+ : parent_window_(new nux::BaseWindow("TestPreviewGeneric"))
+ {
+ glib::Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_generic_preview_new()));
+
+ unity_protocol_preview_set_image_source_uri(proto_obj, "http://ia.media-imdb.com/images/M/MV5BMTM3NDM5MzY5Ml5BMl5BanBnXkFtZTcwNjExMDUwOA@@._V1._SY317_.jpg");
+ unity_protocol_preview_set_title(proto_obj, "Generic Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Generic Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Generic Desctiption");
+ unity_protocol_preview_add_action(proto_obj, "action1", "Action 1", NULL, 0);
+ unity_protocol_preview_add_action(proto_obj, "action2", "Action 2", NULL, 0);
+ unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("s", "string hint 1"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint 2"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint3", "Hint 3", NULL, g_variant_new("i", 12));
+
+ glib::Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())), glib::StealRef());
+ preview_model_ = dash::Preview::PreviewForVariant(v);
+ }
+
+ nux::BaseWindow* parent_window_;
+ dash::Preview::Ptr preview_model_;
+
+ unity::Settings settings;
+ previews::Style panel_style;
+ dash::Style dash_style;
+ ThumbnailGenerator thumbnail_generator;
+};
+
+TEST_F(TestPreviewGeneric, TestCreate)
+{
+ previews::Preview::Ptr preview_view = previews::Preview::PreviewForModel(preview_model_);
+
+ EXPECT_TRUE(dynamic_cast<previews::GenericPreview*>(preview_view.GetPointer()) != NULL);
+}
+
+TEST_F(TestPreviewGeneric, TestUIValues)
+{
+ MockGenericPreview::Ptr preview_view(new MockGenericPreview(preview_model_));
+
+ EXPECT_EQ(preview_view->title_->GetText(), "Generic Title");
+ EXPECT_EQ(preview_view->subtitle_->GetText(), "Generic Subtitle");
+ EXPECT_EQ(preview_view->description_->GetText(), "Generic Desctiption");
+
+ EXPECT_EQ(preview_view->action_buttons_.size(), 2);
+}
+
+}
diff --git a/tests/test_previews_movie.cpp b/tests/test_previews_movie.cpp
new file mode 100644
index 000000000..ae7610bcb
--- /dev/null
+++ b/tests/test_previews_movie.cpp
@@ -0,0 +1,114 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#include <list>
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include <Nux/Nux.h>
+#include <Nux/BaseWindow.h>
+#include <unity-shared/StaticCairoText.h>
+#include <unity-shared/DashStyle.h>
+#include <unity-shared/PreviewStyle.h>
+#include <unity-shared/ThumbnailGenerator.h>
+#include "unity-shared/UnitySettings.h"
+
+#include <unity-protocol.h>
+#include "UnityCore/MoviePreview.h"
+#include "dash/previews/MoviePreview.h"
+#include "dash/previews/PreviewInfoHintWidget.h"
+#include "dash/previews/PreviewRatingsWidget.h"
+#include "test_utils.h"
+using namespace unity;
+using namespace unity::dash;
+
+namespace
+{
+
+class MockMoviePreview : public previews::MoviePreview
+{
+public:
+ typedef nux::ObjectPtr<MockMoviePreview> Ptr;
+
+ MockMoviePreview(dash::Preview::Ptr preview_model)
+ : MoviePreview(preview_model)
+ {}
+
+ using MoviePreview::title_;
+ using MoviePreview::subtitle_;
+ using MoviePreview::description_;
+ using MoviePreview::action_buttons_;
+ using MoviePreview::preview_info_hints_;
+ using MoviePreview::rating_;
+};
+
+class TestPreviewMovie : public Test
+{
+public:
+ TestPreviewMovie()
+ : parent_window_(new nux::BaseWindow("TestPreviewMovie"))
+ {
+ glib::Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_movie_preview_new()));
+
+ unity_protocol_movie_preview_set_rating(UNITY_PROTOCOL_MOVIE_PREVIEW(proto_obj.RawPtr()), 0.8);
+ unity_protocol_movie_preview_set_num_ratings(UNITY_PROTOCOL_MOVIE_PREVIEW(proto_obj.RawPtr()), 12);
+
+ unity_protocol_preview_set_image_source_uri(proto_obj, "http://ia.media-imdb.com/images/M/MV5BMTM3NDM5MzY5Ml5BMl5BanBnXkFtZTcwNjExMDUwOA@@._V1._SY317_.jpg");
+ unity_protocol_preview_set_title(proto_obj, "Movie Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Movie Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Movie Desctiption");
+ unity_protocol_preview_add_action(proto_obj, "action1", "Action 1", NULL, 0);
+ unity_protocol_preview_add_action(proto_obj, "action2", "Action 2", NULL, 0);
+ unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("s", "string hint 1"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint 2"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint3", "Hint 3", NULL, g_variant_new("i", 12));
+
+ glib::Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())), glib::StealRef());
+ preview_model_ = dash::Preview::PreviewForVariant(v);
+ }
+
+ nux::BaseWindow* parent_window_;
+ dash::Preview::Ptr preview_model_;
+
+ unity::Settings settings;
+ previews::Style panel_style;
+ dash::Style dash_style;
+ ThumbnailGenerator thumbnail_generator;
+};
+
+TEST_F(TestPreviewMovie, TestCreate)
+{
+ previews::Preview::Ptr preview_view = previews::Preview::PreviewForModel(preview_model_);
+
+ EXPECT_TRUE(dynamic_cast<previews::MoviePreview*>(preview_view.GetPointer()) != NULL);
+}
+
+TEST_F(TestPreviewMovie, TestUIValues)
+{
+ MockMoviePreview::Ptr preview_view(new MockMoviePreview(preview_model_));
+
+ EXPECT_EQ(preview_view->title_->GetText(), "Movie Title");
+ EXPECT_EQ(preview_view->subtitle_->GetText(), "Movie Subtitle");
+ EXPECT_EQ(preview_view->description_->GetText(), "Movie Desctiption");
+
+ EXPECT_EQ(preview_view->rating_->GetRating(), 0.8f);
+ EXPECT_EQ(preview_view->action_buttons_.size(), 2);
+}
+
+}
diff --git a/tests/test_previews_music.cpp b/tests/test_previews_music.cpp
new file mode 100644
index 000000000..095bdb261
--- /dev/null
+++ b/tests/test_previews_music.cpp
@@ -0,0 +1,109 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#include <list>
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include <Nux/Nux.h>
+#include <Nux/BaseWindow.h>
+#include <unity-shared/StaticCairoText.h>
+#include <unity-shared/DashStyle.h>
+#include <unity-shared/PreviewStyle.h>
+#include <unity-shared/ThumbnailGenerator.h>
+#include "unity-shared/UnitySettings.h"
+
+#include <unity-protocol.h>
+#include "UnityCore/MusicPreview.h"
+#include "dash/previews/MusicPreview.h"
+#include "dash/previews/PreviewInfoHintWidget.h"
+#include "dash/previews/PreviewRatingsWidget.h"
+#include "test_utils.h"
+using namespace unity;
+using namespace unity::dash;
+
+namespace
+{
+
+class MockMusicPreview : public previews::MusicPreview
+{
+public:
+ typedef nux::ObjectPtr<MockMusicPreview> Ptr;
+
+ MockMusicPreview(dash::Preview::Ptr preview_model)
+ : MusicPreview(preview_model)
+ {}
+
+ using MusicPreview::title_;
+ using MusicPreview::subtitle_;
+ using MusicPreview::action_buttons_;
+ using MusicPreview::preview_info_hints_;
+};
+
+class TestPreviewMusic : public Test
+{
+public:
+ TestPreviewMusic()
+ : parent_window_(new nux::BaseWindow("TestPreviewMusic"))
+ {
+ glib::Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_music_preview_new()));
+
+ unity_protocol_preview_set_image_source_uri(proto_obj, "http://ia.media-imdb.com/images/M/MV5BMTM3NDM5MzY5Ml5BMl5BanBnXkFtZTcwNjExMDUwOA@@._V1._SY317_.jpg");
+ unity_protocol_preview_set_title(proto_obj, "Music Title");
+ unity_protocol_preview_set_subtitle(proto_obj, "Music Subtitle");
+ unity_protocol_preview_set_description(proto_obj, "Music Desctiption");
+ unity_protocol_preview_add_action(proto_obj, "action1", "Action 1", NULL, 0);
+ unity_protocol_preview_add_action(proto_obj, "action2", "Action 2", NULL, 0);
+ unity_protocol_preview_add_action(proto_obj, "action3", "Action 3", NULL, 0);
+ unity_protocol_preview_add_action(proto_obj, "action4", "Action 4", NULL, 0);
+ unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("s", "string hint 1"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint 2"));
+ unity_protocol_preview_add_info_hint(proto_obj, "hint3", "Hint 3", NULL, g_variant_new("i", 12));
+
+ glib::Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())), glib::StealRef());
+ preview_model_ = dash::Preview::PreviewForVariant(v);
+ }
+
+ nux::BaseWindow* parent_window_;
+ dash::Preview::Ptr preview_model_;
+
+ unity::Settings settings;
+ previews::Style panel_style;
+ dash::Style dash_style;
+ ThumbnailGenerator thumbnail_generator;
+};
+
+TEST_F(TestPreviewMusic, TestCreate)
+{
+ previews::Preview::Ptr preview_view = previews::Preview::PreviewForModel(preview_model_);
+
+ EXPECT_TRUE(dynamic_cast<previews::MusicPreview*>(preview_view.GetPointer()) != NULL);
+}
+
+TEST_F(TestPreviewMusic, TestUIValues)
+{
+ MockMusicPreview::Ptr preview_view(new MockMusicPreview(preview_model_));
+
+ EXPECT_EQ(preview_view->title_->GetText(), "Music Title");
+ EXPECT_EQ(preview_view->subtitle_->GetText(), "Music Subtitle");
+
+ EXPECT_EQ(preview_view->action_buttons_.size(), 4);
+}
+
+}
diff --git a/tests/test_quicklist_menu_item.cpp b/tests/test_quicklist_menu_item.cpp
new file mode 100644
index 000000000..dbba9d078
--- /dev/null
+++ b/tests/test_quicklist_menu_item.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2010-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: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
+ * Mirco Müller <mirco.mueller@canonical.com>
+ */
+
+#include <gmock/gmock.h>
+#include <libdbusmenu-glib/client.h>
+#include <UnityCore/GLibSignal.h>
+
+#include "QuicklistMenuItem.h"
+#include "QuicklistMenuItemCheckmark.h"
+#include "QuicklistMenuItemLabel.h"
+#include "QuicklistMenuItemRadio.h"
+#include "QuicklistMenuItemSeparator.h"
+#include "unity-shared/UBusWrapper.h"
+#include "unity-shared/UBusMessages.h"
+#include "test_utils.h"
+
+using namespace unity;
+using namespace testing;
+
+namespace
+{
+
+struct TestQuicklistMenuItem : public Test
+{
+ TestQuicklistMenuItem()
+ : item(dbusmenu_menuitem_new())
+ {}
+
+ glib::Object<DbusmenuMenuitem> item;
+};
+
+TEST_F(TestQuicklistMenuItem, QuicklistMenuItemCheckmark)
+{
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Unchecked");
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
+ DBUSMENU_MENUITEM_TOGGLE_CHECK);
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, false);
+ dbusmenu_menuitem_property_set_int(item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
+ DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
+
+ nux::ObjectPtr<QuicklistMenuItemCheckmark> qlitem(new QuicklistMenuItemCheckmark(item));
+
+ EXPECT_EQ(qlitem->GetLabel(), "Unchecked");
+ EXPECT_FALSE(qlitem->GetEnabled());
+ EXPECT_FALSE(qlitem->GetActive());
+ EXPECT_FALSE(qlitem->GetSelectable());
+ EXPECT_FALSE(qlitem->IsMarkupEnabled());
+}
+
+TEST_F(TestQuicklistMenuItem, QuicklistMenuItemLabel)
+{
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "A Label");
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+ dbusmenu_menuitem_property_set_bool(item, QuicklistMenuItem::MARKUP_ENABLED_PROPERTY, true);
+
+ nux::ObjectPtr<QuicklistMenuItemLabel> qlitem(new QuicklistMenuItemLabel(item));
+
+ EXPECT_EQ(qlitem->GetLabel(), "A Label");
+ EXPECT_TRUE(qlitem->GetEnabled());
+ EXPECT_TRUE(qlitem->GetSelectable());
+ EXPECT_TRUE(qlitem->IsMarkupEnabled());
+}
+
+TEST_F(TestQuicklistMenuItem, QuicklistMenuItemRadio)
+{
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Radio Active");
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
+ DBUSMENU_MENUITEM_TOGGLE_RADIO);
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+ dbusmenu_menuitem_property_set_int(item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
+ DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
+
+ nux::ObjectPtr<QuicklistMenuItemRadio> qlitem(new QuicklistMenuItemRadio(item));
+ qlitem->EnableLabelMarkup(true);
+
+ EXPECT_EQ(qlitem->GetLabel(), "Radio Active");
+ EXPECT_TRUE(qlitem->GetEnabled());
+ EXPECT_TRUE(qlitem->GetActive());
+ EXPECT_TRUE(qlitem->GetSelectable());
+ EXPECT_TRUE(qlitem->IsMarkupEnabled());
+}
+
+TEST_F(TestQuicklistMenuItem, QuicklistMenuItemSeparator)
+{
+ dbusmenu_menuitem_property_set(item, "type", DBUSMENU_CLIENT_TYPES_SEPARATOR);
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+
+ nux::ObjectPtr<QuicklistMenuItemSeparator> qlitem(new QuicklistMenuItemSeparator(item));
+
+ EXPECT_TRUE(qlitem->GetEnabled());
+ EXPECT_FALSE(qlitem->GetSelectable());
+}
+
+TEST_F(TestQuicklistMenuItem, OverlayMenuitem)
+{
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Label");
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+
+ nux::ObjectPtr<QuicklistMenuItemLabel> qlitem(new QuicklistMenuItemLabel(item));
+
+ EXPECT_FALSE(qlitem->IsOverlayQuicklist());
+
+ dbusmenu_menuitem_property_set_bool(item, QuicklistMenuItem::OVERLAY_MENU_ITEM_PROPERTY, true);
+ EXPECT_TRUE(qlitem->IsOverlayQuicklist());
+}
+
+TEST_F(TestQuicklistMenuItem, ItemActivate)
+{
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Label");
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+
+ nux::ObjectPtr<QuicklistMenuItemLabel> qlitem(new QuicklistMenuItemLabel(item));
+
+ bool item_activated = false;
+ glib::Signal<void, DbusmenuMenuitem*, int> signal(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ [&] (DbusmenuMenuitem* menu_item, int time) {
+ EXPECT_EQ(menu_item, item);
+ item_activated = true;
+ });
+
+ qlitem->Activate();
+ EXPECT_TRUE(item_activated);
+}
+
+TEST_F(TestQuicklistMenuItem, ItemActivateClosesDash)
+{
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Label");
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+
+ nux::ObjectPtr<QuicklistMenuItemLabel> qlitem(new QuicklistMenuItemLabel(item));
+
+ bool closes_dash = false;
+ UBusManager manager;
+ manager.RegisterInterest(UBUS_PLACE_VIEW_CLOSE_REQUEST, [&] (GVariant*) { closes_dash = true; });
+
+ qlitem->Activate();
+ Utils::WaitUntil(closes_dash);
+
+ EXPECT_TRUE(closes_dash);
+}
+
+TEST_F(TestQuicklistMenuItem, OverlayItemActivateDoesNotCloseDash)
+{
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Label");
+ dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+ dbusmenu_menuitem_property_set_bool(item, QuicklistMenuItem::OVERLAY_MENU_ITEM_PROPERTY, true);
+
+ nux::ObjectPtr<QuicklistMenuItemLabel> qlitem(new QuicklistMenuItemLabel(item));
+
+ bool closes_dash = false;
+ UBusManager manager;
+ manager.RegisterInterest(UBUS_PLACE_VIEW_CLOSE_REQUEST, [&] (GVariant*) { closes_dash = true; });
+
+ qlitem->Activate();
+ Utils::WaitForTimeoutMSec(100);
+
+ EXPECT_FALSE(closes_dash);
+}
+
+}
diff --git a/tests/test_quicklist_view.cpp b/tests/test_quicklist_view.cpp
new file mode 100644
index 000000000..908cb50bc
--- /dev/null
+++ b/tests/test_quicklist_view.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010-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: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
+ * Mirco Müller <mirco.mueller@canonical.com>
+ */
+
+#include <gmock/gmock.h>
+#include <libdbusmenu-glib/client.h>
+
+#include "QuicklistView.h"
+#include "QuicklistMenuItemCheckmark.h"
+#include "QuicklistMenuItemLabel.h"
+#include "QuicklistMenuItemRadio.h"
+#include "QuicklistMenuItemSeparator.h"
+
+using namespace unity;
+using namespace testing;
+
+namespace
+{
+
+struct TestQuicklistView : public Test
+{
+ TestQuicklistView()
+ : quicklist(new QuicklistView())
+ {}
+
+ void AddMenuItems(glib::Object<DbusmenuMenuitem> const& root)
+ {
+ quicklist->RemoveAllMenuItem();
+
+ if (!root)
+ return;
+
+ for (GList* child = dbusmenu_menuitem_get_children(root); child; child = child->next)
+ {
+ glib::Object<DbusmenuMenuitem> item(static_cast<DbusmenuMenuitem*>(child->data), glib::AddRef());
+ const gchar* type = dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_TYPE);
+ const gchar* toggle_type = dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE);
+
+ if (g_strcmp0(type, DBUSMENU_CLIENT_TYPES_SEPARATOR) == 0)
+ {
+ QuicklistMenuItemSeparator* qlitem = new QuicklistMenuItemSeparator(item, NUX_TRACKER_LOCATION);
+ quicklist->AddMenuItem(qlitem);
+ }
+ else if (g_strcmp0(toggle_type, DBUSMENU_MENUITEM_TOGGLE_CHECK) == 0)
+ {
+ QuicklistMenuItemCheckmark* qlitem = new QuicklistMenuItemCheckmark(item, NUX_TRACKER_LOCATION);
+ quicklist->AddMenuItem(qlitem);
+ }
+ else if (g_strcmp0(toggle_type, DBUSMENU_MENUITEM_TOGGLE_RADIO) == 0)
+ {
+ QuicklistMenuItemRadio* qlitem = new QuicklistMenuItemRadio(item, NUX_TRACKER_LOCATION);
+ quicklist->AddMenuItem(qlitem);
+ }
+ else //if (g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0)
+ {
+ QuicklistMenuItemLabel* qlitem = new QuicklistMenuItemLabel(item, NUX_TRACKER_LOCATION);
+ quicklist->AddMenuItem(qlitem);
+ }
+ }
+ }
+
+ nux::ObjectPtr<QuicklistView> quicklist;
+};
+
+TEST_F(TestQuicklistView, AddItems)
+{
+ glib::Object<DbusmenuMenuitem> root(dbusmenu_menuitem_new());
+
+ dbusmenu_menuitem_set_root(root, true);
+
+ DbusmenuMenuitem* child = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_MENUITEM_PROP_LABEL);
+ dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_LABEL, "label 0");
+ dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+ dbusmenu_menuitem_child_append(root, child);
+
+ child = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
+ dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+ dbusmenu_menuitem_child_append(root, child);
+
+ child = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_MENUITEM_PROP_LABEL);
+ dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_LABEL, "label 1");
+ dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+ dbusmenu_menuitem_child_append(root, child);
+
+ child = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK);
+ dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_LABEL, "check mark 0");
+ dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
+ dbusmenu_menuitem_property_set_int(child, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
+ dbusmenu_menuitem_child_append(root, child);
+
+ AddMenuItems(root);
+
+ ASSERT_EQ(quicklist->GetChildren().size(), 4);
+ ASSERT_EQ(quicklist->GetNumItems(), 4);
+ EXPECT_EQ(quicklist->GetNthType(0), unity::QuicklistMenuItemType::LABEL);
+ EXPECT_EQ(quicklist->GetNthType(1), unity::QuicklistMenuItemType::SEPARATOR);
+ EXPECT_EQ(quicklist->GetNthType(2), unity::QuicklistMenuItemType::LABEL);
+ EXPECT_EQ(quicklist->GetNthType(3), unity::QuicklistMenuItemType::CHECK);
+
+ EXPECT_EQ(quicklist->GetNthItems(0)->GetLabel(), "label 0");
+ EXPECT_EQ(quicklist->GetNthItems(2)->GetLabel(), "label 1");
+ EXPECT_EQ(quicklist->GetNthItems(3)->GetLabel(), "check mark 0");
+}
+
+}
diff --git a/tests/test_results.cpp b/tests/test_results.cpp
index 730430333..e4b4d5165 100644
--- a/tests/test_results.cpp
+++ b/tests/test_results.cpp
@@ -3,11 +3,13 @@
#include <UnityCore/GLibWrapper.h>
#include <UnityCore/Results.h>
+#include <UnityCore/ResultIterator.h>
#include "test_utils.h"
using namespace std;
using namespace unity::dash;
+using namespace unity;
namespace
{
@@ -35,27 +37,97 @@ TEST(TestResults, TestSynchronization)
EXPECT_EQ(model.count, n_rows);
}
+TEST(TestResults, TestFilterValid)
+{
+ Results model;
+ DeeFilter filter;
+
+ model.swarm_name = swarm_name;
+ WaitForSynchronize(model);
+
+ dee_filter_new_for_any_column(2, g_variant_new_uint32(1), &filter);
+ glib::Object<DeeModel> filter_model(dee_filter_model_new(model.model(), &filter));
+
+ unsigned int i = 0;
+ for (ResultIterator iter(filter_model); !iter.IsLast(); ++iter)
+ {
+ EXPECT_EQ((*iter).category_index(), 1);
+ i++;
+ }
+
+ EXPECT_EQ(i, 50);
+}
+
TEST(TestResults, TestRowsValid)
{
Results model;
model.swarm_name = swarm_name;
WaitForSynchronize(model);
+
+ ResultIterator iter(model.model);
+ unsigned int i = 0;
+ for (Result result : model)
+ {
+ //Result adaptor = *iter;
+ unity::glib::String tmp(g_strdup_printf("Result%d", i));
+ string value = tmp.Str();
+ EXPECT_EQ(result.uri(), value);
+ EXPECT_EQ(result.icon_hint(), value);
+ EXPECT_EQ(result.category_index(), (i / 50));
+ EXPECT_EQ(result.mimetype(), value);
+ EXPECT_EQ(result.name(), value);
+ EXPECT_EQ(result.comment(), value);
+ EXPECT_EQ(result.dnd_uri(), value);
+ i++;
+ }
- for (unsigned int i = 0; i < n_rows; i++)
+ //test reading a subset
+ i = 20;
+ for (auto iter = model.begin() + i; iter != model.end(); ++iter)
{
- Result adaptor = model.RowAtIndex(i);
+ Result result = (*iter);
+ unity::glib::String tmp(g_strdup_printf("Result%d", i));
+ string value = tmp.Str();
+ EXPECT_EQ(result.uri(), value);
+ i++;
+ }
+ // test post incrementor
+ i = 20;
+ for (auto iter = model.begin() + i; iter != model.end(); iter++)
+ {
+ Result result = (*iter);
unity::glib::String tmp(g_strdup_printf("Result%d", i));
string value = tmp.Str();
- EXPECT_EQ(adaptor.uri, value);
- EXPECT_EQ(adaptor.icon_hint, value);
- EXPECT_EQ(adaptor.category_index, i);
- EXPECT_EQ(adaptor.mimetype, value);
- EXPECT_EQ(adaptor.name, value);
- EXPECT_EQ(adaptor.comment, value);
- EXPECT_EQ(adaptor.dnd_uri, value);
+ EXPECT_EQ(result.uri(), value);
+ i++;
}
+
+ // test equality
+ EXPECT_TRUE(model.begin() == model.begin());
+ EXPECT_TRUE(model.begin() != model.end());
+
+ EXPECT_FALSE(model.begin().IsLast());
+ EXPECT_FALSE(model.end().IsFirst());
+ EXPECT_TRUE(model.begin().IsFirst());
+ EXPECT_TRUE(model.end().IsLast());
+
+ EXPECT_TRUE(model.begin() < model.end());
+ EXPECT_FALSE(model.end() < model.begin());
+ EXPECT_TRUE(model.end() > model.begin());
+ EXPECT_FALSE(model.begin() > model.end());
+ EXPECT_TRUE(model.begin() <= model.end());
+ EXPECT_FALSE(model.end() <= model.begin());
+ EXPECT_TRUE(model.end() >= model.begin());
+ EXPECT_FALSE(model.begin() >= model.end());
+
+
+ EXPECT_TRUE(model.begin() + 20 > model.begin());
+ EXPECT_TRUE(model.begin() + 20 > model.begin() + 19);
+ EXPECT_TRUE(model.end() - 20 < model.end());
+ EXPECT_TRUE(model.end() - 20 < model.end() - 19);
+
}
// We're testing the model's ability to store and retrieve random pointers
diff --git a/tests/test_service_lens.c b/tests/test_service_lens.c
index 854c99ec9..cea0feec0 100644
--- a/tests/test_service_lens.c
+++ b/tests/test_service_lens.c
@@ -174,7 +174,7 @@ on_search_changed(UnityScope* scope, UnityLensSearch *search,
g_free(name);
}
- g_signal_emit_by_name (search, "finished");
+ unity_lens_search_finished (search);
}
static UnityActivationResponse*
@@ -183,15 +183,27 @@ on_activate_uri(UnityScope* scope, const char* uri, ServiceLens* self)
return unity_activation_response_new(UNITY_HANDLED_TYPE_HIDE_DASH, "");
}
+static UnityActivationResponse*
+preview_action_activated(UnityPreviewAction* action, const char* uri)
+{
+ return unity_activation_response_new(UNITY_HANDLED_TYPE_SHOW_DASH, "");
+}
+
static UnityPreview*
on_preview_uri(UnityScope* scope, const char* uri, ServiceLens *self)
{
- return NULL;
- // FIXME: update when the new preview types are well defined
- /*
- return (UnityPreview*)unity_generic_preview_new(
- "Animus Vox", "The Glitch Mob - Drink The Sea", NULL);
- */
+ UnityPreviewAction* action;
+ UnityMoviePreview* preview;
+
+ preview = unity_movie_preview_new("A movie", "With subtitle",
+ "And description", NULL);
+
+ action = unity_preview_action_new("action_A", "An action", NULL);
+ unity_preview_add_action(UNITY_PREVIEW(preview), action);
+ g_signal_connect(action, "activated",
+ G_CALLBACK(preview_action_activated), NULL);
+
+ return (UnityPreview*) preview;
}
ServiceLens*
diff --git a/tests/test_service_model.c b/tests/test_service_model.c
index 8acdda48f..95f07f615 100644
--- a/tests/test_service_model.c
+++ b/tests/test_service_model.c
@@ -58,7 +58,7 @@ service_model_create_results(ServiceModel* self)
dee_model_append(self->results_model_,
name,
name,
- (guint)i,
+ (guint)(i/50), // new category every 50 results
name,
name,
name,
diff --git a/tests/test_single_monitor_launcher_icon.cpp b/tests/test_single_monitor_launcher_icon.cpp
index 22f512b65..eeaa9f373 100644
--- a/tests/test_single_monitor_launcher_icon.cpp
+++ b/tests/test_single_monitor_launcher_icon.cpp
@@ -30,7 +30,7 @@ namespace
TEST(TestSingleMonitorLauncherIcon, Construction)
{
- SingleMonitorLauncherIcon icon(1);
+ SingleMonitorLauncherIcon icon(AbstractLauncherIcon::IconType::NONE, 1);
EXPECT_EQ(icon.GetMonitor(), 1);
EXPECT_TRUE(icon.IsVisibleOnMonitor(1));
@@ -39,7 +39,7 @@ TEST(TestSingleMonitorLauncherIcon, Construction)
TEST(TestSingleMonitorLauncherIcon, MonitorVisibility)
{
- SingleMonitorLauncherIcon icon(2);
+ SingleMonitorLauncherIcon icon(AbstractLauncherIcon::IconType::NONE, 2);
for (int i = 0; i < max_num_monitors; ++i)
{
diff --git a/tests/test_switcher_controller.cpp b/tests/test_switcher_controller.cpp
index b039c3cec..70bda5fd0 100644
--- a/tests/test_switcher_controller.cpp
+++ b/tests/test_switcher_controller.cpp
@@ -24,6 +24,7 @@
#include "test_utils.h"
#include "SwitcherController.h"
+#include "DesktopLauncherIcon.h"
#include "TimeUtil.h"
@@ -127,6 +128,7 @@ TEST(TestSwitcherController, InitialDetailTimeout)
{
MockSwitcherController controller;
std::vector<unity::launcher::AbstractLauncherIcon::Ptr> results;
+ results.push_back(unity::launcher::AbstractLauncherIcon::Ptr(new unity::launcher::DesktopLauncherIcon()));
struct timespec current;
controller.initial_detail_timeout_length = 2000;
@@ -160,6 +162,7 @@ TEST(TestSwitcherController, ShowSwitcher)
{
MockSwitcherController controller;
std::vector<unity::launcher::AbstractLauncherIcon::Ptr> results;
+ results.push_back(unity::launcher::AbstractLauncherIcon::Ptr(new unity::launcher::DesktopLauncherIcon()));
controller.Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, false, results);
@@ -167,4 +170,24 @@ TEST(TestSwitcherController, ShowSwitcher)
ASSERT_TRUE(controller.view_shown_);
}
+TEST(TestSwitcherController, ShowSwitcherNoShowDeskop)
+{
+ MockSwitcherController controller;
+ controller.SetShowDesktopDisabled(true);
+
+ ASSERT_TRUE(controller.IsShowDesktopDisabled());
+ ASSERT_TRUE(controller.StartIndex() == 0);
+}
+
+TEST(TestSwitcherController, ShowSwitcherNoResults)
+{
+ MockSwitcherController controller;
+ controller.SetShowDesktopDisabled(true);
+ std::vector<unity::launcher::AbstractLauncherIcon::Ptr> results;
+
+ controller.Show(ShowMode::CURRENT_VIEWPORT, SortMode::FOCUS_ORDER, false, results);
+
+ ASSERT_FALSE(controller.Visible());
+}
+
}
diff --git a/tests/test_thumbnail_generator.cpp b/tests/test_thumbnail_generator.cpp
new file mode 100644
index 000000000..361837f62
--- /dev/null
+++ b/tests/test_thumbnail_generator.cpp
@@ -0,0 +1,266 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 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 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
+ */
+
+#include <list>
+#include <gmock/gmock.h>
+using namespace testing;
+
+#include <Nux/Nux.h>
+#include <Nux/BaseWindow.h>
+#include <unity-shared/ThumbnailGenerator.h>
+
+#include <unity-protocol.h>
+#include "test_utils.h"
+#include "config.h"
+
+using namespace unity;
+using namespace unity::dash;
+
+namespace
+{
+
+gboolean TimeoutReached (gpointer data)
+{
+ bool *b = static_cast<bool*>(data);
+
+ *b = true;
+
+ return FALSE;
+}
+
+struct LoadResult
+{
+ std::string return_string;
+ bool got_callback;
+ bool succeeded;
+
+ LoadResult() : got_callback(false),succeeded(false) {}
+ void ThumbnailReady(std::string const& result)
+ {
+ return_string = result;
+
+ got_callback = true;
+ succeeded = true;
+ }
+ void ThumbnailFailed(std::string const& result)
+ {
+ return_string = result;
+
+ got_callback = true;
+ succeeded = false;
+ }
+};
+
+TEST(TestThumbnailGenerator, TestNoURIThumbnail)
+{
+ ThumbnailGenerator thumbnail_generator;
+ ThumbnailNotifier::Ptr thumb = thumbnail_generator.GetThumbnail("", 256);
+ EXPECT_TRUE(thumb == nullptr);
+}
+
+TEST(TestThumbnailGenerator, TestGetOneFileThumbnail)
+{
+ ThumbnailGenerator thumbnail_generator;
+
+ LoadResult load_result;
+ ThumbnailNotifier::Ptr thumb = thumbnail_generator.GetThumbnail("file://" PKGDATADIR "/switcher_background.png", 256);
+ EXPECT_TRUE(thumb != nullptr);
+
+ thumb->ready.connect(sigc::mem_fun(load_result, &LoadResult::ThumbnailReady));
+ thumb->error.connect(sigc::mem_fun(load_result, &LoadResult::ThumbnailFailed));
+
+ volatile bool timeout_reached = false;
+ guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached && !load_result.got_callback)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ }
+
+ EXPECT_TRUE(load_result.succeeded);
+ glib::Object<GIcon> icon(g_icon_new_for_string(load_result.return_string.c_str(), NULL));
+ EXPECT_TRUE(G_IS_ICON(icon.RawPtr()));
+
+ g_source_remove (tid);
+}
+
+
+TEST(TestThumbnailGenerator, TestGetManyFileThumbnail)
+{
+ srand ( time(NULL) );
+ ThumbnailGenerator thumbnail_generator;
+
+ const char* thumbs[] = { "file://" PKGDATADIR "/switcher_background.png" , "file://" PKGDATADIR "/star_highlight.png",
+ "file://" PKGDATADIR "/switcher_round_rect.png", "file://" PKGDATADIR "/switcher_corner.png",
+ "file://" PKGDATADIR "/switcher_top.png", "file://" PKGDATADIR "/switcher_left.png",
+ "file://" PKGDATADIR "/dash_bottom_left_corner.png", "file://" PKGDATADIR "/dash_bottom_right_corner.png"};
+
+ std::vector<LoadResult> results;
+ std::vector< ThumbnailNotifier::Ptr> notifiers;
+
+ // 100 times should be good
+ int load_count = 100;
+ results.resize (load_count);
+ notifiers.resize (load_count);
+
+ for (int i = 0; i < load_count; i++)
+ {
+ notifiers[i] = thumbnail_generator.GetThumbnail(thumbs[rand() % (sizeof(thumbs) / sizeof(char*))], 256);
+ EXPECT_TRUE(notifiers[i] != nullptr);
+
+ notifiers[i]->ready.connect(sigc::mem_fun(results[i], &LoadResult::ThumbnailReady));
+ notifiers[i]->error.connect(sigc::mem_fun(results[i], &LoadResult::ThumbnailFailed));
+ }
+
+ // disconnect every other handler (and especially the first one)
+ for (int i = 0; i < load_count; i += 2)
+ {
+ notifiers[i]->Cancel();
+ }
+
+
+ volatile bool timeout_reached = false;
+ guint tid = g_timeout_add (30000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ bool all_loaded = true;
+ bool any_loaded = false;
+ for (int i = 1; i < load_count; i += 2)
+ {
+ all_loaded &= results[i].got_callback;
+ any_loaded |= results[i].got_callback;
+ if (!all_loaded) break;
+ }
+ if (all_loaded) break;
+ }
+
+ for (int i = 0; i < load_count; i++)
+ {
+ if (i % 2)
+ {
+ EXPECT_TRUE(results[i].got_callback);
+ EXPECT_TRUE(results[i].succeeded);
+ glib::Object<GIcon> icon(g_icon_new_for_string(results[i].return_string.c_str(), NULL));
+ EXPECT_TRUE(G_IS_ICON(icon.RawPtr()));
+ }
+ else
+ {
+ EXPECT_FALSE(results[i].got_callback);
+ }
+ }
+
+ g_source_remove (tid);
+}
+
+
+TEST(TestThumbnailGenerator, TestGetOneGIcon)
+{
+ ThumbnailGenerator thumbnail_generator;
+
+ LoadResult load_result;
+ ThumbnailNotifier::Ptr thumb = thumbnail_generator.GetThumbnail("file:///home", 256);
+ EXPECT_TRUE(thumb != nullptr);
+
+ thumb->ready.connect(sigc::mem_fun(load_result, &LoadResult::ThumbnailReady));
+ thumb->error.connect(sigc::mem_fun(load_result, &LoadResult::ThumbnailFailed));
+
+ volatile bool timeout_reached = false;
+ guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached && !load_result.got_callback)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ }
+
+ EXPECT_TRUE(load_result.succeeded);
+ glib::Object<GIcon> icon(g_icon_new_for_string(load_result.return_string.c_str(), NULL));
+ EXPECT_TRUE(G_IS_ICON(icon.RawPtr()));
+
+ g_source_remove (tid);
+}
+
+
+TEST(TestThumbnailGenerator, TestGetManyGIcon)
+{
+ srand ( time(NULL) );
+ ThumbnailGenerator thumbnail_generator;
+
+ const char* thumbs[] = { "file:///home",
+ "file:///usr",
+ "file:///bin/bash",
+ "file:///usr/bin/unity"};
+
+ std::vector<LoadResult> results;
+ std::vector< ThumbnailNotifier::Ptr> notifiers;
+
+ // 100 times should be good
+ int load_count = 100;
+ results.resize (load_count);
+ notifiers.resize (load_count);
+
+ for (int i = 0; i < load_count; i++)
+ {
+ notifiers[i] = thumbnail_generator.GetThumbnail(thumbs[rand() % (sizeof(thumbs) / sizeof(char*))], 256);
+ EXPECT_TRUE(notifiers[i] != nullptr);
+
+ notifiers[i]->ready.connect(sigc::mem_fun(results[i], &LoadResult::ThumbnailReady));
+ notifiers[i]->error.connect(sigc::mem_fun(results[i], &LoadResult::ThumbnailFailed));
+ }
+
+ // disconnect every other handler (and especially the first one)
+ for (int i = 0; i < load_count; i += 2)
+ {
+ notifiers[i]->Cancel();
+ }
+
+ volatile bool timeout_reached = false;
+ guint tid = g_timeout_add (30000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ bool all_loaded = true;
+ bool any_loaded = false;
+ for (int i = 1; i < load_count; i += 2)
+ {
+ all_loaded &= results[i].got_callback;
+ any_loaded |= results[i].got_callback;
+ if (!all_loaded) break;
+ }
+ if (all_loaded) break;
+ }
+
+ for (int i = 0; i < load_count; i++)
+ {
+ if (i % 2)
+ {
+ EXPECT_TRUE(results[i].got_callback);
+ EXPECT_TRUE(results[i].succeeded);
+ glib::Object<GIcon> icon(g_icon_new_for_string(results[i].return_string.c_str(), NULL));
+ EXPECT_TRUE(G_IS_ICON(icon.RawPtr()));
+ }
+ else
+ {
+ EXPECT_FALSE(results[i].got_callback);
+ }
+ }
+
+ g_source_remove (tid);
+}
+
+
+}
diff --git a/tests/test_uscreen_mock.h b/tests/test_uscreen_mock.h
new file mode 100644
index 000000000..a81c6037c
--- /dev/null
+++ b/tests/test_uscreen_mock.h
@@ -0,0 +1,85 @@
+/*
+ * 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: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
+
+ */
+
+#ifndef TEST_USCREEN_MOCK_H
+#define TEST_USCREEN_MOCK_H
+
+#include "MultiMonitor.h"
+#include "UScreen.h"
+
+namespace unity
+{
+
+const unsigned MONITOR_WIDTH = 1024;
+const unsigned MONITOR_HEIGHT = 768;
+
+class MockUScreen : public UScreen
+{
+public:
+ MockUScreen()
+ {
+ Reset(false);
+ }
+
+ ~MockUScreen()
+ {
+ if (default_screen_ == this)
+ default_screen_ = nullptr;
+ }
+
+ void Reset(bool emit = true)
+ {
+ default_screen_ = this;
+ primary_ = 0;
+ monitors_ = {nux::Geometry(0, 0, MONITOR_WIDTH, MONITOR_HEIGHT)};
+
+ changed.emit(primary_, monitors_);
+ }
+
+ void SetupFakeMultiMonitor(int primary = 0, bool emit_update = true)
+ {
+ SetPrimary(primary, false);
+ monitors_.clear();
+
+ for (int i = 0, total_width = 0; i < max_num_monitors; ++i)
+ {
+ monitors_.push_back(nux::Geometry(MONITOR_WIDTH, MONITOR_HEIGHT, total_width, 0));
+ total_width += MONITOR_WIDTH;
+
+ if (emit_update)
+ changed.emit(GetPrimaryMonitor(), GetMonitors());
+ }
+ }
+
+ void SetPrimary(int primary, bool emit = true)
+ {
+ if (primary_ != primary)
+ {
+ primary_ = primary;
+
+ if (emit)
+ changed.emit(primary_, monitors_);
+ }
+ }
+};
+
+}
+
+#endif \ No newline at end of file
diff --git a/tests/unit/TestMain.cpp b/tests/unit/TestMain.cpp
index 76ad925ad..b95b2d0f3 100644
--- a/tests/unit/TestMain.cpp
+++ b/tests/unit/TestMain.cpp
@@ -27,7 +27,6 @@
void TestPanelServiceCreateSuite();
void TestUBusCreateSuite();
-void TestQuicklistMenuitemsCreateSuite();
void TestStaticCairoTextCreateSuite();
nux::WindowThread*
@@ -71,7 +70,6 @@ main(int argc, char** argv)
//Keep alphabetical please
TestPanelServiceCreateSuite();
- TestQuicklistMenuitemsCreateSuite();
TestStaticCairoTextCreateSuite();
TestUBusCreateSuite();
diff --git a/tests/unit/TestQuicklistMenuitems.cpp b/tests/unit/TestQuicklistMenuitems.cpp
deleted file mode 100644
index 1d29f0c08..000000000
--- a/tests/unit/TestQuicklistMenuitems.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright 2010 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: Mirco Müller <mirco.mueller@canonical.com>
- *
- */
-
-#include "config.h"
-
-#include "QuicklistMenuItem.h"
-#include "QuicklistMenuItemCheckmark.h"
-#include "QuicklistMenuItemLabel.h"
-#include "QuicklistMenuItemRadio.h"
-#include "QuicklistMenuItemSeparator.h"
-
-#include "Nux/Nux.h"
-#include "Nux/VLayout.h"
-#include "Nux/HLayout.h"
-#include "Nux/WindowThread.h"
-#include "Nux/WindowCompositor.h"
-#include "Nux/BaseWindow.h"
-
-#include "QuicklistView.h"
-#include "TestThreadHelper.h"
-
-using unity::QuicklistView;
-using unity::QuicklistMenuItem;
-using unity::QuicklistMenuItemCheckmark;
-using unity::QuicklistMenuItemLabel;
-using unity::QuicklistMenuItemRadio;
-using unity::QuicklistMenuItemSeparator;
-
-static void TestMenuItemCheckmark(void);
-static void TestMenuItemLabel(void);
-static void TestMenuItemRadio(void);
-static void TestMenuItemSeparator(void);
-static void TestQuicklistMenuItem(void);
-
-nux::WindowThread* thread = NULL;
-
-void
-TestQuicklistMenuitemsCreateSuite()
-{
-#define _DOMAIN "/Unit/QuicklistMenuitems"
-
- g_test_add_func(_DOMAIN"/MenuItemCheckmark", TestMenuItemCheckmark);
- g_test_add_func(_DOMAIN"/MenuItemLabel", TestMenuItemLabel);
- g_test_add_func(_DOMAIN"/MenuItemRadio", TestMenuItemRadio);
- g_test_add_func(_DOMAIN"/MenuItemSeparator", TestMenuItemSeparator);
- g_test_add_func(_DOMAIN"/QuicklistMenuItem", TestQuicklistMenuItem);
-}
-
-static void
-TestMenuItemCheckmark()
-{
- DbusmenuMenuitem* item = NULL;
-
-
- item = dbusmenu_menuitem_new();
-
- dbusmenu_menuitem_property_set(item,
- DBUSMENU_MENUITEM_PROP_LABEL,
- "Unchecked");
-
- dbusmenu_menuitem_property_set(item,
- DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
- DBUSMENU_MENUITEM_TOGGLE_CHECK);
-
- dbusmenu_menuitem_property_set_bool(item,
- DBUSMENU_MENUITEM_PROP_ENABLED,
- false);
-
- dbusmenu_menuitem_property_set_int(item,
- DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
- DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
-
- QuicklistMenuItemCheckmark* qlCheckmarkItem = NULL;
-
- qlCheckmarkItem = new QuicklistMenuItemCheckmark(item, true);
-
- g_assert_cmpstr(qlCheckmarkItem->GetLabel(), == , "Unchecked");
- g_assert_cmpint(qlCheckmarkItem->GetEnabled(), == , false);
- g_assert_cmpint(qlCheckmarkItem->GetActive(), == , false);
- g_assert_cmpint(qlCheckmarkItem->GetSelectable(), == , false);
- g_assert_cmpint(qlCheckmarkItem->IsMarkupEnabled(), == , false);
-
- //qlCheckmarkItem->sigChanged.connect (sigc::mem_fun (pointerToCallerClass,
- // &CallerClass::RecvChanged));
-
-
- qlCheckmarkItem->Dispose();
- g_object_unref(item);
-}
-
-static void
-TestMenuItemLabel()
-{
- DbusmenuMenuitem* item = NULL;
-
- item = dbusmenu_menuitem_new();
-
- dbusmenu_menuitem_property_set(item,
- DBUSMENU_MENUITEM_PROP_LABEL,
- "A Label");
-
- dbusmenu_menuitem_property_set_bool(item,
- DBUSMENU_MENUITEM_PROP_ENABLED,
- true);
-
- dbusmenu_menuitem_property_set_bool(item,
- "unity-use-markup",
- true);
-
- QuicklistMenuItemLabel* qlLabelItem = NULL;
-
- qlLabelItem = new QuicklistMenuItemLabel(item, true);
-
- g_assert_cmpstr(qlLabelItem->GetLabel(), == , "A Label");
- g_assert_cmpint(qlLabelItem->GetEnabled(), == , true);
- g_assert_cmpint(qlLabelItem->GetSelectable(), == , true);
- g_assert_cmpint(qlLabelItem->IsMarkupEnabled(), == , true);
-
- //qlLabelItem->sigChanged.connect (sigc::mem_fun (pointerToCallerClass,
- // &CallerClass::RecvChanged));
-
- qlLabelItem->Dispose();
- g_object_unref(item);
-}
-
-static void
-TestMenuItemRadio()
-{
- DbusmenuMenuitem* item = NULL;
-
- item = dbusmenu_menuitem_new();
-
- dbusmenu_menuitem_property_set(item,
- DBUSMENU_MENUITEM_PROP_LABEL,
- "Radio Active");
-
- dbusmenu_menuitem_property_set(item,
- DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
- DBUSMENU_MENUITEM_TOGGLE_RADIO);
-
- dbusmenu_menuitem_property_set_bool(item,
- DBUSMENU_MENUITEM_PROP_ENABLED,
- true);
-
- dbusmenu_menuitem_property_set_int(item,
- DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
- DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
-
- QuicklistMenuItemRadio* qlRadioItem = NULL;
-
- qlRadioItem = new QuicklistMenuItemRadio(item, true);
- qlRadioItem->EnableLabelMarkup(true);
-
- g_assert_cmpstr(qlRadioItem->GetLabel(), == , "Radio Active");
- g_assert_cmpint(qlRadioItem->GetEnabled(), == , true);
- g_assert_cmpint(qlRadioItem->GetActive(), == , true);
- g_assert_cmpint(qlRadioItem->GetSelectable(), == , true);
- g_assert_cmpint(qlRadioItem->IsMarkupEnabled(), == , true);
-
- //qlRadioItem->sigChanged.connect (sigc::mem_fun (pointerToCallerClass,
- // &CallerClass::RecvChanged));
-
- qlRadioItem->Dispose();
- g_object_unref(item);
-}
-
-static void
-TestMenuItemSeparator()
-{
- DbusmenuMenuitem* item = NULL;
-
- item = dbusmenu_menuitem_new();
-
- dbusmenu_menuitem_property_set(item,
- "type",
- DBUSMENU_CLIENT_TYPES_SEPARATOR);
-
- dbusmenu_menuitem_property_set_bool(item,
- DBUSMENU_MENUITEM_PROP_ENABLED,
- true);
-
- QuicklistMenuItemSeparator* qlSeparatorItem = NULL;
-
- qlSeparatorItem = new QuicklistMenuItemSeparator(item, true);
-
- g_assert_cmpint(qlSeparatorItem->GetEnabled(), == , true);
- g_assert_cmpint(qlSeparatorItem->GetSelectable(), == , false);
-
- qlSeparatorItem->Dispose();
- g_object_unref(item);
-}
-
-static void
-TestQuicklistMenuItem()
-{
- DbusmenuMenuitem* root = dbusmenu_menuitem_new();
-
- dbusmenu_menuitem_set_root(root, true);
-
- DbusmenuMenuitem* child = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_MENUITEM_PROP_LABEL);
- dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_LABEL, "label 0");
- dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
- dbusmenu_menuitem_child_append(root, child);
-
- child = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
- dbusmenu_menuitem_child_append(root, child);
-
- child = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_MENUITEM_PROP_LABEL);
- dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_LABEL, "label 1");
- dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
- dbusmenu_menuitem_child_append(root, child);
-
- child = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK);
- dbusmenu_menuitem_property_set(child, DBUSMENU_MENUITEM_PROP_LABEL, "check mark 0");
- dbusmenu_menuitem_property_set_bool(child, DBUSMENU_MENUITEM_PROP_ENABLED, true);
- dbusmenu_menuitem_property_set_int(child, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
- dbusmenu_menuitem_child_append(root, child);
-
- QuicklistView* quicklist = new QuicklistView();
-
- quicklist->TestMenuItems(root);
-
- g_assert_cmpint(quicklist->GetNumItems(), == , 4);
- g_assert_cmpint(quicklist->GetNthType(0), == , unity::MENUITEM_TYPE_LABEL);
- g_assert_cmpint(quicklist->GetNthType(1), == , unity::MENUITEM_TYPE_SEPARATOR);
- g_assert_cmpint(quicklist->GetNthType(2), == , unity::MENUITEM_TYPE_LABEL);
- g_assert_cmpint(quicklist->GetNthType(3), == , unity::MENUITEM_TYPE_CHECK);
-
- g_assert_cmpstr(quicklist->GetNthItems(0)->GetLabel(), == , "label 0");
- g_assert_cmpstr(quicklist->GetNthItems(2)->GetLabel(), == , "label 1");
- g_assert_cmpstr(quicklist->GetNthItems(3)->GetLabel(), == , "check mark 0");
-
- g_assert_cmpint(quicklist->GetChildren().size(), == , 4);
-
- quicklist->Dispose();
-}