Merge lp:~3v1n0/unity/unset-bamficon-on-removal-5.0 into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Superseded
Proposed branch: lp:~3v1n0/unity/unset-bamficon-on-removal-5.0
Merge into: lp:unity
Diff against target: 3339 lines (+2740/-1) (has conflicts)
29 files modified
dash/DashController.cpp (+4/-0)
launcher/StandaloneLauncher.cpp (+10/-0)
launcher/SwitcherView.h (+6/-0)
plugins/unityshell/src/ScreenEffectFramebufferObject.cpp (+6/-0)
plugins/unityshell/src/unityshell.cpp (+4/-1)
standalone-clients/CMakeLists.txt.OTHER (+574/-0)
tests/CMakeLists.txt (+54/-0)
tests/autopilot/autopilot/emulators/bamf.py.OTHER (+411/-0)
tests/autopilot/autopilot/keybindings.py.OTHER (+259/-0)
tests/autopilot/autopilot/matchers/__init__.py (+31/-0)
tests/autopilot/unity/emulators/__init__.py (+289/-0)
tests/autopilot/unity/emulators/dash.py (+4/-0)
tests/autopilot/unity/emulators/icons.py (+6/-0)
tests/autopilot/unity/emulators/tooltip.py (+23/-0)
tests/autopilot/unity/emulators/window_manager.py (+25/-0)
tests/autopilot/unity/tests/__init__.py (+315/-0)
tests/autopilot/unity/tests/test_command_lens.py (+8/-0)
tests/autopilot/unity/tests/test_dash.py (+10/-0)
tests/autopilot/unity/tests/test_home_lens.py (+12/-0)
tests/autopilot/unity/tests/test_hud.py (+25/-0)
tests/autopilot/unity/tests/test_ibus.py (+79/-0)
tests/autopilot/unity/tests/test_launcher.py (+152/-0)
tests/autopilot/unity/tests/test_panel.py (+1/-0)
tests/autopilot/unity/tests/test_quicklist.py (+298/-0)
tests/autopilot/unity/tests/test_shortcut_hint.py (+10/-0)
tests/test_resultviewgrid.cpp (+103/-0)
unity-shared/OverlayRenderer.cpp (+10/-0)
unity-shared/UnityWindowView.h (+5/-0)
unity-shared/WindowManager.h (+6/-0)
Text conflict in dash/DashController.cpp
Text conflict in launcher/StandaloneLauncher.cpp
Text conflict in launcher/SwitcherView.h
Text conflict in plugins/unityshell/src/ScreenEffectFramebufferObject.cpp
Conflict adding files to standalone-clients.  Created directory.
Conflict because standalone-clients is not versioned, but has versioned children.  Versioned directory.
Contents conflict in standalone-clients/CMakeLists.txt
Text conflict in tests/CMakeLists.txt
Conflict adding files to tests/autopilot/autopilot.  Created directory.
Conflict because tests/autopilot/autopilot is not versioned, but has versioned children.  Versioned directory.
Conflict adding files to tests/autopilot/autopilot/emulators.  Created directory.
Conflict because tests/autopilot/autopilot/emulators is not versioned, but has versioned children.  Versioned directory.
Contents conflict in tests/autopilot/autopilot/emulators/bamf.py
Contents conflict in tests/autopilot/autopilot/keybindings.py
Text conflict in tests/autopilot/unity/emulators/__init__.py
Text conflict in tests/autopilot/unity/emulators/dash.py
Text conflict in tests/autopilot/unity/emulators/icons.py
Text conflict in tests/autopilot/unity/emulators/tooltip.py
Text conflict in tests/autopilot/unity/emulators/window_manager.py
Text conflict in tests/autopilot/unity/tests/__init__.py
Text conflict in tests/autopilot/unity/tests/test_command_lens.py
Text conflict in tests/autopilot/unity/tests/test_dash.py
Text conflict in tests/autopilot/unity/tests/test_home_lens.py
Text conflict in tests/autopilot/unity/tests/test_hud.py
Text conflict in tests/autopilot/unity/tests/test_ibus.py
Text conflict in tests/autopilot/unity/tests/test_launcher.py
Text conflict in tests/autopilot/unity/tests/test_quicklist.py
Text conflict in tests/autopilot/unity/tests/test_shortcut_hint.py
Conflict adding file tests/test_resultviewgrid.cpp.  Moved existing file to tests/test_resultviewgrid.cpp.moved.
Text conflict in unity-shared/OverlayRenderer.cpp
Text conflict in unity-shared/UnityWindowView.h
Text conflict in unity-shared/WindowManager.h
To merge this branch: bzr merge lp:~3v1n0/unity/unset-bamficon-on-removal-5.0
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+107247@code.launchpad.net

Commit message

BamfLauncherIcon: Unset the BamfApplication when removing the icon.

Doing this manually, we prevent that a duplicated application can be added between the removal of the BamfLauncherIcon and the effective destruction (that is controlled by a timeout in LauncherModel).

Description of the change

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2=== modified file 'dash/DashController.cpp'
3--- dash/DashController.cpp 2012-05-22 15:46:04 +0000
4+++ dash/DashController.cpp 2012-05-24 17:16:22 +0000
5@@ -266,6 +266,10 @@
6 need_show_ = true;
7 return;
8 }
9+<<<<<<< TREE
10+=======
11+
12+>>>>>>> MERGE-SOURCE
13 view_->AboutToShow();
14
15 window_->ShowWindow(true);
16
17=== modified file 'dash/DashView.cpp'
18=== modified file 'dash/LensBar.cpp'
19=== modified file 'dash/LensBarIcon.cpp'
20=== modified file 'dash/PlacesGroup.cpp'
21=== modified file 'dash/ResultRendererTile.cpp'
22=== modified file 'dash/ResultView.cpp'
23=== modified file 'dash/ResultViewGrid.cpp'
24=== modified file 'dash/ResultViewGrid.h'
25=== modified file 'hud/HudController.cpp'
26=== modified file 'hud/HudController.h'
27=== modified file 'hud/HudIcon.h'
28=== modified file 'hud/HudView.cpp'
29=== modified file 'hud/HudView.h'
30=== modified file 'launcher/AbstractLauncherIcon.h'
31=== modified file 'launcher/BFBLauncherIcon.cpp'
32=== modified file 'launcher/BamfLauncherIcon.cpp'
33=== modified file 'launcher/DesktopLauncherIcon.cpp'
34=== modified file 'launcher/DeviceLauncherIcon.cpp'
35=== modified file 'launcher/HudLauncherIcon.cpp'
36=== modified file 'launcher/Launcher.cpp'
37=== modified file 'launcher/Launcher.h'
38=== modified file 'launcher/LauncherController.cpp'
39=== modified file 'launcher/LauncherIcon.cpp'
40=== modified file 'launcher/LauncherIcon.h'
41=== modified file 'launcher/QuicklistMenuItem.cpp'
42=== modified file 'launcher/QuicklistMenuItem.h'
43=== modified file 'launcher/QuicklistMenuItemSeparator.cpp'
44=== modified file 'launcher/QuicklistView.cpp'
45=== modified file 'launcher/QuicklistView.h'
46=== modified file 'launcher/StandaloneLauncher.cpp'
47--- launcher/StandaloneLauncher.cpp 2012-05-07 19:52:54 +0000
48+++ launcher/StandaloneLauncher.cpp 2012-05-24 17:16:22 +0000
49@@ -31,12 +31,22 @@
50 #include "NuxGraphics/GraphicsEngine.h"
51 #include <gtk/gtk.h>
52
53+<<<<<<< TREE
54 #include "unity-shared/BackgroundEffectHelper.h"
55 #include "FavoriteStoreGSettings.h"
56+=======
57+#include "BackgroundEffectHelper.h"
58+#include "FavoriteStoreGSettings.h"
59+>>>>>>> MERGE-SOURCE
60 #include "LauncherController.h"
61 #include "Launcher.h"
62+<<<<<<< TREE
63 #include "unity-shared/PanelStyle.h"
64
65+=======
66+#include "PanelStyle.h"
67+
68+>>>>>>> MERGE-SOURCE
69 #include <dbus/dbus-glib.h>
70
71 using namespace unity;
72
73=== modified file 'launcher/SwitcherController.cpp'
74=== modified file 'launcher/SwitcherView.h'
75--- launcher/SwitcherView.h 2012-05-17 11:52:32 +0000
76+++ launcher/SwitcherView.h 2012-05-24 17:16:22 +0000
77@@ -24,9 +24,15 @@
78 #include "unity-shared/AbstractIconRenderer.h"
79 #include "unity-shared/StaticCairoText.h"
80 #include "LayoutSystem.h"
81+<<<<<<< TREE
82 #include "unity-shared/BackgroundEffectHelper.h"
83 #include "unity-shared/UnityWindowView.h"
84
85+=======
86+#include "BackgroundEffectHelper.h"
87+#include "UnityWindowView.h"
88+
89+>>>>>>> MERGE-SOURCE
90 #include <boost/shared_ptr.hpp>
91 #include <sigc++/sigc++.h>
92
93
94=== modified file 'panel/PanelMenuView.cpp'
95=== modified file 'panel/PanelView.cpp'
96=== modified file 'panel/WindowButtons.cpp'
97=== modified file 'plugins/unityshell/src/ScreenEffectFramebufferObject.cpp'
98--- plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-05-24 07:23:12 +0000
99+++ plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-05-24 17:16:22 +0000
100@@ -101,6 +101,7 @@
101
102 void unity::ScreenEffectFramebufferObject::bind (const nux::Geometry &output)
103 {
104+<<<<<<< TREE
105 /* Very important!
106 * Don't bind unless BackgroundEffectHelper says it's necessary.
107 * Because binding has a severe impact on graphics performance and we
108@@ -109,6 +110,11 @@
109 if (!BackgroundEffectHelper::HasDirtyHelpers())
110 return;
111
112+=======
113+ if (!BackgroundEffectHelper::HasDirtyHelpers())
114+ return;
115+
116+>>>>>>> MERGE-SOURCE
117 /* Clear the error bit */
118 glGetError ();
119
120
121=== modified file 'plugins/unityshell/src/unitya11y.cpp'
122=== modified file 'plugins/unityshell/src/unityshell.cpp'
123--- plugins/unityshell/src/unityshell.cpp 2012-04-24 21:26:55 +0000
124+++ plugins/unityshell/src/unityshell.cpp 2012-05-24 17:16:22 +0000
125@@ -1449,8 +1449,11 @@
126 ShowdesktopHandler::InhibitLeaveShowdesktopMode (event->xmaprequest.window);
127 break;
128 case PropertyNotify:
129- if (event->xproperty.window == GDK_ROOT_WINDOW())
130+ if (event->xproperty.window == GDK_ROOT_WINDOW() &&
131+ event->xproperty.atom == gdk_x11_get_xatom_by_name("_GNOME_BACKGROUND_REPRESENTATIVE_COLORS"))
132+ {
133 _bghash.RefreshColor();
134+ }
135 break;
136 default:
137 if (screen->shapeEvent () + ShapeNotify == event->type)
138
139=== modified file 'plugins/unityshell/src/unityshell.h'
140=== modified file 'shortcuts/ShortcutController.cpp'
141=== modified file 'shortcuts/ShortcutView.cpp'
142=== modified file 'shortcuts/ShortcutView.h'
143=== added directory 'standalone-clients'
144=== added file 'standalone-clients/CMakeLists.txt.OTHER'
145--- standalone-clients/CMakeLists.txt.OTHER 1970-01-01 00:00:00 +0000
146+++ standalone-clients/CMakeLists.txt.OTHER 2012-05-24 17:16:22 +0000
147@@ -0,0 +1,574 @@
148+set(UNITY_SRC ../plugins/unityshell/src)
149+
150+#
151+# Data
152+#
153+
154+#
155+# Unit tests
156+#
157+find_package (PkgConfig)
158+set (TEST_DEPS "${UNITY_PLUGIN_DEPS};unity>=4.0.0 xtst")
159+pkg_check_modules (TEST_UNIT_DEPS REQUIRED ${TEST_DEPS})
160+
161+set (TESTDATADIR "${CMAKE_CURRENT_SOURCE_DIR}/data")
162+
163+set (CFLAGS
164+ ${TEST_UNIT_DEPS_CFLAGS}
165+ ${TEST_UNIT_DEPS_CFLAGS_OTHER}
166+ ${MAINTAINER_CFLAGS}
167+ "-g"
168+ "-DTESTDATADIR=\"${TESTDATADIR}\""
169+ "-DGETTEXT_PACKAGE=\"unity\""
170+ "-DINDICATORDIR=\"${CMAKE_BINARY_DIR}/tests\""
171+ "-DINDICATORICONDIR=\"${CMAKE_BINARY_DIR}/tests\""
172+ "-I${CMAKE_CURRENT_BINARY_DIR}"
173+ )
174+add_definitions (${CFLAGS})
175+
176+set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm -lGL -lGLU -lXtst")
177+link_libraries (${LIBS})
178+
179+set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS})
180+link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS})
181+
182+include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
183+
184+# We can't have convenience libs so we need to rebuild with what we need
185+# Please keep actual test files alphabetically at top and then files
186+# from ../${UNITY_SRC} or ../../services in alphabetically after that
187+
188+#
189+# Standalone tests
190+#
191+add_executable (dash
192+ standalone_dash.cpp
193+ ${UNITY_SRC}/AbstractPlacesGroup.cpp
194+ ${UNITY_SRC}/AbstractPlacesGroup.h
195+ ${UNITY_SRC}/AbstractSeparator.h
196+ ${UNITY_SRC}/AbstractSeparator.cpp
197+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
198+ ${UNITY_SRC}/BackgroundEffectHelper.h
199+ ${UNITY_SRC}/BGHash.cpp
200+ ${UNITY_SRC}/BGHash.h
201+ ${UNITY_SRC}/SearchBar.cpp
202+ ${UNITY_SRC}/SearchBar.h
203+ ${UNITY_SRC}/SearchBarSpinner.cpp
204+ ${UNITY_SRC}/SearchBarSpinner.h
205+ ${UNITY_SRC}/DashView.cpp
206+ ${UNITY_SRC}/DashView.h
207+ ${UNITY_SRC}/DashViewPrivate.cpp
208+ ${UNITY_SRC}/DashViewPrivate.h
209+ ${UNITY_SRC}/DashSettings.cpp
210+ ${UNITY_SRC}/DashSettings.h
211+ ${UNITY_SRC}/FilterAllButton.cpp
212+ ${UNITY_SRC}/FilterAllButton.h
213+ ${UNITY_SRC}/FilterExpanderLabel.cpp
214+ ${UNITY_SRC}/FilterFactory.cpp
215+ ${UNITY_SRC}/FilterAllButton.cpp
216+ ${UNITY_SRC}/FilterBasicButton.cpp
217+ ${UNITY_SRC}/FilterRatingsButton.cpp
218+ ${UNITY_SRC}/FilterRatingsWidget.cpp
219+ ${UNITY_SRC}/FilterMultiRangeWidget.cpp
220+ ${UNITY_SRC}/FilterMultiRangeButton.cpp
221+ ${UNITY_SRC}/FilterGenreButton.cpp
222+ ${UNITY_SRC}/FilterGenreWidget.cpp
223+ ${UNITY_SRC}/FilterBar.cpp
224+ ${UNITY_SRC}/FontSettings.cpp
225+ ${UNITY_SRC}/FontSettings.h
226+ ${UNITY_SRC}/IMTextEntry.cpp
227+ ${UNITY_SRC}/IMTextEntry.h
228+ ${UNITY_SRC}/IntrospectableWrappers.cpp
229+ ${UNITY_SRC}/PlacesGroup.cpp
230+ ${UNITY_SRC}/PlacesGroup.h
231+ ${UNITY_SRC}/PlacesTile.cpp
232+ ${UNITY_SRC}/PlacesTile.h
233+ ${UNITY_SRC}/PlacesSimpleTile.cpp
234+ ${UNITY_SRC}/PlacesSimpleTile.h
235+ ${UNITY_SRC}/PlacesVScrollBar.cpp
236+ ${UNITY_SRC}/PlacesVScrollBar.h
237+ ${UNITY_SRC}/DashView.cpp
238+ ${UNITY_SRC}/DashView.h
239+ ${UNITY_SRC}/DashViewPrivate.cpp
240+ ${UNITY_SRC}/DashViewPrivate.h
241+ ${UNITY_SRC}/DashStyle.cpp
242+ ${UNITY_SRC}/IconLoader.cpp
243+ ${UNITY_SRC}/IconLoader.h
244+ ${UNITY_SRC}/IconTexture.cpp
245+ ${UNITY_SRC}/IconTexture.h
246+ ${UNITY_SRC}/Introspectable.cpp
247+ ${UNITY_SRC}/Introspectable.h
248+ ${UNITY_SRC}/JSONParser.cpp
249+ ${UNITY_SRC}/LensBar.cpp
250+ ${UNITY_SRC}/LensBar.h
251+ ${UNITY_SRC}/LensBarIcon.cpp
252+ ${UNITY_SRC}/LensBarIcon.h
253+ ${UNITY_SRC}/LensView.cpp
254+ ${UNITY_SRC}/LensView.h
255+ ${UNITY_SRC}/LensViewPrivate.cpp
256+ ${UNITY_SRC}/LensViewPrivate.h
257+ ${UNITY_SRC}/LineSeparator.cpp
258+ ${UNITY_SRC}/LineSeparator.h
259+ ${UNITY_SRC}/OverlayRenderer.cpp
260+ ${UNITY_SRC}/PreviewApplications.cpp
261+ ${UNITY_SRC}/PreviewBase.cpp
262+ ${UNITY_SRC}/PreviewBasicButton.cpp
263+ ${UNITY_SRC}/ResultView.cpp
264+ ${UNITY_SRC}/ResultViewGrid.cpp
265+ ${UNITY_SRC}/ResultRenderer.cpp
266+ ${UNITY_SRC}/ResultRendererTile.cpp
267+ ${UNITY_SRC}/ResultRendererHorizontalTile.cpp
268+ ${UNITY_SRC}/TextureCache.h
269+ ${UNITY_SRC}/TextureCache.cpp
270+ ${UNITY_SRC}/Timer.cpp
271+ ${UNITY_SRC}/Timer.h
272+ ${UNITY_SRC}/StaticCairoText.cpp
273+ ${UNITY_SRC}/StaticCairoText.h
274+ ${UNITY_SRC}/UBusMessages.h
275+ ${UNITY_SRC}/UBusWrapper.cpp
276+ ${UNITY_SRC}/UBusWrapper.h
277+ ${UNITY_SRC}/ubus-server.cpp
278+ ${UNITY_SRC}/ubus-server.h
279+ ${UNITY_SRC}/UScreen.cpp
280+ ${UNITY_SRC}/UScreen.h
281+ )
282+add_dependencies (dash unity-core-${UNITY_API_VERSION})
283+
284+add_executable (panel
285+ TestPanel.cpp
286+ ${UNITY_SRC}/Animator.cpp
287+ ${UNITY_SRC}/Animator.h
288+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
289+ ${UNITY_SRC}/BackgroundEffectHelper.h
290+ ${UNITY_SRC}/DashSettings.cpp
291+ ${UNITY_SRC}/DashSettings.h
292+ ${UNITY_SRC}/PanelStyle.cpp
293+ ${UNITY_SRC}/PanelStyle.h
294+ ${UNITY_SRC}/PanelView.cpp
295+ ${UNITY_SRC}/PanelView.h
296+ ${UNITY_SRC}/PanelIndicatorsView.cpp
297+ ${UNITY_SRC}/PanelIndicatorsView.h
298+ ${UNITY_SRC}/PanelIndicatorEntryView.cpp
299+ ${UNITY_SRC}/PanelIndicatorEntryView.h
300+ ${UNITY_SRC}/PanelTitlebarGrabAreaView.h
301+ ${UNITY_SRC}/PanelTitlebarGrabAreaView.cpp
302+ ${UNITY_SRC}/PanelTray.cpp
303+ ${UNITY_SRC}/PanelTray.h
304+ ${UNITY_SRC}/Introspectable.cpp
305+ ${UNITY_SRC}/Introspectable.h
306+ ${UNITY_SRC}/PanelMenuView.cpp
307+ ${UNITY_SRC}/PanelMenuView.h
308+ ${UNITY_SRC}/Timer.cpp
309+ ${UNITY_SRC}/Timer.h
310+ ${UNITY_SRC}/StaticCairoText.cpp
311+ ${UNITY_SRC}/StaticCairoText.h
312+ ${UNITY_SRC}/WindowButtons.cpp
313+ ${UNITY_SRC}/WindowButtons.h
314+ ${UNITY_SRC}/WindowManager.cpp
315+ ${UNITY_SRC}/WindowManager.h
316+ ${UNITY_SRC}/UScreen.cpp
317+ ${UNITY_SRC}/UScreen.h
318+ ${UNITY_SRC}/ubus-server.cpp
319+ ${UNITY_SRC}/ubus-server.h
320+ )
321+add_dependencies (panel unity-core-${UNITY_API_VERSION})
322+
323+add_executable (switcher
324+ TestSwitcher.cpp
325+ ${UNITY_SRC}/AbstractLauncherIcon.h
326+ ${UNITY_SRC}/AbstractIconRenderer.h
327+ ${UNITY_SRC}/SwitcherController.cpp
328+ ${UNITY_SRC}/SwitcherController.h
329+ ${UNITY_SRC}/SwitcherModel.cpp
330+ ${UNITY_SRC}/SwitcherModel.h
331+ ${UNITY_SRC}/SwitcherView.cpp
332+ ${UNITY_SRC}/SwitcherView.h
333+ ${UNITY_SRC}/LayoutSystem.h
334+ ${UNITY_SRC}/LayoutSystem.cpp
335+ ${UNITY_SRC}/WindowManager.h
336+ ${UNITY_SRC}/WindowManager.cpp
337+ ${UNITY_SRC}/IconRenderer.cpp
338+ ${UNITY_SRC}/IconRenderer.h
339+ ${UNITY_SRC}/Introspectable.cpp
340+ ${UNITY_SRC}/Introspectable.h
341+ ${UNITY_SRC}/MockLauncherIcon.h
342+ ${UNITY_SRC}/BackgroundEffectHelper.h
343+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
344+ ${UNITY_SRC}/StaticCairoText.cpp
345+ ${UNITY_SRC}/StaticCairoText.h
346+ ${UNITY_SRC}/UBusMessages.h
347+ ${UNITY_SRC}/ubus-server.cpp
348+ ${UNITY_SRC}/ubus-server.h
349+ )
350+add_dependencies (switcher unity-core-${UNITY_API_VERSION})
351+
352+add_executable (launcher
353+ TestLauncher.cpp
354+ ${UNITY_SRC}/CairoBaseWindow.cpp
355+ ${UNITY_SRC}/AbstractLauncherIcon.h
356+ ${UNITY_SRC}/AbstractLauncherIcon.cpp
357+ ${UNITY_SRC}/AbstractIconRenderer.h
358+ ${UNITY_SRC}/LauncherIcon.cpp
359+ ${UNITY_SRC}/LauncherIcon.h
360+ ${UNITY_SRC}/SimpleLauncherIcon.cpp
361+ ${UNITY_SRC}/SimpleLauncherIcon.h
362+ ${UNITY_SRC}/BamfLauncherIcon.cpp
363+ ${UNITY_SRC}/BamfLauncherIcon.h
364+ ${UNITY_SRC}/BFBLauncherIcon.cpp
365+ ${UNITY_SRC}/BFBLauncherIcon.h
366+ ${UNITY_SRC}/SpacerLauncherIcon.cpp
367+ ${UNITY_SRC}/SpacerLauncherIcon.h
368+ ${UNITY_SRC}/DndData.cpp
369+ ${UNITY_SRC}/DndData.h
370+ ${UNITY_SRC}/TrashLauncherIcon.cpp
371+ ${UNITY_SRC}/TrashLauncherIcon.h
372+ ${UNITY_SRC}/Decaymulator.cpp
373+ ${UNITY_SRC}/Decaymulator.h
374+ ${UNITY_SRC}/DesktopLauncherIcon.cpp
375+ ${UNITY_SRC}/DesktopLauncherIcon.h
376+ ${UNITY_SRC}/DNDCollectionWindow.cpp
377+ ${UNITY_SRC}/DNDCollectionWindow.h
378+ ${UNITY_SRC}/DeviceLauncherIcon.cpp
379+ ${UNITY_SRC}/DeviceLauncherIcon.h
380+ ${UNITY_SRC}/DeviceLauncherSection.cpp
381+ ${UNITY_SRC}/DeviceLauncherSection.h
382+ ${UNITY_SRC}/DevicesSettings.cpp
383+ ${UNITY_SRC}/DevicesSettings.h
384+ ${UNITY_SRC}/EdgeBarrierController.h
385+ ${UNITY_SRC}/EdgeBarrierController.cpp
386+ ${UNITY_SRC}/FavoriteStore.cpp
387+ ${UNITY_SRC}/FavoriteStore.h
388+ ${UNITY_SRC}/FavoriteStoreGSettings.cpp
389+ ${UNITY_SRC}/FavoriteStoreGSettings.h
390+ ${UNITY_SRC}/FavoriteStorePrivate.cpp
391+ ${UNITY_SRC}/FavoriteStorePrivate.h
392+ ${UNITY_SRC}/HudLauncherIcon.cpp
393+ ${UNITY_SRC}/HudLauncherIcon.h
394+ ${UNITY_SRC}/IconLoader.cpp
395+ ${UNITY_SRC}/IconLoader.h
396+ ${UNITY_SRC}/IconTextureSource.h
397+ ${UNITY_SRC}/IconTextureSource.cpp
398+ ${UNITY_SRC}/LauncherOptions.cpp
399+ ${UNITY_SRC}/LauncherOptions.h
400+ ${UNITY_SRC}/LauncherEntryRemoteModel.cpp
401+ ${UNITY_SRC}/LauncherEntryRemoteModel.h
402+ ${UNITY_SRC}/LauncherEntryRemote.cpp
403+ ${UNITY_SRC}/LauncherEntryRemote.h
404+ ${UNITY_SRC}/LauncherController.cpp
405+ ${UNITY_SRC}/LauncherController.h
406+ ${UNITY_SRC}/LauncherModel.cpp
407+ ${UNITY_SRC}/LauncherModel.h
408+ ${UNITY_SRC}/Launcher.cpp
409+ ${UNITY_SRC}/Launcher.h
410+ ${UNITY_SRC}/LauncherHideMachine.cpp
411+ ${UNITY_SRC}/LauncherHideMachine.h
412+ ${UNITY_SRC}/LauncherHoverMachine.cpp
413+ ${UNITY_SRC}/LauncherHoverMachine.h
414+ ${UNITY_SRC}/LauncherDragWindow.cpp
415+ ${UNITY_SRC}/LauncherDragWindow.h
416+ ${UNITY_SRC}/GeisAdapter.cpp
417+ ${UNITY_SRC}/GeisAdapter.h
418+ ${UNITY_SRC}/WindowManager.h
419+ ${UNITY_SRC}/WindowManager.cpp
420+ ${UNITY_SRC}/IconRenderer.cpp
421+ ${UNITY_SRC}/IconRenderer.h
422+ ${UNITY_SRC}/Tooltip.cpp
423+ ${UNITY_SRC}/Tooltip.h
424+ ${UNITY_SRC}/BackgroundEffectHelper.h
425+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
426+ ${UNITY_SRC}/StaticCairoText.cpp
427+ ${UNITY_SRC}/StaticCairoText.h
428+ ${UNITY_SRC}/SingleMonitorLauncherIcon.cpp
429+ ${UNITY_SRC}/SingleMonitorLauncherIcon.h
430+ ${UNITY_SRC}/SoftwareCenterLauncherIcon.cpp
431+ ${UNITY_SRC}/SoftwareCenterLauncherIcon.h
432+ ${UNITY_SRC}/Introspectable.cpp
433+ ${UNITY_SRC}/Introspectable.h
434+ ${UNITY_SRC}/PanelStyle.cpp
435+ ${UNITY_SRC}/PanelStyle.h
436+ ${UNITY_SRC}/PointerBarrier.cpp
437+ ${UNITY_SRC}/PointerBarrier.h
438+ ${UNITY_SRC}/QuicklistMenuItem.cpp
439+ ${UNITY_SRC}/QuicklistMenuItem.h
440+ ${UNITY_SRC}/QuicklistMenuItemCheckmark.cpp
441+ ${UNITY_SRC}/QuicklistMenuItemCheckmark.h
442+ ${UNITY_SRC}/QuicklistMenuItemLabel.cpp
443+ ${UNITY_SRC}/QuicklistMenuItemLabel.h
444+ ${UNITY_SRC}/QuicklistMenuItemRadio.cpp
445+ ${UNITY_SRC}/QuicklistMenuItemRadio.h
446+ ${UNITY_SRC}/QuicklistMenuItemSeparator.cpp
447+ ${UNITY_SRC}/QuicklistMenuItemSeparator.h
448+ ${UNITY_SRC}/QuicklistView.cpp
449+ ${UNITY_SRC}/QuicklistView.h
450+ ${UNITY_SRC}/QuicklistManager.cpp
451+ ${UNITY_SRC}/QuicklistManager.h
452+ ${UNITY_SRC}/TextureCache.cpp
453+ ${UNITY_SRC}/TextureCache.h
454+ ${UNITY_SRC}/Timer.cpp
455+ ${UNITY_SRC}/Timer.h
456+ ${UNITY_SRC}/UBusMessages.h
457+ ${UNITY_SRC}/UBusWrapper.cpp
458+ ${UNITY_SRC}/UBusWrapper.h
459+ ${UNITY_SRC}/ubus-server.cpp
460+ ${UNITY_SRC}/ubus-server.h
461+ ${UNITY_SRC}/UScreen.cpp
462+ ${UNITY_SRC}/UScreen.h
463+ )
464+add_dependencies (launcher unity-core-${UNITY_API_VERSION})
465+
466+add_executable (keyutil
467+ TestKeyboardUtil.cpp
468+ ${UNITY_SRC}/KeyboardUtil.h
469+ ${UNITY_SRC}/KeyboardUtil.cpp
470+ )
471+add_dependencies (keyutil unity-core-${UNITY_API_VERSION})
472+
473+add_executable (quicklist
474+ ui/TestQuicklist.cpp
475+ nux_test_framework.cpp
476+ nux_test_framework.h
477+ nux_automated_test_framework.cpp
478+ nux_automated_test_framework.h
479+ ${UNITY_SRC}/CairoBaseWindow.cpp
480+ ${UNITY_SRC}/Introspectable.cpp
481+ ${UNITY_SRC}/QuicklistMenuItem.cpp
482+ ${UNITY_SRC}/QuicklistMenuItemCheckmark.cpp
483+ ${UNITY_SRC}/QuicklistMenuItemLabel.cpp
484+ ${UNITY_SRC}/QuicklistMenuItemRadio.cpp
485+ ${UNITY_SRC}/QuicklistMenuItemSeparator.cpp
486+ ${UNITY_SRC}/QuicklistView.cpp
487+ ${UNITY_SRC}/ubus-server.cpp
488+ )
489+add_dependencies(quicklist unity-core-${UNITY_API_VERSION})
490+
491+add_executable (quicklist-visuals
492+ ui/TestQuicklistVisuals.cpp
493+ ui/EventFaker.cpp
494+ ui/EventFaker.h
495+ ${UNITY_SRC}/CairoBaseWindow.cpp
496+ ${UNITY_SRC}/Introspectable.cpp
497+ ${UNITY_SRC}/QuicklistMenuItem.cpp
498+ ${UNITY_SRC}/QuicklistMenuItemCheckmark.cpp
499+ ${UNITY_SRC}/QuicklistMenuItemLabel.cpp
500+ ${UNITY_SRC}/QuicklistMenuItemRadio.cpp
501+ ${UNITY_SRC}/QuicklistMenuItemSeparator.cpp
502+ ${UNITY_SRC}/QuicklistView.cpp
503+ ${UNITY_SRC}/ubus-server.cpp
504+ )
505+add_dependencies(quicklist-visuals unity-core-${UNITY_API_VERSION})
506+
507+add_executable (filters
508+ TestFilters.cpp
509+ ${UNITY_SRC}/FilterExpanderLabel.cpp
510+ ${UNITY_SRC}/FilterBasicButton.cpp
511+ ${UNITY_SRC}/FilterRatingsButton.cpp
512+ ${UNITY_SRC}/FilterRatingsWidget.cpp
513+ ${UNITY_SRC}/FilterGenreButton.cpp
514+ ${UNITY_SRC}/FilterGenreWidget.cpp
515+ ${UNITY_SRC}/FilterMultiRangeButton.cpp
516+ ${UNITY_SRC}/FilterMultiRangeWidget.cpp
517+ ${UNITY_SRC}/DashStyle.cpp
518+ ${UNITY_SRC}/JSONParser.cpp
519+ )
520+add_dependencies(filters unity-core-${UNITY_API_VERSION})
521+
522+add_executable (filter-bar
523+ TestFilterBar.cpp
524+ ${UNITY_SRC}/FilterAllButton.cpp
525+ ${UNITY_SRC}/FilterBar.cpp
526+ ${UNITY_SRC}/FilterBasicButton.cpp
527+ ${UNITY_SRC}/FilterExpanderLabel.cpp
528+ ${UNITY_SRC}/FilterFactory.cpp
529+ ${UNITY_SRC}/FilterMultiRangeWidget.cpp
530+ ${UNITY_SRC}/FilterMultiRangeButton.cpp
531+ ${UNITY_SRC}/FilterGenreButton.cpp
532+ ${UNITY_SRC}/FilterGenreWidget.cpp
533+ ${UNITY_SRC}/FilterRatingsButton.cpp
534+ ${UNITY_SRC}/FilterRatingsWidget.cpp
535+ ${UNITY_SRC}/DashStyle.cpp
536+ ${UNITY_SRC}/JSONParser.cpp
537+ )
538+add_dependencies(filter-bar unity-core-${UNITY_API_VERSION})
539+
540+add_executable (preview-applicaiton
541+ TestPreviewApplications.cpp
542+ ${UNITY_SRC}/PreviewApplications.cpp
543+ ${UNITY_SRC}/PreviewBase.cpp
544+ ${UNITY_SRC}/PreviewBasicButton.cpp
545+ ${UNITY_SRC}/IconTexture.cpp
546+ ${UNITY_SRC}/IconLoader.cpp
547+ ${UNITY_SRC}/Introspectable.cpp
548+ ${UNITY_SRC}/StaticCairoText.cpp
549+ ${UNITY_SRC}/TextureCache.cpp
550+ ${UNITY_SRC}/DashStyle.cpp
551+ ${UNITY_SRC}/JSONParser.cpp
552+ ${UNITY_SRC}/Timer.cpp
553+ )
554+add_dependencies(preview-applicaiton unity-core-${UNITY_API_VERSION})
555+
556+add_executable (preview-generic
557+ TestPreviewGeneric.cpp
558+ ${UNITY_SRC}/PreviewGeneric.cpp
559+ ${UNITY_SRC}/PreviewBase.cpp
560+ ${UNITY_SRC}/PreviewBasicButton.cpp
561+ ${UNITY_SRC}/IconTexture.cpp
562+ ${UNITY_SRC}/IconLoader.cpp
563+ ${UNITY_SRC}/Introspectable.cpp
564+ ${UNITY_SRC}/StaticCairoText.cpp
565+ ${UNITY_SRC}/TextureCache.cpp
566+ ${UNITY_SRC}/DashStyle.cpp
567+ ${UNITY_SRC}/JSONParser.cpp
568+ ${UNITY_SRC}/Timer.cpp
569+ )
570+add_dependencies(preview-generic unity-core-${UNITY_API_VERSION})
571+
572+add_executable (preview-music
573+ TestPreviewMusic.cpp
574+ ${UNITY_SRC}/PreviewBase.cpp
575+ ${UNITY_SRC}/PreviewBasicButton.cpp
576+ ${UNITY_SRC}/PreviewMusic.cpp
577+ ${UNITY_SRC}/PreviewMusicTrack.cpp
578+ ${UNITY_SRC}/PreviewMusicTrackWidget.cpp
579+ ${UNITY_SRC}/IconTexture.cpp
580+ ${UNITY_SRC}/IconLoader.cpp
581+ ${UNITY_SRC}/Introspectable.cpp
582+ ${UNITY_SRC}/StaticCairoText.cpp
583+ ${UNITY_SRC}/TextureCache.cpp
584+ ${UNITY_SRC}/DashStyle.cpp
585+ ${UNITY_SRC}/JSONParser.cpp
586+ ${UNITY_SRC}/Timer.cpp
587+ )
588+add_dependencies(preview-music unity-core-${UNITY_API_VERSION})
589+
590+add_executable (result-view
591+ TestResultView.cpp
592+ ${UNITY_SRC}/PreviewApplications.cpp
593+ ${UNITY_SRC}/PreviewBase.cpp
594+ ${UNITY_SRC}/PreviewBasicButton.cpp
595+ ${UNITY_SRC}/ResultView.cpp
596+ ${UNITY_SRC}/ResultViewGrid.cpp
597+ ${UNITY_SRC}/ResultRenderer.cpp
598+ ${UNITY_SRC}/ResultRendererTile.cpp
599+ ${UNITY_SRC}/ResultRendererHorizontalTile.cpp
600+ ${UNITY_SRC}/IconTexture.cpp
601+ ${UNITY_SRC}/IconLoader.cpp
602+ ${UNITY_SRC}/Introspectable.cpp
603+ ${UNITY_SRC}/StaticCairoText.cpp
604+ ${UNITY_SRC}/TextureCache.cpp
605+ ${UNITY_SRC}/Timer.cpp
606+ ${UNITY_SRC}/DashStyle.cpp
607+ ${UNITY_SRC}/JSONParser.cpp
608+ ${UNITY_SRC}/UBusMessages.h
609+ ${UNITY_SRC}/UBusWrapper.cpp
610+ ${UNITY_SRC}/UBusWrapper.h
611+ ${UNITY_SRC}/ubus-server.cpp
612+ ${UNITY_SRC}/ubus-server.h
613+ )
614+add_dependencies(result-view unity-core-${UNITY_API_VERSION})
615+
616+add_executable (dash-style
617+ TestDashStyle.cpp
618+ ${UNITY_SRC}/DashStyle.cpp
619+ ${UNITY_SRC}/DashStyle.h
620+ ${UNITY_SRC}/JSONParser.cpp
621+ ${PLACES_COMMON_SOURCE}
622+ )
623+add_dependencies(dash-style unity-core-${UNITY_API_VERSION})
624+
625+add_executable (bg-hash
626+ TestBGHash.cpp
627+ ${UNITY_SRC}/BGHash.cpp
628+ ${UNITY_SRC}/BGHash.h
629+ ${UNITY_SRC}/ubus-server.cpp
630+ ${UNITY_SRC}/ubus-server.h
631+ )
632+add_dependencies (bg-hash unity-core-${UNITY_API_VERSION})
633+
634+add_executable (hud
635+ StandaloneHud.cpp
636+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
637+ ${UNITY_SRC}/BackgroundEffectHelper.h
638+ ${UNITY_SRC}/DashSettings.cpp
639+ ${UNITY_SRC}/DashSettings.h
640+ ${UNITY_SRC}/DashStyle.cpp
641+ ${UNITY_SRC}/HudButton.cpp
642+ ${UNITY_SRC}/HudIcon.cpp
643+ ${UNITY_SRC}/HudIcon.h
644+ ${UNITY_SRC}/HudIconTextureSource.cpp
645+ ${UNITY_SRC}/HudIconTextureSource.h
646+ ${UNITY_SRC}/HudView.cpp
647+ ${UNITY_SRC}/IMTextEntry.cpp
648+ ${UNITY_SRC}/Introspectable.cpp
649+ ${UNITY_SRC}/IconTexture.cpp
650+ ${UNITY_SRC}/IconLoader.cpp
651+ ${UNITY_SRC}/IconRenderer.cpp
652+ ${UNITY_SRC}/IconTextureSource.cpp
653+ ${UNITY_SRC}/JSONParser.cpp
654+ ${UNITY_SRC}/OverlayRenderer.cpp
655+ ${UNITY_SRC}/SearchBar.cpp
656+ ${UNITY_SRC}/SearchBarSpinner.cpp
657+ ${UNITY_SRC}/StaticCairoText.cpp
658+ ${UNITY_SRC}/TextureCache.cpp
659+ ${UNITY_SRC}/Timer.cpp
660+ ${UNITY_SRC}/UBusWrapper.cpp
661+ ${UNITY_SRC}/ubus-server.cpp
662+ ${UNITY_SRC}/UScreen.cpp
663+ ${UNITY_SRC}/UScreen.h
664+ )
665+add_dependencies (hud unity-core-${UNITY_API_VERSION})
666+
667+add_executable (test-shortcut
668+ TestShortcut.cpp
669+ ${UNITY_SRC}/AbstractSeparator.cpp
670+ ${UNITY_SRC}/AbstractSeparator.h
671+ ${UNITY_SRC}/AbstractShortcutHint.h
672+ ${UNITY_SRC}/Animator.cpp
673+ ${UNITY_SRC}/Animator.h
674+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
675+ ${UNITY_SRC}/BackgroundEffectHelper.h
676+ ${UNITY_SRC}/LineSeparator.cpp
677+ ${UNITY_SRC}/LineSeparator.h
678+ ${UNITY_SRC}/MockShortcutHint.h
679+ ${UNITY_SRC}/ShortcutController.cpp
680+ ${UNITY_SRC}/ShortcutController.h
681+ ${UNITY_SRC}/ShortcutModel.cpp
682+ ${UNITY_SRC}/ShortcutModel.h
683+ ${UNITY_SRC}/ShortcutView.cpp
684+ ${UNITY_SRC}/ShortcutView.h
685+ ${UNITY_SRC}/StaticCairoText.cpp
686+ ${UNITY_SRC}/StaticCairoText.h
687+ ${UNITY_SRC}/UBusMessages.h
688+ ${UNITY_SRC}/ubus-server.cpp
689+ ${UNITY_SRC}/ubus-server.h
690+ )
691+
692+add_executable (tooltip
693+ ui/TestTooltip.cpp
694+ ${UNITY_SRC}/Introspectable.cpp
695+ ${UNITY_SRC}/CairoBaseWindow.cpp
696+ ${UNITY_SRC}/StaticCairoText.cpp
697+ ${UNITY_SRC}/Tooltip.cpp
698+ ${UNITY_SRC}/ubus-server.cpp
699+ )
700+add_dependencies(quicklist unity-core-${UNITY_API_VERSION})
701+
702+find_package (OpenGL)
703+include_directories (${OPENGL_gl_INCDIRS})
704+add_library (glfuncloader SHARED
705+ ${CMAKE_CURRENT_SOURCE_DIR}/GLFuncLoader.cpp)
706+add_dependencies (glfuncloader unity-core-${UNITY_API_VERSION})
707+target_link_libraries (glfuncloader dl ${OPENGL_gl_LIBRARY})
708+add_executable (screen-effect-fbo
709+ TestScreenEffectFramebufferObject.cpp
710+ ${UNITY_SRC}/ScreenEffectFramebufferObject.cpp
711+ ${UNITY_SRC}/BackgroundEffectHelper.cpp)
712+
713+target_link_libraries (screen-effect-fbo glfuncloader ${OPENGL_gl_LIBRARY})
714+add_dependencies (screen-effect-fbo ${UNITY_API_VERSION})
715+
716+# Custom target to make all the other targets here, add your test to this list
717+add_custom_target(standalone-clients DEPENDS dash panel launcher switcher keyutil quicklist quicklist-visuals filters filter-bar preview-applicaiton preview-generic preview-music result-view dash-style bg-hash shortcut-view tooltip)
718+
719+
720+
721+
722
723=== modified file 'tests/CMakeLists.txt'
724--- tests/CMakeLists.txt 2012-05-22 15:48:31 +0000
725+++ tests/CMakeLists.txt 2012-05-24 17:16:22 +0000
726@@ -205,6 +205,7 @@
727 test_single_monitor_launcher_icon.cpp
728 test_switcher_controller.cpp
729 test_switcher_model.cpp
730+<<<<<<< TREE
731 ${CMAKE_SOURCE_DIR}/dash/AbstractPlacesGroup.cpp
732 ${CMAKE_SOURCE_DIR}/dash/DashViewPrivate.cpp
733 ${CMAKE_SOURCE_DIR}/dash/LensViewPrivate.cpp
734@@ -257,6 +258,59 @@
735 ${CMAKE_SOURCE_DIR}/unity-shared/UnityWindowView.cpp
736 ${CMAKE_SOURCE_DIR}/unity-shared/WindowManager.cpp
737 ${CMAKE_SOURCE_DIR}/unity-shared/ubus-server.cpp
738+=======
739+ ${UNITY_SRC}/AbstractLauncherIcon.cpp
740+ ${UNITY_SRC}/AbstractPlacesGroup.cpp
741+ ${UNITY_SRC}/BackgroundEffectHelper.cpp
742+ ${UNITY_SRC}/CairoBaseWindow.cpp
743+ ${UNITY_SRC}/DashViewPrivate.cpp
744+ ${UNITY_SRC}/Decaymulator.cpp
745+ ${UNITY_SRC}/DNDCollectionWindow.cpp
746+ ${UNITY_SRC}/DndData.cpp
747+ ${UNITY_SRC}/GeisAdapter.cpp
748+ ${UNITY_SRC}/IconLoader.cpp
749+ ${UNITY_SRC}/IconRenderer.cpp
750+ ${UNITY_SRC}/IconTextureSource.cpp
751+ ${UNITY_SRC}/Introspectable.cpp
752+ ${UNITY_SRC}/LayoutSystem.cpp
753+ ${UNITY_SRC}/Launcher.cpp
754+ ${UNITY_SRC}/LauncherDragWindow.cpp
755+ ${UNITY_SRC}/LauncherEntryRemote.cpp
756+ ${UNITY_SRC}/LauncherHideMachine.cpp
757+ ${UNITY_SRC}/LauncherHoverMachine.cpp
758+ ${UNITY_SRC}/LauncherIcon.cpp
759+ ${UNITY_SRC}/LauncherModel.cpp
760+ ${UNITY_SRC}/SimpleLauncherIcon.cpp
761+ ${UNITY_SRC}/SingleMonitorLauncherIcon.cpp
762+ ${UNITY_SRC}/LensViewPrivate.cpp
763+ ${UNITY_SRC}/StaticCairoText.cpp
764+ ${UNITY_SRC}/SwitcherController.cpp
765+ ${UNITY_SRC}/SwitcherModel.cpp
766+ ${UNITY_SRC}/SwitcherView.cpp
767+ ${UNITY_SRC}/Timer.cpp
768+ ${UNITY_SRC}/Tooltip.cpp
769+ ${UNITY_SRC}/PanelStyle.cpp
770+ ${UNITY_SRC}/PointerBarrier.cpp
771+ ${UNITY_SRC}/QuicklistView.cpp
772+ ${UNITY_SRC}/QuicklistManager.cpp
773+ ${UNITY_SRC}/QuicklistMenuItem.cpp
774+ ${UNITY_SRC}/QuicklistMenuItemCheckmark.cpp
775+ ${UNITY_SRC}/QuicklistMenuItemLabel.cpp
776+ ${UNITY_SRC}/QuicklistMenuItemRadio.cpp
777+ ${UNITY_SRC}/QuicklistMenuItemSeparator.cpp
778+ ${UNITY_SRC}/SpacerLauncherIcon.cpp
779+ ${UNITY_SRC}/TextureCache.cpp
780+ ${UNITY_SRC}/UBusWrapper.cpp
781+ ${UNITY_SRC}/UnityWindowStyle.cpp
782+ ${UNITY_SRC}/UnityWindowView.cpp
783+ ${UNITY_SRC}/ubus-server.cpp
784+ ${UNITY_SRC}/UScreen.cpp
785+ ${UNITY_SRC}/WindowManager.cpp
786+ ${UNITY_SRC}/ResultView.cpp
787+ ${UNITY_SRC}/ResultViewGrid.cpp
788+ ${UNITY_SRC}/ResultRenderer.cpp
789+ ${UNITY_SRC}/IntrospectableWrappers.cpp
790+>>>>>>> MERGE-SOURCE
791 )
792 target_link_libraries(test-gtest gtest gmock ${LIBS})
793 add_test(UnityGTest test-gtest)
794
795=== added directory 'tests/autopilot/autopilot'
796=== added directory 'tests/autopilot/autopilot/emulators'
797=== added file 'tests/autopilot/autopilot/emulators/bamf.py.OTHER'
798--- tests/autopilot/autopilot/emulators/bamf.py.OTHER 1970-01-01 00:00:00 +0000
799+++ tests/autopilot/autopilot/emulators/bamf.py.OTHER 2012-05-24 17:16:22 +0000
800@@ -0,0 +1,411 @@
801+# Copyright 2011 Canonical
802+# Author: Thomi Richards
803+#
804+# This program is free software: you can redistribute it and/or modify it
805+# under the terms of the GNU General Public License version 3, as published
806+# by the Free Software Foundation.
807+
808+"Various classes for interacting with BAMF."
809+
810+import dbus
811+import dbus.glib
812+import gio
813+import gobject
814+import os
815+from Xlib import display, X, protocol
816+from gtk import gdk
817+
818+from autopilot.emulators.dbus_handler import session_bus
819+
820+__all__ = [
821+ "Bamf",
822+ "BamfApplication",
823+ "BamfWindow",
824+ ]
825+
826+_BAMF_BUS_NAME = 'org.ayatana.bamf'
827+_X_DISPLAY = display.Display()
828+
829+
830+def _filter_user_visible(win):
831+ """Filter out non-user-visible objects.
832+
833+ In some cases the DBus method we need to call hasn't been registered yet,
834+ in which case we do the safe thing and return False.
835+
836+ """
837+ try:
838+ return win.user_visible
839+ except dbus.DBusException:
840+ return False
841+
842+
843+class Bamf(object):
844+ """High-level class for interacting with Bamf from within a test.
845+
846+ Use this class to inspect the state of running applications and open
847+ windows.
848+
849+ """
850+
851+ def __init__(self):
852+ matcher_path = '/org/ayatana/bamf/matcher'
853+ self.matcher_interface_name = 'org.ayatana.bamf.matcher'
854+ self.matcher_proxy = session_bus.get_object(_BAMF_BUS_NAME, matcher_path)
855+ self.matcher_interface = dbus.Interface(self.matcher_proxy, self.matcher_interface_name)
856+
857+ def get_running_applications(self, user_visible_only=True):
858+ """Get a list of the currently running applications.
859+
860+ If user_visible_only is True (the default), only applications
861+ visible to the user in the switcher will be returned.
862+
863+ """
864+ apps = [BamfApplication(p) for p in self.matcher_interface.RunningApplications()]
865+ if user_visible_only:
866+ return filter(_filter_user_visible, apps)
867+ return apps
868+
869+ def get_running_applications_by_desktop_file(self, desktop_file):
870+ """Return a list of applications that have the desktop file 'desktop_file'`.
871+
872+ This method may return an empty list, if no applications
873+ are found with the specified desktop file.
874+
875+ """
876+ return [a for a in self.get_running_applications() if a.desktop_file == desktop_file]
877+
878+ def get_application_by_xid(self, xid):
879+ """Return the application that has a child with the requested xid or None."""
880+
881+ app_path = self.matcher_interface.ApplicationForXid(xid)
882+ if len(app_path):
883+ return BamfApplication(app_path)
884+ return None
885+
886+ def get_open_windows(self, user_visible_only=True):
887+ """Get a list of currently open windows.
888+
889+ If user_visible_only is True (the default), only applications
890+ visible to the user in the switcher will be returned.
891+
892+ The result is sorted to be in stacking order.
893+
894+ """
895+
896+ windows = [BamfWindow(w) for w in self.matcher_interface.WindowStackForMonitor(-1)]
897+ if user_visible_only:
898+ windows = filter(_filter_user_visible, windows)
899+ # Now sort on stacking order.
900+ return reversed(windows)
901+
902+ def get_window_by_xid(self, xid):
903+ """Get the BamfWindow that matches the provided 'xid'."""
904+ windows = [BamfWindow(w) for w in self.matcher_interface.WindowPaths() if BamfWindow(w).x_id == xid]
905+ return windows[0] if windows else None
906+
907+ def wait_until_application_is_running(self, desktop_file, timeout):
908+ """Wait until a given application is running.
909+
910+ 'desktop_file' is the name of the application desktop file.
911+ 'timeout' is the maximum time to wait, in seconds. If set to
912+ something less than 0, this method will wait forever.
913+
914+ This method returns true once the application is found, or false
915+ if the application was not found until the timeout was reached.
916+ """
917+ desktop_file = os.path.split(desktop_file)[1]
918+ # python workaround since you can't assign to variables in the enclosing scope:
919+ # see on_timeout_reached below...
920+ found_app = [True]
921+
922+ # maybe the app is running already?
923+ if len(self.get_running_applications_by_desktop_file(desktop_file)) == 0:
924+ wait_forever = timeout < 0
925+ gobject_loop = gobject.MainLoop()
926+
927+ # No, so define a callback to watch the ViewOpened signal:
928+ def on_view_added(bamf_path, name):
929+ if bamf_path.split('/')[-1].startswith('application'):
930+ app = BamfApplication(bamf_path)
931+ if desktop_file == os.path.split(app.desktop_file)[1]:
932+ gobject_loop.quit()
933+
934+ # ...and one for when the user-defined timeout has been reached:
935+ def on_timeout_reached():
936+ gobject_loop.quit()
937+ found_app[0] = False
938+ return False
939+
940+ # need a timeout? if so, connect it:
941+ if not wait_forever:
942+ gobject.timeout_add(timeout * 1000, on_timeout_reached)
943+ # connect signal handler:
944+ session_bus.add_signal_receiver(on_view_added, 'ViewOpened')
945+ # pump the gobject main loop until either the correct signal is emitted, or the
946+ # timeout happens.
947+ gobject_loop.run()
948+
949+ return found_app[0]
950+
951+ def launch_application(self, desktop_file, files=[], wait=True):
952+ """Launch an application by specifying a desktop file.
953+
954+ `files` is a list of files to pass to the application. Not all apps support this.
955+
956+ If `wait` is True, this method will block until the application has launched.
957+
958+ Returns the Gobject process object. if wait is True (the default),
959+ this method will not return until an instance of this application
960+ appears in the BAMF application list.
961+ """
962+ if type(files) is not list:
963+ raise TypeError("files must be a list.")
964+ proc = gio.unix.DesktopAppInfo(desktop_file)
965+ proc.launch_uris(files)
966+ if wait:
967+ self.wait_until_application_is_running(desktop_file, -1)
968+ return proc
969+
970+
971+class BamfApplication(object):
972+ """Represents an application, with information as returned by Bamf.
973+
974+ Don't instantiate this class yourself. instead, use the methods as
975+ provided by the Bamf class.
976+
977+ """
978+ def __init__(self, bamf_app_path):
979+ self.bamf_app_path = bamf_app_path
980+ try:
981+ self._app_proxy = session_bus.get_object(_BAMF_BUS_NAME, bamf_app_path)
982+ self._view_iface = dbus.Interface(self._app_proxy, 'org.ayatana.bamf.view')
983+ self._app_iface = dbus.Interface(self._app_proxy, 'org.ayatana.bamf.application')
984+ except dbus.DBusException, e:
985+ e.message += 'bamf_app_path=%r' % (bamf_app_path)
986+ raise
987+
988+ @property
989+ def desktop_file(self):
990+ """Get the application desktop file"""
991+ return os.path.split(self._app_iface.DesktopFile())[1]
992+
993+ @property
994+ def name(self):
995+ """Get the application name.
996+
997+ Note: This may change according to the current locale. If you want a unique
998+ string to match applications against, use the desktop_file instead.
999+
1000+ """
1001+ return self._view_iface.Name()
1002+
1003+ @property
1004+ def icon(self):
1005+ """Get the application icon."""
1006+ return self._view_iface.Icon()
1007+
1008+ @property
1009+ def is_active(self):
1010+ """Is the application active (i.e.- has keyboard focus)?"""
1011+ return self._view_iface.IsActive()
1012+
1013+ @property
1014+ def is_urgent(self):
1015+ """Is the application currently signalling urgency?"""
1016+ return self._view_iface.IsUrgent()
1017+
1018+ @property
1019+ def user_visible(self):
1020+ """Is this application visible to the user?
1021+
1022+ Some applications (such as the panel) are hidden to the user but will
1023+ still be returned by bamf.
1024+
1025+ """
1026+ return self._view_iface.UserVisible()
1027+
1028+ def get_windows(self):
1029+ """Get a list of the application windows."""
1030+ return [BamfWindow(w) for w in self._view_iface.Children()]
1031+
1032+ def __repr__(self):
1033+ return "<BamfApplication '%s'>" % (self.name)
1034+
1035+
1036+class BamfWindow(object):
1037+ """Represents an application window, as returned by Bamf.
1038+
1039+ Don't instantiate this class yourself. Instead, use the appropriate methods
1040+ in BamfApplication.
1041+
1042+ """
1043+ def __init__(self, window_path):
1044+ self._bamf_win_path = window_path
1045+ self._app_proxy = session_bus.get_object(_BAMF_BUS_NAME, window_path)
1046+ self._window_iface = dbus.Interface(self._app_proxy, 'org.ayatana.bamf.window')
1047+ self._view_iface = dbus.Interface(self._app_proxy, 'org.ayatana.bamf.view')
1048+
1049+ self._xid = int(self._window_iface.GetXid())
1050+ self._x_root_win = _X_DISPLAY.screen().root
1051+ self._x_win = _X_DISPLAY.create_resource_object('window', self._xid)
1052+
1053+ @property
1054+ def x_id(self):
1055+ """Get the X11 Window Id."""
1056+ return self._xid
1057+
1058+ @property
1059+ def x_win(self):
1060+ """Get the X11 window object of the underlying window."""
1061+ return self._x_win
1062+
1063+ @property
1064+ def name(self):
1065+ """Get the window name.
1066+
1067+ Note: This may change according to the current locale. If you want a unique
1068+ string to match windows against, use the x_id instead.
1069+
1070+ """
1071+ return self._view_iface.Name()
1072+
1073+ @property
1074+ def title(self):
1075+ """Get the window title.
1076+
1077+ This may be different from the application name.
1078+
1079+ Note that this may change depending on the current locale.
1080+
1081+ """
1082+ return self._getProperty('_NET_WM_NAME')
1083+
1084+ @property
1085+ def geometry(self):
1086+ """Get the geometry for this window.
1087+
1088+ Returns a tuple containing (x, y, width, height).
1089+
1090+ """
1091+ # FIXME: We need to use the gdk window here to get the real coordinates
1092+ geometry = self._x_win.get_geometry()
1093+ origin = gdk.window_foreign_new(self._xid).get_origin()
1094+ return (origin[0], origin[1], geometry.width, geometry.height)
1095+
1096+ @property
1097+ def is_maximized(self):
1098+ """Is the window maximized?
1099+
1100+ Maximized in this case means both maximized
1101+ vertically and horizontally. If a window is only maximized in one
1102+ direction it is not considered maximized.
1103+
1104+ """
1105+ win_state = self._get_window_states()
1106+ return '_NET_WM_STATE_MAXIMIZED_VERT' in win_state and \
1107+ '_NET_WM_STATE_MAXIMIZED_HORZ' in win_state
1108+
1109+ @property
1110+ def application(self):
1111+ """Get the application that owns this window.
1112+
1113+ This method may return None if the window does not have an associated
1114+ application. The 'desktop' window is one such example.
1115+
1116+ """
1117+ # BAMF returns a list of parents since some windows don't have an
1118+ # associated application. For these windows we return none.
1119+ parents = self._view_iface.Parents()
1120+ if parents:
1121+ return BamfApplication(parents[0])
1122+ else:
1123+ return None
1124+
1125+ @property
1126+ def user_visible(self):
1127+ """Is this window visible to the user in the switcher?"""
1128+ return self._view_iface.UserVisible()
1129+
1130+ @property
1131+ def is_hidden(self):
1132+ """Is this window hidden?
1133+
1134+ Windows are hidden when the 'Show Desktop' mode is activated.
1135+
1136+ """
1137+ win_state = self._get_window_states()
1138+ return '_NET_WM_STATE_HIDDEN' in win_state
1139+
1140+ @property
1141+ def is_focused(self):
1142+ """Is this window focused?"""
1143+ win_state = self._get_window_states()
1144+ return '_NET_WM_STATE_FOCUSED' in win_state
1145+
1146+ @property
1147+ def is_valid(self):
1148+ """Is this window object valid?
1149+
1150+ Invalid windows are caused by windows closing during the construction of
1151+ this object instance.
1152+
1153+ """
1154+ return not self._x_win is None
1155+
1156+ @property
1157+ def monitor(self):
1158+ """Returns the monitor to which the windows belongs to"""
1159+ return self._window_iface.Monitor()
1160+
1161+ @property
1162+ def closed(self):
1163+ """Returns True if the window has been closed"""
1164+ # This will return False when the window is closed and then removed from BUS
1165+ try:
1166+ return (self._window_iface.GetXid() != self.x_id)
1167+ except:
1168+ return True
1169+
1170+ def close(self):
1171+ """Close the window."""
1172+
1173+ self._setProperty('_NET_CLOSE_WINDOW', [0, 0])
1174+
1175+ def set_focus(self):
1176+ self._x_win.set_input_focus(X.RevertToParent, X.CurrentTime)
1177+ self._x_win.configure(stack_mode=X.Above)
1178+
1179+ def __repr__(self):
1180+ return "<BamfWindow '%s'>" % (self.title if self._x_win else str(self._xid))
1181+
1182+ def _getProperty(self, _type):
1183+ """Get an X11 property.
1184+
1185+ _type is a string naming the property type. win is the X11 window object.
1186+
1187+ """
1188+ atom = self._x_win.get_full_property(_X_DISPLAY.get_atom(_type), X.AnyPropertyType)
1189+ if atom:
1190+ return atom.value
1191+
1192+ def _setProperty(self, _type, data, mask=None):
1193+ if type(data) is str:
1194+ dataSize = 8
1195+ else:
1196+ # data length must be 5 - pad with 0's if it's short, truncate otherwise.
1197+ data = (data + [0] * (5 - len(data)))[:5]
1198+ dataSize = 32
1199+
1200+ ev = protocol.event.ClientMessage(window=self._x_win, client_type=_X_DISPLAY.get_atom(_type), data=(dataSize, data))
1201+
1202+ if not mask:
1203+ mask = (X.SubstructureRedirectMask | X.SubstructureNotifyMask)
1204+ self._x_root_win.send_event(ev, event_mask=mask)
1205+ _X_DISPLAY.sync()
1206+
1207+ def _get_window_states(self):
1208+ """Return a list of strings representing the current window state."""
1209+
1210+ _X_DISPLAY.sync()
1211+ return map(_X_DISPLAY.get_atom_name, self._getProperty('_NET_WM_STATE'))
1212
1213=== added file 'tests/autopilot/autopilot/keybindings.py.OTHER'
1214--- tests/autopilot/autopilot/keybindings.py.OTHER 1970-01-01 00:00:00 +0000
1215+++ tests/autopilot/autopilot/keybindings.py.OTHER 2012-05-24 17:16:22 +0000
1216@@ -0,0 +1,259 @@
1217+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1218+# Copyright 2012 Canonical
1219+# Author: Thomi Richards
1220+#
1221+# This program is free software: you can redistribute it and/or modify it
1222+# under the terms of the GNU General Public License version 3, as published
1223+# by the Free Software Foundation.
1224+
1225+"""Utility functions to get shortcut keybindings for various parts of Unity.
1226+
1227+Inside autopilot we deal with keybindings by naming them with unique names. For
1228+example, instead of hard-coding the fact that 'Alt+F2' opens the command lens, we
1229+might call:
1230+
1231+>>> keybindings.get('lens_reveal/command')
1232+'Alt+F2'
1233+
1234+Keybindings come from two different places:
1235+ 1) Keybindings from compiz. We can get these if we have the plugin name and
1236+ setting name.
1237+ 2) Elsewhere. Right now we're hard-coding these in a separate dictionary.
1238+"""
1239+
1240+from compizconfig import Plugin, Setting
1241+import logging
1242+from types import NoneType
1243+import re
1244+
1245+from autopilot.emulators.X11 import Keyboard
1246+from autopilot.globals import global_context
1247+
1248+
1249+logger = logging.getLogger(__name__)
1250+
1251+
1252+#
1253+# Fill this dictionary with keybindings we want to store.
1254+#
1255+# If keybindings are from compizconfig, the value should be a 2-value tuple
1256+# containging (plugin_name, setting_name).
1257+#
1258+# If keybindings are elsewhere, just store the keybinding string.
1259+_keys = {
1260+ # Launcher:
1261+ "launcher/reveal": ('unityshell', 'show_launcher'),
1262+ "launcher/keynav": ('unityshell', 'keyboard_focus'),
1263+ "launcher/keynav/next": "Down",
1264+ "launcher/keynav/prev": "Up",
1265+ "launcher/keynav/activate": "Enter",
1266+ "launcher/keynav/exit": "Escape",
1267+ "launcher/keynav/open-quicklist": "Right",
1268+ "launcher/keynav/close-quicklist": "Left",
1269+ "launcher/switcher": ('unityshell', 'launcher_switcher_forward'),
1270+ "launcher/switcher/exit": "Escape",
1271+ "launcher/switcher/next": "Tab",
1272+ "launcher/switcher/prev": "Shift+Tab",
1273+ "launcher/switcher/down": "Down",
1274+ "launcher/switcher/up": "Up",
1275+ # Quicklist:
1276+ "quicklist/keynav/first": "Home",
1277+ "quicklist/keynav/last": "End",
1278+ "quicklist/keynav/next": "Down",
1279+ "quicklist/keynav/prev": "Up",
1280+ "quicklist/keynav/activate": "Enter",
1281+ "quicklist/keynav/exit": "Escape",
1282+ # Panel:
1283+ "panel/show_menus": "Alt",
1284+ "panel/open_first_menu": ('unityshell', 'panel_first_menu'),
1285+ "panel/next_indicator": "Right",
1286+ "panel/prev_indicator": "Left",
1287+ # Dash:
1288+ "dash/reveal": "Super",
1289+ "dash/lens/next": "Ctrl+Tab",
1290+ "dash/lens/prev": "Ctrl+Shift+Tab",
1291+ # Lenses:
1292+ "lens_reveal/command": ("unityshell", "execute_command"),
1293+ "lens_reveal/apps": "Super+a",
1294+ "lens_reveal/files": "Super+f",
1295+ "lens_reveal/music": "Super+m",
1296+ # Hud:
1297+ "hud/reveal": ("unityshell", "show_hud"),
1298+ # Switcher:
1299+ "switcher/reveal_normal": ("unityshell", "alt_tab_forward"),
1300+ "switcher/reveal_impropper": "Alt+Right",
1301+ "switcher/reveal_details": "Alt+`",
1302+ "switcher/reveal_all": ("unityshell", "alt_tab_forward_all"),
1303+ "switcher/cancel": "Escape",
1304+ # Shortcut Hint:
1305+ "shortcuthint/reveal": ('unityshell', 'show_launcher'),
1306+ "shortcuthint/cancel": "Escape",
1307+ # These are in compiz as 'Alt+Right' and 'Alt+Left', but the fact that it
1308+ # lists the Alt key won't work for us, so I'm defining them manually.
1309+ "switcher/next": "Tab",
1310+ "switcher/prev": "Shift+Tab",
1311+ "switcher/right": "Right",
1312+ "switcher/left": "Left",
1313+ "switcher/detail_start": "Down",
1314+ "switcher/detail_stop": "Up",
1315+ "switcher/detail_next": "`",
1316+ "switcher/detail_prev": "`",
1317+ # Workspace switcher (wall):
1318+ "workspace/move_left": ("wall", "left_key"),
1319+ "workspace/move_right": ("wall", "right_key"),
1320+ "workspace/move_up": ("wall", "up_key"),
1321+ "workspace/move_down": ("wall", "down_key"),
1322+ # Window management:
1323+ "window/show_desktop" : ("core", "show_desktop_key"),
1324+ "window/minimize": ("core", "minimize_window_key"),
1325+ "window/maximize": ("core", "maximize_window_key"),
1326+ "window/restore": ("core", "unmaximize_window_key"),
1327+ "window/close": ("core", "close_window_key"),
1328+ # expo plugin:
1329+ "expo/start": ("expo", "expo_key"),
1330+ "expo/cancel": "Escape",
1331+ # spread (scale) plugin:
1332+ "spread/start": ("scale", "initiate_all_key"),
1333+ "spread/cancel": "Escape",
1334+}
1335+
1336+
1337+
1338+def get(binding_name):
1339+ """Get a keybinding, given its well-known name.
1340+
1341+ binding_name must be a string, or a TypeError will be raised.
1342+
1343+ If binding_name cannot be found in the bindings dictionaries, a ValueError
1344+ will be raised.
1345+
1346+ """
1347+ if not isinstance(binding_name, basestring):
1348+ raise TypeError("binding_name must be a string.")
1349+ if binding_name not in _keys:
1350+ raise ValueError("Unknown binding name '%s'." % (binding_name))
1351+ v = _keys[binding_name]
1352+ if isinstance(v, basestring):
1353+ return v
1354+ else:
1355+ return _get_compiz_keybinding(v)
1356+
1357+
1358+def get_hold_part(binding_name):
1359+ """Returns the part of a keybinding that must be held permenantly.
1360+
1361+ Use this function to split bindings like "Alt+Tab" into the part that must be
1362+ held down. See get_tap_part for the part that must be tapped.
1363+
1364+ Raises a ValueError if the binding specified does not have multiple parts.
1365+
1366+ """
1367+ binding = get(binding_name)
1368+ parts = binding.split('+')
1369+ if len(parts) == 1:
1370+ logger.warning("Key binding '%s' does not have a hold part.", binding_name)
1371+ return parts[0]
1372+ return '+'.join(parts[:-1])
1373+
1374+
1375+def get_tap_part(binding_name):
1376+ """Returns the part of a keybinding that must be tapped.
1377+
1378+ Use this function to split bindings like "Alt+Tab" into the part that must be
1379+ held tapped. See get_hold_part for the part that must be held down.
1380+
1381+ Raises a ValueError if the binding specified does not have multiple parts.
1382+
1383+ """
1384+ binding = get(binding_name)
1385+ parts = binding.split('+')
1386+ if len(parts) == 1:
1387+ logger.warning("Key binding '%s' does not have a tap part.", binding_name)
1388+ return parts[0]
1389+ return parts[-1]
1390+
1391+
1392+def _get_compiz_keybinding(compiz_tuple):
1393+ """Given a keybinding name, get the keybinding string from the compiz option.
1394+
1395+ Raises ValueError if the compiz setting described does not hold a keybinding.
1396+ Raises RuntimeError if the compiz keybinding has been disabled.
1397+
1398+ """
1399+ plugin_name, setting_name = compiz_tuple
1400+ plugin = Plugin(global_context, plugin_name)
1401+ setting = Setting(plugin, setting_name)
1402+ if setting.Type != 'Key':
1403+ raise ValueError("Key binding maps to a compiz option that does not hold a keybinding.")
1404+ if not plugin.Enabled:
1405+ logger.warning("Returning keybinding for '%s' which is in un-enabled plugin '%s'",
1406+ setting.ShortDesc,
1407+ plugin.ShortDesc)
1408+ if setting.Value == "Disabled":
1409+ raise RuntimeError("Keybinding '%s' in compiz plugin '%s' has been disabled." %
1410+ (setting.ShortDesc, plugin.ShortDesc))
1411+
1412+ return _translate_compiz_keystroke_string(setting.Value)
1413+
1414+
1415+def _translate_compiz_keystroke_string(keystroke_string):
1416+ """Get a string representing the keystroke stored in `keystroke_string`.
1417+
1418+ `keystroke_string` is a compizconfig-style keystroke string.
1419+
1420+ The returned value is suitable for passing into the Keyboard emulator.
1421+
1422+ """
1423+ if not isinstance(keystroke_string, basestring):
1424+ raise TypeError("keystroke string must be a string.")
1425+
1426+ translations = {
1427+ 'Control': 'Ctrl',
1428+ 'Primary': 'Ctrl',
1429+ }
1430+ regex = re.compile('[<>]')
1431+ parts = regex.split(keystroke_string)
1432+ result = []
1433+ for part in parts:
1434+ part = part.strip()
1435+ if part != "" and not part.isspace():
1436+ translated = translations.get(part, part)
1437+ if translated not in result:
1438+ result.append(translated)
1439+
1440+ return '+'.join(result)
1441+
1442+
1443+class KeybindingsHelper(object):
1444+ """A helper class that makes it easier to use unity keybindings."""
1445+ _keyboard = Keyboard()
1446+
1447+ def keybinding(self, binding_name, delay=None):
1448+ """Press and release the keybinding with the given name.
1449+
1450+ If set, the delay parameter will override the default delay set by the
1451+ keyboard emulator.
1452+
1453+ """
1454+ if type(delay) not in (float, NoneType):
1455+ raise TypeError("delay parameter must be a float if it is defined.")
1456+ if delay:
1457+ self._keyboard.press_and_release(get(binding_name), delay)
1458+ else:
1459+ self._keyboard.press_and_release(get(binding_name))
1460+
1461+ def keybinding_hold(self, binding_name):
1462+ """Hold down the hold-part of a keybinding."""
1463+ self._keyboard.press(get_hold_part(binding_name))
1464+
1465+ def keybinding_release(self, binding_name):
1466+ """Release the hold-part of a keybinding."""
1467+ self._keyboard.release(get_hold_part(binding_name))
1468+
1469+ def keybinding_tap(self, binding_name):
1470+ """Tap the tap-part of a keybinding."""
1471+ self._keyboard.press_and_release(get_tap_part(binding_name))
1472+
1473+ def keybinding_hold_part_then_tap(self, binding_name):
1474+ self.keybinding_hold(binding_name)
1475+ self.keybinding_tap(binding_name)
1476
1477=== added directory 'tests/autopilot/autopilot/matchers'
1478=== added file 'tests/autopilot/autopilot/matchers/__init__.py'
1479--- tests/autopilot/autopilot/matchers/__init__.py 1970-01-01 00:00:00 +0000
1480+++ tests/autopilot/autopilot/matchers/__init__.py 2012-05-24 17:16:22 +0000
1481@@ -0,0 +1,31 @@
1482+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1483+# Copyright 2012 Canonical
1484+# Author: Thomi Richards
1485+#
1486+# This program is free software: you can redistribute it and/or modify it
1487+# under the terms of the GNU General Public License version 3, as published
1488+# by the Free Software Foundation.
1489+
1490+"Autopilot-specific matchers."
1491+
1492+from testtools.matchers import Matcher
1493+
1494+
1495+class Eventually(Matcher):
1496+ """Asserts that a value will eventually equal a given Matcher object."""
1497+
1498+ def __init__(self, matcher):
1499+ super(Eventually, self).__init__()
1500+ match_fun = getattr(matcher, 'match', None)
1501+ if match_fun is None or not callable(match_fun):
1502+ raise TypeError("Eventually must be called with a testtools matcher argument.")
1503+ self.matcher = matcher
1504+
1505+ def match(self, value):
1506+ wait_fun = getattr(value, 'wait_for', None)
1507+ if wait_fun is None or not callable(wait_fun):
1508+ raise TypeError("Eventually can only be used against autopilot attributes that have a wait_for funtion.")
1509+ wait_fun(self.matcher)
1510+
1511+ def __str__(self):
1512+ return "Eventually " + str(self.matcher)
1513
1514=== modified file 'tests/autopilot/unity/emulators/__init__.py'
1515--- tests/autopilot/unity/emulators/__init__.py 2012-05-08 16:13:17 +0000
1516+++ tests/autopilot/unity/emulators/__init__.py 2012-05-24 17:16:22 +0000
1517@@ -7,4 +7,293 @@
1518 # by the Free Software Foundation.
1519 #
1520
1521+<<<<<<< TREE
1522 """A collection of Unity-specific emulators."""
1523+=======
1524+from dbus import Interface
1525+import logging
1526+from testtools.matchers import Equals
1527+from time import sleep
1528+
1529+from autopilot.emulators.dbus_handler import session_bus
1530+
1531+_object_registry = {}
1532+logger = logging.getLogger(__name__)
1533+
1534+
1535+class StateNotFoundError(RuntimeError):
1536+ """Raised when a piece of state information from unity is not found."""
1537+
1538+ message = "State not found for class with name '{}' and id '{}'."
1539+
1540+ def __init__(self, class_name, class_id):
1541+ super(StateNotFoundError, self).__init__(self.message.format(class_name, class_id))
1542+
1543+
1544+class IntrospectableObjectMetaclass(type):
1545+ """Metaclass to insert appropriate classes into the object registry."""
1546+
1547+ def __new__(cls, classname, bases, classdict):
1548+ """Add class name to type registry."""
1549+ class_object = type.__new__(cls, classname, bases, classdict)
1550+ _object_registry[classname] = class_object
1551+ return class_object
1552+
1553+
1554+# acquire the debugging dbus object
1555+UNITY_BUS_NAME = 'com.canonical.Unity'
1556+DEBUG_PATH = '/com/canonical/Unity/Debug'
1557+INTROSPECTION_IFACE = 'com.canonical.Unity.Debug.Introspection'
1558+
1559+
1560+_debug_proxy_obj = session_bus.get_object(UNITY_BUS_NAME, DEBUG_PATH)
1561+_introspection_iface = Interface(_debug_proxy_obj, INTROSPECTION_IFACE)
1562+
1563+
1564+def get_state_by_path(piece='/Unity'):
1565+ """Returns a full dump of unity's state."""
1566+ return _introspection_iface.GetState(piece)
1567+
1568+
1569+def get_state_by_name_and_id(class_name, unique_id):
1570+ """Get a state dictionary from unity given a class name and id.
1571+
1572+ raises StateNotFoundError if the state is not found.
1573+
1574+ Returns a dictionary of information. Unlike get_state_by_path, this
1575+ method can never return state for more than one object.
1576+ """
1577+ try:
1578+ query = "//%(class_name)s[id=%(unique_id)d]" % (dict(
1579+ class_name=class_name,
1580+ unique_id=unique_id))
1581+ return get_state_by_path(query)[0]
1582+ except IndexError:
1583+ raise StateNotFoundError(class_name, unique_id)
1584+
1585+
1586+def make_introspection_object(dbus_tuple):
1587+ """Make an introspection object given a DBus tuple of (name, state_dict).
1588+
1589+ This only works for classes that derive from UnityIntrospectionObject.
1590+ """
1591+ name, state = dbus_tuple
1592+ try:
1593+ class_type = _object_registry[name]
1594+ except KeyError:
1595+ print name, "is not a valid introspection type!"
1596+ return None
1597+ return class_type(state)
1598+
1599+
1600+def start_log_to_file(file_path):
1601+ """Instruct Unity to start logging to the given file."""
1602+ _introspection_iface.StartLogToFile(file_path)
1603+
1604+
1605+def reset_logging():
1606+ """Instruct Unity to stop logging to a file."""
1607+ _introspection_iface.ResetLogging()
1608+
1609+
1610+def set_log_severity(component, severity):
1611+ """Instruct Unity to set a log component's severity.
1612+
1613+ 'component' is the unity logging component name.
1614+
1615+ 'severity' is the severity name (like 'DEBUG', 'INFO' etc.)
1616+
1617+ """
1618+ _introspection_iface.SetLogSeverity(component, severity)
1619+
1620+
1621+def log_unity_message(severity, message):
1622+ """Instruct unity to log a message for us.
1623+
1624+ severity: one of ('TRACE', 'DEBUG', 'INFO', 'WARNING', 'ERROR').
1625+
1626+ message: The message to log.
1627+
1628+ For debugging purposes only! If you want to log a message during an autopilot
1629+ test, use the python logging framework instead.
1630+
1631+ """
1632+ _introspection_iface.LogMessage(severity, message)
1633+
1634+
1635+def translate_state_keys(state_dict):
1636+ """Translates the state_dict passed in so the keys are usable as python attributes."""
1637+ return {k.replace('-','_'):v for k,v in state_dict.iteritems() }
1638+
1639+
1640+class UnityIntrospectionObject(object):
1641+ """A class that can be created using a dictionary of state from Unity."""
1642+ __metaclass__ = IntrospectableObjectMetaclass
1643+
1644+ def __init__(self, state_dict):
1645+ self.__state = {}
1646+ self.set_properties(state_dict)
1647+
1648+ def set_properties(self, state_dict):
1649+ """Creates and set attributes of `self` based on contents of `state_dict`.
1650+
1651+ Translates '-' to '_', so a key of 'icon-type' for example becomes 'icon_type'.
1652+
1653+ """
1654+ self.__state = {}
1655+ for key, value in translate_state_keys(state_dict).iteritems():
1656+ # don't store id in state dictionary -make it a proper instance attribute
1657+ if key == 'id':
1658+ self.id = value
1659+ self.__state[key] = self._make_attribute(key, value)
1660+
1661+ def _make_attribute(self, name, value):
1662+ """Make an attribute for 'value', patched with the wait_for function."""
1663+
1664+ def wait_for(self, expected_value):
1665+ """Wait up to 10 seconds for our value to change to 'expected_value'.
1666+
1667+ expected_value can be a testtools.matcher.Matcher subclass (like
1668+ LessThan, for example), or an ordinary value.
1669+
1670+ This works by refreshing the value using repeated dbus calls.
1671+
1672+ Raises RuntimeError if the attribute was not equal to the expected value
1673+ after 10 seconds.
1674+
1675+ """
1676+ # It's guaranteed that our value is up to date, since __getattr__ calls
1677+ # refresh_state. This if statement stops us waiting if the value is
1678+ # already what we expect:
1679+ if self == expected_value:
1680+ return
1681+
1682+ # unfortunately not all testtools matchers derive from the Matcher
1683+ # class, so we can't use issubclass, isinstance for this:
1684+ match_fun = getattr(expected_value, 'match', None)
1685+ is_matcher = match_fun and callable(match_fun)
1686+ if not is_matcher:
1687+ expected_value = Equals(expected_value)
1688+
1689+ for i in range(11):
1690+ new_state = translate_state_keys(get_state_by_name_and_id(
1691+ self.parent.__class__.__name__,
1692+ self.parent.id)
1693+ )
1694+ new_value = new_state[self.name]
1695+ # Support for testtools.matcher classes:
1696+ mismatch = expected_value.match(new_value)
1697+ if mismatch:
1698+ failure_msg = mismatch.describe()
1699+ else:
1700+ self.parent.set_properties(new_state)
1701+ return
1702+
1703+ sleep(1)
1704+
1705+ raise AssertionError("After 10 seconds test on %s.%s failed: %s"
1706+ % (self.parent.__class__.__name__, self.name, failure_msg))
1707+
1708+ # This looks like magic, but it's really not. We're creating a new type
1709+ # on the fly that derives from the type of 'value' with a couple of
1710+ # extra attributes: wait_for is the wait_for method above. 'parent' and
1711+ # 'name' are needed by the wait_for method.
1712+ #
1713+ # We can't use traditional meta-classes here, since the type we're
1714+ # deriving from is only known at call time, not at parse time (we could
1715+ # override __call__ in the meta class, but that doesn't buy us anything
1716+ # extra).
1717+ #
1718+ # A better way to do this would be with functools.partial, which I tried
1719+ # initially, but doesn't work well with bound methods.
1720+ t = type(value)
1721+ attrs = {'wait_for': wait_for, 'parent':self, 'name':name}
1722+ return type(t.__name__, (t,), attrs)(value)
1723+
1724+ def _get_child_tuples_by_type(self, desired_type):
1725+ """Get a list of (name,dict) pairs from children of the specified type.
1726+
1727+ desired_type must be a subclass of UnityIntrospectionObject.
1728+
1729+ """
1730+ if not issubclass(desired_type, UnityIntrospectionObject):
1731+ raise TypeError("%r must be a subclass of %r" % (desired_type,
1732+ UnityIntrospectionObject))
1733+
1734+ children = getattr(self, 'Children', [])
1735+ results = []
1736+ # loop through all children, and try find one that matches the type the
1737+ # user wants.
1738+ for child_type, child_state in children:
1739+ try:
1740+ if issubclass(_object_registry[child_type], desired_type):
1741+ results.append((child_type, child_state))
1742+ except KeyError:
1743+ pass
1744+ return results
1745+
1746+ def get_children_by_type(self, desired_type, **kwargs):
1747+ """Get a list of children of the specified type.
1748+
1749+ desired_type must be a subclass of UnityIntrospectionObject.
1750+
1751+ Keyword arguments can be used to restrict returned instances. For example:
1752+
1753+ >>> get_children_by_type(Launcher, monitor=1)
1754+
1755+ ... will return only LauncherInstances that have an attribute 'monitor'
1756+ that is equal to 1.
1757+
1758+ """
1759+ self.refresh_state()
1760+ result = []
1761+ for child in self._get_child_tuples_by_type(desired_type):
1762+ instance = make_introspection_object(child)
1763+ filters_passed = True
1764+ for attr, val in kwargs.iteritems():
1765+ if not hasattr(instance, attr) or getattr(instance, attr) != val:
1766+ # Either attribute is not present, or is present but with
1767+ # the wrong value - don't add this instance to the results list.
1768+ filters_passed = False
1769+ break
1770+ if filters_passed:
1771+ result.append(instance)
1772+ return result
1773+
1774+ def refresh_state(self):
1775+ """Refreshes the object's state from unity.
1776+
1777+ raises StateNotFound if the object in unity has been destroyed.
1778+
1779+ """
1780+ # need to get name from class object.
1781+ new_state = get_state_by_name_and_id(self.__class__.__name__, self.id)
1782+ self.set_properties(new_state)
1783+
1784+ @classmethod
1785+ def get_all_instances(cls):
1786+ """Get all instances of this class that exist within the Unity state tree.
1787+
1788+ For example, to get all the BamfLauncherIcons:
1789+
1790+ icons = BamfLauncherIcons.get_all_instances()
1791+
1792+ The return value is a list (possibly empty) of class instances.
1793+
1794+ """
1795+ cls_name = cls.__name__
1796+ instances = get_state_by_path("//%s" % (cls_name))
1797+ return [make_introspection_object((cls_name,i)) for i in instances]
1798+
1799+ def __getattr__(self, name):
1800+ # avoid recursion if for some reason we have no state set (should never)
1801+ # happen.
1802+ if name == '__state':
1803+ raise AttributeError()
1804+
1805+ if name in self.__state:
1806+ self.refresh_state()
1807+ return self.__state[name]
1808+ # attribute not found.
1809+ raise AttributeError("Attribute '%s' not found." % (name))
1810+>>>>>>> MERGE-SOURCE
1811
1812=== modified file 'tests/autopilot/unity/emulators/dash.py'
1813--- tests/autopilot/unity/emulators/dash.py 2012-05-08 16:13:17 +0000
1814+++ tests/autopilot/unity/emulators/dash.py 2012-05-24 17:16:22 +0000
1815@@ -7,9 +7,13 @@
1816 # by the Free Software Foundation.
1817 #
1818
1819+<<<<<<< TREE
1820 from __future__ import absolute_import
1821
1822 from autopilot.introspection.unity import (
1823+=======
1824+from autopilot.emulators.unity import (
1825+>>>>>>> MERGE-SOURCE
1826 get_state_by_path,
1827 make_introspection_object,
1828 UnityIntrospectionObject,
1829
1830=== modified file 'tests/autopilot/unity/emulators/hud.py'
1831=== modified file 'tests/autopilot/unity/emulators/icons.py'
1832--- tests/autopilot/unity/emulators/icons.py 2012-05-16 02:57:25 +0000
1833+++ tests/autopilot/unity/emulators/icons.py 2012-05-24 17:16:22 +0000
1834@@ -7,11 +7,17 @@
1835 # by the Free Software Foundation.
1836 #
1837
1838+<<<<<<< TREE
1839 from __future__ import absolute_import
1840
1841 from autopilot.introspection.unity import UnityIntrospectionObject
1842 from unity.emulators.quicklist import Quicklist
1843 from unity.emulators.tooltip import ToolTip
1844+=======
1845+from autopilot.emulators.unity import UnityIntrospectionObject
1846+from autopilot.emulators.unity.quicklist import Quicklist
1847+from autopilot.emulators.unity.tooltip import ToolTip
1848+>>>>>>> MERGE-SOURCE
1849
1850 class SimpleLauncherIcon(UnityIntrospectionObject):
1851 """Holds information about a simple launcher icon.
1852
1853=== modified file 'tests/autopilot/unity/emulators/launcher.py'
1854=== modified file 'tests/autopilot/unity/emulators/quicklist.py'
1855=== modified file 'tests/autopilot/unity/emulators/shortcut_hint.py'
1856=== modified file 'tests/autopilot/unity/emulators/tooltip.py'
1857--- tests/autopilot/unity/emulators/tooltip.py 2012-05-16 02:57:25 +0000
1858+++ tests/autopilot/unity/emulators/tooltip.py 2012-05-24 17:16:22 +0000
1859@@ -1,3 +1,4 @@
1860+<<<<<<< TREE
1861 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1862 # Copyright 2012 Canonical
1863 # Author: Andrea Azzarone
1864@@ -18,3 +19,25 @@
1865
1866 class ToolTip(UnityIntrospectionObject):
1867 """Represents a tooltip."""
1868+=======
1869+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1870+# Copyright 2012 Canonical
1871+# Author: Andrea Azzarone
1872+#
1873+# This program is free software: you can redistribute it and/or modify it
1874+# under the terms of the GNU General Public License version 3, as published
1875+# by the Free Software Foundation.
1876+#
1877+
1878+import logging
1879+from time import sleep
1880+
1881+from autopilot.emulators.unity import UnityIntrospectionObject
1882+
1883+
1884+logger = logging.getLogger(__name__)
1885+
1886+
1887+class ToolTip(UnityIntrospectionObject):
1888+ """Represents a tooltip."""
1889+>>>>>>> MERGE-SOURCE
1890
1891=== modified file 'tests/autopilot/unity/emulators/window_manager.py'
1892--- tests/autopilot/unity/emulators/window_manager.py 2012-05-08 16:13:17 +0000
1893+++ tests/autopilot/unity/emulators/window_manager.py 2012-05-24 17:16:22 +0000
1894@@ -1,3 +1,4 @@
1895+<<<<<<< TREE
1896 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1897 # Copyright 2012 Canonical
1898 # Author: Marco Trevisan (Treviño)
1899@@ -22,3 +23,27 @@
1900 def screen_geometry(self):
1901 """Returns a tuple of (x,y,w,h) for the screen."""
1902 return (self.x, self.y, self.width, self.height)
1903+=======
1904+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1905+# Copyright 2012 Canonical
1906+# Author: Marco Trevisan (Treviño)
1907+#
1908+# This program is free software: you can redistribute it and/or modify it
1909+# under the terms of the GNU General Public License version 3, as published
1910+# by the Free Software Foundation.
1911+#
1912+
1913+import logging
1914+from autopilot.emulators.unity import UnityIntrospectionObject
1915+
1916+logger = logging.getLogger(__name__)
1917+
1918+
1919+class WindowManager(UnityIntrospectionObject):
1920+ """The WindowManager class."""
1921+
1922+ @property
1923+ def screen_geometry(self):
1924+ """Returns a tuple of (x,y,w,h) for the screen."""
1925+ return (self.x, self.y, self.width, self.height)
1926+>>>>>>> MERGE-SOURCE
1927
1928=== modified file 'tests/autopilot/unity/tests/__init__.py'
1929--- tests/autopilot/unity/tests/__init__.py 2012-05-16 23:02:38 +0000
1930+++ tests/autopilot/unity/tests/__init__.py 2012-05-24 17:16:22 +0000
1931@@ -29,6 +29,7 @@
1932 start_log_to_file,
1933 reset_logging,
1934 )
1935+<<<<<<< TREE
1936
1937
1938
1939@@ -94,6 +95,95 @@
1940 managers = WindowManager.get_all_instances()
1941 self.assertThat(len(managers), Equals(1))
1942 return managers[0]
1943+=======
1944+from autopilot.emulators.unity.dash import Dash
1945+from autopilot.emulators.unity.hud import Hud
1946+from autopilot.emulators.unity.launcher import LauncherController
1947+from autopilot.emulators.unity.panel import PanelController
1948+from autopilot.emulators.unity.switcher import Switcher
1949+from autopilot.emulators.unity.window_manager import WindowManager
1950+from autopilot.emulators.unity.workspace import WorkspaceManager
1951+from autopilot.emulators.X11 import ScreenGeometry, Keyboard, Mouse, reset_display
1952+from autopilot.glibrunner import GlibRunner
1953+from autopilot.globals import (global_context,
1954+ video_recording_enabled,
1955+ video_record_directory,
1956+ )
1957+from autopilot.keybindings import KeybindingsHelper
1958+
1959+
1960+logger = logging.getLogger(__name__)
1961+
1962+
1963+try:
1964+ from testscenarios.scenarios import multiply_scenarios
1965+except ImportError:
1966+ from itertools import product
1967+ def multiply_scenarios(*scenarios):
1968+ """Multiply two or more iterables of scenarios.
1969+
1970+ It is safe to pass scenario generators or iterators.
1971+
1972+ :returns: A list of compound scenarios: the cross-product of all
1973+ scenarios, with the names concatenated and the parameters
1974+ merged together.
1975+ """
1976+ result = []
1977+ scenario_lists = map(list, scenarios)
1978+ for combination in product(*scenario_lists):
1979+ names, parameters = zip(*combination)
1980+ scenario_name = ','.join(names)
1981+ scenario_parameters = {}
1982+ for parameter in parameters:
1983+ scenario_parameters.update(parameter)
1984+ result.append((scenario_name, scenario_parameters))
1985+ return result
1986+
1987+
1988+class LoggedTestCase(TestWithScenarios, TestCase):
1989+ """Initialize the logging for the test case."""
1990+
1991+ def setUp(self):
1992+ self._setUpTestLogging()
1993+ self._setUpUnityLogging()
1994+ # The reason that the super setup is done here is due to making sure
1995+ # that the logging is properly set up prior to calling it.
1996+ super(LoggedTestCase, self).setUp()
1997+
1998+ def _setUpTestLogging(self):
1999+ class MyFormatter(logging.Formatter):
2000+
2001+ def formatTime(self, record, datefmt=None):
2002+ ct = self.converter(record.created)
2003+ if datefmt:
2004+ s = time.strftime(datefmt, ct)
2005+ else:
2006+ t = time.strftime("%H:%M:%S", ct)
2007+ s = "%s.%03d" % (t, record.msecs)
2008+ return s
2009+
2010+ self._log_buffer = StringIO()
2011+ root_logger = logging.getLogger()
2012+ root_logger.setLevel(logging.DEBUG)
2013+ handler = logging.StreamHandler(stream=self._log_buffer)
2014+ log_format = "%(asctime)s %(levelname)s %(module)s:%(lineno)d - %(message)s"
2015+ handler.setFormatter(MyFormatter(log_format))
2016+ root_logger.addHandler(handler)
2017+ #Tear down logging in a cleanUp handler, so it's done after all other
2018+ # tearDown() calls and cleanup handlers.
2019+ self.addCleanup(self._tearDownLogging)
2020+
2021+ def _tearDownLogging(self):
2022+ logger = logging.getLogger()
2023+ for handler in logger.handlers:
2024+ handler.flush()
2025+ self._log_buffer.seek(0)
2026+ self.addDetail('test-log', text_content(self._log_buffer.getvalue()))
2027+ logger.removeHandler(handler)
2028+ # Calling del to remove the handler and flush the buffer. We are
2029+ # abusing the log handlers here a little.
2030+ del self._log_buffer
2031+>>>>>>> MERGE-SOURCE
2032
2033 def _setUpUnityLogging(self):
2034 self._unity_log_file_name = mktemp(prefix=self.shortDescription())
2035@@ -122,3 +212,228 @@
2036 """
2037 set_log_severity(component, level)
2038
2039+<<<<<<< TREE
2040+=======
2041+
2042+class VideoCapturedTestCase(LoggedTestCase):
2043+ """Video capture autopilot tests, saving the results if the test failed."""
2044+
2045+ _recording_app = '/usr/bin/recordmydesktop'
2046+ _recording_opts = ['--no-sound', '--no-frame', '-o',]
2047+
2048+ def setUp(self):
2049+ super(VideoCapturedTestCase, self).setUp()
2050+ global video_recording_enabled
2051+ if video_recording_enabled and not self._have_recording_app():
2052+ video_recording_enabled = False
2053+ logger.warning("Disabling video capture since '%s' is not present", self._recording_app)
2054+
2055+ if video_recording_enabled:
2056+ self._test_passed = True
2057+ self.addOnException(self._on_test_failed)
2058+ self.addCleanup(self._stop_video_capture)
2059+ self._start_video_capture()
2060+
2061+ def _have_recording_app(self):
2062+ return os.path.exists(self._recording_app)
2063+
2064+ def _start_video_capture(self):
2065+ args = self._get_capture_command_line()
2066+ self._capture_file = self._get_capture_output_file()
2067+ self._ensure_directory_exists_but_not_file(self._capture_file)
2068+ args.append(self._capture_file)
2069+ logger.debug("Starting: %r", args)
2070+ self._capture_process = Popen(args, stdout=PIPE, stderr=STDOUT)
2071+
2072+ def _stop_video_capture(self):
2073+ """Stop the video capture. If the test failed, save the resulting file."""
2074+
2075+ if self._test_passed:
2076+ # We use kill here because we don't want the recording app to start
2077+ # encoding the video file (since we're removing it anyway.)
2078+ self._capture_process.kill()
2079+ self._capture_process.wait()
2080+ else:
2081+ self._capture_process.terminate()
2082+ self._capture_process.wait()
2083+ if self._capture_process.returncode != 0:
2084+ self.addDetail('video capture log', text_content(self._capture_process.stdout.read()))
2085+ self._capture_process = None
2086+
2087+ def _get_capture_command_line(self):
2088+ return [self._recording_app] + self._recording_opts
2089+
2090+ def _get_capture_output_file(self):
2091+ return os.path.join(video_record_directory, '%s.ogv' % (self.shortDescription()))
2092+
2093+ def _ensure_directory_exists_but_not_file(self, file_path):
2094+ dirpath = os.path.dirname(file_path)
2095+ if not os.path.exists(dirpath):
2096+ os.makedirs(dirpath)
2097+ elif os.path.exists(file_path):
2098+ logger.warning("Video capture file '%s' already exists, deleting.", file_path)
2099+ os.remove(file_path)
2100+
2101+ def _on_test_failed(self, ex_info):
2102+ """Called when a test fails."""
2103+ self._test_passed = False
2104+
2105+
2106+class AutopilotTestCase(VideoCapturedTestCase, KeybindingsHelper):
2107+ """Wrapper around testtools.TestCase that takes care of some cleaning."""
2108+
2109+ run_test_with = GlibRunner
2110+
2111+ KNOWN_APPS = {
2112+ 'Character Map' : {
2113+ 'desktop-file': 'gucharmap.desktop',
2114+ 'process-name': 'gucharmap',
2115+ },
2116+ 'Calculator' : {
2117+ 'desktop-file': 'gcalctool.desktop',
2118+ 'process-name': 'gcalctool',
2119+ },
2120+ 'Mahjongg' : {
2121+ 'desktop-file': 'mahjongg.desktop',
2122+ 'process-name': 'mahjongg',
2123+ },
2124+ 'Remmina' : {
2125+ 'desktop-file': 'remmina.desktop',
2126+ 'process-name': 'remmina',
2127+ },
2128+ 'System Settings' : {
2129+ 'desktop-file': 'gnome-control-center.desktop',
2130+ 'process-name': 'gnome-control-center',
2131+ },
2132+ 'Text Editor' : {
2133+ 'desktop-file': 'gedit.desktop',
2134+ 'process-name': 'gedit',
2135+ },
2136+ }
2137+
2138+ def setUp(self):
2139+ super(AutopilotTestCase, self).setUp()
2140+ self.bamf = Bamf()
2141+ self.keyboard = Keyboard()
2142+ self.mouse = Mouse()
2143+ self.dash = Dash()
2144+ self.hud = Hud()
2145+ self.launcher = self._get_launcher_controller()
2146+ self.panels = self._get_panel_controller()
2147+ self.switcher = Switcher()
2148+ self.window_manager = self._get_window_manager()
2149+ self.workspace = WorkspaceManager()
2150+ self.screen_geo = ScreenGeometry()
2151+ self.addCleanup(self.workspace.switch_to, self.workspace.current_workspace)
2152+ self.addCleanup(Keyboard.cleanup)
2153+ self.addCleanup(Mouse.cleanup)
2154+
2155+ def start_app(self, app_name, files=[], locale=None):
2156+ """Start one of the known apps, and kill it on tear down.
2157+
2158+ If files is specified, start the application with the specified files.
2159+ If locale is specified, the locale will be set when the application is launched.
2160+
2161+ The method returns the BamfApplication instance.
2162+
2163+ """
2164+ if locale:
2165+ os.putenv("LC_ALL", locale)
2166+ self.addCleanup(os.unsetenv, "LC_ALL")
2167+ logger.info("Starting application '%s' with files %r in locale %s", app_name, files, locale)
2168+ else:
2169+ logger.info("Starting application '%s' with files %r", app_name, files)
2170+
2171+ app = self.KNOWN_APPS[app_name]
2172+ self.bamf.launch_application(app['desktop-file'], files)
2173+ apps = self.bamf.get_running_applications_by_desktop_file(app['desktop-file'])
2174+ self.addCleanup(call, "kill `pidof %s`" % (app['process-name']), shell=True)
2175+ self.assertThat(len(apps), Equals(1))
2176+ return apps[0]
2177+
2178+ def close_all_app(self, app_name):
2179+ """Close all instances of the app_name."""
2180+ app = self.KNOWN_APPS[app_name]
2181+ pids = check_output(["pidof", app['process-name']]).split()
2182+ if len(pids):
2183+ call(["kill"] + pids)
2184+
2185+ def get_app_instances(self, app_name):
2186+ """Get BamfApplication instances for app_name."""
2187+ desktop_file = self.KNOWN_APPS[app_name]['desktop-file']
2188+ return self.bamf.get_running_applications_by_desktop_file(desktop_file)
2189+
2190+ def app_is_running(self, app_name):
2191+ """Returns true if an instance of the application is running."""
2192+ apps = self.get_app_instances(app_name)
2193+ return len(apps) > 0
2194+
2195+ def call_gsettings_cmd(self, command, schema, *args):
2196+ """Set a desktop wide gsettings option
2197+
2198+ Using the gsettings command because there's a bug with importing
2199+ from gobject introspection and pygtk2 simultaneously, and the Xlib
2200+ keyboard layout bits are very unweildy. This seems like the best
2201+ solution, even a little bit brutish.
2202+ """
2203+ cmd = ['gsettings', command, schema] + list(args)
2204+ # strip to remove the trailing \n.
2205+ ret = check_output(cmd).strip()
2206+ time.sleep(5)
2207+ reset_display()
2208+ return ret
2209+
2210+ def set_unity_option(self, option_name, option_value):
2211+ """Set an option in the unity compiz plugin options.
2212+
2213+ The value will be set for the current test only.
2214+
2215+ """
2216+ self.set_compiz_option("unityshell", option_name, option_value)
2217+
2218+ def set_compiz_option(self, plugin_name, setting_name, setting_value):
2219+ """Set setting `setting_name` in compiz plugin `plugin_name` to value `setting_value`
2220+ for one test only.
2221+ """
2222+ old_value = self._set_compiz_option(plugin_name, setting_name, setting_value)
2223+ self.addCleanup(self._set_compiz_option, plugin_name, setting_name, old_value)
2224+ # Allow unity time to respond to the new setting.
2225+ time.sleep(0.5)
2226+
2227+ def _set_compiz_option(self, plugin_name, option_name, option_value):
2228+ logger.info("Setting compiz option '%s' in plugin '%s' to %r",
2229+ option_name, plugin_name, option_value)
2230+ plugin = Plugin(global_context, plugin_name)
2231+ setting = Setting(plugin, option_name)
2232+ old_value = setting.Value
2233+ setting.Value = option_value
2234+ global_context.Write()
2235+ return old_value
2236+
2237+ def _get_launcher_controller(self):
2238+ controllers = LauncherController.get_all_instances()
2239+ self.assertThat(len(controllers), Equals(1))
2240+ return controllers[0]
2241+
2242+ def _get_panel_controller(self):
2243+ controllers = PanelController.get_all_instances()
2244+ self.assertThat(len(controllers), Equals(1))
2245+ return controllers[0]
2246+
2247+ def _get_window_manager(self):
2248+ managers = WindowManager.get_all_instances()
2249+ self.assertThat(len(managers), Equals(1))
2250+ return managers[0]
2251+
2252+ def assertVisibleWindowStack(self, stack_start):
2253+ """Check that the visible window stack starts with the windows passed in.
2254+
2255+ The start_stack is an iterable of BamfWindow objects.
2256+ Minimised windows are skipped.
2257+
2258+ """
2259+ stack = [win for win in self.bamf.get_open_windows() if not win.is_hidden]
2260+ for pos, win in enumerate(stack_start):
2261+ self.assertThat(stack[pos].x_id, Equals(win.x_id),
2262+ "%r at %d does not equal %r" % (stack[pos], pos, win))
2263+>>>>>>> MERGE-SOURCE
2264
2265=== modified file 'tests/autopilot/unity/tests/test_command_lens.py'
2266--- tests/autopilot/unity/tests/test_command_lens.py 2012-05-08 16:13:17 +0000
2267+++ tests/autopilot/unity/tests/test_command_lens.py 2012-05-24 17:16:22 +0000
2268@@ -12,10 +12,18 @@
2269 from testtools.matchers import Equals
2270 from time import sleep
2271
2272+<<<<<<< TREE
2273 from unity.tests import UnityTestCase
2274
2275
2276 class CommandLensSearchTests(UnityTestCase):
2277+=======
2278+from autopilot.tests import AutopilotTestCase
2279+from autopilot.matchers import Eventually
2280+
2281+
2282+class CommandLensSearchTests(AutopilotTestCase):
2283+>>>>>>> MERGE-SOURCE
2284 """Test the command lense search bahavior."""
2285
2286 def setUp(self):
2287
2288=== modified file 'tests/autopilot/unity/tests/test_dash.py'
2289--- tests/autopilot/unity/tests/test_dash.py 2012-05-08 16:13:17 +0000
2290+++ tests/autopilot/unity/tests/test_dash.py 2012-05-24 17:16:22 +0000
2291@@ -12,12 +12,22 @@
2292
2293 from autopilot.matchers import Eventually
2294 from gtk import Clipboard
2295+<<<<<<< TREE
2296 from testtools.matchers import Equals, NotEquals
2297
2298 from unity.tests import UnityTestCase
2299
2300
2301 class DashTestCase(UnityTestCase):
2302+=======
2303+from testtools.matchers import Equals, NotEquals
2304+
2305+from autopilot.matchers import Eventually
2306+from autopilot.tests import AutopilotTestCase
2307+
2308+
2309+class DashTestCase(AutopilotTestCase):
2310+>>>>>>> MERGE-SOURCE
2311 def setUp(self):
2312 super(DashTestCase, self).setUp()
2313 self.set_unity_log_level("unity.shell", "DEBUG")
2314
2315=== modified file 'tests/autopilot/unity/tests/test_home_lens.py'
2316--- tests/autopilot/unity/tests/test_home_lens.py 2012-05-08 16:13:17 +0000
2317+++ tests/autopilot/unity/tests/test_home_lens.py 2012-05-24 17:16:22 +0000
2318@@ -6,16 +6,28 @@
2319 # under the terms of the GNU General Public License version 3, as published
2320 # by the Free Software Foundation.
2321
2322+<<<<<<< TREE
2323 from __future__ import absolute_import
2324
2325 from autopilot.matchers import Eventually
2326 from testtools.matchers import Equals
2327+=======
2328+from testtools.matchers import Equals
2329+>>>>>>> MERGE-SOURCE
2330 from time import sleep
2331
2332+<<<<<<< TREE
2333 from unity.tests import UnityTestCase
2334
2335
2336 class HomeLensSearchTests(UnityTestCase):
2337+=======
2338+from autopilot.matchers import Eventually
2339+from autopilot.tests import AutopilotTestCase
2340+
2341+
2342+class HomeLensSearchTests(AutopilotTestCase):
2343+>>>>>>> MERGE-SOURCE
2344 """Test the command lense search bahavior."""
2345
2346 def setUp(self):
2347
2348=== modified file 'tests/autopilot/unity/tests/test_hud.py'
2349--- tests/autopilot/unity/tests/test_hud.py 2012-05-08 16:13:17 +0000
2350+++ tests/autopilot/unity/tests/test_hud.py 2012-05-24 17:16:22 +0000
2351@@ -7,6 +7,7 @@
2352 # under the terms of the GNU General Public License version 3, as published
2353 # by the Free Software Foundation.
2354
2355+<<<<<<< TREE
2356 from __future__ import absolute_import
2357
2358 from autopilot.matchers import Eventually
2359@@ -20,10 +21,28 @@
2360 LessThan,
2361 NotEquals,
2362 )
2363+=======
2364+from os import remove
2365+from testtools.matchers import (
2366+ Equals,
2367+ EndsWith,
2368+ GreaterThan,
2369+ LessThan,
2370+ NotEquals,
2371+ )
2372+>>>>>>> MERGE-SOURCE
2373 from time import sleep
2374
2375+<<<<<<< TREE
2376 from unity.emulators.icons import HudLauncherIcon
2377 from unity.tests import UnityTestCase
2378+=======
2379+from autopilot.emulators.unity.icons import HudLauncherIcon
2380+from autopilot.emulators.X11 import ScreenGeometry
2381+from autopilot.matchers import Eventually
2382+from autopilot.tests import AutopilotTestCase, multiply_scenarios
2383+
2384+>>>>>>> MERGE-SOURCE
2385
2386
2387 def _make_monitor_scenarios():
2388@@ -208,9 +227,15 @@
2389 """When switching from the hud to the dash alt+f1 is disabled."""
2390 self.hud.ensure_visible()
2391 self.dash.ensure_visible()
2392+<<<<<<< TREE
2393 self.addCleanup(self.dash.ensure_hidden)
2394
2395 self.keybinding("launcher/keynav")
2396+=======
2397+ self.addCleanup(self.dash.ensure_hidden)
2398+
2399+ self.keybinding("launcher/keynav")
2400+>>>>>>> MERGE-SOURCE
2401 self.assertThat(self.launcher.key_nav_is_active, Equals(False))
2402
2403 def test_hud_to_dash_has_key_focus(self):
2404
2405=== modified file 'tests/autopilot/unity/tests/test_ibus.py'
2406--- tests/autopilot/unity/tests/test_ibus.py 2012-05-16 02:57:25 +0000
2407+++ tests/autopilot/unity/tests/test_ibus.py 2012-05-24 17:16:22 +0000
2408@@ -8,13 +8,18 @@
2409
2410 """Tests to ensure unity is compatible with ibus input method."""
2411
2412+<<<<<<< TREE
2413 from __future__ import absolute_import
2414+=======
2415+from testtools.matchers import Equals, NotEquals
2416+>>>>>>> MERGE-SOURCE
2417
2418 from autopilot.emulators.ibus import (
2419 get_active_input_engines,
2420 set_active_engines,
2421 get_available_input_engines,
2422 )
2423+<<<<<<< TREE
2424 from autopilot.matchers import Eventually
2425 from autopilot.testcase import multiply_scenarios
2426 from testtools.matchers import Equals, NotEquals
2427@@ -23,6 +28,13 @@
2428
2429
2430 class IBusTests(UnityTestCase):
2431+=======
2432+from autopilot.matchers import Eventually
2433+from autopilot.tests import AutopilotTestCase, multiply_scenarios
2434+
2435+
2436+class IBusTests(AutopilotTestCase):
2437+>>>>>>> MERGE-SOURCE
2438 """Base class for IBus tests."""
2439
2440 def setUp(self):
2441@@ -31,6 +43,7 @@
2442 def tearDown(self):
2443 super(IBusTests, self).tearDown()
2444
2445+<<<<<<< TREE
2446 @classmethod
2447 def setUpClass(cls):
2448 cls._old_engines = None
2449@@ -41,11 +54,30 @@
2450 set_active_engines(cls._old_engines)
2451
2452 def activate_input_engine_or_skip(self, engine_name):
2453+=======
2454+ @classmethod
2455+ def setUpClass(cls):
2456+ cls._old_engines = None
2457+ cls.activate_input_engine_or_skip(cls.engine_name)
2458+
2459+ @classmethod
2460+ def tearDownClass(cls):
2461+ if cls._old_engines is not None:
2462+ set_active_engines(cls._old_engines)
2463+
2464+ @classmethod
2465+ def activate_input_engine_or_skip(cls, engine_name):
2466+>>>>>>> MERGE-SOURCE
2467 available_engines = get_available_input_engines()
2468 if engine_name in available_engines:
2469+<<<<<<< TREE
2470 if get_active_input_engines() != [engine_name]:
2471 IBusTests._old_engines = set_active_engines([engine_name])
2472+=======
2473+ cls._old_engines = set_active_engines([engine_name])
2474+>>>>>>> MERGE-SOURCE
2475 else:
2476+<<<<<<< TREE
2477 self.skip("This test requires the '%s' engine to be installed." % (engine_name))
2478
2479 def activate_ibus(self, widget):
2480@@ -81,6 +113,43 @@
2481 self.keyboard.press_and_release(commit_key)
2482 self.deactivate_ibus(self.hud.searchbar)
2483 self.assertThat(self.hud.search_string, Eventually(Equals(self.result)))
2484+=======
2485+ raise AutopilotTestCase.skipException("This test requires the '%s' engine to be installed." % (engine_name))
2486+
2487+ def activate_ibus(self, widget):
2488+ """Activate IBus, and wait till it's actived on 'widget'"""
2489+ self.assertThat(widget.im_active, Equals(False))
2490+ self.keyboard.press_and_release('Ctrl+Space', 0.05)
2491+ self.assertThat(widget.im_active, Eventually(Equals(True)))
2492+
2493+ def deactivate_ibus(self, widget):
2494+ """Deactivate ibus, and wait till it's inactive on 'widget'"""
2495+ self.assertThat(widget.im_active, Equals(True))
2496+ self.keyboard.press_and_release('Ctrl+Space', 0.05)
2497+ self.assertThat(widget.im_active, Eventually(Equals(False)))
2498+
2499+ def do_dash_test_with_engine(self):
2500+ self.dash.ensure_visible()
2501+ self.addCleanup(self.dash.ensure_hidden)
2502+ self.activate_ibus(self.dash.searchbar)
2503+ self.keyboard.type(self.input)
2504+ commit_key = getattr(self, 'commit_key', None)
2505+ if commit_key:
2506+ self.keyboard.press_and_release(commit_key)
2507+ self.deactivate_ibus(self.dash.searchbar)
2508+ self.assertThat(self.dash.search_string, Eventually(Equals(self.result)))
2509+
2510+ def do_hud_test_with_engine(self):
2511+ self.hud.ensure_visible()
2512+ self.addCleanup(self.hud.ensure_hidden)
2513+ self.activate_ibus(self.hud.searchbar)
2514+ self.keyboard.type(self.input)
2515+ commit_key = getattr(self, 'commit_key', None)
2516+ if commit_key:
2517+ self.keyboard.press_and_release(commit_key)
2518+ self.deactivate_ibus(self.hud.searchbar)
2519+ self.assertThat(self.hud.search_string, Eventually(Equals(self.result)))
2520+>>>>>>> MERGE-SOURCE
2521
2522
2523 class IBusTestsPinyin(IBusTests):
2524@@ -160,12 +229,17 @@
2525 class IBusTestsPinyinIgnore(IBusTests):
2526 """Tests for ignoring key events while the Pinyin input engine is active."""
2527
2528+<<<<<<< TREE
2529 engine_name = "pinyin"
2530
2531 def setUp(self):
2532 super(IBusTestsPinyinIgnore, self).setUp()
2533 self.activate_input_engine_or_skip(self.engine_name)
2534
2535+=======
2536+ engine_name = "pinyin"
2537+
2538+>>>>>>> MERGE-SOURCE
2539 def test_ignore_key_events_on_dash(self):
2540 self.dash.ensure_visible()
2541 self.addCleanup(self.dash.ensure_hidden)
2542@@ -194,12 +268,17 @@
2543 class IBusTestsAnthyIgnore(IBusTests):
2544 """Tests for ignoring key events while the Anthy input engine is active."""
2545
2546+<<<<<<< TREE
2547 engine_name = "anthy"
2548
2549 def setUp(self):
2550 super(IBusTestsAnthyIgnore, self).setUp()
2551 self.activate_input_engine_or_skip(self.engine_name)
2552
2553+=======
2554+ engine_name = "anthy"
2555+
2556+>>>>>>> MERGE-SOURCE
2557 def test_ignore_key_events_on_dash(self):
2558 self.dash.ensure_visible()
2559 self.addCleanup(self.dash.ensure_hidden)
2560
2561=== modified file 'tests/autopilot/unity/tests/test_launcher.py'
2562--- tests/autopilot/unity/tests/test_launcher.py 2012-05-17 22:49:33 +0000
2563+++ tests/autopilot/unity/tests/test_launcher.py 2012-05-24 17:16:22 +0000
2564@@ -19,9 +19,17 @@
2565 from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan
2566 from time import sleep
2567
2568+<<<<<<< TREE
2569 from unity.emulators.icons import BFBLauncherIcon
2570 from unity.emulators.switcher import SwitcherMode
2571 from unity.tests import UnityTestCase
2572+=======
2573+from autopilot.emulators.bamf import Bamf
2574+from autopilot.emulators.unity.icons import BFBLauncherIcon
2575+from autopilot.emulators.X11 import ScreenGeometry
2576+from autopilot.matchers import Eventually
2577+from autopilot.tests import AutopilotTestCase, multiply_scenarios
2578+>>>>>>> MERGE-SOURCE
2579
2580 logger = logging.getLogger(__name__)
2581
2582@@ -41,8 +49,13 @@
2583 ('launcher on all', {'only_primary': False})]
2584 return multiply_scenarios(monitor_scenarios, launcher_mode_scenarios)
2585
2586+<<<<<<< TREE
2587
2588 class LauncherTestCase(UnityTestCase):
2589+=======
2590+
2591+class LauncherTestCase(AutopilotTestCase):
2592+>>>>>>> MERGE-SOURCE
2593 """A base class for all launcher tests that uses scenarios to run on
2594 each launcher (for multi-monitor setups).
2595 """
2596@@ -381,9 +394,15 @@
2597 def test_launcher_keynav_alt_grave_quits(self):
2598 """Tests that alt+` exits keynav mode."""
2599
2600+<<<<<<< TREE
2601 # Can't use switcher emulat here since the switcher won't appear.
2602 self.keybinding("switcher/reveal_details")
2603 self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
2604+=======
2605+ self.switcher.initiate_detail_mode()
2606+ self.addCleanup(self.switcher.terminate)
2607+ self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False)))
2608+>>>>>>> MERGE-SOURCE
2609
2610
2611 class LauncherIconsBehaviorTests(LauncherTestCase):
2612@@ -586,6 +605,7 @@
2613 self.mouse.move(x + w/2, y + h/2)
2614 sleep(.5)
2615 for icon in self.launcher.model.get_launcher_icons():
2616+<<<<<<< TREE
2617 self.assertThat(icon.desaturated, Eventually(Equals(False)))
2618
2619 class BamfDaemonTests(LauncherTestCase):
2620@@ -685,6 +705,107 @@
2621
2622
2623 class LauncherCaptureTests(UnityTestCase):
2624+=======
2625+ self.assertThat(icon.desaturated, Eventually(Equals(False)))
2626+
2627+class BamfDaemonTests(LauncherTestCase):
2628+ """Test interaction between the launcher and the BAMF Daemon."""
2629+
2630+ def start_test_apps(self):
2631+ """Starts some test applications."""
2632+ self.start_app("Calculator")
2633+ self.start_app("System Settings")
2634+
2635+ def start_desktopless_test_apps(self):
2636+ """Start test applications with no .desktop file associated."""
2637+ test_apps = ["xclock"]
2638+
2639+ for app in test_apps:
2640+ os.spawnlp(os.P_NOWAIT, app, app)
2641+ self.addCleanup(call, ["killall", app])
2642+ self.wait_for_process_started(app)
2643+
2644+ def get_test_apps(self):
2645+ """Return a tuple of test application instances.
2646+
2647+ We don't store these since when we kill the bamf daemon all references
2648+ to the old apps will die.
2649+
2650+ """
2651+ [calc] = self.get_app_instances("Calculator")
2652+ [sys_settings] = self.get_app_instances("System Settings")
2653+ return [calc, sys_settings]
2654+
2655+ def get_desktopless_test_apps(self):
2656+ """Return a tuple of test application with no .desktop files instances."""
2657+ [xclock_win] = [w for w in self.bamf.get_open_windows() if w.name == "xclock"]
2658+ return [xclock_win.application]
2659+
2660+ def assertOnlyOneLauncherIcon(self, **kwargs):
2661+ """Asserts that there is only one launcher icon with the given filter."""
2662+ icons = self.launcher.model.get_icons_by_filter(**kwargs)
2663+ self.assertThat(len(icons), Equals(1))
2664+
2665+ def wait_for_process_started(self, app):
2666+ """Wait until the application app has been started."""
2667+ for i in range(10):
2668+ sleep(1)
2669+ #pgrep returns 0 if it matched something:
2670+ if call(["pgrep", app]) == 0:
2671+ return
2672+
2673+ def wait_for_process_killed(self, app):
2674+ """Wait until the application app has been killed."""
2675+ for i in range(10):
2676+ #pgrep returns 0 if it matched something:
2677+ if call(["pgrep", app]) != 0:
2678+ return
2679+ sleep(1)
2680+
2681+ def kill_and_restart_bamfdaemon(self):
2682+ """Kills and resumes bamfdaemon."""
2683+ call(["pkill", "bamfdaemon"])
2684+ self.wait_for_process_killed("bamfdaemon")
2685+
2686+ # trigger the bamfdaemon to be reloaded again, and wait for it to appear:
2687+ self.bamf = Bamf()
2688+ self.wait_for_process_started("bamfdaemon")
2689+
2690+ def test_killing_bamfdaemon_does_not_duplicate_desktop_ids(self):
2691+ """Killing bamfdaemon should not duplicate any desktop ids in the model."""
2692+ self.start_test_apps()
2693+ self.kill_and_restart_bamfdaemon()
2694+
2695+ for test_app in self.get_test_apps():
2696+ logger.info("Checking for duplicated launcher icon for application %s", test_app.name)
2697+ self.assertOnlyOneLauncherIcon(desktop_id=test_app.desktop_file)
2698+
2699+ def test_killing_bamfdaemon_does_not_duplicate_application_xids(self):
2700+ """Killing bamfdaemon should not duplicate any xid in the model."""
2701+ self.start_test_apps()
2702+ self.start_desktopless_test_apps()
2703+ self.kill_and_restart_bamfdaemon()
2704+
2705+ test_apps = self.get_test_apps() + self.get_desktopless_test_apps()
2706+
2707+ for test_app in test_apps:
2708+ logger.info("Checking for duplicated launcher icon for application %s", test_app.name)
2709+ test_windows = [w.x_id for w in test_app.get_windows()]
2710+ self.assertOnlyOneLauncherIcon(xids=test_windows)
2711+
2712+ def test_killing_bamfdaemon_does_not_duplicate_any_icon_application_id(self):
2713+ """Killing bamfdaemon should not duplicate any application ids in the model."""
2714+ self.start_test_apps()
2715+ self.start_desktopless_test_apps()
2716+ self.kill_and_restart_bamfdaemon()
2717+
2718+ for icon in self.launcher.model.get_bamf_launcher_icons():
2719+ logger.info("Checking for duplicated launcher icon %s", icon.tooltip_text)
2720+ self.assertOnlyOneLauncherIcon(application_id=icon.application_id)
2721+
2722+
2723+class LauncherCaptureTests(AutopilotTestCase):
2724+>>>>>>> MERGE-SOURCE
2725 """Test the launchers ability to capture/not capture the mouse."""
2726
2727 screen_geo = ScreenGeometry()
2728@@ -783,6 +904,7 @@
2729 x_fin, y_fin = self.mouse.position()
2730 # The launcher should have held the mouse a little bit
2731 self.assertThat(x_fin, LessThan(x + width * 1.5))
2732+<<<<<<< TREE
2733
2734
2735 class LauncherTooltipTests(UnityTestCase):
2736@@ -811,3 +933,33 @@
2737 self.mouse.move(bfb.center_x, bfb.center_y)
2738
2739 self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False)))
2740+=======
2741+
2742+
2743+class LauncherTooltipTests(AutopilotTestCase):
2744+ """Test the launcher tooltips"""
2745+
2746+ def setUp(self):
2747+ super(LauncherTooltipTests, self).setUp()
2748+ self.set_unity_option('launcher_hide_mode', 0)
2749+
2750+ def test_bfb_tooltip_disappear_when_dash_is_opened(self):
2751+ """Tests that the bfb tooltip disappear when the dash is opened."""
2752+ bfb = self.launcher.model.get_bfb_icon()
2753+ self.mouse.move(bfb.center_x, bfb.center_y)
2754+
2755+ self.dash.ensure_visible()
2756+ self.addCleanup(self.dash.ensure_hidden)
2757+
2758+ self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False)))
2759+
2760+ def test_bfb_tooltip_is_disabled_when_dash_is_open(self):
2761+ """Tests the that bfb tooltip is disabled when the dash is open."""
2762+ self.dash.ensure_visible()
2763+ self.addCleanup(self.dash.ensure_hidden)
2764+
2765+ bfb = self.launcher.model.get_bfb_icon()
2766+ self.mouse.move(bfb.center_x, bfb.center_y)
2767+
2768+ self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False)))
2769+>>>>>>> MERGE-SOURCE
2770
2771=== modified file 'tests/autopilot/unity/tests/test_panel.py'
2772--- tests/autopilot/unity/tests/test_panel.py 2012-05-08 16:13:17 +0000
2773+++ tests/autopilot/unity/tests/test_panel.py 2012-05-24 17:16:22 +0000
2774@@ -19,6 +19,7 @@
2775 from unity.tests import UnityTestCase
2776
2777
2778+
2779 logger = logging.getLogger(__name__)
2780
2781
2782
2783=== modified file 'tests/autopilot/unity/tests/test_quicklist.py'
2784--- tests/autopilot/unity/tests/test_quicklist.py 2012-05-17 23:16:25 +0000
2785+++ tests/autopilot/unity/tests/test_quicklist.py 2012-05-24 17:16:22 +0000
2786@@ -13,6 +13,7 @@
2787 import os.path
2788 from testtools.matchers import Contains, Equals, NotEquals
2789 from xdg.DesktopEntry import DesktopEntry
2790+<<<<<<< TREE
2791 from time import sleep
2792
2793 from unity.emulators.quicklist import QuicklistMenuItemLabel
2794@@ -20,12 +21,23 @@
2795
2796
2797 class QuicklistActionTests(UnityTestCase):
2798+=======
2799+from time import sleep
2800+
2801+from autopilot.emulators.unity.quicklist import QuicklistMenuItemLabel
2802+from autopilot.matchers import Eventually
2803+from autopilot.tests import AutopilotTestCase
2804+
2805+
2806+class QuicklistActionTests(AutopilotTestCase):
2807+>>>>>>> MERGE-SOURCE
2808 """Tests for quicklist actions."""
2809
2810 scenarios = [
2811 ('remmina', {'app_name': 'Remmina'}),
2812 ]
2813
2814+<<<<<<< TREE
2815 def open_quicklist_for_icon(self, launcher_icon):
2816 """Open the quicklist for the given launcher icon.
2817
2818@@ -41,6 +53,13 @@
2819 return ql
2820 sleep(1)
2821
2822+=======
2823+ def open_quicklist_for_icon(self, launcher_icon):
2824+ launcher = self.launcher.get_launcher_for_monitor(0)
2825+ launcher.click_launcher_icon(launcher_icon, button=3)
2826+ self.addCleanup(self.keyboard.press_and_release, "Escape")
2827+
2828+>>>>>>> MERGE-SOURCE
2829 def test_quicklist_actions(self):
2830 """Test that all actions present in the destop file are shown in the quicklist."""
2831 self.start_app(self.app_name)
2832@@ -54,7 +73,12 @@
2833 self.assertThat(launcher_icon, NotEquals(None))
2834
2835 # open the icon quicklist, and get all the text labels:
2836+<<<<<<< TREE
2837 ql = self.open_quicklist_for_icon(launcher_icon)
2838+=======
2839+ self.open_quicklist_for_icon(launcher_icon)
2840+ ql = launcher_icon.get_quicklist()
2841+>>>>>>> MERGE-SOURCE
2842 ql_item_texts = [i.text for i in ql.items if type(i) is QuicklistMenuItemLabel]
2843
2844 # iterate over all the actions from the desktop file, make sure they're
2845@@ -67,6 +91,7 @@
2846 name = de.content[key]['Name']
2847 self.assertThat(ql_item_texts, Contains(name))
2848
2849+<<<<<<< TREE
2850 def test_quicklist_application_item_focus_last_active_window(self):
2851 """This tests shows that when you activate a quicklist application item
2852 only the last focused instance of that application is rasied.
2853@@ -335,3 +360,276 @@
2854 mouse_item.mouse_move_to()
2855 self.assertThat(mouse_item.selected, Eventually(Equals(True)))
2856 self.assertThat(self.quicklist.selected_item.id, Equals(mouse_item.id))
2857+=======
2858+ def test_quicklist_application_item_focus_last_active_window(self):
2859+ """This tests shows that when you activate a quicklist application item
2860+ only the last focused instance of that application is rasied.
2861+
2862+ This is tested by opening 2 Mahjongg and a Calculator.
2863+ Then we activate the Calculator quicklist item.
2864+ Then we actiavte the Mahjongg launcher icon.
2865+ """
2866+ mahj = self.start_app("Mahjongg")
2867+ [mah_win1] = mahj.get_windows()
2868+ self.assertTrue(mah_win1.is_focused)
2869+
2870+ calc = self.start_app("Calculator")
2871+ [calc_win] = calc.get_windows()
2872+ self.assertTrue(calc_win.is_focused)
2873+
2874+ self.start_app("Mahjongg")
2875+ # Sleeping due to the start_app only waiting for the bamf model to be
2876+ # updated with the application. Since the app has already started,
2877+ # and we are just waiting on a second window, however a defined sleep
2878+ # here is likely to be problematic.
2879+ # TODO: fix bamf emulator to enable waiting for new windows.
2880+ sleep(1)
2881+ [mah_win2] = [w for w in mahj.get_windows() if w.x_id != mah_win1.x_id]
2882+ self.assertTrue(mah_win2.is_focused)
2883+
2884+ self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
2885+
2886+ mahj_icon = self.launcher.model.get_icon_by_desktop_id(mahj.desktop_file)
2887+ calc_icon = self.launcher.model.get_icon_by_desktop_id(calc.desktop_file)
2888+
2889+ self.open_quicklist_for_icon(calc_icon)
2890+ calc_ql = calc_icon.get_quicklist()
2891+ calc_ql.get_quicklist_application_item(calc.name).mouse_click()
2892+ sleep(1)
2893+ self.assertTrue(calc_win.is_focused)
2894+ self.assertVisibleWindowStack([calc_win, mah_win2, mah_win1])
2895+
2896+ self.open_quicklist_for_icon(mahj_icon)
2897+ mahj_ql = mahj_icon.get_quicklist()
2898+ mahj_ql.get_quicklist_application_item(mahj.name).mouse_click()
2899+ sleep(1)
2900+ self.assertTrue(mah_win2.is_focused)
2901+ self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
2902+
2903+ def test_quicklist_application_item_initiate_spread(self):
2904+ """This tests shows that when you activate a quicklist application item
2905+ when an application window is focused, the spread is initiated.
2906+ """
2907+ calc = self.start_app("Calculator")
2908+ [calc_win1] = calc.get_windows()
2909+ self.assertTrue(calc_win1.is_focused)
2910+
2911+ self.start_app("Calculator")
2912+ # Sleeping due to the start_app only waiting for the bamf model to be
2913+ # updated with the application. Since the app has already started,
2914+ # and we are just waiting on a second window, however a defined sleep
2915+ # here is likely to be problematic.
2916+ # TODO: fix bamf emulator to enable waiting for new windows.
2917+ sleep(1)
2918+ [calc_win2] = [w for w in calc.get_windows() if w.x_id != calc_win1.x_id]
2919+
2920+ self.assertVisibleWindowStack([calc_win2, calc_win1])
2921+ self.assertTrue(calc_win2.is_focused)
2922+
2923+ calc_icon = self.launcher.model.get_icon_by_desktop_id(calc.desktop_file)
2924+
2925+ self.open_quicklist_for_icon(calc_icon)
2926+ calc_ql = calc_icon.get_quicklist()
2927+ app_item = calc_ql.get_quicklist_application_item(calc.name)
2928+
2929+ self.addCleanup(self.keybinding, "spread/cancel")
2930+ app_item.mouse_click()
2931+ self.assertThat(self.window_manager.scale_active, Eventually(Equals(True)))
2932+ self.assertThat(self.window_manager.scale_active_for_group, Eventually(Equals(True)))
2933+
2934+
2935+class QuicklistKeyNavigationTests(AutopilotTestCase):
2936+ """Tests for the quicklist key navigation."""
2937+
2938+ def setUp(self):
2939+ super(QuicklistKeyNavigationTests, self).setUp()
2940+
2941+ self.ql_app = self.start_app("Text Editor")
2942+
2943+ self.ql_launcher_icon = self.launcher.model.get_icon_by_desktop_id(self.ql_app.desktop_file)
2944+ self.assertThat(self.ql_launcher_icon, NotEquals(None))
2945+
2946+ self.ql_launcher = self.launcher.get_launcher_for_monitor(0)
2947+
2948+ def open_quicklist_with_mouse(self):
2949+ """Opens a quicklist with the mouse."""
2950+ self.ql_launcher.click_launcher_icon(self.ql_launcher_icon, button=3)
2951+ self.addCleanup(self.keyboard.press_and_release, "Escape")
2952+ self.quicklist = self.ql_launcher_icon.get_quicklist()
2953+ self.assertThat(self.quicklist, NotEquals(None))
2954+ self.quicklist.move_mouse_to_right()
2955+ self.assertThat(self.quicklist.selected_item, Equals(None))
2956+
2957+ def open_quicklist_with_keyboard(self):
2958+ """Opens a quicklist using the keyboard."""
2959+ self.screen_geo.move_mouse_to_monitor(0)
2960+ self.ql_launcher.key_nav_start()
2961+ self.addCleanup(self.ql_launcher.key_nav_cancel)
2962+
2963+ for icon in self.launcher.model.get_launcher_icons():
2964+ if icon.tooltip_text != self.ql_app.name:
2965+ self.ql_launcher.key_nav_next()
2966+ else:
2967+ self.keybinding("launcher/keynav/open-quicklist")
2968+ self.addCleanup(self.keybinding, "launcher/keynav/close-quicklist")
2969+ break
2970+
2971+ self.quicklist = self.ql_launcher_icon.get_quicklist()
2972+ self.assertThat(self.quicklist, NotEquals(None))
2973+ self.assertThat(self.quicklist.selected_item, NotEquals(None))
2974+
2975+ def test_keynav_selects_first_item_when_unselected(self):
2976+ """Home key MUST select the first selectable item in a quicklist."""
2977+ self.open_quicklist_with_mouse()
2978+
2979+ self.keybinding("quicklist/keynav/first")
2980+
2981+ expected_item = self.quicklist.selectable_items[0]
2982+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
2983+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
2984+
2985+ def test_keynav_selects_first_item_when_selected(self):
2986+ """Home key MUST select the first selectable item in a quicklist when
2987+ another item is selected.
2988+ """
2989+ self.open_quicklist_with_mouse()
2990+ mouse_item = self.quicklist.selectable_items[-1]
2991+ mouse_item.mouse_move_to()
2992+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
2993+
2994+ self.keybinding("quicklist/keynav/first")
2995+
2996+ expected_item = self.quicklist.selectable_items[0]
2997+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
2998+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
2999+
3000+ def test_keynav_next_selects_first_item_when_unselected(self):
3001+ """Down key MUST select the first valid item when nothing is selected."""
3002+ self.open_quicklist_with_mouse()
3003+
3004+ self.keybinding("quicklist/keynav/next")
3005+
3006+ expected_item = self.quicklist.selectable_items[0]
3007+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
3008+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
3009+
3010+ def test_keynav_selects_last_item_when_unselected(self):
3011+ """End key MUST select the last selectable item in a quicklist."""
3012+ self.open_quicklist_with_mouse()
3013+
3014+ self.keybinding("quicklist/keynav/last")
3015+
3016+ expected_item = self.quicklist.selectable_items[-1]
3017+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
3018+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
3019+
3020+ def test_keynav_selects_last_item_when_selected(self):
3021+ """End key MUST select the last selectable item in a quicklist when
3022+ another item is selected.
3023+ """
3024+ self.open_quicklist_with_mouse()
3025+ mouse_item = self.quicklist.selectable_items[0]
3026+ mouse_item.mouse_move_to()
3027+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
3028+
3029+ self.keybinding("quicklist/keynav/last")
3030+
3031+ expected_item = self.quicklist.selectable_items[-1]
3032+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
3033+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
3034+
3035+ def test_keynav_prev_selects_last_item_when_unselected(self):
3036+ """Up key MUST select the last valid item when nothing is selected."""
3037+ self.open_quicklist_with_mouse()
3038+
3039+ self.keybinding("quicklist/keynav/prev")
3040+
3041+ expected_item = self.quicklist.selectable_items[-1]
3042+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
3043+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
3044+
3045+ def test_launcher_keynav_selects_first_item(self):
3046+ """The first selectable item of the quicklist must be selected when
3047+ opening the quicklist using the launcher key navigation.
3048+ """
3049+ self.open_quicklist_with_keyboard()
3050+
3051+ expected_item = self.quicklist.selectable_items[0]
3052+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
3053+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
3054+
3055+ def test_keynav_next_selection_works(self):
3056+ """Down key MUST select the next valid item."""
3057+ self.open_quicklist_with_mouse()
3058+
3059+ for item in self.quicklist.selectable_items:
3060+ self.keybinding("quicklist/keynav/next")
3061+ self.assertThat(item.selected, Eventually(Equals(True)))
3062+ self.assertThat(self.quicklist.selected_item.id, Equals(item.id))
3063+
3064+ def test_keynav_prev_selection_works(self):
3065+ """Up key MUST select the previous valid item."""
3066+ self.open_quicklist_with_mouse()
3067+
3068+ for item in reversed(self.quicklist.selectable_items):
3069+ self.keybinding("quicklist/keynav/prev")
3070+ self.assertThat(item.selected, Eventually(Equals(True)))
3071+ self.assertThat(self.quicklist.selected_item.id, Equals(item.id))
3072+
3073+ def test_keynav_prev_is_cyclic(self):
3074+ """Up key MUST select the last item, when the first one is selected."""
3075+ self.open_quicklist_with_mouse()
3076+
3077+ mouse_item = self.quicklist.selectable_items[0]
3078+ mouse_item.mouse_move_to()
3079+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
3080+
3081+ self.keybinding("quicklist/keynav/prev")
3082+ expected_item = self.quicklist.selectable_items[-1]
3083+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
3084+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
3085+
3086+ def test_keynav_next_is_cyclic(self):
3087+ """Down key MUST select the first item, when the last one is selected."""
3088+ self.open_quicklist_with_mouse()
3089+
3090+ mouse_item = self.quicklist.selectable_items[-1]
3091+ mouse_item.mouse_move_to()
3092+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
3093+
3094+ self.keybinding("quicklist/keynav/next")
3095+ expected_item = self.quicklist.selectable_items[0]
3096+ self.assertThat(expected_item.selected, Eventually(Equals(True)))
3097+ self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
3098+
3099+ def test_keynav_mouse_interaction(self):
3100+ """Tests that the interaction between key-navigation and mouse works as
3101+ expected. See bug #911561.
3102+ """
3103+ self.open_quicklist_with_mouse()
3104+ mouse_item = self.quicklist.selectable_items[-1]
3105+ mouse_item.mouse_move_to()
3106+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
3107+
3108+ self.keybinding("quicklist/keynav/prev")
3109+ sleep(.1)
3110+ self.keybinding("quicklist/keynav/prev")
3111+
3112+ key_item = self.quicklist.selectable_items[-3]
3113+ self.assertThat(key_item.selected, Eventually(Equals(True)))
3114+ self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
3115+
3116+ # Moving the mouse horizontally doesn't change the selection
3117+ self.mouse.move(mouse_item.x + mouse_item.width - 10, mouse_item.y + mouse_item.height / 2)
3118+ self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
3119+
3120+ # Moving the mouse outside doesn't change the selection
3121+ self.mouse.move(mouse_item.x + mouse_item.width + 50, mouse_item.y + mouse_item.height / 2)
3122+ self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
3123+
3124+ # Moving the mouse to another entry, changes the selection
3125+ mouse_item = self.quicklist.selectable_items[-2]
3126+ mouse_item.mouse_move_to()
3127+ self.assertThat(mouse_item.selected, Eventually(Equals(True)))
3128+ self.assertThat(self.quicklist.selected_item.id, Equals(mouse_item.id))
3129+>>>>>>> MERGE-SOURCE
3130
3131=== modified file 'tests/autopilot/unity/tests/test_shortcut_hint.py'
3132--- tests/autopilot/unity/tests/test_shortcut_hint.py 2012-05-17 11:52:32 +0000
3133+++ tests/autopilot/unity/tests/test_shortcut_hint.py 2012-05-24 17:16:22 +0000
3134@@ -12,11 +12,21 @@
3135 from testtools.matchers import Equals
3136 from time import sleep
3137
3138+<<<<<<< TREE
3139 from unity.emulators.shortcut_hint import ShortcutController
3140 from unity.tests import UnityTestCase
3141
3142
3143 class BaseShortcutHintTests(UnityTestCase):
3144+=======
3145+from autopilot.emulators.unity.shortcut_hint import ShortcutController
3146+from autopilot.matchers import Eventually
3147+from autopilot.tests import AutopilotTestCase
3148+
3149+
3150+
3151+class BaseShortcutHintTests(AutopilotTestCase):
3152+>>>>>>> MERGE-SOURCE
3153 """Base class for the shortcut hint tests"""
3154
3155 def setUp(self):
3156
3157=== modified file 'tests/test-gesture-engine/CMakeLists.txt'
3158=== added file 'tests/test_resultviewgrid.cpp'
3159--- tests/test_resultviewgrid.cpp 1970-01-01 00:00:00 +0000
3160+++ tests/test_resultviewgrid.cpp 2012-05-24 17:16:22 +0000
3161@@ -0,0 +1,103 @@
3162+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
3163+/*
3164+ * Copyright 2012 Canonical Ltd.
3165+ *
3166+ * This program is free software: you can redistribute it and/or modify it
3167+ * under the terms of the GNU Lesser General Public License version 3, as
3168+ * published by the Free Software Foundation.
3169+ *
3170+ * This program is distributed in the hope that it will be useful, but
3171+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3172+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
3173+ * PURPOSE. See the applicable version of the GNU Lesser General Public
3174+ * License for more details.
3175+ *
3176+ * You should have received a copy of both the GNU Lesser General Public
3177+ * License version 3 along with this program. If not, see
3178+ * <http://www.gnu.org/licenses/>
3179+ *
3180+ * Authored by: Andrea Azzarone <azzaronea@gmail.com>
3181+ *
3182+ */
3183+
3184+#include <gtest/gtest.h>
3185+#include <gmock/gmock.h>
3186+using namespace testing;
3187+
3188+#include "ResultViewGrid.h"
3189+using namespace unity;
3190+
3191+namespace
3192+{
3193+
3194+class MockResultViewGrid : public dash::ResultViewGrid
3195+{
3196+public:
3197+ MockResultViewGrid(NUX_FILE_LINE_DECL) : dash::ResultViewGrid(NUX_FILE_LINE_PARAM) {}
3198+
3199+ MOCK_METHOD0(QueueDraw, void());
3200+ MOCK_METHOD2(GetIndexAtPosition, uint(int x, int y));
3201+
3202+ void FakeMouseMoveSignal(int x = 0, int y = 0, int dx = 0, int dy = 0, unsigned long mouse_button_state = 0, unsigned long special_keys_state = 0)
3203+ {
3204+ EmitMouseMoveSignal(x, y, dy, dy, mouse_button_state, special_keys_state);
3205+ }
3206+};
3207+
3208+class TestResultViewGrid : public Test
3209+{
3210+public:
3211+ virtual void SetUp()
3212+ {
3213+ view.Adopt(new MockResultViewGrid(NUX_TRACKER_LOCATION));
3214+ renderer.Adopt(new dash::ResultRenderer(NUX_TRACKER_LOCATION));
3215+
3216+ view->SetModelRenderer(renderer.GetPointer());
3217+ nux::GetWindowCompositor().SetKeyFocusArea(view.GetPointer());
3218+ }
3219+
3220+ nux::ObjectPtr<MockResultViewGrid> view;
3221+ nux::ObjectPtr<dash::ResultRenderer> renderer;
3222+};
3223+
3224+
3225+TEST_F(TestResultViewGrid, TestQueueDrawMouseMoveInsideUnfocusedIcon)
3226+{
3227+ EXPECT_CALL(*view, QueueDraw())
3228+ .Times(1);
3229+
3230+ EXPECT_CALL(*view, GetIndexAtPosition(_, _))
3231+ .WillOnce(Return(7));
3232+
3233+ view->FakeMouseMoveSignal();
3234+}
3235+
3236+
3237+TEST_F(TestResultViewGrid, TestQueueDrawMouseMoveInsideFocusedIcon)
3238+{
3239+ EXPECT_CALL(*view, GetIndexAtPosition(_, _))
3240+ .WillRepeatedly(Return(7));
3241+
3242+ view->FakeMouseMoveSignal();
3243+
3244+ EXPECT_CALL(*view, QueueDraw())
3245+ .Times(0);
3246+
3247+ view->FakeMouseMoveSignal();
3248+}
3249+
3250+
3251+TEST_F(TestResultViewGrid, TestQueueDrawMouseMoveOutside)
3252+{
3253+ EXPECT_CALL(*view, GetIndexAtPosition(_, _))
3254+ .WillRepeatedly(Return(-1));
3255+
3256+ view->FakeMouseMoveSignal();
3257+
3258+ EXPECT_CALL(*view, QueueDraw())
3259+ .Times(0);
3260+
3261+ view->FakeMouseMoveSignal();
3262+}
3263+
3264+}
3265
3266=== renamed file 'tests/test_resultviewgrid.cpp' => 'tests/test_resultviewgrid.cpp.moved'
3267=== modified file 'unity-shared/DashStyle.cpp'
3268=== modified file 'unity-shared/DashStyle.h'
3269=== modified file 'unity-shared/IconTexture.h'
3270=== modified file 'unity-shared/OverlayRenderer.cpp'
3271--- unity-shared/OverlayRenderer.cpp 2012-05-22 10:15:47 +0000
3272+++ unity-shared/OverlayRenderer.cpp 2012-05-24 17:16:22 +0000
3273@@ -378,8 +378,13 @@
3274 bool paint_blur = BackgroundEffectHelper::blur_type != BLUR_NONE;
3275 nux::Geometry geo(content_geo);
3276
3277+<<<<<<< TREE
3278 int excess_border = (Settings::Instance().GetFormFactor() != FormFactor::NETBOOK || force_edges) ? EXCESS_BORDER : 0;
3279
3280+=======
3281+ int excess_border = (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK || force_edges) ? EXCESS_BORDER : 0;
3282+
3283+>>>>>>> MERGE-SOURCE
3284 nux::Geometry larger_content_geo = content_geo;
3285 larger_content_geo.OffsetSize(excess_border, excess_border);
3286
3287@@ -767,8 +772,13 @@
3288 nux::Geometry geo = geometry;
3289 bgs = 0;
3290
3291+<<<<<<< TREE
3292 int excess_border = (Settings::Instance().GetFormFactor() != FormFactor::NETBOOK) ? EXCESS_BORDER : 0;
3293
3294+=======
3295+ int excess_border = (dash::Settings::Instance().GetFormFactor() != dash::FormFactor::NETBOOK) ? EXCESS_BORDER : 0;
3296+
3297+>>>>>>> MERGE-SOURCE
3298 nux::Geometry larger_content_geo = content_geo;
3299 larger_content_geo.OffsetSize(excess_border, excess_border);
3300
3301
3302=== modified file 'unity-shared/SearchBar.cpp'
3303=== modified file 'unity-shared/UnityWindowView.h'
3304--- unity-shared/UnityWindowView.h 2012-05-17 11:52:32 +0000
3305+++ unity-shared/UnityWindowView.h 2012-05-24 17:16:22 +0000
3306@@ -20,8 +20,13 @@
3307 #ifndef UNITYWINDOWVIEW_H
3308 #define UNITYWINDOWVIEW_H
3309
3310+<<<<<<< TREE
3311 #include "unity-shared/BackgroundEffectHelper.h"
3312 #include "Introspectable.h"
3313+=======
3314+#include "BackgroundEffectHelper.h"
3315+#include "Introspectable.h"
3316+>>>>>>> MERGE-SOURCE
3317 #include "UnityWindowStyle.h"
3318 #include <sigc++/sigc++.h>
3319
3320
3321=== modified file 'unity-shared/WindowManager.h'
3322--- unity-shared/WindowManager.h 2012-05-07 00:49:31 +0000
3323+++ unity-shared/WindowManager.h 2012-05-24 17:16:22 +0000
3324@@ -23,9 +23,15 @@
3325 #include <gdk/gdkx.h>
3326 #include <core/core.h>
3327
3328+<<<<<<< TREE
3329 #include "unity-shared/Introspectable.h"
3330
3331 class WindowManager : public unity::debug::Introspectable
3332+=======
3333+#include "Introspectable.h"
3334+
3335+class WindowManager : public unity::debug::Introspectable
3336+>>>>>>> MERGE-SOURCE
3337 {
3338 // This is a glue interface that breaks the dependancy of Unity with Compiz
3339 // Basically it has a default implementation that does nothing useful, but