| 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 |