[go: nahoru, domu]

blob: 7cf7c8adc0c54ce018909a477d6d9dcdc8bba8a1 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/bubble/bubble_view.h"
#import "base/apple/foundation_util.h"
#import "base/ios/ios_util.h"
#import "ios/chrome/browser/ui/bubble/bubble_unittest_util.h"
#import "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
#import "testing/platform_test.h"
@interface BubbleViewDelegateTest : NSObject <BubbleViewDelegate>
- (instancetype)init;
@property(nonatomic) int tapCounter;
@end
@implementation BubbleViewDelegateTest
- (instancetype)init {
self = [super init];
if (self) {
_tapCounter = 0;
}
return self;
}
- (void)didTapCloseButton {
_tapCounter += 1;
}
- (void)didTapSnoozeButton {
_tapCounter += 1;
}
@end
// Fixture to test BubbleView.
class BubbleViewTest : public PlatformTest {
public:
BubbleViewTest()
: maxSize_(CGSizeMake(500.0f, 500.0f)),
arrowDirection_(BubbleArrowDirectionUp),
alignment_(BubbleAlignmentCenter),
alignmentOffset_(35.0f),
shortText_(@"I"),
longText_(@"Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
textAlignment_(NSTextAlignmentNatural) {}
protected:
// The maximum size of the bubble.
const CGSize maxSize_;
// The direction that the bubble's arrow points.
const BubbleArrowDirection arrowDirection_;
// The alignment of the bubble's arrow relative to the rest of the bubble.
const BubbleAlignment alignment_;
// Distance between the arrow's centerX and the (leading or trailing) edge of
// the bubble, depending on the BubbleAlignment. If BubbleAlignment is center,
// then `alignmentOffset` is ignored.
const CGFloat alignmentOffset_;
// Text that is shorter than the minimum line width.
NSString* shortText_;
// Text that is longer than the maximum line width. It should wrap onto
// multiple lines.
NSString* longText_;
// Text alignment for bubble's title, text and snooze button.
NSTextAlignment textAlignment_;
};
// Test `sizeThatFits` given short text.
TEST_F(BubbleViewTest, BubbleSizeShortText) {
BubbleView* bubble = [[BubbleView alloc] initWithText:shortText_
arrowDirection:arrowDirection_
alignment:alignment_];
CGSize bubbleSize = [bubble sizeThatFits:maxSize_];
// Since the label is shorter than the minimum line width, expect the bubble
// to be the minimum width and accommodate one line of text.
EXPECT_NEAR(68.0f, bubbleSize.width, 1.0f);
EXPECT_NEAR(67.0f, bubbleSize.height, 1.0f);
}
// Test that the accessibility label matches the display text.
TEST_F(BubbleViewTest, Accessibility) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
// Add the bubble view to the view hierarchy.
[superview addSubview:bubble];
EXPECT_NSEQ(longText_, bubble.accessibilityValue);
}
// Tests that the close button is not showed when the option is set to hidden.
TEST_F(BubbleViewTest, CloseButtonIsNotPresent) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_
showsCloseButton:NO
title:nil
image:nil
showsSnoozeButton:NO
textAlignment:textAlignment_
delegate:nil];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UIButton* closeButton = GetCloseButtonFromBubbleView(bubble);
ASSERT_FALSE(closeButton);
}
// Tests the close button action and its presence.
TEST_F(BubbleViewTest, CloseButtonActionAndPresent) {
BubbleViewDelegateTest* delegate = [[BubbleViewDelegateTest alloc] init];
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_
showsCloseButton:YES
title:nil
image:nil
showsSnoozeButton:NO
textAlignment:textAlignment_
delegate:delegate];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UIButton* closeButton = GetCloseButtonFromBubbleView(bubble);
ASSERT_TRUE(closeButton);
// Tests close button action.
[closeButton sendActionsForControlEvents:UIControlEventTouchUpInside];
EXPECT_EQ(delegate.tapCounter, 1);
}
// Tests that the title is not showed when the option is set to hidden.
TEST_F(BubbleViewTest, TitleIsNotPresent) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UILabel* titleLabel = GetTitleLabelFromBubbleView(bubble);
ASSERT_FALSE(titleLabel);
}
// Tests that the title is present and correct.
TEST_F(BubbleViewTest, TitleIsPresentAndCorrect) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_
showsCloseButton:NO
title:shortText_
image:nil
showsSnoozeButton:NO
textAlignment:textAlignment_
delegate:nil];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UILabel* titleLabel = GetTitleLabelFromBubbleView(bubble);
ASSERT_TRUE(titleLabel);
ASSERT_EQ(titleLabel.text, shortText_);
}
// Tests that the title is aligned correctly.
TEST_F(BubbleViewTest, TitleIsAligned) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_
showsCloseButton:NO
title:shortText_
image:nil
showsSnoozeButton:NO
textAlignment:NSTextAlignmentNatural
delegate:nil];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UILabel* titleLabel = GetTitleLabelFromBubbleView(bubble);
ASSERT_TRUE(titleLabel);
ASSERT_EQ(titleLabel.textAlignment, NSTextAlignmentNatural);
}
// Tests that the image is not showed when the image is empty.
TEST_F(BubbleViewTest, ImageIsNotPresent) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UIImageView* imageView = GetImageViewFromBubbleView(bubble);
ASSERT_FALSE(imageView);
}
// Tests that the image is present and correct.
TEST_F(BubbleViewTest, ImageIsPresentAndCorrect) {
UIImage* testImage = [[UIImage alloc] init];
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_
showsCloseButton:NO
title:nil
image:testImage
showsSnoozeButton:NO
textAlignment:textAlignment_
delegate:nil];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UIImageView* imageView = GetImageViewFromBubbleView(bubble);
ASSERT_TRUE(imageView);
EXPECT_EQ(imageView.image, testImage);
}
// Tests that the snooze button is not showed when the option is set to hidden.
TEST_F(BubbleViewTest, SnoozeButtonIsNotPresent) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_
showsCloseButton:NO
title:nil
image:nil
showsSnoozeButton:NO
textAlignment:textAlignment_
delegate:nil];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UIButton* snoozeButton = GetSnoozeButtonFromBubbleView(bubble);
ASSERT_FALSE(snoozeButton);
}
// Tests the snooze button action and its presence.
TEST_F(BubbleViewTest, SnoozeButtonActionAndPresent) {
BubbleViewDelegateTest* delegate = [[BubbleViewDelegateTest alloc] init];
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:alignment_
showsCloseButton:NO
title:nil
image:nil
showsSnoozeButton:YES
textAlignment:textAlignment_
delegate:delegate];
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
UIButton* snoozeButton = GetSnoozeButtonFromBubbleView(bubble);
ASSERT_TRUE(snoozeButton);
// Tests snooze button action.
[snoozeButton sendActionsForControlEvents:UIControlEventTouchUpInside];
EXPECT_EQ(delegate.tapCounter, 1);
}
// Tests the arrow view is aligned properly with BubbleAlignmentTopOrLeading.
TEST_F(BubbleViewTest, ArrowViewLeadingAligned) {
BubbleView* bubble =
[[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:BubbleAlignmentTopOrLeading];
bubble.alignmentOffset = alignmentOffset_;
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
[bubble layoutIfNeeded];
UIView* arrowView = GetArrowViewFromBubbleView(bubble);
ASSERT_TRUE(arrowView);
// The center of the arrow must be at a distance of `alignmentOffset_` to the
// leading edge of the bubble.
EXPECT_EQ(CGRectGetMidX(arrowView.frame), alignmentOffset_);
}
// Tests the arrow view is aligned properly with BubbleAlignmentCenter.
TEST_F(BubbleViewTest, ArrowViewCenterAligned) {
BubbleView* bubble = [[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:BubbleAlignmentCenter];
bubble.alignmentOffset = alignmentOffset_;
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
[bubble layoutIfNeeded];
UIView* arrowView = GetArrowViewFromBubbleView(bubble);
ASSERT_TRUE(arrowView);
// `alignmentOffset` should be ignored with BubbleAlignmentCenter.
EXPECT_EQ(CGRectGetMidX(arrowView.frame), CGRectGetMidX(bubble.frame));
}
// Tests the arrow view is aligned properly with
// BubbleAlignmentBottomOrTrailing.
TEST_F(BubbleViewTest, ArrowViewTrailingAligned) {
BubbleView* bubble =
[[BubbleView alloc] initWithText:longText_
arrowDirection:arrowDirection_
alignment:BubbleAlignmentBottomOrTrailing];
bubble.alignmentOffset = alignmentOffset_;
UIView* superview = [[UIView alloc] initWithFrame:CGRectZero];
[superview addSubview:bubble];
[bubble layoutIfNeeded];
UIView* arrowView = GetArrowViewFromBubbleView(bubble);
ASSERT_TRUE(arrowView);
// The center of the arrow must be at a distance of `alignmentOffset_` to the
// trailing edge of the bubble.
EXPECT_EQ(CGRectGetMidX(arrowView.frame),
bubble.frame.size.width - alignmentOffset_);
}