Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / test / base / view_event_test_base.h
blob5629c38b28c2737b2d193f64b9c767fb40518931
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.
5 #ifndef CHROME_TEST_BASE_VIEW_EVENT_TEST_BASE_H_
6 #define CHROME_TEST_BASE_VIEW_EVENT_TEST_BASE_H_
8 // We only want to use ViewEventTestBase in test targets which properly
9 // isolate each test case by running each test in a separate process.
10 // This way if a test hangs the test launcher can reliably terminate it.
11 #if defined(HAS_OUT_OF_PROC_TEST_RUNNER)
13 #include "base/bind.h"
14 #include "base/callback.h"
15 #include "base/compiler_specific.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h"
18 #include "base/threading/thread.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/views/test/test_views_delegate.h"
22 #include "ui/views/widget/widget_delegate.h"
24 #if defined(OS_WIN)
25 #include "ui/base/win/scoped_ole_initializer.h"
26 #endif
28 namespace gfx {
29 class Size;
32 class ViewEventTestPlatformPart;
34 // Base class for Views based tests that dispatch events.
36 // As views based event test involves waiting for events to be processed,
37 // writing a views based test is slightly different than that of writing
38 // other unit tests. In particular when the test fails or is done you need
39 // to stop the message loop. This can be done by way of invoking the Done
40 // method.
42 // Any delayed callbacks should be done by way of CreateEventTask.
43 // CreateEventTask checks to see if ASSERT_XXX has been invoked after invoking
44 // the task. If there was a failure Done is invoked and the test stops.
46 // ViewEventTestBase creates a Window with the View returned from
47 // CreateContentsView. The preferred size for the view can be customized by
48 // overriding GetPreferredSize. If you do not override GetPreferredSize the
49 // preferred size of the view returned from CreateContentsView is used.
51 // Subclasses of ViewEventTestBase must implement two methods:
52 // . DoTestOnMessageLoop: invoked when the message loop is running. Run your
53 // test here, invoke Done when done.
54 // . CreateContentsView: returns the view to place in the window.
56 // Once you have created a ViewEventTestBase use the macro VIEW_TEST to define
57 // the fixture.
59 // I encountered weird timing problems in initiating dragging and drop that
60 // necessitated ugly hacks. In particular when the hook installed by
61 // ui_controls received the mouse event and posted a task that task was not
62 // processed. To work around this use the following pattern when initiating
63 // dnd:
64 // // Schedule the mouse move at a location slightly different from where
65 // // you really want to move to.
66 // ui_controls::SendMouseMoveNotifyWhenDone(loc.x + 10, loc.y,
67 // base::Bind(&YYY, this));
68 // // Then use this to schedule another mouse move.
69 // ScheduleMouseMoveInBackground(loc.x, loc.y);
71 class ViewEventTestBase : public views::WidgetDelegate,
72 public testing::Test {
73 public:
74 ViewEventTestBase();
76 // Invoke when done either because of failure or success. Quits the message
77 // loop.
78 void Done();
80 static void SetUpTestCase();
82 // Creates a window.
83 void SetUp() override;
85 // Destroys the window.
86 void TearDown() override;
88 // Returns an empty Size. Subclasses that want a preferred size other than
89 // that of the View returned by CreateContentsView should override this
90 // appropriately.
91 virtual gfx::Size GetPreferredSize() const;
93 // Overridden from views::WidgetDelegate:
94 bool CanResize() const override;
95 views::View* GetContentsView() override;
96 const views::Widget* GetWidget() const override;
97 views::Widget* GetWidget() override;
99 // Overridden to do nothing so that this class can be used in runnable tasks.
100 void AddRef() {}
101 void Release() {}
103 protected:
104 ~ViewEventTestBase() override;
106 // Returns the view that is added to the window.
107 virtual views::View* CreateContentsView() = 0;
109 // Called once the message loop is running.
110 virtual void DoTestOnMessageLoop() = 0;
112 // Invoke from test main. Shows the window, starts the message loop and
113 // schedules a task that invokes DoTestOnMessageLoop.
114 void StartMessageLoopAndRunTest();
116 // Creates a task that calls the specified method back. The specified
117 // method is called in such a way that if there are any test failures
118 // Done is invoked.
119 template <class T, class Method>
120 base::Closure CreateEventTask(T* target, Method method) {
121 return base::Bind(&ViewEventTestBase::RunTestMethod, this,
122 base::Bind(method, target));
125 // Spawns a new thread posts a MouseMove in the background.
126 void ScheduleMouseMoveInBackground(int x, int y);
128 views::Widget* window_;
130 private:
131 // Stops the thread started by ScheduleMouseMoveInBackground.
132 void StopBackgroundThread();
134 // Callback from CreateEventTask. Stops the background thread, runs the
135 // supplied task and if there are failures invokes Done.
136 void RunTestMethod(const base::Closure& task);
138 // The content of the Window.
139 views::View* content_view_;
141 // Thread for posting background MouseMoves.
142 scoped_ptr<base::Thread> dnd_thread_;
144 content::TestBrowserThreadBundle thread_bundle_;
146 #if defined(OS_WIN)
147 ui::ScopedOleInitializer ole_initializer_;
148 #endif
150 scoped_ptr<ViewEventTestPlatformPart> platform_part_;
152 views::TestViewsDelegate views_delegate_;
154 base::RunLoop run_loop_;
156 DISALLOW_COPY_AND_ASSIGN(ViewEventTestBase);
159 // Convenience macro for defining a ViewEventTestBase. See class description
160 // of ViewEventTestBase for details.
161 #define VIEW_TEST(test_class, name) \
162 TEST_F(test_class, name) {\
163 StartMessageLoopAndRunTest();\
166 #endif // defined(HAS_OUT_OF_PROC_TEST_RUNNER)
168 #endif // CHROME_TEST_BASE_VIEW_EVENT_TEST_BASE_H_