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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « views/widget/widget.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: views/widget/widget_unittest.cc
===================================================================
--- views/widget/widget_unittest.cc (revision 0)
+++ views/widget/widget_unittest.cc (revision 0)
@@ -0,0 +1,362 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "views/widget/native_widget_views.h"
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "views/test/test_views_delegate.h"
+#include "views/views_delegate.h"
+
+#if defined(OS_WIN)
+#include "views/widget/native_widget_win.h"
+#elif defined(TOOLKIT_USES_GTK)
+#include "views/widget/native_widget_gtk.h"
+#endif
+
+namespace views {
+namespace {
+
+class WidgetTestViewsDelegate : public TestViewsDelegate {
+ public:
+ WidgetTestViewsDelegate() : default_parent_view_(NULL) {
+ }
+ virtual ~WidgetTestViewsDelegate() {}
+
+ void set_default_parent_view(View* default_parent_view) {
+ default_parent_view_ = default_parent_view;
+ }
+
+ // Overridden from TestViewsDelegate:
+ virtual View* GetDefaultParentView() OVERRIDE {
+ return default_parent_view_;
+ }
+
+ private:
+ View* default_parent_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetTestViewsDelegate);
+};
+
+class WidgetTest : public testing::Test {
+ public:
+ WidgetTest() {
+#if defined(OS_WIN)
+ OleInitialize(NULL);
+#endif
+ }
+ virtual ~WidgetTest() {
+#if defined(OS_WIN)
+ OleUninitialize();
+#endif
+ }
+
+ virtual void TearDown() {
+ // Flush the message loop because we have pending release tasks
+ // and these tasks if un-executed would upset Valgrind.
+ RunPendingMessages();
+ }
+
+ void RunPendingMessages() {
+ message_loop_.RunAllPending();
+ }
+
+ protected:
+ WidgetTestViewsDelegate views_delegate;
+
+ private:
+ MessageLoopForUI message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetTest);
+};
+
+NativeWidget* CreatePlatformNativeWidget(
+ internal::NativeWidgetDelegate* delegate) {
+#if defined(OS_WIN)
+ return new NativeWidgetWin(delegate);
+#elif defined(TOOLKIT_USES_GTK)
+ return new NativeWidgetGtk(delegate);
+#endif
+}
+
+Widget* CreateTopLevelPlatformWidget() {
+ Widget* toplevel = new Widget;
+ Widget::InitParams toplevel_params(Widget::InitParams::TYPE_WINDOW);
+ toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel);
+ toplevel->Init(toplevel_params);
+ return toplevel;
+}
+
+Widget* CreateChildPlatformWidget(gfx::NativeView parent_native_view) {
+ Widget* child = new Widget;
+ Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
+ child_params.native_widget = CreatePlatformNativeWidget(child);
+ child_params.parent = parent_native_view;
+ child->Init(child_params);
+ return child;
+}
+
+Widget* CreateChildNativeWidgetViews() {
+ Widget* child = new Widget;
+ Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
+ child_params.native_widget = new NativeWidgetViews(child);
+ child->Init(child_params);
+ return child;
+}
+
+TEST_F(WidgetTest, GetTopLevelWidget_Native) {
+ // Create a hierarchy of native widgets.
+ Widget* toplevel = CreateTopLevelPlatformWidget();
+#if defined(OS_WIN)
+ gfx::NativeView parent = toplevel->GetNativeView();
+#elif defined(TOOLKIT_USES_GTK)
+ NativeWidgetGtk* native_widget =
+ static_cast<NativeWidgetGtk*>(toplevel->native_widget());
+ gfx::NativeView parent = native_widget->window_contents();
+#endif
+ Widget* child = CreateChildPlatformWidget(parent);
+
+ EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
+ EXPECT_EQ(toplevel, child->GetTopLevelWidget());
+
+ toplevel->CloseNow();
+ // |child| should be automatically destroyed with |toplevel|.
+}
+
+TEST_F(WidgetTest, GetTopLevelWidget_Synthetic) {
+ // Create a hierarchy consisting of a top level platform native widget and a
+ // child NativeWidgetViews.
+ Widget* toplevel = CreateTopLevelPlatformWidget();
+ views_delegate.set_default_parent_view(toplevel->GetRootView());
+ Widget* child = CreateChildNativeWidgetViews();
+
+ EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
+ EXPECT_EQ(child, child->GetTopLevelWidget());
+
+ toplevel->CloseNow();
+ // |child| should be automatically destroyed with |toplevel|.
+}
+
+// TODO(beng): write test cases for child NativeWidgetViews parented to
+// arbitrary views that aren't the default parent view.
+
+////////////////////////////////////////////////////////////////////////////////
+// Widget ownership tests.
+//
+// Tests various permutations of Widget ownership specified in the
+// InitParams::Ownership param.
+
+// A WidgetTest that supplies a toplevel widget for NativeWidgetViews to parent
+// to.
+class WidgetOwnershipTest : public WidgetTest {
+ public:
+ WidgetOwnershipTest() {}
+ virtual ~WidgetOwnershipTest() {}
+
+ virtual void SetUp() {
+ desktop_widget_ = CreateTopLevelPlatformWidget();
+ views_delegate.set_default_parent_view(desktop_widget_->GetRootView());
+ }
+
+ virtual void TearDown() {
+ desktop_widget_->CloseNow();
+ WidgetTest::TearDown();
+ }
+
+ private:
+ Widget* desktop_widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetOwnershipTest);
+};
+
+// A bag of state to monitor destructions.
+struct OwnershipTestState {
+ OwnershipTestState() : widget_deleted(false), native_widget_deleted(false) {}
+
+ bool widget_deleted;
+ bool native_widget_deleted;
+};
+
+// A platform NativeWidget subclass that updates a bag of state when it is
+// destroyed.
+class OwnershipTestNativeWidget :
+#if defined(OS_WIN)
+ public NativeWidgetWin {
+#elif defined(TOOLKIT_USES_GTK)
+ public NativeWidgetGtk {
+#endif
+public:
+ OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
+ OwnershipTestState* state)
+#if defined(OS_WIN)
+ : NativeWidgetWin(delegate),
+#elif defined(TOOLKIT_USES_GTK)
+ : NativeWidgetGtk(delegate),
+#endif
+ state_(state) {
+ }
+ virtual ~OwnershipTestNativeWidget() {
+ state_->native_widget_deleted = true;
+ }
+
+ private:
+ OwnershipTestState* state_;
+
+ DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
+};
+
+// A views NativeWidget subclass that updates a bag of state when it is
+// destroyed.
+class OwnershipTestNativeWidgetViews : public NativeWidgetViews {
+ public:
+ OwnershipTestNativeWidgetViews(internal::NativeWidgetDelegate* delegate,
+ OwnershipTestState* state)
+ : NativeWidgetViews(delegate),
+ state_(state) {
+ }
+ virtual ~OwnershipTestNativeWidgetViews() {
+ state_->native_widget_deleted = true;
+ }
+
+ private:
+ OwnershipTestState* state_;
+
+ DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetViews);
+};
+
+// A Widget subclass that updates a bag of state when it is destroyed.
+class OwnershipTestWidget : public Widget {
+ public:
+ OwnershipTestWidget(OwnershipTestState* state) : state_(state) {}
+ virtual ~OwnershipTestWidget() {
+ state_->widget_deleted = true;
+ }
+
+ private:
+ OwnershipTestState* state_;
+
+ DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
+};
+
+// Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
+// widget.
+TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
+ OwnershipTestState state;
+
+ scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.native_widget = new OwnershipTestNativeWidget(widget.get(), &state);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget->Init(params);
+
+ // Now delete the Widget, which should delete the NativeWidget.
+ widget.reset();
+
+ EXPECT_TRUE(state.widget_deleted);
+ EXPECT_TRUE(state.native_widget_deleted);
+
+ // TODO(beng): write test for this ownership scenario and the NativeWidget
+ // being deleted out from under the Widget.
+}
+
+// Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidgetViews.
+TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
+ OwnershipTestState state;
+
+ scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.native_widget =
+ new OwnershipTestNativeWidgetViews(widget.get(), &state);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget->Init(params);
+
+ // Now delete the Widget, which should delete the NativeWidget.
+ widget.reset();
+
+ EXPECT_TRUE(state.widget_deleted);
+ EXPECT_TRUE(state.native_widget_deleted);
+
+ // TODO(beng): write test for this ownership scenario and the NativeWidget
+ // being deleted out from under the Widget.
+}
+
+// NativeWidget owns its Widget, part 1: NativeWidget is a platform-native
+// widget.
+TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
+ OwnershipTestState state;
+
+ Widget* widget = new OwnershipTestWidget(&state);
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.native_widget = new OwnershipTestNativeWidget(widget, &state);
+ widget->Init(params);
+
+ // Now destroy the native widget.
+ widget->CloseNow();
+
+ EXPECT_TRUE(state.widget_deleted);
+ EXPECT_TRUE(state.native_widget_deleted);
+}
+
+// NativeWidget owns its Widget, part 2: NativeWidget is a NativeWidgetViews.
+TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
+ OwnershipTestState state;
+
+ Widget* widget = new OwnershipTestWidget(&state);
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.native_widget = new OwnershipTestNativeWidgetViews(widget, &state);
+ widget->Init(params);
+
+ // Now destroy the native widget.
+ widget->CloseNow();
+
+ EXPECT_TRUE(state.widget_deleted);
+ EXPECT_TRUE(state.native_widget_deleted);
+}
+
+// NativeWidget owns its Widget, part 3: NativeWidget is a platform-native
+// widget, destroyed out from under it by the OS.
+TEST_F(WidgetOwnershipTest,
+ Ownership_PlatformNativeWidgetOwnsWidget_NativeDestroy) {
+ OwnershipTestState state;
+
+ Widget* widget = new OwnershipTestWidget(&state);
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.native_widget = new OwnershipTestNativeWidget(widget, &state);
+ widget->Init(params);
+
+ // Now simulate a destroy of the platform native widget from the OS:
+#if defined(OS_WIN)
+ DestroyWindow(widget->GetNativeView());
+#elif defined(TOOLKIT_USES_GTK)
+ gtk_widget_destroy(widget->GetNativeView());
+#endif
+
+ EXPECT_TRUE(state.widget_deleted);
+ EXPECT_TRUE(state.native_widget_deleted);
+}
+
+// NativeWidget owns its Widget, part 4: NativeWidget is a NativeWidgetViews,
+// destroyed by the view hierarchy that contains it.
+TEST_F(WidgetOwnershipTest,
+ Ownership_ViewsNativeWidgetOwnsWidget_NativeDestroy) {
+ OwnershipTestState state;
+
+ Widget* widget = new OwnershipTestWidget(&state);
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.native_widget = new OwnershipTestNativeWidgetViews(widget, &state);
+ widget->Init(params);
+
+ // Now simulate a destroy of the NativeWidgetView from its parent.
+ NativeWidgetViews* native_widget =
+ static_cast<NativeWidgetViews*>(widget->native_widget());
+ delete native_widget->GetView();
+
+ EXPECT_TRUE(state.widget_deleted);
+ EXPECT_TRUE(state.native_widget_deleted);
+}
+
+} // namespace
+} // namespace views
Property changes on: views\widget\widget_unittest.cc
___________________________________________________________________
Added: svn:eol-style
+ LF
« 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