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.
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/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"
18 namespace message_center
{
20 /* Types **********************************************************************/
28 /* Instrumented/Mock NotificationView subclass ********************************/
30 class MockNotificationView
: public NotificationView
{
34 virtual void RegisterCall(int receiver_id
, CallType type
) = 0;
37 explicit MockNotificationView(const Notification
& notification
,
38 MessageCenter
* message_center
,
41 virtual ~MockNotificationView();
43 virtual gfx::Size
GetPreferredSize() OVERRIDE
;
44 virtual int GetHeightForWidth(int w
) OVERRIDE
;
45 virtual void Layout() OVERRIDE
;
47 int get_id() { return id_
; };
50 void RegisterCall(CallType type
);
55 DISALLOW_COPY_AND_ASSIGN(MockNotificationView
);
58 MockNotificationView::MockNotificationView(const Notification
& notification
,
59 MessageCenter
* message_center
,
62 : NotificationView(notification
, message_center
, NULL
, true),
67 MockNotificationView::~MockNotificationView() {
70 gfx::Size
MockNotificationView::GetPreferredSize() {
71 RegisterCall(GET_PREFERRED_SIZE
);
72 return child_count() ? NotificationView::GetPreferredSize() :
76 int MockNotificationView::GetHeightForWidth(int width
) {
77 RegisterCall(GET_HEIGHT_FOR_WIDTH
);
78 return child_count() ? NotificationView::GetHeightForWidth(width
) : (id_
);
81 void MockNotificationView::Layout() {
84 NotificationView::Layout();
87 void MockNotificationView::RegisterCall(CallType type
) {
89 test_
->RegisterCall(id_
, type
);
92 /* Test fixture ***************************************************************/
94 class MessageCenterViewTest
: public testing::Test
,
95 public MockNotificationView::Test
{
97 MessageCenterViewTest();
98 virtual ~MessageCenterViewTest();
100 virtual void SetUp() OVERRIDE
;
101 virtual void TearDown() OVERRIDE
;
103 MessageCenterView
* GetMessageCenterView();
104 int GetNotificationCount();
105 int GetCallCount(CallType type
);
107 virtual void RegisterCall(int receiver_id
, CallType type
) OVERRIDE
;
109 void LogBounds(int depth
, views::View
* view
);
112 views::View
* MakeParent(views::View
* child1
, views::View
* child2
);
115 scoped_ptr
<MessageCenterView
> message_center_view_
;
116 FakeMessageCenter message_center_
;
117 std::map
<CallType
,int> callCounts_
;
119 DISALLOW_COPY_AND_ASSIGN(MessageCenterViewTest
);
122 MessageCenterViewTest::MessageCenterViewTest() {
125 MessageCenterViewTest::~MessageCenterViewTest() {
128 void MessageCenterViewTest::SetUp() {
129 // Create a dummy notification.
130 Notification
notification(NOTIFICATION_TYPE_SIMPLE
,
131 std::string("notification id"),
132 UTF8ToUTF16("title"),
133 UTF8ToUTF16("message"),
135 UTF8ToUTF16("display source"),
136 std::string("extension id"),
137 message_center::RichNotificationData(),
140 // ...and a list for it.
141 NotificationList::Notifications notifications
;
142 notifications
.insert(¬ification
);
144 // Then create a new MessageCenterView with that single notification.
145 message_center_view_
.reset(new MessageCenterView(
146 &message_center_
, NULL
, 100, false, /*top_down =*/false));
147 message_center_view_
->SetNotifications(notifications
);
149 // Remove and delete the NotificationView now owned by the MessageCenterView's
150 // MessageListView and replace it with an instrumented MockNotificationView
151 // that will become owned by the MessageListView.
152 MockNotificationView
* mock
;
153 mock
= new MockNotificationView(notification
, &message_center_
, this, 42);
154 message_center_view_
->message_views_
.push_back(mock
);
155 message_center_view_
->SetNotificationViewForTest(mock
);
158 void MessageCenterViewTest::TearDown() {
159 message_center_view_
.reset();
162 MessageCenterView
* MessageCenterViewTest::GetMessageCenterView() {
163 return message_center_view_
.get();
166 int MessageCenterViewTest::GetNotificationCount() {
170 int MessageCenterViewTest::GetCallCount(CallType type
) {
171 return callCounts_
[type
];
174 void MessageCenterViewTest::RegisterCall(int receiver_id
, CallType type
) {
175 callCounts_
[type
] += 1;
178 void MessageCenterViewTest::LogBounds(int depth
, views::View
* view
) {
180 for (int i
= 0; i
< depth
; ++i
)
181 inset
.append(UTF8ToUTF16(" "));
182 gfx::Rect bounds
= view
->bounds();
183 DVLOG(0) << inset
<< bounds
.width() << " x " << bounds
.height()
184 << " @ " << bounds
.x() << ", " << bounds
.y();
185 for (int i
= 0; i
< view
->child_count(); ++i
)
186 LogBounds(depth
+ 1, view
->child_at(i
));
189 /* Unit tests *****************************************************************/
191 TEST_F(MessageCenterViewTest
, CallTest
) {
192 // Exercise (with size values that just need to be large enough).
193 GetMessageCenterView()->SetBounds(0, 0, 100, 100);
195 // Verify that this didn't generate more than 2 Layout() call per descendant
196 // NotificationView or more than a total of 20 GetPreferredSize() and
197 // GetHeightForWidth() calls per descendant NotificationView. 20 is a very
198 // large number corresponding to the current reality. That number will be
199 // ratcheted down over time as the code improves.
200 EXPECT_LE(GetCallCount(LAYOUT
), GetNotificationCount() * 2);
201 EXPECT_LE(GetCallCount(GET_PREFERRED_SIZE
) +
202 GetCallCount(GET_HEIGHT_FOR_WIDTH
),
203 GetNotificationCount() * 20);
206 } // namespace message_center