summaryrefslogtreecommitdiffstats
path: root/views/view_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'views/view_unittest.cc')
-rw-r--r--views/view_unittest.cc139
1 files changed, 139 insertions, 0 deletions
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 605d4838..1f4cfc1 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -16,6 +16,7 @@
#if defined(OS_WIN)
#include "views/controls/button/native_button_win.h"
#endif
+#include "views/controls/native/native_view_host.h"
#include "views/controls/scroll_view.h"
#include "views/controls/textfield/textfield.h"
#include "views/event.h"
@@ -59,6 +60,9 @@ class ViewTest : public testing::Test {
#endif
}
+ void RunPendingMessages() {
+ message_loop_.RunAllPending();
+ }
private:
MessageLoopForUI message_loop_;
};
@@ -1207,3 +1211,138 @@ TEST_F(ViewTest, ChangeVisibility) {
native->SetVisible(true);
}
*/
+
+////////////////////////////////////////////////////////////////////////////////
+// Native view hierachy
+////////////////////////////////////////////////////////////////////////////////
+class TestNativeViewHierarchy : public views::View {
+ public:
+ TestNativeViewHierarchy() {
+ }
+
+ virtual void NativeViewHierarchyChanged(bool attached,
+ gfx::NativeView native_view,
+ RootView* root_view) {
+ NotificationInfo info;
+ info.attached = attached;
+ info.native_view = native_view;
+ info.root_view = root_view;
+ notifications_.push_back(info);
+ };
+ struct NotificationInfo {
+ bool attached;
+ gfx::NativeView native_view;
+ RootView* root_view;
+ };
+ static const size_t kTotalViews = 2;
+ std::vector<NotificationInfo> notifications_;
+};
+
+class TestChangeNativeViewHierarchy {
+ public:
+ explicit TestChangeNativeViewHierarchy(ViewTest *view_test) {
+ view_test_ = view_test;
+ native_host_ = new views::NativeViewHost();
+ host_ = view_test->CreateWidget();
+ host_->Init(NULL, gfx::Rect(0, 0, 500, 300));
+ host_->GetRootView()->AddChildView(native_host_);
+ for (size_t i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
+ windows_[i] = view_test->CreateWidget();
+ windows_[i]->Init(host_->GetNativeView(), gfx::Rect(0, 0, 500, 300));
+ root_views_[i] = windows_[i]->GetRootView();
+ test_views_[i] = new TestNativeViewHierarchy;
+ root_views_[i]->AddChildView(test_views_[i]);
+ }
+ }
+
+ ~TestChangeNativeViewHierarchy() {
+ for (size_t i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
+ windows_[i]->Close();
+ }
+ host_->Close();
+ // Will close and self-delete widgets - no need to manually delete them.
+ view_test_->RunPendingMessages();
+ }
+
+ void CheckEnumeratingRootViews() {
+ std::vector<RootView*> enumerated_root_views;
+#if defined(OS_WIN)
+ views::Widget::FindAllRootViews(host_->GetNativeView(),
+ &enumerated_root_views);
+#else
+ // host_->GetNativeView() returns gfx::NativeView which is GtkWidget on
+ // systems other than Windows and views::Widget::FindAllRootViews()
+ // requires GtkWindow.
+ if (host_->GetWindow()) {
+ views::Widget::FindAllRootViews(host_->GetWindow()->GetNativeWindow(),
+ &enumerated_root_views);
+ } else {
+ return;
+ }
+#endif
+ EXPECT_EQ(TestNativeViewHierarchy::kTotalViews + 1,
+ enumerated_root_views.size());
+ // Unfortunately there is no guarantee the sequence of views here so always
+ // go through all of them.
+ for (std::vector<RootView*>::iterator i = enumerated_root_views.begin();
+ i != enumerated_root_views.end(); ++i) {
+ if (host_->GetRootView() == *i)
+ continue;
+ size_t j;
+ for (j = 0; j < TestNativeViewHierarchy::kTotalViews; ++j)
+ if (root_views_[j] == *i)
+ break;
+ // EXPECT_LT/GT/GE() fails to compile with class-defined constants
+ // with gcc, with error
+ // "error: undefined reference to 'TestNativeViewHierarchy::kTotalViews'"
+ // so I forced to use EXPECT_TRUE() instead.
+ EXPECT_TRUE(TestNativeViewHierarchy::kTotalViews > j);
+ }
+ }
+
+ void CheckChangingHierarhy() {
+ size_t i;
+ for (i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
+ // TODO(georgey): use actual hierarchy changes to send notifications.
+ root_views_[i]->NotifyNativeViewHierarchyChanged(false,
+ host_->GetNativeView());
+ root_views_[i]->NotifyNativeViewHierarchyChanged(true,
+ host_->GetNativeView());
+ }
+ for (i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
+ ASSERT_EQ(static_cast<size_t>(2), test_views_[i]->notifications_.size());
+ EXPECT_FALSE(test_views_[i]->notifications_[0].attached);
+ EXPECT_EQ(host_->GetNativeView(),
+ test_views_[i]->notifications_[0].native_view);
+ EXPECT_EQ(root_views_[i], test_views_[i]->notifications_[0].root_view);
+ EXPECT_TRUE(test_views_[i]->notifications_[1].attached);
+ EXPECT_EQ(host_->GetNativeView(),
+ test_views_[i]->notifications_[1].native_view);
+ EXPECT_EQ(root_views_[i], test_views_[i]->notifications_[1].root_view);
+ }
+ }
+
+ views::NativeViewHost* native_host_;
+ views::Widget* host_;
+ views::Widget* windows_[TestNativeViewHierarchy::kTotalViews];
+ views::RootView* root_views_[TestNativeViewHierarchy::kTotalViews];
+ TestNativeViewHierarchy* test_views_[TestNativeViewHierarchy::kTotalViews];
+ ViewTest* view_test_;
+};
+
+TEST_F(ViewTest, ChangeNativeViewHierarchyFindRoots) {
+ // TODO(georgey): Fix the test for Linux
+#if defined(OS_WIN)
+ TestChangeNativeViewHierarchy test(this);
+ test.CheckEnumeratingRootViews();
+#endif
+}
+
+TEST_F(ViewTest, ChangeNativeViewHierarchyChangeHierarchy) {
+ // TODO(georgey): Fix the test for Linux
+#if defined(OS_WIN)
+ TestChangeNativeViewHierarchy test(this);
+ test.CheckChangingHierarhy();
+#endif
+}
+