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

Unified Diff: ui/message_center/views/message_popup_collection_unittest.cc

Issue 1913433004: Supporting shrinking/enlarging for notifications (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: compilation: stl variations Created 4 years, 7 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 | « no previous file | ui/message_center/views/toast_contents_view.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/message_center/views/message_popup_collection_unittest.cc
diff --git a/ui/message_center/views/message_popup_collection_unittest.cc b/ui/message_center/views/message_popup_collection_unittest.cc
index 105d91fd55094830104c8529643512fc2f3c7dfe..3de515c5a7204a28d7e00ae468089e74cf5bdc82 100644
--- a/ui/message_center/views/message_popup_collection_unittest.cc
+++ b/ui/message_center/views/message_popup_collection_unittest.cc
@@ -6,10 +6,13 @@
#include <stddef.h>
+#include <algorithm>
#include <list>
+#include <numeric>
#include <utility>
#include "base/message_loop/message_loop.h"
+#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
@@ -18,14 +21,33 @@
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_utils.h"
+#include "ui/gfx/animation/animation_delegate.h"
+#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/message_center/fake_message_center.h"
+#include "ui/message_center/message_center_style.h"
#include "ui/message_center/views/desktop_popup_alignment_delegate.h"
#include "ui/message_center/views/toast_contents_view.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
+namespace {
+
+std::unique_ptr<message_center::Notification> CreateTestNotification(
+ std::string id,
+ std::string text) {
+ return base::WrapUnique(new message_center::Notification(
+ message_center::NOTIFICATION_TYPE_BASE_FORMAT, id,
+ base::UTF8ToUTF16("test title"), base::ASCIIToUTF16(text), gfx::Image(),
+ base::string16() /* display_source */, GURL(),
+ message_center::NotifierId(message_center::NotifierId::APPLICATION, id),
+ message_center::RichNotificationData(),
+ new message_center::NotificationDelegate()));
+}
+
+} // namespace
+
namespace message_center {
namespace test {
@@ -126,12 +148,165 @@ class MessagePopupCollectionTest : public views::ViewsTestBase {
return collection_->GetToastRectAt(index);
}
+ // Checks:
+ // 1) sizes of toast and corresponding widget are equal;
+ // 2) widgets do not owerlap;
+ // 3) after animation is done, aligment is propper;
+ class CheckedAnimationDelegate : public gfx::AnimationDelegate {
+ public:
+ explicit CheckedAnimationDelegate(MessagePopupCollectionTest* test);
+
+ // returns first encountered error
+ const base::Optional<std::string>& error_msg() const { return error_msg_; }
+
+ // gfx::AnimationDelegate overrides
+ void AnimationEnded(const gfx::Animation* animation) override;
+ void AnimationProgressed(const gfx::Animation* animation) override;
+ void AnimationCanceled(const gfx::Animation* animation) override;
+
+ private:
+ // we attach ourselves to the last toast, because we accept
+ // invalidation of invariants during intermidiate
+ // notification updates.
+ ToastContentsView& animation_delegate() { return *toasts_->back(); }
+ const ToastContentsView& animation_delegate() const {
+ return *toasts_->back();
+ }
+
+ void CheckWidgetLEView(const std::string& calling_func);
+ void CheckToastsAreAligned(const std::string& calling_func);
+ void CheckToastsDontOverlap(const std::string& calling_func);
+
+ static int ComputeYDistance(const ToastContentsView& top,
+ const ToastContentsView& bottom);
+
+ MessagePopupCollection::Toasts* toasts_;
+
+ // first encountered error
+ base::Optional<std::string> error_msg_;
+
+ DISALLOW_COPY_AND_ASSIGN(CheckedAnimationDelegate);
+ };
+
+ static std::string YPositionsToString(
+ const MessagePopupCollection::Toasts& toasts);
+
private:
std::unique_ptr<MessagePopupCollection> collection_;
std::unique_ptr<DesktopPopupAlignmentDelegate> alignment_delegate_;
int id_;
};
+MessagePopupCollectionTest::CheckedAnimationDelegate::CheckedAnimationDelegate(
+ MessagePopupCollectionTest* test)
+ : toasts_(&test->collection_->toasts_) {
+ DCHECK(!toasts_->empty());
+ animation_delegate().bounds_animation_->set_delegate(this);
+}
+
+void MessagePopupCollectionTest::CheckedAnimationDelegate::AnimationEnded(
+ const gfx::Animation* animation) {
+ animation_delegate().AnimationEnded(animation);
+ CheckWidgetLEView("AnimationEnded");
+ CheckToastsAreAligned("AnimationEnded");
+}
+
+void MessagePopupCollectionTest::CheckedAnimationDelegate::AnimationProgressed(
+ const gfx::Animation* animation) {
+ animation_delegate().AnimationProgressed(animation);
+ CheckWidgetLEView("AnimationProgressed");
+ CheckToastsDontOverlap("AnimationProgressed");
+}
+
+void MessagePopupCollectionTest::CheckedAnimationDelegate::AnimationCanceled(
+ const gfx::Animation* animation) {
+ animation_delegate().AnimationCanceled(animation);
+ CheckWidgetLEView("AnimationCanceled");
+ CheckToastsDontOverlap("AnimationCanceled");
+}
+
+void MessagePopupCollectionTest::CheckedAnimationDelegate::CheckWidgetLEView(
+ const std::string& calling_func) {
+ if (error_msg_)
+ return;
+ for (ToastContentsView* toast : *toasts_) {
+ auto* widget = toast->GetWidget();
+ DCHECK(widget) << "no widget for: " << toast->id();
+ if (toast->bounds().height() < widget->GetWindowBoundsInScreen().height()) {
+ error_msg_ = calling_func + " CheckWidgetSizeLEView: id: " + toast->id() +
+ "\ntoast size: " + toast->bounds().size().ToString() +
+ "\nwidget size: " +
+ widget->GetWindowBoundsInScreen().size().ToString();
+ return;
+ }
+ }
+};
+
+void MessagePopupCollectionTest::CheckedAnimationDelegate::
+ CheckToastsAreAligned(const std::string& calling_func) {
+ if (error_msg_)
+ return;
+ auto poorly_aligned = std::adjacent_find(
+ toasts_->begin(), toasts_->end(),
+ [this](ToastContentsView* top, ToastContentsView* bottom) {
+ return ComputeYDistance(*top, *bottom) != kMarginBetweenItems;
+ });
+ if (poorly_aligned != toasts_->end())
+ error_msg_ = calling_func + " CheckToastsAreAligned: distance between: " +
+ (*poorly_aligned)->id() + ' ' +
+ (*std::next(poorly_aligned))->id() + ": " +
+ std::to_string(ComputeYDistance(**poorly_aligned,
+ **std::next(poorly_aligned))) +
+ " expected: " + std::to_string(kMarginBetweenItems) +
+ "\nLayout:\n" + YPositionsToString(*toasts_);
+}
+
+void MessagePopupCollectionTest::CheckedAnimationDelegate::
+ CheckToastsDontOverlap(const std::string& calling_func) {
+ if (error_msg_)
+ return;
+ auto poorly_aligned = std::adjacent_find(
+ toasts_->begin(), toasts_->end(),
+ [this](ToastContentsView* top, ToastContentsView* bottom) {
+ return ComputeYDistance(*top, *bottom) < 0;
+ });
+ if (poorly_aligned != toasts_->end())
+ error_msg_ = calling_func + " CheckToastsDontOverlap: distance between: " +
+ (*poorly_aligned)->id() + ' ' +
+ (*std::next(poorly_aligned))->id() + ": " +
+ std::to_string(ComputeYDistance(**poorly_aligned,
+ **std::next(poorly_aligned))) +
+ "\nLayout:\n" + YPositionsToString(*toasts_);
+}
+
+// static
+std::string MessagePopupCollectionTest::YPositionsToString(
+ const MessagePopupCollection::Toasts& toasts) {
+ return std::accumulate(toasts.begin(), toasts.end(), std::string(),
+ [](std::string res, const ToastContentsView* toast) {
+ const auto& bounds =
+ toast->GetWidget()->GetWindowBoundsInScreen();
+ res += toast->id();
+ res += ' ';
+ res += std::to_string(bounds.y());
+ res += ", ";
+ res += std::to_string(bounds.y() + bounds.height());
+ res += '\n';
+ return res;
+ });
+}
+
+// static
+int MessagePopupCollectionTest::CheckedAnimationDelegate::ComputeYDistance(
+ const ToastContentsView& top,
+ const ToastContentsView& bottom) {
+ const auto* top_widget = top.GetWidget();
+ const auto* bottom_widget = bottom.GetWidget();
+ const auto& top_bounds = top_widget->GetWindowBoundsInScreen();
+ const auto& bottom_bounds = bottom_widget->GetWindowBoundsInScreen();
+ return bottom_bounds.y() - (top_bounds.y() + top_bounds.height());
+}
+
#if defined(OS_CHROMEOS)
TEST_F(MessagePopupCollectionTest, DismissOnClick) {
@@ -266,11 +441,6 @@ TEST_F(MessagePopupCollectionTest, DefaultPositioningWithRightTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
-
- // Restore simulated taskbar position to bottom.
- SetDisplayInfo(gfx::Rect(0, 0, 600, 390), // Work-area.
- gfx::Rect(0, 0, 600, 400)); // Display-bounds.
-
WaitForTransitionsDone();
}
@@ -297,10 +467,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithTopTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
WaitForTransitionsDone();
-
- // Restore simulated taskbar position to bottom.
- SetDisplayInfo(gfx::Rect(0, 0, 600, 390), // Work-area.
- gfx::Rect(0, 0, 600, 400)); // Display-bounds.
}
TEST_F(MessagePopupCollectionTest, TopDownPositioningWithLeftAndTopTaskbar) {
@@ -329,10 +495,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithLeftAndTopTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
WaitForTransitionsDone();
-
- // Restore simulated taskbar position to bottom.
- SetDisplayInfo(gfx::Rect(0, 0, 600, 390), // Work-area.
- gfx::Rect(0, 0, 600, 400)); // Display-bounds.
}
TEST_F(MessagePopupCollectionTest, TopDownPositioningWithBottomAndTopTaskbar) {
@@ -361,10 +523,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithBottomAndTopTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
WaitForTransitionsDone();
-
- // Restore simulated taskbar position to bottom.
- SetDisplayInfo(gfx::Rect(0, 0, 600, 390), // Work-area.
- gfx::Rect(0, 0, 600, 400)); // Display-bounds.
}
TEST_F(MessagePopupCollectionTest, LeftPositioningWithLeftTaskbar) {
@@ -393,10 +551,6 @@ TEST_F(MessagePopupCollectionTest, LeftPositioningWithLeftTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
WaitForTransitionsDone();
-
- // Restore simulated taskbar position to bottom.
- SetDisplayInfo(gfx::Rect(0, 0, 600, 390), // Work-area.
- gfx::Rect(0, 0, 600, 400)); // Display-bounds.
}
TEST_F(MessagePopupCollectionTest, DetectMouseHover) {
@@ -520,5 +674,57 @@ TEST_F(MessagePopupCollectionTest, CloseNonClosableNotifications) {
#endif // defined(OS_CHROMEOS)
+// When notifications were displayed on top, change of notification
+// size didn't affect corresponding widget.
+TEST_F(MessagePopupCollectionTest, ChangingNotificationSize) {
+ // Simulate a taskbar at the top.
+ SetDisplayInfo(gfx::Rect(0, 10, 600, 390), // Work-area.
+ gfx::Rect(0, 0, 600, 400)); // Display-bounds.
+
+ struct TestCase {
+ std::string name;
+ std::string text;
+ };
+ std::vector<TestCase> updates = {
+ {"shrinking", ""},
+ {"enlarging", "abc\ndef\nghk\n"},
+ {"restoring", "abc\ndef\n"},
+ };
+
+ std::vector<std::string> notification_ids;
+ // adding notifications
+ {
+ constexpr int max_visible_popup_notifications = 3;
+ notification_ids.reserve(max_visible_popup_notifications);
+ for (int i = 0; i < max_visible_popup_notifications; ++i) {
+ notification_ids.push_back(std::to_string(i));
+ auto notification =
+ CreateTestNotification(notification_ids.back(), updates.back().text);
+ MessageCenter::Get()->AddNotification(std::move(notification));
+ }
+ }
+
+ WaitForTransitionsDone();
+
+ // updating notifications one by one
+ for (const std::string& id : notification_ids) {
+ for (const auto& update : updates) {
+ MessageCenter::Get()->UpdateNotification(
+ id, CreateTestNotification(id, update.text));
+
+ CheckedAnimationDelegate checked_animation(this);
+
+ WaitForTransitionsDone();
+
+ EXPECT_FALSE(checked_animation.error_msg())
+ << "Animation error, test case: " << id << ' ' << update.name << ":\n"
+ << *checked_animation.error_msg();
+ }
+ }
+
+ CloseAllToasts();
+ WaitForTransitionsDone();
+}
+
} // namespace test
} // namespace message_center
« no previous file with comments | « no previous file | ui/message_center/views/toast_contents_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698