• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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.
4 
5 #include "chrome/test/base/view_event_test_base.h"
6 
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/test/base/chrome_unit_test_suite.h"
10 #include "chrome/test/base/interactive_test_utils.h"
11 #include "chrome/test/base/testing_browser_process.h"
12 #include "chrome/test/base/view_event_test_platform_part.h"
13 #include "ui/base/ime/input_method_initializer.h"
14 #include "ui/base/test/ui_controls.h"
15 #include "ui/compositor/test/context_factories_for_test.h"
16 #include "ui/views/view.h"
17 #include "ui/views/widget/widget.h"
18 
19 namespace {
20 
21 // View subclass that allows you to specify the preferred size.
22 class TestView : public views::View {
23  public:
TestView()24   TestView() {}
25 
SetPreferredSize(const gfx::Size & size)26   void SetPreferredSize(const gfx::Size& size) {
27     preferred_size_ = size;
28     PreferredSizeChanged();
29   }
30 
GetPreferredSize() const31   virtual gfx::Size GetPreferredSize() const OVERRIDE {
32     if (!preferred_size_.IsEmpty())
33       return preferred_size_;
34     return View::GetPreferredSize();
35   }
36 
Layout()37   virtual void Layout() OVERRIDE {
38     View* child_view = child_at(0);
39     child_view->SetBounds(0, 0, width(), height());
40   }
41 
42  private:
43   gfx::Size preferred_size_;
44 
45   DISALLOW_COPY_AND_ASSIGN(TestView);
46 };
47 
48 // Delay in background thread before posting mouse move.
49 const int kMouseMoveDelayMS = 200;
50 
51 }  // namespace
52 
ViewEventTestBase()53 ViewEventTestBase::ViewEventTestBase()
54   : window_(NULL),
55     content_view_(NULL) {
56   // The TestingBrowserProcess must be created in the constructor because there
57   // are tests that require it before SetUp() is called.
58   TestingBrowserProcess::CreateInstance();
59 }
60 
Done()61 void ViewEventTestBase::Done() {
62   base::MessageLoop::current()->Quit();
63 
64   // If we're in a nested message loop, as is the case with menus, we
65   // need to quit twice. The second quit does that for us. Finish all
66   // pending UI events before posting closure because events it may be
67   // executed before UI events are executed.
68   ui_controls::RunClosureAfterAllPendingUIEvents(
69       base::MessageLoop::QuitClosure());
70 }
71 
SetUpTestCase()72 void ViewEventTestBase::SetUpTestCase() {
73   ChromeUnitTestSuite::InitializeProviders();
74   ChromeUnitTestSuite::InitializeResourceBundle();
75 }
76 
SetUp()77 void ViewEventTestBase::SetUp() {
78   views::ViewsDelegate::views_delegate = &views_delegate_;
79   ui::InitializeInputMethodForTesting();
80 
81   // The ContextFactory must exist before any Compositors are created.
82   bool enable_pixel_output = false;
83   ui::ContextFactory* context_factory =
84       ui::InitializeContextFactoryForTests(enable_pixel_output);
85 
86   platform_part_.reset(ViewEventTestPlatformPart::Create(context_factory));
87   gfx::NativeWindow context = platform_part_->GetContext();
88   window_ = views::Widget::CreateWindowWithContext(this, context);
89 }
90 
TearDown()91 void ViewEventTestBase::TearDown() {
92   if (window_) {
93     window_->Close();
94     content::RunAllPendingInMessageLoop();
95     window_ = NULL;
96   }
97 
98   ui::Clipboard::DestroyClipboardForCurrentThread();
99   platform_part_.reset();
100 
101   ui::TerminateContextFactoryForTests();
102 
103   ui::ShutdownInputMethodForTesting();
104   views::ViewsDelegate::views_delegate = NULL;
105 }
106 
CanResize() const107 bool ViewEventTestBase::CanResize() const {
108   return true;
109 }
110 
GetContentsView()111 views::View* ViewEventTestBase::GetContentsView() {
112   if (!content_view_) {
113     // Wrap the real view (as returned by CreateContentsView) in a View so
114     // that we can customize the preferred size.
115     TestView* test_view = new TestView();
116     test_view->SetPreferredSize(GetPreferredSize());
117     test_view->AddChildView(CreateContentsView());
118     content_view_ = test_view;
119   }
120   return content_view_;
121 }
122 
GetWidget() const123 const views::Widget* ViewEventTestBase::GetWidget() const {
124   return content_view_->GetWidget();
125 }
126 
GetWidget()127 views::Widget* ViewEventTestBase::GetWidget() {
128   return content_view_->GetWidget();
129 }
130 
~ViewEventTestBase()131 ViewEventTestBase::~ViewEventTestBase() {
132   TestingBrowserProcess::DeleteInstance();
133 }
134 
StartMessageLoopAndRunTest()135 void ViewEventTestBase::StartMessageLoopAndRunTest() {
136   ASSERT_TRUE(
137       ui_test_utils::ShowAndFocusNativeWindow(window_->GetNativeWindow()));
138 
139   // Flush any pending events to make sure we start with a clean slate.
140   content::RunAllPendingInMessageLoop();
141 
142   // Schedule a task that starts the test. Need to do this as we're going to
143   // run the message loop.
144   base::MessageLoop::current()->PostTask(
145       FROM_HERE, base::Bind(&ViewEventTestBase::DoTestOnMessageLoop, this));
146 
147   content::RunMessageLoop();
148 }
149 
GetPreferredSize() const150 gfx::Size ViewEventTestBase::GetPreferredSize() const {
151   return gfx::Size();
152 }
153 
ScheduleMouseMoveInBackground(int x,int y)154 void ViewEventTestBase::ScheduleMouseMoveInBackground(int x, int y) {
155   if (!dnd_thread_.get()) {
156     dnd_thread_.reset(new base::Thread("mouse-move-thread"));
157     dnd_thread_->Start();
158   }
159   dnd_thread_->message_loop()->PostDelayedTask(
160       FROM_HERE,
161       base::Bind(base::IgnoreResult(&ui_controls::SendMouseMove), x, y),
162       base::TimeDelta::FromMilliseconds(kMouseMoveDelayMS));
163 }
164 
StopBackgroundThread()165 void ViewEventTestBase::StopBackgroundThread() {
166   dnd_thread_.reset(NULL);
167 }
168 
RunTestMethod(const base::Closure & task)169 void ViewEventTestBase::RunTestMethod(const base::Closure& task) {
170   StopBackgroundThread();
171 
172   task.Run();
173   if (HasFatalFailure())
174     Done();
175 }
176