OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 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 #ifndef CHROME_TEST_INTERACTIVE_UI_VIEW_EVENT_TEST_BASE_H_ | |
6 #define CHROME_TEST_INTERACTIVE_UI_VIEW_EVENT_TEST_BASE_H_ | |
7 #pragma once | |
8 | |
9 // We only want to use ViewEventTestBase in test targets which properly | |
10 // isolate each test case by running each test in a separate process. | |
11 // This way if a test hangs the test launcher can reliably terminate it. | |
12 #if defined(HAS_OUT_OF_PROC_TEST_RUNNER) | |
13 | |
14 #include "base/message_loop.h" | |
15 #include "base/task.h" | |
16 #include "base/threading/thread.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 #include "views/widget/widget_delegate.h" | |
19 | |
20 class Task; | |
21 | |
22 namespace gfx { | |
23 class Size; | |
24 } | |
25 | |
26 // Base class for Views based tests that dispatch events. | |
27 // | |
28 // As views based event test involves waiting for events to be processed, | |
29 // writing a views based test is slightly different than that of writing | |
30 // other unit tests. In particular when the test fails or is done you need | |
31 // to stop the message loop. This can be done by way of invoking the Done | |
32 // method. | |
33 // | |
34 // Any delayed callbacks should be done by way of CreateEventTask. | |
35 // CreateEventTask checks to see if ASSERT_XXX has been invoked after invoking | |
36 // the task. If there was a failure Done is invoked and the test stops. | |
37 // | |
38 // ViewEventTestBase creates a Window with the View returned from | |
39 // CreateContentsView. The preferred size for the view can be customized by | |
40 // overriding GetPreferredSize. If you do not override GetPreferredSize the | |
41 // preferred size of the view returned from CreateContentsView is used. | |
42 // | |
43 // Subclasses of ViewEventTestBase must implement two methods: | |
44 // . DoTestOnMessageLoop: invoked when the message loop is running. Run your | |
45 // test here, invoke Done when done. | |
46 // . CreateContentsView: returns the view to place in the window. | |
47 // | |
48 // Once you have created a ViewEventTestBase use the macro VIEW_TEST to define | |
49 // the fixture. | |
50 // | |
51 // I encountered weird timing problems in initiating dragging and drop that | |
52 // necessitated ugly hacks. In particular when the hook installed by | |
53 // ui_controls received the mouse event and posted a task that task was not | |
54 // processed. To work around this use the following pattern when initiating | |
55 // dnd: | |
56 // // Schedule the mouse move at a location slightly different from where | |
57 // // you really want to move to. | |
58 // ui_controls::SendMouseMoveNotifyWhenDone(loc.x + 10, loc.y, | |
59 // NewRunnableMethod(this, YYY)); | |
60 // // Then use this to schedule another mouse move. | |
61 // ScheduleMouseMoveInBackground(loc.x, loc.y); | |
62 | |
63 class ViewEventTestBase : public views::WidgetDelegate, | |
64 public testing::Test { | |
65 public: | |
66 ViewEventTestBase(); | |
67 | |
68 // Invoke when done either because of failure or success. Quits the message | |
69 // loop. | |
70 void Done(); | |
71 | |
72 // Creates a window. | |
73 virtual void SetUp(); | |
74 | |
75 // Destroys the window. | |
76 virtual void TearDown(); | |
77 | |
78 // Overridden from views::WidgetDelegate: | |
79 virtual bool CanResize() const OVERRIDE; | |
80 virtual views::View* GetContentsView() OVERRIDE; | |
81 virtual const views::Widget* GetWidget() const OVERRIDE; | |
82 virtual views::Widget* GetWidget() OVERRIDE; | |
83 | |
84 // Overriden to do nothing so that this class can be used in runnable tasks. | |
85 void AddRef() {} | |
86 void Release() {} | |
87 static bool ImplementsThreadSafeReferenceCounting() { return false; } | |
88 | |
89 protected: | |
90 virtual ~ViewEventTestBase(); | |
91 | |
92 // Returns the view that is added to the window. | |
93 virtual views::View* CreateContentsView() = 0; | |
94 | |
95 // Called once the message loop is running. | |
96 virtual void DoTestOnMessageLoop() = 0; | |
97 | |
98 // Invoke from test main. Shows the window, starts the message loop and | |
99 // schedules a task that invokes DoTestOnMessageLoop. | |
100 void StartMessageLoopAndRunTest(); | |
101 | |
102 // Returns an empty Size. Subclasses that want a preferred size other than | |
103 // that of the View returned by CreateContentsView should override this | |
104 // appropriately. | |
105 virtual gfx::Size GetPreferredSize(); | |
106 | |
107 // Creates a task that calls the specified method back. The specified | |
108 // method is called in such a way that if there are any test failures | |
109 // Done is invoked. | |
110 template <class T, class Method> | |
111 Task* CreateEventTask(T* target, Method method) { | |
112 return NewRunnableMethod(this, &ViewEventTestBase::RunTestMethod, | |
113 NewRunnableMethod(target, method)); | |
114 } | |
115 | |
116 // Spawns a new thread posts a MouseMove in the background. | |
117 void ScheduleMouseMoveInBackground(int x, int y); | |
118 | |
119 views::Widget* window_; | |
120 | |
121 private: | |
122 // Stops the thread started by ScheduleMouseMoveInBackground. | |
123 void StopBackgroundThread(); | |
124 | |
125 // Callback from CreateEventTask. Stops the background thread, runs the | |
126 // supplied task and if there are failures invokes Done. | |
127 void RunTestMethod(Task* task); | |
128 | |
129 // The content of the Window. | |
130 views::View* content_view_; | |
131 | |
132 // Thread for posting background MouseMoves. | |
133 scoped_ptr<base::Thread> dnd_thread_; | |
134 | |
135 MessageLoopForUI message_loop_; | |
136 | |
137 // Method factory used for time-outs. | |
138 ScopedRunnableMethodFactory<ViewEventTestBase> method_factory_; | |
139 | |
140 DISALLOW_COPY_AND_ASSIGN(ViewEventTestBase); | |
141 }; | |
142 | |
143 // Convenience macro for defining a ViewEventTestBase. See class description | |
144 // of ViewEventTestBase for details. | |
145 #define VIEW_TEST(test_class, name) \ | |
146 TEST_F(test_class, name) {\ | |
147 StartMessageLoopAndRunTest();\ | |
148 } | |
149 | |
150 #endif // defined(HAS_OUT_OF_PROC_TEST_RUNNER) | |
151 | |
152 #endif // CHROME_TEST_INTERACTIVE_UI_VIEW_EVENT_TEST_BASE_H_ | |
OLD | NEW |