Add Profile::IsChild and IsLegacySupervised
[chromium-blink-merge.git] / ui / views / corewm / tooltip_controller_unittest.cc
blobc7871556ed13282117847e03ec670000e6a0f0d4
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/corewm/tooltip_controller.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "ui/aura/client/cursor_client.h"
9 #include "ui/aura/client/screen_position_client.h"
10 #include "ui/aura/env.h"
11 #include "ui/aura/test/aura_test_base.h"
12 #include "ui/aura/test/test_screen.h"
13 #include "ui/aura/test/test_window_delegate.h"
14 #include "ui/aura/window.h"
15 #include "ui/aura/window_event_dispatcher.h"
16 #include "ui/events/test/event_generator.h"
17 #include "ui/gfx/font.h"
18 #include "ui/gfx/point.h"
19 #include "ui/gfx/screen.h"
20 #include "ui/gfx/screen_type_delegate.h"
21 #include "ui/gfx/text_elider.h"
22 #include "ui/views/corewm/tooltip_aura.h"
23 #include "ui/views/corewm/tooltip_controller_test_helper.h"
24 #include "ui/views/test/desktop_test_views_delegate.h"
25 #include "ui/views/test/test_views_delegate.h"
26 #include "ui/views/view.h"
27 #include "ui/views/widget/tooltip_manager.h"
28 #include "ui/views/widget/widget.h"
29 #include "ui/wm/core/default_activation_client.h"
30 #include "ui/wm/core/default_screen_position_client.h"
31 #include "ui/wm/core/wm_state.h"
32 #include "ui/wm/public/tooltip_client.h"
33 #include "ui/wm/public/window_types.h"
35 #if defined(OS_WIN)
36 #include "ui/base/win/scoped_ole_initializer.h"
37 #endif
39 #if !defined(OS_CHROMEOS)
40 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
41 #include "ui/views/widget/desktop_aura/desktop_screen.h"
42 #endif
44 using base::ASCIIToUTF16;
46 namespace views {
47 namespace corewm {
48 namespace test {
49 namespace {
51 views::Widget* CreateWidget(aura::Window* root) {
52 views::Widget* widget = new views::Widget;
53 views::Widget::InitParams params;
54 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
55 params.accept_events = true;
56 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
57 #if defined(OS_CHROMEOS)
58 params.parent = root;
59 #else
60 params.native_widget = new DesktopNativeWidgetAura(widget);
61 #endif
62 params.bounds = gfx::Rect(0, 0, 200, 100);
63 widget->Init(params);
64 widget->Show();
65 return widget;
68 TooltipController* GetController(Widget* widget) {
69 return static_cast<TooltipController*>(
70 aura::client::GetTooltipClient(
71 widget->GetNativeWindow()->GetRootWindow()));
74 } // namespace
76 class TooltipControllerTest : public aura::test::AuraTestBase {
77 public:
78 TooltipControllerTest() : view_(NULL) {}
79 ~TooltipControllerTest() override {}
81 void SetUp() override {
82 #if defined(OS_CHROMEOS)
83 views_delegate_.reset(new TestViewsDelegate);
84 #else
85 views_delegate_.reset(new DesktopTestViewsDelegate);
86 #endif
88 aura::test::AuraTestBase::SetUp();
89 new wm::DefaultActivationClient(root_window());
90 #if defined(OS_CHROMEOS)
91 controller_.reset(new TooltipController(
92 scoped_ptr<views::corewm::Tooltip>(
93 new views::corewm::TooltipAura(gfx::SCREEN_TYPE_ALTERNATE))));
94 root_window()->AddPreTargetHandler(controller_.get());
95 SetTooltipClient(root_window(), controller_.get());
96 #endif
97 widget_.reset(CreateWidget(root_window()));
98 widget_->SetContentsView(new View);
99 view_ = new TooltipTestView;
100 widget_->GetContentsView()->AddChildView(view_);
101 view_->SetBoundsRect(widget_->GetContentsView()->GetLocalBounds());
102 helper_.reset(new TooltipControllerTestHelper(
103 GetController(widget_.get())));
104 generator_.reset(new ui::test::EventGenerator(GetRootWindow()));
107 void TearDown() override {
108 #if defined(OS_CHROMEOS)
109 root_window()->RemovePreTargetHandler(controller_.get());
110 aura::client::SetTooltipClient(root_window(), NULL);
111 controller_.reset();
112 #endif
113 generator_.reset();
114 helper_.reset();
115 widget_.reset();
116 aura::test::AuraTestBase::TearDown();
117 views_delegate_.reset();
120 protected:
121 aura::Window* GetWindow() {
122 return widget_->GetNativeWindow();
125 aura::Window* GetRootWindow() {
126 return GetWindow()->GetRootWindow();
129 TooltipTestView* PrepareSecondView() {
130 TooltipTestView* view2 = new TooltipTestView;
131 widget_->GetContentsView()->AddChildView(view2);
132 view_->SetBounds(0, 0, 100, 100);
133 view2->SetBounds(100, 0, 100, 100);
134 return view2;
137 scoped_ptr<views::Widget> widget_;
138 TooltipTestView* view_;
139 scoped_ptr<TooltipControllerTestHelper> helper_;
140 scoped_ptr<ui::test::EventGenerator> generator_;
142 private:
143 scoped_ptr<TooltipController> controller_;
145 scoped_ptr<views::TestViewsDelegate> views_delegate_;
147 #if defined(OS_WIN)
148 ui::ScopedOleInitializer ole_initializer_;
149 #endif
151 DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest);
154 TEST_F(TooltipControllerTest, ViewTooltip) {
155 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text"));
156 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
157 EXPECT_EQ(NULL, helper_->GetTooltipWindow());
158 generator_->MoveMouseToCenterOf(GetWindow());
160 EXPECT_EQ(GetWindow(), GetRootWindow()->GetEventHandlerForPoint(
161 generator_->current_location()));
162 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text");
163 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow()));
164 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
165 EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow());
167 // Fire tooltip timer so tooltip becomes visible.
168 helper_->FireTooltipTimer();
170 EXPECT_TRUE(helper_->IsTooltipVisible());
171 generator_->MoveMouseBy(1, 0);
173 EXPECT_TRUE(helper_->IsTooltipVisible());
174 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow()));
175 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText());
176 EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow());
179 TEST_F(TooltipControllerTest, TooltipsInMultipleViews) {
180 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text"));
181 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
182 EXPECT_EQ(NULL, helper_->GetTooltipWindow());
184 PrepareSecondView();
185 aura::Window* window = GetWindow();
186 aura::Window* root_window = GetRootWindow();
188 // Fire tooltip timer so tooltip becomes visible.
189 generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint());
190 helper_->FireTooltipTimer();
191 EXPECT_TRUE(helper_->IsTooltipVisible());
192 for (int i = 0; i < 49; ++i) {
193 generator_->MoveMouseBy(1, 0);
194 EXPECT_TRUE(helper_->IsTooltipVisible());
195 EXPECT_EQ(window, root_window->GetEventHandlerForPoint(
196 generator_->current_location()));
197 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text");
198 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window));
199 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText());
200 EXPECT_EQ(window, helper_->GetTooltipWindow());
202 for (int i = 0; i < 49; ++i) {
203 generator_->MoveMouseBy(1, 0);
204 EXPECT_FALSE(helper_->IsTooltipVisible());
205 EXPECT_EQ(window, root_window->GetEventHandlerForPoint(
206 generator_->current_location()));
207 base::string16 expected_tooltip; // = ""
208 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window));
209 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText());
210 EXPECT_EQ(window, helper_->GetTooltipWindow());
214 TEST_F(TooltipControllerTest, EnableOrDisableTooltips) {
215 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text"));
216 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
217 EXPECT_EQ(NULL, helper_->GetTooltipWindow());
219 generator_->MoveMouseRelativeTo(GetWindow(), view_->bounds().CenterPoint());
220 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text");
222 // Fire tooltip timer so tooltip becomes visible.
223 helper_->FireTooltipTimer();
224 EXPECT_TRUE(helper_->IsTooltipVisible());
226 // Disable tooltips and check again.
227 helper_->controller()->SetTooltipsEnabled(false);
228 EXPECT_FALSE(helper_->IsTooltipVisible());
229 helper_->FireTooltipTimer();
230 EXPECT_FALSE(helper_->IsTooltipVisible());
232 // Enable tooltips back and check again.
233 helper_->controller()->SetTooltipsEnabled(true);
234 EXPECT_FALSE(helper_->IsTooltipVisible());
235 helper_->FireTooltipTimer();
236 EXPECT_TRUE(helper_->IsTooltipVisible());
239 // Verifies tooltip isn't shown if tooltip text consists entirely of whitespace.
240 TEST_F(TooltipControllerTest, DontShowEmptyTooltips) {
241 view_->set_tooltip_text(ASCIIToUTF16(" "));
242 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
243 EXPECT_EQ(NULL, helper_->GetTooltipWindow());
245 generator_->MoveMouseRelativeTo(GetWindow(), view_->bounds().CenterPoint());
247 helper_->FireTooltipTimer();
248 EXPECT_FALSE(helper_->IsTooltipVisible());
251 TEST_F(TooltipControllerTest, TooltipHidesOnKeyPressAndStaysHiddenUntilChange) {
252 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 1"));
253 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
254 EXPECT_EQ(NULL, helper_->GetTooltipWindow());
256 TooltipTestView* view2 = PrepareSecondView();
257 view2->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 2"));
259 aura::Window* window = GetWindow();
261 // Fire tooltip timer so tooltip becomes visible.
262 generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint());
263 helper_->FireTooltipTimer();
264 EXPECT_TRUE(helper_->IsTooltipVisible());
265 EXPECT_TRUE(helper_->IsTooltipShownTimerRunning());
267 generator_->PressKey(ui::VKEY_1, 0);
268 EXPECT_FALSE(helper_->IsTooltipVisible());
269 EXPECT_FALSE(helper_->IsTooltipTimerRunning());
270 EXPECT_FALSE(helper_->IsTooltipShownTimerRunning());
272 // Moving the mouse inside |view1| should not change the state of the tooltip
273 // or the timers.
274 for (int i = 0; i < 49; i++) {
275 generator_->MoveMouseBy(1, 0);
276 EXPECT_FALSE(helper_->IsTooltipVisible());
277 EXPECT_FALSE(helper_->IsTooltipTimerRunning());
278 EXPECT_FALSE(helper_->IsTooltipShownTimerRunning());
279 EXPECT_EQ(window,
280 GetRootWindow()->GetEventHandlerForPoint(
281 generator_->current_location()));
282 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text for view 1");
283 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window));
284 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText());
285 EXPECT_EQ(window, helper_->GetTooltipWindow());
288 // Now we move the mouse on to |view2|. It should re-start the tooltip timer.
289 generator_->MoveMouseBy(1, 0);
290 EXPECT_TRUE(helper_->IsTooltipTimerRunning());
291 helper_->FireTooltipTimer();
292 EXPECT_TRUE(helper_->IsTooltipVisible());
293 EXPECT_TRUE(helper_->IsTooltipShownTimerRunning());
294 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text for view 2");
295 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window));
296 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText());
297 EXPECT_EQ(window, helper_->GetTooltipWindow());
300 TEST_F(TooltipControllerTest, TooltipHidesOnTimeoutAndStaysHiddenUntilChange) {
301 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 1"));
302 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
303 EXPECT_EQ(NULL, helper_->GetTooltipWindow());
305 TooltipTestView* view2 = PrepareSecondView();
306 view2->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 2"));
308 aura::Window* window = GetWindow();
310 // Fire tooltip timer so tooltip becomes visible.
311 generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint());
312 helper_->FireTooltipTimer();
313 EXPECT_TRUE(helper_->IsTooltipVisible());
314 EXPECT_TRUE(helper_->IsTooltipShownTimerRunning());
316 helper_->FireTooltipShownTimer();
317 EXPECT_FALSE(helper_->IsTooltipVisible());
318 EXPECT_FALSE(helper_->IsTooltipTimerRunning());
319 EXPECT_FALSE(helper_->IsTooltipShownTimerRunning());
321 // Moving the mouse inside |view1| should not change the state of the tooltip
322 // or the timers.
323 for (int i = 0; i < 49; ++i) {
324 generator_->MoveMouseBy(1, 0);
325 EXPECT_FALSE(helper_->IsTooltipVisible());
326 EXPECT_FALSE(helper_->IsTooltipTimerRunning());
327 EXPECT_FALSE(helper_->IsTooltipShownTimerRunning());
328 EXPECT_EQ(window, GetRootWindow()->GetEventHandlerForPoint(
329 generator_->current_location()));
330 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text for view 1");
331 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window));
332 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText());
333 EXPECT_EQ(window, helper_->GetTooltipWindow());
336 // Now we move the mouse on to |view2|. It should re-start the tooltip timer.
337 generator_->MoveMouseBy(1, 0);
338 EXPECT_TRUE(helper_->IsTooltipTimerRunning());
339 helper_->FireTooltipTimer();
340 EXPECT_TRUE(helper_->IsTooltipVisible());
341 EXPECT_TRUE(helper_->IsTooltipShownTimerRunning());
342 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text for view 2");
343 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(window));
344 EXPECT_EQ(expected_tooltip, helper_->GetTooltipText());
345 EXPECT_EQ(window, helper_->GetTooltipWindow());
348 // Verifies a mouse exit event hides the tooltips.
349 TEST_F(TooltipControllerTest, HideOnExit) {
350 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text"));
351 generator_->MoveMouseToCenterOf(GetWindow());
352 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text");
353 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow()));
354 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
355 EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow());
357 // Fire tooltip timer so tooltip becomes visible.
358 helper_->FireTooltipTimer();
360 EXPECT_TRUE(helper_->IsTooltipVisible());
361 generator_->SendMouseExit();
362 EXPECT_FALSE(helper_->IsTooltipVisible());
365 TEST_F(TooltipControllerTest, ReshowOnClickAfterEnterExit) {
366 // Owned by |view_|.
367 TooltipTestView* v1 = new TooltipTestView;
368 TooltipTestView* v2 = new TooltipTestView;
369 view_->AddChildView(v1);
370 view_->AddChildView(v2);
371 gfx::Rect view_bounds(view_->GetLocalBounds());
372 view_bounds.set_height(view_bounds.height() / 2);
373 v1->SetBoundsRect(view_bounds);
374 view_bounds.set_y(view_bounds.height());
375 v2->SetBoundsRect(view_bounds);
376 const base::string16 v1_tt(ASCIIToUTF16("v1"));
377 const base::string16 v2_tt(ASCIIToUTF16("v2"));
378 v1->set_tooltip_text(v1_tt);
379 v2->set_tooltip_text(v2_tt);
381 gfx::Point v1_point(1, 1);
382 View::ConvertPointToWidget(v1, &v1_point);
383 generator_->MoveMouseRelativeTo(GetWindow(), v1_point);
385 // Fire tooltip timer so tooltip becomes visible.
386 helper_->FireTooltipTimer();
387 EXPECT_TRUE(helper_->IsTooltipVisible());
388 EXPECT_EQ(v1_tt, helper_->GetTooltipText());
390 // Press the mouse, move to v2 and back to v1.
391 generator_->ClickLeftButton();
393 gfx::Point v2_point(1, 1);
394 View::ConvertPointToWidget(v2, &v2_point);
395 generator_->MoveMouseRelativeTo(GetWindow(), v2_point);
396 generator_->MoveMouseRelativeTo(GetWindow(), v1_point);
398 helper_->FireTooltipTimer();
399 EXPECT_TRUE(helper_->IsTooltipVisible());
400 EXPECT_EQ(v1_tt, helper_->GetTooltipText());
403 namespace {
405 // Returns the index of |window| in its parent's children.
406 int IndexInParent(const aura::Window* window) {
407 aura::Window::Windows::const_iterator i =
408 std::find(window->parent()->children().begin(),
409 window->parent()->children().end(),
410 window);
411 return i == window->parent()->children().end() ? -1 :
412 static_cast<int>(i - window->parent()->children().begin());
415 } // namespace
417 class TooltipControllerCaptureTest : public TooltipControllerTest {
418 public:
419 TooltipControllerCaptureTest() {}
420 ~TooltipControllerCaptureTest() override {}
422 void SetUp() override {
423 TooltipControllerTest::SetUp();
424 aura::client::SetScreenPositionClient(GetRootWindow(),
425 &screen_position_client_);
426 #if !defined(OS_CHROMEOS)
427 desktop_screen_.reset(CreateDesktopScreen());
428 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE,
429 desktop_screen_.get());
430 #endif
433 void TearDown() override {
434 #if !defined(OS_CHROMEOS)
435 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen());
436 desktop_screen_.reset();
437 #endif
438 aura::client::SetScreenPositionClient(GetRootWindow(), NULL);
439 TooltipControllerTest::TearDown();
442 private:
443 wm::DefaultScreenPositionClient screen_position_client_;
444 scoped_ptr<gfx::Screen> desktop_screen_;
446 DISALLOW_COPY_AND_ASSIGN(TooltipControllerCaptureTest);
449 // Verifies when capture is released the TooltipController resets state.
450 // Flaky on all builders. http://crbug.com/388268
451 TEST_F(TooltipControllerCaptureTest, DISABLED_CloseOnCaptureLost) {
452 view_->GetWidget()->SetCapture(view_);
453 RunAllPendingInMessageLoop();
454 view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text"));
455 generator_->MoveMouseToCenterOf(GetWindow());
456 base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text");
457 EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow()));
458 EXPECT_EQ(base::string16(), helper_->GetTooltipText());
459 EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow());
461 // Fire tooltip timer so tooltip becomes visible.
462 helper_->FireTooltipTimer();
464 EXPECT_TRUE(helper_->IsTooltipVisible());
465 view_->GetWidget()->ReleaseCapture();
466 EXPECT_FALSE(helper_->IsTooltipVisible());
467 EXPECT_TRUE(helper_->GetTooltipWindow() == NULL);
470 // Disabled on linux as DesktopScreenX11::GetWindowAtScreenPoint() doesn't
471 // consider z-order.
472 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
473 #define MAYBE_Capture DISABLED_Capture
474 #else
475 #define MAYBE_Capture Capture
476 #endif
477 // Verifies the correct window is found for tooltips when there is a capture.
478 TEST_F(TooltipControllerCaptureTest, MAYBE_Capture) {
479 const base::string16 tooltip_text(ASCIIToUTF16("1"));
480 const base::string16 tooltip_text2(ASCIIToUTF16("2"));
482 widget_->SetBounds(gfx::Rect(0, 0, 200, 200));
483 view_->set_tooltip_text(tooltip_text);
485 scoped_ptr<views::Widget> widget2(CreateWidget(root_window()));
486 widget2->SetContentsView(new View);
487 TooltipTestView* view2 = new TooltipTestView;
488 widget2->GetContentsView()->AddChildView(view2);
489 view2->set_tooltip_text(tooltip_text2);
490 widget2->SetBounds(gfx::Rect(0, 0, 200, 200));
491 view2->SetBoundsRect(widget2->GetContentsView()->GetLocalBounds());
493 widget_->SetCapture(view_);
494 EXPECT_TRUE(widget_->HasCapture());
495 widget2->Show();
496 EXPECT_GE(IndexInParent(widget2->GetNativeWindow()),
497 IndexInParent(widget_->GetNativeWindow()));
499 generator_->MoveMouseRelativeTo(widget_->GetNativeWindow(),
500 view_->bounds().CenterPoint());
502 EXPECT_TRUE(helper_->IsTooltipTimerRunning());
503 helper_->FireTooltipTimer();
504 // Even though the mouse is over a window with a tooltip it shouldn't be
505 // picked up because the windows don't have the same value for
506 // |TooltipManager::kGroupingPropertyKey|.
507 EXPECT_TRUE(helper_->GetTooltipText().empty());
509 // Now make both the windows have same transient value for
510 // kGroupingPropertyKey. In this case the tooltip should be picked up from
511 // |widget2| (because the mouse is over it).
512 const int grouping_key = 1;
513 widget_->SetNativeWindowProperty(TooltipManager::kGroupingPropertyKey,
514 reinterpret_cast<void*>(grouping_key));
515 widget2->SetNativeWindowProperty(TooltipManager::kGroupingPropertyKey,
516 reinterpret_cast<void*>(grouping_key));
517 generator_->MoveMouseBy(1, 10);
518 EXPECT_TRUE(helper_->IsTooltipTimerRunning());
519 helper_->FireTooltipTimer();
520 EXPECT_EQ(tooltip_text2, helper_->GetTooltipText());
522 widget2.reset();
525 namespace {
527 class TestTooltip : public Tooltip {
528 public:
529 TestTooltip() : is_visible_(false) {}
530 ~TestTooltip() override {}
532 const base::string16& tooltip_text() const { return tooltip_text_; }
534 // Tooltip:
535 void SetText(aura::Window* window,
536 const base::string16& tooltip_text,
537 const gfx::Point& location) override {
538 tooltip_text_ = tooltip_text;
539 location_ = location;
541 void Show() override { is_visible_ = true; }
542 void Hide() override { is_visible_ = false; }
543 bool IsVisible() override { return is_visible_; }
544 const gfx::Point& location() { return location_; }
546 private:
547 bool is_visible_;
548 base::string16 tooltip_text_;
549 gfx::Point location_;
551 DISALLOW_COPY_AND_ASSIGN(TestTooltip);
554 } // namespace
556 // Use for tests that don't depend upon views.
557 class TooltipControllerTest2 : public aura::test::AuraTestBase {
558 public:
559 TooltipControllerTest2() : test_tooltip_(new TestTooltip) {}
560 ~TooltipControllerTest2() override {}
562 void SetUp() override {
563 wm_state_.reset(new wm::WMState);
564 aura::test::AuraTestBase::SetUp();
565 new wm::DefaultActivationClient(root_window());
566 controller_.reset(new TooltipController(
567 scoped_ptr<corewm::Tooltip>(test_tooltip_)));
568 root_window()->AddPreTargetHandler(controller_.get());
569 SetTooltipClient(root_window(), controller_.get());
570 helper_.reset(new TooltipControllerTestHelper(controller_.get()));
571 generator_.reset(new ui::test::EventGenerator(root_window()));
574 void TearDown() override {
575 root_window()->RemovePreTargetHandler(controller_.get());
576 aura::client::SetTooltipClient(root_window(), NULL);
577 controller_.reset();
578 generator_.reset();
579 helper_.reset();
580 aura::test::AuraTestBase::TearDown();
581 wm_state_.reset();
584 protected:
585 // Owned by |controller_|.
586 TestTooltip* test_tooltip_;
587 scoped_ptr<TooltipControllerTestHelper> helper_;
588 scoped_ptr<ui::test::EventGenerator> generator_;
590 private:
591 scoped_ptr<TooltipController> controller_;
592 scoped_ptr<wm::WMState> wm_state_;
594 DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest2);
597 TEST_F(TooltipControllerTest2, VerifyLeadingTrailingWhitespaceStripped) {
598 aura::test::TestWindowDelegate test_delegate;
599 scoped_ptr<aura::Window> window(
600 CreateNormalWindow(100, root_window(), &test_delegate));
601 window->SetBounds(gfx::Rect(0, 0, 300, 300));
602 base::string16 tooltip_text(ASCIIToUTF16(" \nx "));
603 aura::client::SetTooltipText(window.get(), &tooltip_text);
604 generator_->MoveMouseToCenterOf(window.get());
605 helper_->FireTooltipTimer();
606 EXPECT_EQ(ASCIIToUTF16("x"), test_tooltip_->tooltip_text());
609 // Verifies that tooltip is hidden and tooltip window closed upon cancel mode.
610 TEST_F(TooltipControllerTest2, CloseOnCancelMode) {
611 aura::test::TestWindowDelegate test_delegate;
612 scoped_ptr<aura::Window> window(
613 CreateNormalWindow(100, root_window(), &test_delegate));
614 window->SetBounds(gfx::Rect(0, 0, 300, 300));
615 base::string16 tooltip_text(ASCIIToUTF16("Tooltip Text"));
616 aura::client::SetTooltipText(window.get(), &tooltip_text);
617 generator_->MoveMouseToCenterOf(window.get());
619 // Fire tooltip timer so tooltip becomes visible.
620 helper_->FireTooltipTimer();
621 EXPECT_TRUE(helper_->IsTooltipVisible());
623 // Send OnCancelMode event and verify that tooltip becomes invisible and
624 // the tooltip window is closed.
625 ui::CancelModeEvent event;
626 helper_->controller()->OnCancelMode(&event);
627 EXPECT_FALSE(helper_->IsTooltipVisible());
628 EXPECT_TRUE(helper_->GetTooltipWindow() == NULL);
631 // Use for tests that need both views and a TestTooltip.
632 class TooltipControllerTest3 : public aura::test::AuraTestBase {
633 public:
634 TooltipControllerTest3() : test_tooltip_(new TestTooltip) {}
635 ~TooltipControllerTest3() override {}
637 void SetUp() override {
638 wm_state_.reset(new wm::WMState);
639 aura::test::AuraTestBase::SetUp();
640 new wm::DefaultActivationClient(root_window());
642 widget_.reset(CreateWidget(root_window()));
643 widget_->SetContentsView(new View);
644 view_ = new TooltipTestView;
645 widget_->GetContentsView()->AddChildView(view_);
646 view_->SetBoundsRect(widget_->GetContentsView()->GetLocalBounds());
648 generator_.reset(new ui::test::EventGenerator(GetRootWindow()));
649 controller_.reset(new TooltipController(
650 scoped_ptr<views::corewm::Tooltip>(test_tooltip_)));
651 GetRootWindow()->RemovePreTargetHandler(
652 static_cast<TooltipController*>(aura::client::GetTooltipClient(
653 widget_->GetNativeWindow()->GetRootWindow())));
654 GetRootWindow()->AddPreTargetHandler(controller_.get());
655 helper_.reset(new TooltipControllerTestHelper(controller_.get()));
656 SetTooltipClient(GetRootWindow(), controller_.get());
659 void TearDown() override {
660 GetRootWindow()->RemovePreTargetHandler(controller_.get());
661 aura::client::SetTooltipClient(GetRootWindow(), NULL);
663 controller_.reset();
664 generator_.reset();
665 helper_.reset();
666 widget_.reset();
667 aura::test::AuraTestBase::TearDown();
668 wm_state_.reset();
671 aura::Window* GetWindow() { return widget_->GetNativeWindow(); }
673 protected:
674 // Owned by |controller_|.
675 TestTooltip* test_tooltip_;
676 scoped_ptr<TooltipControllerTestHelper> helper_;
677 scoped_ptr<ui::test::EventGenerator> generator_;
678 scoped_ptr<views::Widget> widget_;
679 TooltipTestView* view_;
681 private:
682 scoped_ptr<TooltipController> controller_;
683 scoped_ptr<wm::WMState> wm_state_;
685 #if defined(OS_WIN)
686 ui::ScopedOleInitializer ole_initializer_;
687 #endif
689 aura::Window* GetRootWindow() { return GetWindow()->GetRootWindow(); }
691 DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest3);
694 TEST_F(TooltipControllerTest3, TooltipPositionChangesOnTwoViewsWithSameLabel) {
695 // Owned by |view_|.
696 // These two views have the same tooltip text
697 TooltipTestView* v1 = new TooltipTestView;
698 TooltipTestView* v2 = new TooltipTestView;
699 // v1_1 is a view inside v1 that has an identical tooltip text to that of v1
700 // and v2
701 TooltipTestView* v1_1 = new TooltipTestView;
702 // v2_1 is a view inside v2 that has an identical tooltip text to that of v1
703 // and v2
704 TooltipTestView* v2_1 = new TooltipTestView;
705 // v2_2 is a view inside v2 with the tooltip text different from all the
706 // others
707 TooltipTestView* v2_2 = new TooltipTestView;
709 // Setup all the views' relations
710 view_->AddChildView(v1);
711 view_->AddChildView(v2);
712 v1->AddChildView(v1_1);
713 v2->AddChildView(v2_1);
714 v2->AddChildView(v2_2);
715 const base::string16 reference_string(
716 base::ASCIIToUTF16("Identical Tooltip Text"));
717 const base::string16 alternative_string(
718 base::ASCIIToUTF16("Another Shrubbery"));
719 v1->set_tooltip_text(reference_string);
720 v2->set_tooltip_text(reference_string);
721 v1_1->set_tooltip_text(reference_string);
722 v2_1->set_tooltip_text(reference_string);
723 v2_2->set_tooltip_text(alternative_string);
725 // Set views' bounds
726 gfx::Rect view_bounds(view_->GetLocalBounds());
727 view_bounds.set_height(view_bounds.height() / 2);
728 v1->SetBoundsRect(view_bounds);
729 v1_1->SetBounds(0, 0, 3, 3);
730 view_bounds.set_y(view_bounds.height());
731 v2->SetBoundsRect(view_bounds);
732 v2_2->SetBounds(view_bounds.width() - 3, view_bounds.height() - 3, 3, 3);
733 v2_1->SetBounds(0, 0, 3, 3);
735 // Test whether a toolbar appears on v1
736 gfx::Point center = v1->bounds().CenterPoint();
737 generator_->MoveMouseRelativeTo(GetWindow(), center);
738 helper_->FireTooltipTimer();
739 EXPECT_TRUE(helper_->IsTooltipVisible());
740 EXPECT_EQ(reference_string, helper_->GetTooltipText());
741 gfx::Point tooltip_bounds1 = test_tooltip_->location();
743 // Test whether the toolbar changes position on mouse over v2
744 center = v2->bounds().CenterPoint();
745 generator_->MoveMouseRelativeTo(GetWindow(), center);
746 helper_->FireTooltipTimer();
747 EXPECT_TRUE(helper_->IsTooltipVisible());
748 EXPECT_EQ(reference_string, helper_->GetTooltipText());
749 gfx::Point tooltip_bounds2 = test_tooltip_->location();
751 EXPECT_NE(tooltip_bounds1, gfx::Point());
752 EXPECT_NE(tooltip_bounds2, gfx::Point());
753 EXPECT_NE(tooltip_bounds1, tooltip_bounds2);
755 // Test if the toolbar does not change position on encountering a contained
756 // view with the same tooltip text
757 center = v2_1->GetLocalBounds().CenterPoint();
758 views::View::ConvertPointToTarget(v2_1, view_, &center);
759 generator_->MoveMouseRelativeTo(GetWindow(), center);
760 helper_->FireTooltipTimer();
761 gfx::Point tooltip_bounds2_1 = test_tooltip_->location();
763 EXPECT_NE(tooltip_bounds2, tooltip_bounds2_1);
764 EXPECT_TRUE(helper_->IsTooltipVisible());
765 EXPECT_EQ(reference_string, helper_->GetTooltipText());
767 // Test if the toolbar changes position on encountering a contained
768 // view with a different tooltip text
769 center = v2_2->GetLocalBounds().CenterPoint();
770 views::View::ConvertPointToTarget(v2_2, view_, &center);
771 generator_->MoveMouseRelativeTo(GetWindow(), center);
772 helper_->FireTooltipTimer();
773 gfx::Point tooltip_bounds2_2 = test_tooltip_->location();
775 EXPECT_NE(tooltip_bounds2_1, tooltip_bounds2_2);
776 EXPECT_TRUE(helper_->IsTooltipVisible());
777 EXPECT_EQ(alternative_string, helper_->GetTooltipText());
779 // Test if moving from a view that is contained by a larger view, both with
780 // the same tooltip text, does not change tooltip's position.
781 center = v1_1->GetLocalBounds().CenterPoint();
782 views::View::ConvertPointToTarget(v1_1, view_, &center);
783 generator_->MoveMouseRelativeTo(GetWindow(), center);
784 helper_->FireTooltipTimer();
785 gfx::Point tooltip_bounds1_1 = test_tooltip_->location();
787 EXPECT_TRUE(helper_->IsTooltipVisible());
788 EXPECT_EQ(reference_string, helper_->GetTooltipText());
790 center = v1->bounds().CenterPoint();
791 generator_->MoveMouseRelativeTo(GetWindow(), center);
792 helper_->FireTooltipTimer();
793 tooltip_bounds1 = test_tooltip_->location();
795 EXPECT_NE(tooltip_bounds1_1, tooltip_bounds1);
796 EXPECT_EQ(reference_string, helper_->GetTooltipText());
799 } // namespace test
800 } // namespace corewm
801 } // namespace views