diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | tests/autopilot/unity/emulators/dash.py | 8 | ||||
| -rw-r--r-- | tests/autopilot/unity/emulators/launcher.py | 2 | ||||
| -rw-r--r-- | tests/autopilot/unity/emulators/screen.py | 8 | ||||
| -rw-r--r-- | tests/autopilot/unity/emulators/switcher.py | 12 | ||||
| -rw-r--r-- | tests/autopilot/unity/tests/__init__.py | 21 | ||||
| -rw-r--r-- | tests/autopilot/unity/tests/launcher/test_icon_behavior.py | 8 | ||||
| -rw-r--r-- | tests/autopilot/unity/tests/test_dash.py | 35 | ||||
| -rw-r--r-- | tests/autopilot/unity/tests/test_showdesktop.py | 2 | ||||
| -rw-r--r-- | tests/autopilot/unity/tests/test_switcher.py | 35 | ||||
| -rw-r--r-- | tests/test_layout_system.cpp | 158 | ||||
| -rw-r--r-- | tests/test_main.cpp | 2 |
12 files changed, 259 insertions, 35 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cd12621ad..3adaff164 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -136,6 +136,7 @@ if (GTEST_SRC_DIR AND test_favorite_store_private.cpp test_home_lens.cpp test_launcher_entry_remote.cpp + test_layout_system.cpp test_model_iterator.cpp test_previews.cpp test_ubus.cpp @@ -152,6 +153,7 @@ if (GTEST_SRC_DIR AND set (GTEST_XLESS_LIBS gtest unity-shared + unity-shared-standalone launcher-lib ${GMOCK_LIB} ${GMOCK_MAIN_LIB} @@ -160,6 +162,7 @@ if (GTEST_SRC_DIR AND if (ENABLE_X_SUPPORT) set (GTEST_XLESS_SOURCES + ${GTEST_XLESS_SOURCES} test_hud_private.cpp test_pointer_barrier.cpp test_shortcut_model.cpp diff --git a/tests/autopilot/unity/emulators/dash.py b/tests/autopilot/unity/emulators/dash.py index f73eddb81..7954b14af 100644 --- a/tests/autopilot/unity/emulators/dash.py +++ b/tests/autopilot/unity/emulators/dash.py @@ -360,8 +360,8 @@ class FilterExpanderLabel(UnityIntrospectionObject): def ensure_expanded(self): """Expand the filter expander label, if it's not already""" if not self.expanded: - tx = x + width / 2 - ty = y + height / 2 + tx = self.x + self.width / 2 + ty = self.y + self.height / 2 m = Mouse() m.move(tx, ty) m.click() @@ -370,8 +370,8 @@ class FilterExpanderLabel(UnityIntrospectionObject): def ensure_collapsed(self): """Collapse the filter expander label, if it's not already""" if self.expanded: - tx = x + width / 2 - ty = y + height / 2 + tx = self.x + self.width / 2 + ty = self.y + self.height / 2 m = Mouse() m.move(tx, ty) m.click() diff --git a/tests/autopilot/unity/emulators/launcher.py b/tests/autopilot/unity/emulators/launcher.py index a3a35b409..5bff403b9 100644 --- a/tests/autopilot/unity/emulators/launcher.py +++ b/tests/autopilot/unity/emulators/launcher.py @@ -423,7 +423,7 @@ class Launcher(UnityIntrospectionObject, KeybindingsHelper): """ if not isinstance(icon, ApplicationLauncherIcon): - raise TypeError("Can only unlock instances of ApplicationLauncherIcon") + raise TypeError("Can only unlock instances of ApplicationLauncherIcon, not %s" % type(icon).__name__) if not icon.sticky: # nothing to do. return diff --git a/tests/autopilot/unity/emulators/screen.py b/tests/autopilot/unity/emulators/screen.py index 9a7bd7513..2eb50ecf1 100644 --- a/tests/autopilot/unity/emulators/screen.py +++ b/tests/autopilot/unity/emulators/screen.py @@ -27,6 +27,14 @@ class Screen(UnityIntrospectionObject): """Return the available scaled windows, or None.""" return self.get_children_by_type(Window, scaled=True) + def window(self, xid): + """Return the window with given xid.""" + windows = self.get_children_by_type(Window, xid=xid) + if len(windows): + return windows[0] + + return None + class Window(UnityIntrospectionObject): """An individual window.""" diff --git a/tests/autopilot/unity/emulators/switcher.py b/tests/autopilot/unity/emulators/switcher.py index 16f6bdfc2..d675ecafb 100644 --- a/tests/autopilot/unity/emulators/switcher.py +++ b/tests/autopilot/unity/emulators/switcher.py @@ -72,6 +72,16 @@ class Switcher(KeybindingsHelper): return self.controller.model.selection_index @property + def label(self): + """The current switcher label""" + return self.controller.view.label + + @property + def label_visible(self): + """The switcher label visibility""" + return self.controller.view.label_visible + + @property def mode(self): """Returns the SwitcherMode that the switcher is currently in.""" if not self.visible: @@ -126,7 +136,7 @@ class Switcher(KeybindingsHelper): If no icon matches, a ValueError will be raised. """ - if self.mode != SwitcherMode.NORMAL: + if self.mode == SwitcherMode.DETAIL: raise RuntimeError("Switcher must be initiated in normal mode before calling this method.") if direction not in (self.DIRECTION_BACKWARDS, self.DIRECTION_FORWARDS): diff --git a/tests/autopilot/unity/tests/__init__.py b/tests/autopilot/unity/tests/__init__.py index 0d96931dc..164f8dba7 100644 --- a/tests/autopilot/unity/tests/__init__.py +++ b/tests/autopilot/unity/tests/__init__.py @@ -19,6 +19,7 @@ from logging import getLogger import os import sys from tempfile import mktemp +from time import sleep try: import testapp import json @@ -69,7 +70,7 @@ class UnityTestCase(AutopilotTestCase): # # Setting this here since the show desktop feature seems to be a bit # ropey. Once it's been proven to work reliably we can remove this line: - self.set_unity_log_level("unity.plugin", "DEBUG") + self.set_unity_log_level("unity.wm.compiz", "DEBUG") def check_test_behavior(self): """Fail the test if it did something naughty. @@ -106,7 +107,23 @@ class UnityTestCase(AutopilotTestCase): well_behaved = False reasons.append("The test left the system in show_desktop mode.") log.warning("Test left the system in show desktop mode, exiting it...") - self.window_manager.leave_show_desktop() + # It is not possible to leave show desktop mode if there are no + # app windows. So, just open a window and perform the show + # desktop action until the desired state is acheived, then close + # the window. The showdesktop_active state will persist. + # + # In the event that this doesn't work, wait_for will throw an + # exception. + win = self.start_app_window('Calculator', locale='C') + count = 1 + while self.window_manager.showdesktop_active: + self.keybinding("window/show_desktop") + sleep(count) + count+=1 + if count > 10: + break + win.close() + self.window_manager.showdesktop_active.wait_for(False) for launcher in self.launcher.get_launchers(): if not self.well_behaved(launcher, in_keynav_mode=False): well_behaved = False diff --git a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py index 023a19333..e8b5e868f 100644 --- a/tests/autopilot/unity/tests/launcher/test_icon_behavior.py +++ b/tests/autopilot/unity/tests/launcher/test_icon_behavior.py @@ -232,9 +232,13 @@ class LauncherDragIconsBehavior(LauncherTestCase): # Normally we'd use get_icon(desktop_id="...") but we're expecting it to # not exist, and we don't want to wait for 10 seconds, so we do this # the old fashioned way. - refresh_fn = lambda: self.launcher.model.get_children_by_type( + get_icon_fn = lambda: self.launcher.model.get_children_by_type( ApplicationLauncherIcon, desktop_id="gcalctool.desktop") - self.assertThat(refresh_fn, Eventually(Equals([]))) + calc_icon = get_icon_fn() + if calc_icon: + self.launcher_instance.unlock_from_launcher(calc_icon[0]) + + self.assertThat(get_icon_fn, Eventually(Equals([]))) def test_can_drag_icon_below_bfb(self): """Application icons must be draggable to below the BFB.""" diff --git a/tests/autopilot/unity/tests/test_dash.py b/tests/autopilot/unity/tests/test_dash.py index ad34f07b3..9f2c55f13 100644 --- a/tests/autopilot/unity/tests/test_dash.py +++ b/tests/autopilot/unity/tests/test_dash.py @@ -15,16 +15,18 @@ from time import sleep from unity.tests import UnityTestCase +import gettext class DashTestCase(UnityTestCase): def setUp(self): super(DashTestCase, self).setUp() - self.set_unity_log_level("unity.shell", "DEBUG") + self.set_unity_log_level("unity.shell.compiz", "DEBUG") self.set_unity_log_level("unity.launcher", "DEBUG") self.dash.ensure_hidden() # On shutdown, ensure hidden too. Also add a delay. Cleanup is LIFO. self.addCleanup(self.dash.ensure_hidden) self.addCleanup(sleep, 1) + gettext.install("unity-lens-files") class DashRevealTests(DashTestCase): @@ -361,24 +363,27 @@ class DashKeyNavTests(DashTestCase): lens = self.dash.get_current_lens() filter_bar = lens.get_filterbar() + # Need to ensure the filter expander has focus, so if it's already + # expanded, we collapse it first: + filter_bar.ensure_collapsed() filter_bar.ensure_expanded() # Tab to fist filter expander self.keyboard.press_and_release('Tab') - self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(NotEquals(None))) + self.assertThat(filter_bar.get_focused_filter, Eventually(NotEquals(None))) old_focused_filter = filter_bar.get_focused_filter() old_focused_filter.ensure_expanded() # Tab to the next filter expander self.keyboard.press_and_release('Tab') - self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(NotEquals(None))) + self.assertThat(filter_bar.get_focused_filter, Eventually(NotEquals(None))) new_focused_filter = filter_bar.get_focused_filter() self.assertNotEqual(old_focused_filter, new_focused_filter) new_focused_filter.ensure_expanded() # Move the focus up. self.keyboard.press_and_release("Up") - self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(Equals(None))) + self.assertThat(filter_bar.get_focused_filter, Eventually(Equals(None))) self.assertThat(old_focused_filter.content_has_focus, Eventually(Equals(True))) @@ -659,10 +664,10 @@ class CategoryHeaderTests(DashTestCase): """Clicking into a category highlight must expand/collapse the view. """ - lens = self.dash.reveal_file_lens() + lens = self.dash.reveal_application_lens() self.addCleanup(self.dash.ensure_hidden) - category = lens.get_category_by_name("Folders") + category = lens.get_category_by_name(_("Installed")) is_expanded = category.is_expanded self.mouse.move(self.dash.view.x + self.dash.view.width / 2, @@ -687,7 +692,7 @@ class PreviewInvocationTests(DashTestCase): lens = self.dash.reveal_application_lens() self.addCleanup(self.dash.ensure_hidden) - category = lens.get_category_by_name("Installed") + category = lens.get_category_by_name("More suggestions") results = category.get_results() result = results[0] # result.preview handles finding xy co-ords and right mouse-click @@ -780,7 +785,7 @@ class PreviewInvocationTests(DashTestCase): lens = self.dash.reveal_application_lens() self.addCleanup(self.dash.ensure_hidden) - category = lens.get_category_by_name("Installed") + category = lens.get_category_by_name("More suggestions") results = category.get_results() result = results[0] # result.preview_key() handles finding xy co-ords and key press @@ -794,16 +799,14 @@ class PreviewNavigateTests(DashTestCase): def setUp(self): super(PreviewNavigateTests, self).setUp() - self.dash.reveal_application_lens() + lens = self.dash.reveal_application_lens() self.addCleanup(self.dash.ensure_hidden) - lens = self.dash.get_current_lens() - - results_category = lens.get_category_by_name("Installed") - results = results_category.get_results() + results_category = lens.get_category_by_name("More suggestions") # wait for results (we need 4 results to perorm the multi-navigation tests) - refresh_fn = lambda: len(results) + refresh_fn = lambda: len(results_category.get_results()) self.assertThat(refresh_fn, Eventually(GreaterThan(4))) + results = results_category.get_results() result = results[2] # 2 so we can navigate left result.preview() @@ -917,7 +920,7 @@ class PreviewNavigateTests(DashTestCase): cover_art = self.preview_container.current_preview.cover_art tx = cover_art.x + (cover_art.width / 2) - ty = cover_art.y + (cover_art.height / 2) + ty = cover_art.y + (cover_art.height / 4) self.mouse.move(tx, ty) self.mouse.click(button=1) @@ -928,7 +931,7 @@ class PreviewNavigateTests(DashTestCase): cover_art = self.preview_container.current_preview.cover_art tx = cover_art.x + (cover_art.width / 2) - ty = cover_art.y + (cover_art.height / 2) + ty = cover_art.y + (cover_art.height / 4) self.mouse.move(tx, ty) self.mouse.click(button=3) diff --git a/tests/autopilot/unity/tests/test_showdesktop.py b/tests/autopilot/unity/tests/test_showdesktop.py index 3110d8f37..e6469fb77 100644 --- a/tests/autopilot/unity/tests/test_showdesktop.py +++ b/tests/autopilot/unity/tests/test_showdesktop.py @@ -19,7 +19,7 @@ class ShowDesktopTests(UnityTestCase): def setUp(self): super(ShowDesktopTests, self).setUp() - self.set_unity_log_level("unity.plugin", "DEBUG") + self.set_unity_log_level("unity.wm.compiz", "DEBUG") # we need this to let the unity models update after we shutdown apps # before we start the next test. sleep(2) diff --git a/tests/autopilot/unity/tests/test_switcher.py b/tests/autopilot/unity/tests/test_switcher.py index fd0b00d8c..964bf3d4c 100644 --- a/tests/autopilot/unity/tests/test_switcher.py +++ b/tests/autopilot/unity/tests/test_switcher.py @@ -14,7 +14,7 @@ import logging from testtools.matchers import Equals, Contains, Not from time import sleep -from unity.emulators.switcher import SwitcherMode +from unity.emulators.switcher import Switcher, SwitcherMode from unity.tests import UnityTestCase logger = logging.getLogger(__name__) @@ -75,7 +75,7 @@ class SwitcherTests(SwitcherTestCase): def tearDown(self): super(SwitcherTests, self).tearDown() - def test_witcher_starts_in_normal_mode(self): + def test_switcher_starts_in_normal_mode(self): """Switcher must start in normal (i.e.- not details) mode.""" self.start_app("Character Map") @@ -83,15 +83,38 @@ class SwitcherTests(SwitcherTestCase): self.addCleanup(self.switcher.terminate) self.assertProperty(self.switcher, mode=SwitcherMode.NORMAL) - def test_first_detail_mode_has_correct_label(self): - """Starting switcher in details mode must show the focused window title.""" + def test_label_matches_application_name(self): + """The switcher label must match the selected application name in normal mode.""" + windows = self.start_applications() + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + for win in windows: + app_name = win.application.name + self.switcher.select_icon(Switcher.DIRECTION_FORWARDS, tooltip_text=app_name) + self.assertThat(self.switcher.label_visible, Eventually(Equals(True))) + self.assertThat(self.switcher.label, Eventually(Equals(app_name))) + + def test_application_window_is_fake_decorated(self): + """When the switcher is in details mode must not show the focused window title.""" window = self.start_app_window("Text Editor") - title = window.title + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + self.switcher.select_icon(Switcher.DIRECTION_BACKWARDS, tooltip_text=window.application.name) + self.switcher.show_details() + self.assertThat(self.switcher.label_visible, Eventually(Equals(False))) + self.assertThat(self.screen.window(window.x_id).fake_decorated, Eventually(Equals(True))) + + def test_application_window_is_fake_decorated_in_detail_mode(self): + """Starting switcher in details mode must not show the focused window title.""" + window = self.start_app_window("Text Editor") self.switcher.initiate(SwitcherMode.DETAIL) self.addCleanup(self.switcher.terminate) - self.assertThat(self.switcher.controller.view.label, Eventually(Equals(title))) + self.assertThat(self.switcher.label_visible, Eventually(Equals(False))) + self.assertThat(self.screen.window(window.x_id).fake_decorated, Eventually(Equals(True))) def test_switcher_move_next(self): """Test that pressing the next icon binding moves to the next icon""" diff --git a/tests/test_layout_system.cpp b/tests/test_layout_system.cpp new file mode 100644 index 000000000..d991e36d9 --- /dev/null +++ b/tests/test_layout_system.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with this program. If not, see + * <http://www.gnu.org/licenses/> + * + * Authored by: Marco Trevisan (TreviƱo) <marco.trevisan@canonical.com> + */ + +#include <gmock/gmock.h> +#include "LayoutSystem.h" +#include "StandaloneWindowManager.h" + +namespace unity +{ +namespace ui +{ +namespace +{ +StandaloneWindowManager* wm = nullptr; + +StandaloneWindow::Ptr AddFakeWindowToWM(Window xid, nux::Geometry const& geo = nux::Geometry(1, 2, 30, 40)) +{ + const unsigned top_deco = 5; + auto fake_window = std::make_shared<StandaloneWindow>(xid); + fake_window->geo = geo; + fake_window->deco_sizes[unsigned(WindowManager::Edge::TOP)] = nux::Size(geo.width, top_deco); + + if (!wm) + wm = dynamic_cast<StandaloneWindowManager*>(&WindowManager::Default()); + + wm->AddStandaloneWindow(fake_window); + + return fake_window; +} + +TEST(TestLayoutWindow, InitializationNormalWindow) +{ + const Window xid = g_random_int(); + auto fake_window = AddFakeWindowToWM(xid); + + LayoutWindow lwin(xid); + EXPECT_EQ(lwin.xid, xid); + EXPECT_EQ(lwin.geo, fake_window->geo); + EXPECT_EQ(lwin.decoration_height, 0); + EXPECT_EQ(lwin.selected, false); + EXPECT_EQ(lwin.aspect_ratio, fake_window->geo.width / static_cast<float>(fake_window->geo.height)); +} + +TEST(TestLayoutWindow, InitializationMinimizedNormalWindow) +{ + const Window xid = g_random_int(); + auto fake_window = AddFakeWindowToWM(xid); + wm->Minimize(xid); + + LayoutWindow lwin(xid); + EXPECT_EQ(lwin.xid, xid); + EXPECT_EQ(lwin.geo, fake_window->geo); + EXPECT_EQ(lwin.decoration_height, 0); + EXPECT_EQ(lwin.selected, false); + EXPECT_EQ(lwin.aspect_ratio, fake_window->geo.width / static_cast<float>(fake_window->geo.height)); +} + +TEST(TestLayoutWindow, InitializationMaximizedWindow) +{ + const Window xid = g_random_int(); + auto fake_window = AddFakeWindowToWM(xid); + wm->Maximize(xid); + + nux::Geometry expected_geo(fake_window->geo); + unsigned top_deco = wm->GetWindowDecorationSize(xid, WindowManager::Edge::TOP).height; + expected_geo.height += top_deco; + + LayoutWindow lwin(xid); + EXPECT_EQ(lwin.xid, xid); + EXPECT_EQ(lwin.geo, expected_geo); + EXPECT_EQ(lwin.decoration_height, top_deco); + EXPECT_EQ(lwin.selected, false); + EXPECT_EQ(lwin.aspect_ratio, expected_geo.width / static_cast<float>(expected_geo.height)); +} + +TEST(TestLayoutWindow, InitializationMinimizedMaximizedWindow) +{ + const Window xid = g_random_int(); + auto fake_window = AddFakeWindowToWM(xid); + wm->Maximize(xid); + wm->Minimize(xid); + + LayoutWindow lwin(xid); + EXPECT_EQ(lwin.xid, xid); + EXPECT_EQ(lwin.geo, fake_window->geo); + EXPECT_EQ(lwin.decoration_height, 0); + EXPECT_EQ(lwin.selected, false); + EXPECT_EQ(lwin.aspect_ratio, fake_window->geo.width / static_cast<float>(fake_window->geo.height)); +} + +struct TestLayoutSystem : testing::Test +{ + TestLayoutSystem() + { + Window xid = 1; + AddFakeWindowToWM(xid, nux::Geometry(4, 5, 500, 600)); + lwindows.push_back(std::make_shared<LayoutWindow>(xid)); + + xid = 2; + AddFakeWindowToWM(xid, nux::Geometry(10, 20, 800, 300)); + lwindows.push_back(std::make_shared<LayoutWindow>(xid)); + } + + LayoutSystem ls; + LayoutWindow::Vector lwindows; +}; + +TEST_F(TestLayoutSystem, Initialization) +{ + EXPECT_EQ(ls.spacing, 8); + EXPECT_EQ(ls.max_row_height, 400); +} + +TEST_F(TestLayoutSystem, LayoutWindows) +{ + nux::Geometry max_bounds(0, 0, 200, 100); + nux::Geometry final_bounds; + ls.LayoutWindows(lwindows, max_bounds, final_bounds); + + nux::Geometry const& win_new_geo1 = lwindows.at(0)->result; + nux::Geometry const& win_new_geo2 = lwindows.at(1)->result; + + EXPECT_EQ(max_bounds.Intersect(final_bounds), final_bounds); + EXPECT_NE(lwindows.at(0)->geo, win_new_geo1); + EXPECT_NE(lwindows.at(1)->geo, win_new_geo1); + + // Computing the area occupied by the grouped windows + unsigned min_start_x = std::min(win_new_geo1.x, win_new_geo2.x); + unsigned min_start_y = std::min(win_new_geo1.y, win_new_geo2.y); + unsigned max_last_x = std::max(win_new_geo1.x + win_new_geo1.width, + win_new_geo2.x + win_new_geo2.width); + unsigned max_last_y = std::max(win_new_geo1.y + win_new_geo1.height, + win_new_geo2.y + win_new_geo2.height); + + nux::Geometry windows_area(min_start_x, min_start_y, max_last_x - min_start_x, max_last_y - min_start_y); + + EXPECT_EQ(final_bounds.Intersect(windows_area), windows_area); +} + +} +} +} diff --git a/tests/test_main.cpp b/tests/test_main.cpp index fa4a8abd4..c0af3dbd5 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -4,8 +4,6 @@ #include <NuxCore/Logger.h> #include <Nux/Nux.h> -#include "unity-shared/WindowManager.h" - int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); |
