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/utf_string_conversions.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/message_center/notification.h"
12 #include "ui/message_center/notification_change_observer.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 /* Dummy NotificationChangeObserver *******************************************/
30 class DummyObserver
: public NotificationChangeObserver
{
33 virtual ~DummyObserver();
36 DISALLOW_COPY_AND_ASSIGN(DummyObserver
);
39 DummyObserver::DummyObserver() {
42 DummyObserver::~DummyObserver() {
45 /* Instrumented/Mock NotificationView subclass ********************************/
47 class MockNotificationView
: public NotificationView
{
51 virtual void RegisterCall(int receiver_id
, CallType type
) = 0;
54 explicit MockNotificationView(const Notification
& notification
,
55 NotificationChangeObserver
* observer
,
58 virtual ~MockNotificationView();
60 virtual gfx::Size
GetPreferredSize();
61 virtual int GetHeightForWidth(int w
);
62 virtual void Layout();
64 int get_id() { return id_
; };
67 void RegisterCall(CallType type
);
72 DISALLOW_COPY_AND_ASSIGN(MockNotificationView
);
75 MockNotificationView::MockNotificationView(const Notification
& notification
,
76 NotificationChangeObserver
* observer
,
79 : NotificationView(notification
, observer
, true),
84 MockNotificationView::~MockNotificationView() {
87 gfx::Size
MockNotificationView::GetPreferredSize() {
88 RegisterCall(GET_PREFERRED_SIZE
);
89 return child_count() ? NotificationView::GetPreferredSize() :
93 int MockNotificationView::GetHeightForWidth(int width
) {
94 RegisterCall(GET_HEIGHT_FOR_WIDTH
);
95 return child_count() ? NotificationView::GetHeightForWidth(width
) : (id_
);
98 void MockNotificationView::Layout() {
101 NotificationView::Layout();
104 void MockNotificationView::RegisterCall(CallType type
) {
106 test_
->RegisterCall(id_
, type
);
109 /* Test fixture ***************************************************************/
111 class MessageCenterViewTest
: public testing::Test
,
112 public MockNotificationView::Test
{
114 MessageCenterViewTest();
115 virtual ~MessageCenterViewTest();
117 virtual void SetUp() OVERRIDE
;
119 MessageCenterView
* GetMessageCenterView();
120 int GetNotificationCount();
121 int GetCallCount(CallType type
);
123 void RegisterCall(int receiver_id
, CallType type
);
125 void LogBounds(int depth
, views::View
* view
);
128 views::View
* MakeParent(views::View
* child1
, views::View
* child2
);
131 scoped_ptr
<MessageCenterView
> message_center_view_
;
132 DummyObserver observer
;
133 std::map
<CallType
,int> callCounts_
;
135 DISALLOW_COPY_AND_ASSIGN(MessageCenterViewTest
);
138 MessageCenterViewTest::MessageCenterViewTest() {
141 MessageCenterViewTest::~MessageCenterViewTest() {
144 void MessageCenterViewTest::SetUp() {
145 // Create a dummy notification.
146 Notification
notification(
147 NOTIFICATION_TYPE_SIMPLE
,
148 std::string("notification id"),
149 UTF8ToUTF16("title"),
150 UTF8ToUTF16("message"),
151 UTF8ToUTF16("display source"),
152 std::string("extension id"),
155 // ...and a list for it.
156 NotificationList::Notifications notifications
;
157 notifications
.insert(¬ification
);
159 // Then create a new MessageCenterView with that single notification.
160 message_center_view_
.reset(new MessageCenterView(&observer
, 100));
161 message_center_view_
->SetNotifications(notifications
);
163 // Remove and delete the NotificationView now owned by the MessageCenterView's
164 // MessageListView and replace it with an instrumented MockNotificationView
165 // that will become owned by the MessageListView.
166 MockNotificationView
* mock
;
167 mock
= new MockNotificationView(notification
, &observer
, this, 42);
168 message_center_view_
->message_views_
[notification
.id()] = mock
;
169 message_center_view_
->message_list_view_
->RemoveAllChildViews(true);
170 message_center_view_
->message_list_view_
->AddChildView(mock
);
173 MessageCenterView
* MessageCenterViewTest::GetMessageCenterView() {
174 return message_center_view_
.get();
177 int MessageCenterViewTest::GetNotificationCount() {
181 int MessageCenterViewTest::GetCallCount(CallType type
) {
182 return callCounts_
[type
];
185 void MessageCenterViewTest::RegisterCall(int receiver_id
, CallType type
) {
186 callCounts_
[type
] += 1;
189 void MessageCenterViewTest::LogBounds(int depth
, views::View
* view
) {
191 for (int i
= 0; i
< depth
; ++i
)
192 inset
.append(UTF8ToUTF16(" "));
193 gfx::Rect bounds
= view
->bounds();
194 DVLOG(0) << inset
<< bounds
.width() << " x " << bounds
.height()
195 << " @ " << bounds
.x() << ", " << bounds
.y();
196 for (int i
= 0; i
< view
->child_count(); ++i
)
197 LogBounds(depth
+ 1, view
->child_at(i
));
200 /* Unit tests *****************************************************************/
202 TEST_F(MessageCenterViewTest
, CallTest
) {
203 // Exercise (with size values that just need to be large enough).
204 GetMessageCenterView()->SetBounds(0, 0, 100, 100);
206 // Verify that this didn't generate more than 1 Layout() call per descendant
207 // NotificationView or more than a total of 14 GetPreferredSize() and
208 // GetHeightForWidth() calls per descendant NotificationView. 14 is a very
209 // large number corresponding to the current reality. That number will be
210 // ratcheted down over time as the code improves.
211 EXPECT_LE(GetCallCount(LAYOUT
), GetNotificationCount());
212 EXPECT_LE(GetCallCount(GET_PREFERRED_SIZE
) +
213 GetCallCount(GET_HEIGHT_FOR_WIDTH
),
214 GetNotificationCount() * 14);
217 } // namespace message_center