Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Side by Side Diff: views/widget/widget_unittest.cc

Issue 7273084: Change the meaning of "Widget::GetTopLevelWidget()" to mean the logical top level Window in the v... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/widget/widget.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "views/widget/native_widget_views.h"
6
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "views/test/test_views_delegate.h"
12 #include "views/views_delegate.h"
13
14 #if defined(OS_WIN)
15 #include "views/widget/native_widget_win.h"
16 #elif defined(TOOLKIT_USES_GTK)
17 #include "views/widget/native_widget_gtk.h"
18 #endif
19
20 namespace views {
21 namespace {
22
23 class WidgetTestViewsDelegate : public TestViewsDelegate {
24 public:
25 WidgetTestViewsDelegate() : default_parent_view_(NULL) {
26 }
27 virtual ~WidgetTestViewsDelegate() {}
28
29 void set_default_parent_view(View* default_parent_view) {
30 default_parent_view_ = default_parent_view;
31 }
32
33 // Overridden from TestViewsDelegate:
34 virtual View* GetDefaultParentView() OVERRIDE {
35 return default_parent_view_;
36 }
37
38 private:
39 View* default_parent_view_;
40
41 DISALLOW_COPY_AND_ASSIGN(WidgetTestViewsDelegate);
42 };
43
44 class WidgetTest : public testing::Test {
45 public:
46 WidgetTest() {
47 #if defined(OS_WIN)
48 OleInitialize(NULL);
49 #endif
50 }
51 virtual ~WidgetTest() {
52 #if defined(OS_WIN)
53 OleUninitialize();
54 #endif
55 }
56
57 virtual void TearDown() {
58 // Flush the message loop because we have pending release tasks
59 // and these tasks if un-executed would upset Valgrind.
60 RunPendingMessages();
61 }
62
63 void RunPendingMessages() {
64 message_loop_.RunAllPending();
65 }
66
67 protected:
68 WidgetTestViewsDelegate views_delegate;
69
70 private:
71 MessageLoopForUI message_loop_;
72
73 DISALLOW_COPY_AND_ASSIGN(WidgetTest);
74 };
75
76 NativeWidget* CreatePlatformNativeWidget(
77 internal::NativeWidgetDelegate* delegate) {
78 #if defined(OS_WIN)
79 return new NativeWidgetWin(delegate);
80 #elif defined(TOOLKIT_USES_GTK)
81 return new NativeWidgetGtk(delegate);
82 #endif
83 }
84
85 Widget* CreateTopLevelPlatformWidget() {
86 Widget* toplevel = new Widget;
87 Widget::InitParams toplevel_params(Widget::InitParams::TYPE_WINDOW);
88 toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel);
89 toplevel->Init(toplevel_params);
90 return toplevel;
91 }
92
93 Widget* CreateChildPlatformWidget(gfx::NativeView parent_native_view) {
94 Widget* child = new Widget;
95 Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
96 child_params.native_widget = CreatePlatformNativeWidget(child);
97 child_params.parent = parent_native_view;
98 child->Init(child_params);
99 return child;
100 }
101
102 Widget* CreateChildNativeWidgetViews() {
103 Widget* child = new Widget;
104 Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
105 child_params.native_widget = new NativeWidgetViews(child);
106 child->Init(child_params);
107 return child;
108 }
109
110 TEST_F(WidgetTest, GetTopLevelWidget_Native) {
111 // Create a hierarchy of native widgets.
112 Widget* toplevel = CreateTopLevelPlatformWidget();
113 #if defined(OS_WIN)
114 gfx::NativeView parent = toplevel->GetNativeView();
115 #elif defined(TOOLKIT_USES_GTK)
116 NativeWidgetGtk* native_widget =
117 static_cast<NativeWidgetGtk*>(toplevel->native_widget());
118 gfx::NativeView parent = native_widget->window_contents();
119 #endif
120 Widget* child = CreateChildPlatformWidget(parent);
121
122 EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
123 EXPECT_EQ(toplevel, child->GetTopLevelWidget());
124
125 toplevel->CloseNow();
126 // |child| should be automatically destroyed with |toplevel|.
127 }
128
129 TEST_F(WidgetTest, GetTopLevelWidget_Synthetic) {
130 // Create a hierarchy consisting of a top level platform native widget and a
131 // child NativeWidgetViews.
132 Widget* toplevel = CreateTopLevelPlatformWidget();
133 views_delegate.set_default_parent_view(toplevel->GetRootView());
134 Widget* child = CreateChildNativeWidgetViews();
135
136 EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
137 EXPECT_EQ(child, child->GetTopLevelWidget());
138
139 toplevel->CloseNow();
140 // |child| should be automatically destroyed with |toplevel|.
141 }
142
143 // TODO(beng): write test cases for child NativeWidgetViews parented to
144 // arbitrary views that aren't the default parent view.
145
146 ////////////////////////////////////////////////////////////////////////////////
147 // Widget ownership tests.
148 //
149 // Tests various permutations of Widget ownership specified in the
150 // InitParams::Ownership param.
151
152 // A WidgetTest that supplies a toplevel widget for NativeWidgetViews to parent
153 // to.
154 class WidgetOwnershipTest : public WidgetTest {
155 public:
156 WidgetOwnershipTest() {}
157 virtual ~WidgetOwnershipTest() {}
158
159 virtual void SetUp() {
160 desktop_widget_ = CreateTopLevelPlatformWidget();
161 views_delegate.set_default_parent_view(desktop_widget_->GetRootView());
162 }
163
164 virtual void TearDown() {
165 desktop_widget_->CloseNow();
166 WidgetTest::TearDown();
167 }
168
169 private:
170 Widget* desktop_widget_;
171
172 DISALLOW_COPY_AND_ASSIGN(WidgetOwnershipTest);
173 };
174
175 // A bag of state to monitor destructions.
176 struct OwnershipTestState {
177 OwnershipTestState() : widget_deleted(false), native_widget_deleted(false) {}
178
179 bool widget_deleted;
180 bool native_widget_deleted;
181 };
182
183 // A platform NativeWidget subclass that updates a bag of state when it is
184 // destroyed.
185 class OwnershipTestNativeWidget :
186 #if defined(OS_WIN)
187 public NativeWidgetWin {
188 #elif defined(TOOLKIT_USES_GTK)
189 public NativeWidgetGtk {
190 #endif
191 public:
192 OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
193 OwnershipTestState* state)
194 #if defined(OS_WIN)
195 : NativeWidgetWin(delegate),
196 #elif defined(TOOLKIT_USES_GTK)
197 : NativeWidgetGtk(delegate),
198 #endif
199 state_(state) {
200 }
201 virtual ~OwnershipTestNativeWidget() {
202 state_->native_widget_deleted = true;
203 }
204
205 private:
206 OwnershipTestState* state_;
207
208 DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
209 };
210
211 // A views NativeWidget subclass that updates a bag of state when it is
212 // destroyed.
213 class OwnershipTestNativeWidgetViews : public NativeWidgetViews {
214 public:
215 OwnershipTestNativeWidgetViews(internal::NativeWidgetDelegate* delegate,
216 OwnershipTestState* state)
217 : NativeWidgetViews(delegate),
218 state_(state) {
219 }
220 virtual ~OwnershipTestNativeWidgetViews() {
221 state_->native_widget_deleted = true;
222 }
223
224 private:
225 OwnershipTestState* state_;
226
227 DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetViews);
228 };
229
230 // A Widget subclass that updates a bag of state when it is destroyed.
231 class OwnershipTestWidget : public Widget {
232 public:
233 OwnershipTestWidget(OwnershipTestState* state) : state_(state) {}
234 virtual ~OwnershipTestWidget() {
235 state_->widget_deleted = true;
236 }
237
238 private:
239 OwnershipTestState* state_;
240
241 DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
242 };
243
244 // Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
245 // widget.
246 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
247 OwnershipTestState state;
248
249 scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
250 Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
251 params.native_widget = new OwnershipTestNativeWidget(widget.get(), &state);
252 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
253 widget->Init(params);
254
255 // Now delete the Widget, which should delete the NativeWidget.
256 widget.reset();
257
258 EXPECT_TRUE(state.widget_deleted);
259 EXPECT_TRUE(state.native_widget_deleted);
260
261 // TODO(beng): write test for this ownership scenario and the NativeWidget
262 // being deleted out from under the Widget.
263 }
264
265 // Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidgetViews.
266 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
267 OwnershipTestState state;
268
269 scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
270 Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
271 params.native_widget =
272 new OwnershipTestNativeWidgetViews(widget.get(), &state);
273 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
274 widget->Init(params);
275
276 // Now delete the Widget, which should delete the NativeWidget.
277 widget.reset();
278
279 EXPECT_TRUE(state.widget_deleted);
280 EXPECT_TRUE(state.native_widget_deleted);
281
282 // TODO(beng): write test for this ownership scenario and the NativeWidget
283 // being deleted out from under the Widget.
284 }
285
286 // NativeWidget owns its Widget, part 1: NativeWidget is a platform-native
287 // widget.
288 TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
289 OwnershipTestState state;
290
291 Widget* widget = new OwnershipTestWidget(&state);
292 Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
293 params.native_widget = new OwnershipTestNativeWidget(widget, &state);
294 widget->Init(params);
295
296 // Now destroy the native widget.
297 widget->CloseNow();
298
299 EXPECT_TRUE(state.widget_deleted);
300 EXPECT_TRUE(state.native_widget_deleted);
301 }
302
303 // NativeWidget owns its Widget, part 2: NativeWidget is a NativeWidgetViews.
304 TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
305 OwnershipTestState state;
306
307 Widget* widget = new OwnershipTestWidget(&state);
308 Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
309 params.native_widget = new OwnershipTestNativeWidgetViews(widget, &state);
310 widget->Init(params);
311
312 // Now destroy the native widget.
313 widget->CloseNow();
314
315 EXPECT_TRUE(state.widget_deleted);
316 EXPECT_TRUE(state.native_widget_deleted);
317 }
318
319 // NativeWidget owns its Widget, part 3: NativeWidget is a platform-native
320 // widget, destroyed out from under it by the OS.
321 TEST_F(WidgetOwnershipTest,
322 Ownership_PlatformNativeWidgetOwnsWidget_NativeDestroy) {
323 OwnershipTestState state;
324
325 Widget* widget = new OwnershipTestWidget(&state);
326 Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
327 params.native_widget = new OwnershipTestNativeWidget(widget, &state);
328 widget->Init(params);
329
330 // Now simulate a destroy of the platform native widget from the OS:
331 #if defined(OS_WIN)
332 DestroyWindow(widget->GetNativeView());
333 #elif defined(TOOLKIT_USES_GTK)
334 gtk_widget_destroy(widget->GetNativeView());
335 #endif
336
337 EXPECT_TRUE(state.widget_deleted);
338 EXPECT_TRUE(state.native_widget_deleted);
339 }
340
341 // NativeWidget owns its Widget, part 4: NativeWidget is a NativeWidgetViews,
342 // destroyed by the view hierarchy that contains it.
343 TEST_F(WidgetOwnershipTest,
344 Ownership_ViewsNativeWidgetOwnsWidget_NativeDestroy) {
345 OwnershipTestState state;
346
347 Widget* widget = new OwnershipTestWidget(&state);
348 Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
349 params.native_widget = new OwnershipTestNativeWidgetViews(widget, &state);
350 widget->Init(params);
351
352 // Now simulate a destroy of the NativeWidgetView from its parent.
353 NativeWidgetViews* native_widget =
354 static_cast<NativeWidgetViews*>(widget->native_widget());
355 delete native_widget->GetView();
356
357 EXPECT_TRUE(state.widget_deleted);
358 EXPECT_TRUE(state.native_widget_deleted);
359 }
360
361 } // namespace
362 } // namespace views
OLDNEW
« no previous file with comments | « views/widget/widget.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698