message_center_view_unittest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright 2013 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 <map> 6 7#include "base/logging.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/utf_string_conversions.h" 10#include "testing/gtest/include/gtest/gtest.h" 11#include "ui/message_center/fake_message_center.h" 12#include "ui/message_center/notification.h" 13#include "ui/message_center/notification_list.h" 14#include "ui/message_center/notification_types.h" 15#include "ui/message_center/views/message_center_view.h" 16#include "ui/message_center/views/notification_view.h" 17 18namespace message_center { 19 20/* Types **********************************************************************/ 21 22enum CallType { 23 GET_PREFERRED_SIZE, 24 GET_HEIGHT_FOR_WIDTH, 25 LAYOUT 26}; 27 28/* Instrumented/Mock NotificationView subclass ********************************/ 29 30class MockNotificationView : public NotificationView { 31 public: 32 class Test { 33 public: 34 virtual void RegisterCall(int receiver_id, CallType type) = 0; 35 }; 36 37 explicit MockNotificationView(const Notification& notification, 38 MessageCenter* message_center, 39 Test* test, 40 int view_id); 41 virtual ~MockNotificationView(); 42 43 virtual gfx::Size GetPreferredSize() OVERRIDE; 44 virtual int GetHeightForWidth(int w) OVERRIDE; 45 virtual void Layout() OVERRIDE; 46 47 int get_id() { return id_; }; 48 49 private: 50 void RegisterCall(CallType type); 51 52 Test* test_; 53 int id_; 54 55 DISALLOW_COPY_AND_ASSIGN(MockNotificationView); 56}; 57 58MockNotificationView::MockNotificationView(const Notification& notification, 59 MessageCenter* message_center, 60 Test* test, 61 int view_id) 62 : NotificationView(notification, message_center, true), 63 test_(test), 64 id_(view_id) { 65} 66 67MockNotificationView::~MockNotificationView() { 68} 69 70gfx::Size MockNotificationView::GetPreferredSize() { 71 RegisterCall(GET_PREFERRED_SIZE); 72 return child_count() ? NotificationView::GetPreferredSize() : 73 gfx::Size(id_, id_); 74} 75 76int MockNotificationView::GetHeightForWidth(int width) { 77 RegisterCall(GET_HEIGHT_FOR_WIDTH); 78 return child_count() ? NotificationView::GetHeightForWidth(width) : (id_); 79} 80 81void MockNotificationView::Layout() { 82 RegisterCall(LAYOUT); 83 if (child_count()) 84 NotificationView::Layout(); 85} 86 87void MockNotificationView::RegisterCall(CallType type) { 88 if (test_) 89 test_->RegisterCall(id_, type); 90} 91 92/* Test fixture ***************************************************************/ 93 94class MessageCenterViewTest : public testing::Test, 95 public MockNotificationView::Test { 96 public: 97 MessageCenterViewTest(); 98 virtual ~MessageCenterViewTest(); 99 100 virtual void SetUp() OVERRIDE; 101 virtual void TearDown() OVERRIDE; 102 103 MessageCenterView* GetMessageCenterView(); 104 int GetNotificationCount(); 105 int GetCallCount(CallType type); 106 107 virtual void RegisterCall(int receiver_id, CallType type) OVERRIDE; 108 109 void LogBounds(int depth, views::View* view); 110 111 private: 112 views::View* MakeParent(views::View* child1, views::View* child2); 113 114 115 scoped_ptr<MessageCenterView> message_center_view_; 116 FakeMessageCenter message_center_; 117 std::map<CallType,int> callCounts_; 118 119 DISALLOW_COPY_AND_ASSIGN(MessageCenterViewTest); 120}; 121 122MessageCenterViewTest::MessageCenterViewTest() { 123} 124 125MessageCenterViewTest::~MessageCenterViewTest() { 126} 127 128void MessageCenterViewTest::SetUp() { 129 // Create a dummy notification. 130 Notification notification( 131 NOTIFICATION_TYPE_SIMPLE, 132 std::string("notification id"), 133 UTF8ToUTF16("title"), 134 UTF8ToUTF16("message"), 135 UTF8ToUTF16("display source"), 136 std::string("extension id"), 137 NULL); 138 139 // ...and a list for it. 140 NotificationList::Notifications notifications; 141 notifications.insert(¬ification); 142 143 // Then create a new MessageCenterView with that single notification. 144 message_center_view_.reset(new MessageCenterView(&message_center_, 100)); 145 message_center_view_->SetNotifications(notifications); 146 147 // Remove and delete the NotificationView now owned by the MessageCenterView's 148 // MessageListView and replace it with an instrumented MockNotificationView 149 // that will become owned by the MessageListView. 150 MockNotificationView* mock; 151 mock = new MockNotificationView(notification, &message_center_, this, 42); 152 message_center_view_->message_views_.push_back(mock); 153 message_center_view_->SetNotificationViewForTest(mock); 154} 155 156void MessageCenterViewTest::TearDown() { 157 message_center_view_.reset(); 158} 159 160MessageCenterView* MessageCenterViewTest::GetMessageCenterView() { 161 return message_center_view_.get(); 162} 163 164int MessageCenterViewTest::GetNotificationCount() { 165 return 1; 166} 167 168int MessageCenterViewTest::GetCallCount(CallType type) { 169 return callCounts_[type]; 170} 171 172void MessageCenterViewTest::RegisterCall(int receiver_id, CallType type) { 173 callCounts_[type] += 1; 174} 175 176void MessageCenterViewTest::LogBounds(int depth, views::View* view) { 177 string16 inset; 178 for (int i = 0; i < depth; ++i) 179 inset.append(UTF8ToUTF16(" ")); 180 gfx::Rect bounds = view->bounds(); 181 DVLOG(0) << inset << bounds.width() << " x " << bounds.height() 182 << " @ " << bounds.x() << ", " << bounds.y(); 183 for (int i = 0; i < view->child_count(); ++i) 184 LogBounds(depth + 1, view->child_at(i)); 185} 186 187/* Unit tests *****************************************************************/ 188 189TEST_F(MessageCenterViewTest, CallTest) { 190 // Exercise (with size values that just need to be large enough). 191 GetMessageCenterView()->SetBounds(0, 0, 100, 100); 192 193 // Verify that this didn't generate more than 2 Layout() call per descendant 194 // NotificationView or more than a total of 20 GetPreferredSize() and 195 // GetHeightForWidth() calls per descendant NotificationView. 20 is a very 196 // large number corresponding to the current reality. That number will be 197 // ratcheted down over time as the code improves. 198 EXPECT_LE(GetCallCount(LAYOUT), GetNotificationCount() * 2); 199 EXPECT_LE(GetCallCount(GET_PREFERRED_SIZE) + 200 GetCallCount(GET_HEIGHT_FOR_WIDTH), 201 GetNotificationCount() * 20); 202} 203 204} // namespace message_center 205