mirror of
https://github.com/material-components/material-components-ios.git
synced 2026-02-20 08:27:32 +08:00
1056 lines
37 KiB
Objective-C
1056 lines
37 KiB
Objective-C
// Copyright 2017-present the Material Components for iOS authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#import <XCTest/XCTest.h>
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wprivate-header"
|
|
#import "MDCBottomNavigationBar+Private.h"
|
|
#import "MDCBottomNavigationItemView.h"
|
|
#pragma clang diagnostic pop
|
|
#import "MDCAvailability.h"
|
|
#import "MDCBottomNavigationBar.h"
|
|
#import "MDCShadowElevations.h"
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
static NSString *const kTestItemTitleText = @"Title";
|
|
|
|
/**
|
|
A testing MDCBottomNavigationBar that allows safeAreaInsets to be set programmatically.
|
|
*/
|
|
@interface MDCSafeAreaCustomizingBottomNavigationBar : MDCBottomNavigationBar
|
|
/** Set this to override the value returned by @c safeAreaInsets. */
|
|
@property(nonatomic, assign) UIEdgeInsets test_safeAreaInsets;
|
|
@end
|
|
|
|
@implementation MDCSafeAreaCustomizingBottomNavigationBar
|
|
|
|
- (UIEdgeInsets)safeAreaInsets {
|
|
return self.test_safeAreaInsets;
|
|
}
|
|
|
|
@end
|
|
|
|
@interface MDCBottomNavigationBar (Testing)
|
|
@property(nonatomic, strong) NSMutableArray<MDCBottomNavigationItemView *> *itemViews;
|
|
@end
|
|
|
|
@interface MDCBottomNavigationItemView (Testing)
|
|
@property(nonatomic, strong) UILabel *label;
|
|
@end
|
|
|
|
@interface MDCBottomNavigationBarTests : XCTestCase
|
|
@property(nonatomic, strong, nullable) MDCBottomNavigationBar *bottomNavBar;
|
|
@end
|
|
|
|
@implementation MDCBottomNavigationBarTests
|
|
|
|
- (void)setUp {
|
|
self.bottomNavBar = [[MDCBottomNavigationBar alloc] init];
|
|
}
|
|
|
|
- (void)tearDown {
|
|
self.bottomNavBar = nil;
|
|
}
|
|
|
|
#pragma mark - Fonts
|
|
|
|
- (void)testItemTitleFontDefault {
|
|
// Then
|
|
XCTAssertNotNil(self.bottomNavBar.itemTitleFont);
|
|
}
|
|
|
|
- (void)testItemTitleFontAppliesToNewItems {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.itemTitleFont = [UIFont systemFontOfSize:31];
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
|
|
// Then
|
|
for (MDCBottomNavigationItemView *item in self.bottomNavBar.itemViews) {
|
|
XCTAssertEqualObjects(item.itemTitleFont, self.bottomNavBar.itemTitleFont);
|
|
}
|
|
}
|
|
|
|
- (void)testItemTitleFontAppliesToExistingItems {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
self.bottomNavBar.itemTitleFont = [UIFont systemFontOfSize:31];
|
|
|
|
// Then
|
|
for (MDCBottomNavigationItemView *item in self.bottomNavBar.itemViews) {
|
|
XCTAssertEqualObjects(item.itemTitleFont, self.bottomNavBar.itemTitleFont);
|
|
}
|
|
}
|
|
|
|
- (void)testItemReset {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
self.bottomNavBar.items = @[ item1, item2, item3 ];
|
|
|
|
// Then
|
|
NSUInteger tabsCount = 3;
|
|
XCTAssertEqual(self.bottomNavBar.itemViews.count, tabsCount);
|
|
}
|
|
|
|
- (void)testFramesAfterReset {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:1];
|
|
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:2];
|
|
[self.bottomNavBar sizeToFit];
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 320, 56);
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
self.bottomNavBar.items = @[ item1, item2, item3 ];
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
|
|
// Then
|
|
XCTAssertFalse(CGRectEqualToRect(self.bottomNavBar.itemViews[0].frame, CGRectZero));
|
|
}
|
|
|
|
- (void)testSelectedItemAfterReset {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
self.bottomNavBar.items = @[ item1, item2, item3 ];
|
|
|
|
// Then
|
|
XCTAssertNil(self.bottomNavBar.selectedItem);
|
|
}
|
|
|
|
- (NSInteger)countOfViewsWithAccessibilityIdentifier:(NSString *)accessibilityIdentifier
|
|
fromRootView:(UIView *)view {
|
|
NSInteger sum = [view.accessibilityIdentifier isEqualToString:accessibilityIdentifier] ? 1 : 0;
|
|
for (UIView *subview in view.subviews) {
|
|
sum += [self countOfViewsWithAccessibilityIdentifier:accessibilityIdentifier
|
|
fromRootView:subview];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
- (void)testSettingAccessibilityIdentifierAffectsExactlyOneSubview {
|
|
// Given
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:1];
|
|
item.accessibilityIdentifier = @"__i_d__";
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// Then
|
|
XCTAssertEqual([self countOfViewsWithAccessibilityIdentifier:item.accessibilityIdentifier
|
|
fromRootView:self.bottomNavBar],
|
|
1);
|
|
}
|
|
|
|
- (void)testAccessibilityLabelInitialValue {
|
|
// Given
|
|
NSString *initialLabel = @"initialLabel";
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.accessibilityLabel = initialLabel;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
|
|
// When
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(bar.itemViews.firstObject.accessibilityLabel, initialLabel);
|
|
}
|
|
|
|
- (void)testAccessibilityLabelValueChanged {
|
|
// Given
|
|
NSString *oldLabel = @"oldLabel";
|
|
NSString *newLabel = @"newLabel";
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.accessibilityLabel = oldLabel;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// When
|
|
tabBarItem.accessibilityLabel = newLabel;
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(bar.itemViews.firstObject.accessibilityLabel, newLabel);
|
|
}
|
|
|
|
- (void)testAccessibilityHintInitialValue {
|
|
// Given
|
|
NSString *initialHint = @"initialHint";
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.accessibilityHint = initialHint;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
|
|
// When
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// Then
|
|
MDCBottomNavigationItemView *itemView = bar.itemViews.firstObject;
|
|
UIButton *itemViewButton = itemView.button;
|
|
XCTAssertEqualObjects(itemViewButton.accessibilityHint, initialHint);
|
|
}
|
|
|
|
- (void)testAccessibilityHintValueChanged {
|
|
// Given
|
|
NSString *oldHint = @"oldHint";
|
|
NSString *newHint = @"newHint";
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.accessibilityHint = oldHint;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// When
|
|
tabBarItem.accessibilityHint = newHint;
|
|
|
|
// Then
|
|
MDCBottomNavigationItemView *itemView = bar.itemViews.firstObject;
|
|
UIButton *itemViewButton = itemView.button;
|
|
XCTAssertEqualObjects(itemViewButton.accessibilityHint, newHint);
|
|
}
|
|
|
|
- (void)testIsAccessibilityElementInitialValue {
|
|
// Given
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.isAccessibilityElement = NO;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
|
|
// When
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// Then
|
|
XCTAssert(!bar.itemViews.firstObject.isAccessibilityElement);
|
|
}
|
|
|
|
- (void)testIsAccessibilityElementValueChanged {
|
|
// Given
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.isAccessibilityElement = NO;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// When
|
|
tabBarItem.isAccessibilityElement = YES;
|
|
|
|
// Then
|
|
XCTAssert(bar.itemViews.firstObject.isAccessibilityElement);
|
|
}
|
|
|
|
- (void)testTagInitialValue {
|
|
// Given
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.tag = 1234;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
|
|
// When
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// Then
|
|
XCTAssertEqual(bar.itemViews.firstObject.tag, tabBarItem.tag);
|
|
}
|
|
|
|
- (void)testTagValueChanged {
|
|
// Given
|
|
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Home" image:nil tag:0];
|
|
tabBarItem.tag = 1234;
|
|
MDCBottomNavigationBar *bar = [[MDCBottomNavigationBar alloc] init];
|
|
bar.items = @[ tabBarItem ];
|
|
|
|
// When
|
|
tabBarItem.tag = 4321;
|
|
|
|
// Then
|
|
XCTAssertEqual(bar.itemViews.firstObject.tag, tabBarItem.tag);
|
|
}
|
|
|
|
- (void)testTitleVisibility {
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
self.bottomNavBar.titleVisibility = MDCBottomNavigationBarTitleVisibilityNever;
|
|
for (MDCBottomNavigationItemView *itemView in self.bottomNavBar.itemViews) {
|
|
XCTAssertEqualWithAccuracy(itemView.label.alpha, 0.0, 0.001);
|
|
}
|
|
self.bottomNavBar.titleVisibility = MDCBottomNavigationBarTitleVisibilityAlways;
|
|
for (MDCBottomNavigationItemView *itemView in self.bottomNavBar.itemViews) {
|
|
XCTAssertEqualWithAccuracy(itemView.label.alpha, 1.0, 0.001);
|
|
}
|
|
self.bottomNavBar.titleVisibility = MDCBottomNavigationBarTitleVisibilitySelected;
|
|
self.bottomNavBar.itemViews.firstObject.selected = YES;
|
|
self.bottomNavBar.itemViews.lastObject.selected = NO;
|
|
XCTAssertEqualWithAccuracy(self.bottomNavBar.itemViews.firstObject.label.alpha, 1.0, 0.001);
|
|
XCTAssertEqualWithAccuracy(self.bottomNavBar.itemViews.lastObject.label.alpha, 0.0, 0.001);
|
|
}
|
|
|
|
- (void)testDefaultElevation {
|
|
// Then
|
|
XCTAssertEqualWithAccuracy(self.bottomNavBar.elevation, MDCShadowElevationBottomNavigationBar,
|
|
0.001);
|
|
}
|
|
|
|
- (void)testCustomElevation {
|
|
// Given
|
|
CGFloat customElevation = 20;
|
|
|
|
// When
|
|
self.bottomNavBar.elevation = customElevation;
|
|
|
|
// Then
|
|
XCTAssertEqualWithAccuracy(self.bottomNavBar.elevation, customElevation, 0.001);
|
|
}
|
|
|
|
- (void)testDefaultShadowColor {
|
|
// Then
|
|
XCTAssertEqualObjects(self.bottomNavBar.shadowColor, UIColor.blackColor);
|
|
XCTAssertTrue(
|
|
CGColorEqualToColor(self.bottomNavBar.layer.shadowColor, UIColor.blackColor.CGColor),
|
|
@"(%@) is not equal to (%@)", self.bottomNavBar.layer.shadowColor,
|
|
UIColor.blackColor.CGColor);
|
|
}
|
|
|
|
- (void)testCustomShadowColor {
|
|
// Given
|
|
UIColor *fakeColor = UIColor.orangeColor;
|
|
|
|
// When
|
|
self.bottomNavBar.shadowColor = fakeColor;
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(self.bottomNavBar.shadowColor, fakeColor);
|
|
XCTAssertTrue(CGColorEqualToColor(self.bottomNavBar.layer.shadowColor, fakeColor.CGColor),
|
|
@"(%@) is not equal to (%@)", self.bottomNavBar.layer.shadowColor,
|
|
fakeColor.CGColor);
|
|
}
|
|
|
|
- (void)testViewForItemFound {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
|
|
// Then
|
|
MDCBottomNavigationItemView *viewForItem1 =
|
|
(MDCBottomNavigationItemView *)[self.bottomNavBar viewForItem:item1];
|
|
MDCBottomNavigationItemView *viewForItem2 =
|
|
(MDCBottomNavigationItemView *)[self.bottomNavBar viewForItem:item2];
|
|
XCTAssertNotEqual(viewForItem1, viewForItem2);
|
|
XCTAssertTrue(
|
|
[self.bottomNavBar.itemViews containsObject:viewForItem1],
|
|
@"BottomNavBar.itemViews did not contain the view (%@) returned for UITabBarItem (%@)",
|
|
viewForItem1, item1);
|
|
XCTAssertTrue(
|
|
[self.bottomNavBar.itemViews containsObject:viewForItem2],
|
|
@"BottomNavBar.itemViews did not contain the view (%@) returned for UITabBarItem (%@)",
|
|
viewForItem2, item2);
|
|
}
|
|
|
|
- (void)testViewForItemNotFound {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"3" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
|
|
// Then
|
|
XCTAssert([self.bottomNavBar viewForItem:item3] == nil);
|
|
}
|
|
|
|
- (void)testSizeThatFitsDefaultIncludesSafeArea {
|
|
// Given
|
|
CGRect barFrame = CGRectMake(0, 0, 360, 56);
|
|
MDCSafeAreaCustomizingBottomNavigationBar *bottomNavBar =
|
|
[[MDCSafeAreaCustomizingBottomNavigationBar alloc] initWithFrame:barFrame];
|
|
bottomNavBar.test_safeAreaInsets = UIEdgeInsetsZero;
|
|
CGSize initialSize = [bottomNavBar sizeThatFits:barFrame.size];
|
|
|
|
// When
|
|
bottomNavBar.test_safeAreaInsets = UIEdgeInsetsMake(20, 20, 20, 20);
|
|
|
|
// Then
|
|
CGSize finalSize = [bottomNavBar sizeThatFits:barFrame.size];
|
|
XCTAssertFalse(CGSizeEqualToSize(finalSize, CGSizeZero),
|
|
"sizeThatFits: should not return CGSizeZero");
|
|
XCTAssertTrue(CGSizeEqualToSize(finalSize, initialSize), @"(%@) is not equal to (%@)",
|
|
NSStringFromCGSize(finalSize), NSStringFromCGSize(initialSize));
|
|
}
|
|
|
|
- (void)testSizeThatFitsExcludesSafeArea {
|
|
// Given
|
|
CGRect barFrame = CGRectMake(0, 0, 360, 56);
|
|
MDCSafeAreaCustomizingBottomNavigationBar *bottomNavBar =
|
|
[[MDCSafeAreaCustomizingBottomNavigationBar alloc] initWithFrame:barFrame];
|
|
bottomNavBar.test_safeAreaInsets = UIEdgeInsetsZero;
|
|
CGSize initialSize = [bottomNavBar sizeThatFits:barFrame.size];
|
|
|
|
// When
|
|
bottomNavBar.test_safeAreaInsets = UIEdgeInsetsMake(20, 20, 20, 20);
|
|
|
|
// Then
|
|
CGSize finalSize = [bottomNavBar sizeThatFits:barFrame.size];
|
|
XCTAssertFalse(CGSizeEqualToSize(finalSize, CGSizeZero),
|
|
"sizeThatFits: should not return CGSizeZero");
|
|
XCTAssertTrue(CGSizeEqualToSize(finalSize, initialSize), @"(%@) is not equal to (%@)",
|
|
NSStringFromCGSize(finalSize), NSStringFromCGSize(initialSize));
|
|
}
|
|
|
|
/*
|
|
Tests when the bottomNavBar width is not evenly divisible by the number of items, the difference
|
|
between start of the frame and center of the first element and end of the frame and center of the
|
|
last element is max one pixel
|
|
*/
|
|
- (void)testLaysoutAcrossBarEvenly {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
UITabBarItem *item3 = [[UITabBarItem alloc] initWithTitle:@"3" image:nil tag:0];
|
|
UITabBarItem *item4 = [[UITabBarItem alloc] initWithTitle:@"4" image:nil tag:0];
|
|
UITabBarItem *item5 = [[UITabBarItem alloc] initWithTitle:@"5" image:nil tag:0];
|
|
CGFloat bottomNavBarWidth = 304;
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, bottomNavBarWidth, 56);
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2, item3, item4, item5 ];
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
|
|
// Then
|
|
MDCBottomNavigationItemView *viewForItem1 =
|
|
(MDCBottomNavigationItemView *)[self.bottomNavBar viewForItem:item1];
|
|
MDCBottomNavigationItemView *viewForItem5 =
|
|
(MDCBottomNavigationItemView *)[self.bottomNavBar viewForItem:item5];
|
|
XCTAssertEqualWithAccuracy(viewForItem1.center.x, bottomNavBarWidth - viewForItem5.center.x, 1.0);
|
|
}
|
|
|
|
#pragma mark - Autolayout support
|
|
|
|
- (void)testIntrinsicContentSizeIgnoresSafeArea {
|
|
// Given
|
|
CGRect barFrame = CGRectMake(0, 0, 360, 56);
|
|
MDCSafeAreaCustomizingBottomNavigationBar *bottomNavBar =
|
|
[[MDCSafeAreaCustomizingBottomNavigationBar alloc] initWithFrame:barFrame];
|
|
bottomNavBar.test_safeAreaInsets = UIEdgeInsetsZero;
|
|
CGSize initialSize = [bottomNavBar intrinsicContentSize];
|
|
|
|
// When
|
|
bottomNavBar.test_safeAreaInsets = UIEdgeInsetsMake(20, 20, 20, 20);
|
|
|
|
// Then
|
|
CGSize finalSize = [bottomNavBar intrinsicContentSize];
|
|
XCTAssertFalse(CGSizeEqualToSize(finalSize, CGSizeZero),
|
|
"intrinsicContentSize should not return CGSizeZero");
|
|
XCTAssertTrue(CGSizeEqualToSize(finalSize, initialSize), @"(%@) is not equal to (%@)",
|
|
NSStringFromCGSize(finalSize), NSStringFromCGSize(initialSize));
|
|
}
|
|
|
|
#pragma mark - Property propagation
|
|
|
|
- (void)testTitlesNumberOfLinesPassedToViewsBeforeItemsAssigned {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
self.bottomNavBar.alignment = MDCBottomNavigationBarAlignmentJustified;
|
|
|
|
// When
|
|
self.bottomNavBar.titlesNumberOfLines = 7;
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
|
|
// Then
|
|
for (MDCBottomNavigationItemView *itemView in self.bottomNavBar.itemViews) {
|
|
XCTAssertEqual(itemView.titleNumberOfLines, self.bottomNavBar.titlesNumberOfLines);
|
|
}
|
|
}
|
|
|
|
- (void)testTitlesNumberOfLinesPassedToViewsAfterItemsAssigned {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
self.bottomNavBar.alignment = MDCBottomNavigationBarAlignmentJustified;
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
self.bottomNavBar.titlesNumberOfLines = 7;
|
|
|
|
// Then
|
|
for (MDCBottomNavigationItemView *itemView in self.bottomNavBar.itemViews) {
|
|
XCTAssertEqual(itemView.titleNumberOfLines, self.bottomNavBar.titlesNumberOfLines);
|
|
}
|
|
}
|
|
|
|
- (void)testItemForPointInsideItemViewReturnsCorrespondingItem {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 320, 56);
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
UIView *view1 = [self.bottomNavBar viewForItem:item1];
|
|
UIView *view2 = [self.bottomNavBar viewForItem:item2];
|
|
UITabBarItem *result1 = [self.bottomNavBar tabBarItemForPoint:view1.center];
|
|
UITabBarItem *result2 = [self.bottomNavBar tabBarItemForPoint:view2.center];
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(result1, item1);
|
|
XCTAssertEqualObjects(result2, item2);
|
|
}
|
|
|
|
- (void)testItemForPointOutsideNavigationBarReturnsNil {
|
|
// Given
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"1" image:nil tag:0];
|
|
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"2" image:nil tag:0];
|
|
CGFloat navBarHeight = 56;
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 320, navBarHeight);
|
|
CGPoint testPoint = CGPointMake(0, navBarHeight + 10);
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item1, item2 ];
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
UITabBarItem *result = [self.bottomNavBar tabBarItemForPoint:testPoint];
|
|
|
|
// Then
|
|
XCTAssertNil(result);
|
|
}
|
|
|
|
- (void)testItemForPointInsideNavigationBarNoTabBarItemsReturnsNil {
|
|
// Given
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 320, 56);
|
|
|
|
// When
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
UITabBarItem *result = [self.bottomNavBar tabBarItemForPoint:self.bottomNavBar.center];
|
|
|
|
// Then
|
|
XCTAssertNil(result);
|
|
}
|
|
|
|
- (NSInteger)countOfButtonsWithAccessibilityHint:(NSString *)accessibilityHint
|
|
fromRootView:(UIView *)view {
|
|
BOOL foundMatchingElement = NO;
|
|
foundMatchingElement = ([view isKindOfClass:[UIButton class]] &&
|
|
[view.accessibilityHint isEqualToString:accessibilityHint]);
|
|
NSInteger count = foundMatchingElement ? 1 : 0;
|
|
for (UIView *subview in view.subviews) {
|
|
count += [self countOfButtonsWithAccessibilityHint:accessibilityHint fromRootView:subview];
|
|
}
|
|
return count;
|
|
}
|
|
|
|
- (void)testSettingAccessibilityHintPropagatesToOneUIButtonSubview {
|
|
// Given
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:9];
|
|
item.accessibilityHint = @"__h_i_n_t__";
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// Then
|
|
XCTAssertEqual([self countOfButtonsWithAccessibilityHint:item.accessibilityHint
|
|
fromRootView:self.bottomNavBar],
|
|
1);
|
|
}
|
|
|
|
#pragma mark - traitCollectionDidChangeBlock
|
|
|
|
- (void)testTraitCollectionDidChangeBlockCalledWhenTraitCollectionChanges {
|
|
// Given
|
|
__block MDCBottomNavigationBar *passedBottomNavigationBar = nil;
|
|
__block UITraitCollection *passedTraitCollection = nil;
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Called traitCollectionDidChangeBlock"];
|
|
UITraitCollection *testTraitCollection = [UITraitCollection traitCollectionWithDisplayScale:77];
|
|
void (^block)(MDCBottomNavigationBar *_Nonnull, UITraitCollection *_Nullable) = ^void(
|
|
MDCBottomNavigationBar *bottomNavigationBar, UITraitCollection *previousTraitCollection) {
|
|
passedBottomNavigationBar = bottomNavigationBar;
|
|
passedTraitCollection = previousTraitCollection;
|
|
[expectation fulfill];
|
|
};
|
|
self.bottomNavBar.traitCollectionDidChangeBlock = block;
|
|
|
|
// When
|
|
[self.bottomNavBar traitCollectionDidChange:testTraitCollection];
|
|
[self waitForExpectations:@[ expectation ] timeout:1];
|
|
|
|
// Then
|
|
XCTAssertEqual(passedBottomNavigationBar, self.bottomNavBar);
|
|
XCTAssertEqual(passedTraitCollection, testTraitCollection);
|
|
}
|
|
|
|
#pragma mark - MaterialElevation
|
|
|
|
- (void)testDefaultValueForOverrideBaseElevationIsNegative {
|
|
// Given
|
|
MDCBottomNavigationBar *bottomNavigationBar = [[MDCBottomNavigationBar alloc] init];
|
|
|
|
// Then
|
|
XCTAssertLessThan(bottomNavigationBar.mdc_overrideBaseElevation, 0);
|
|
}
|
|
|
|
- (void)testSettingOverrideBaseElevationReturnsSetValue {
|
|
// Given
|
|
CGFloat expectedBaseElevation = 99;
|
|
|
|
// When
|
|
self.bottomNavBar.mdc_overrideBaseElevation = expectedBaseElevation;
|
|
|
|
// Then
|
|
XCTAssertEqualWithAccuracy(self.bottomNavBar.mdc_overrideBaseElevation, expectedBaseElevation,
|
|
0.001);
|
|
}
|
|
|
|
- (void)testCurrentElevationMatchesElevationWhenElevationChanges {
|
|
// When
|
|
self.bottomNavBar.elevation = MDCShadowElevationQuickEntryResting;
|
|
|
|
// Then
|
|
XCTAssertEqualWithAccuracy(self.bottomNavBar.mdc_currentElevation, self.bottomNavBar.elevation,
|
|
0.001);
|
|
}
|
|
|
|
- (void)testElevationDidChangeBlockCalledWhenElevationChangesValue {
|
|
// Given
|
|
self.bottomNavBar.elevation = 5;
|
|
__block BOOL blockCalled = NO;
|
|
self.bottomNavBar.mdc_elevationDidChangeBlock = ^(id<MDCElevatable> _, CGFloat elevation) {
|
|
blockCalled = YES;
|
|
};
|
|
|
|
// When
|
|
self.bottomNavBar.elevation = self.bottomNavBar.elevation + 1;
|
|
|
|
// Then
|
|
XCTAssertTrue(blockCalled);
|
|
}
|
|
|
|
- (void)testElevationDidChangeBlockNotCalledWhenElevationIsSetWithoutChangingValue {
|
|
// Given
|
|
self.bottomNavBar.elevation = 5;
|
|
__block BOOL blockCalled = NO;
|
|
self.bottomNavBar.mdc_elevationDidChangeBlock = ^(id<MDCElevatable> _, CGFloat elevation) {
|
|
blockCalled = YES;
|
|
};
|
|
|
|
// When
|
|
self.bottomNavBar.elevation = self.bottomNavBar.elevation;
|
|
|
|
// Then
|
|
XCTAssertFalse(blockCalled);
|
|
}
|
|
|
|
- (void)testSettingBarHeightPropertyUpdatesIntrinsicContentSizeOfBar {
|
|
// Given
|
|
CGFloat barHeight = 20;
|
|
|
|
// When
|
|
self.bottomNavBar.barHeight = barHeight;
|
|
|
|
// Then
|
|
XCTAssertEqual(self.bottomNavBar.intrinsicContentSize.height, barHeight);
|
|
}
|
|
|
|
- (void)testSettingBarHeightPropertyUpdatesSizeThatFitsOfBar {
|
|
// Given
|
|
CGFloat barHeight = 20;
|
|
|
|
// When
|
|
self.bottomNavBar.barHeight = barHeight;
|
|
|
|
// Then
|
|
XCTAssertEqual([self.bottomNavBar sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)].height,
|
|
barHeight);
|
|
}
|
|
|
|
- (void)testSettingSelectionIndicatorColor {
|
|
// Given
|
|
UIColor *testColor = UIColor.greenColor;
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item ];
|
|
self.bottomNavBar.selectionIndicatorColor = testColor;
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(self.bottomNavBar.itemViews.firstObject.selectionIndicatorColor,
|
|
UIColor.greenColor);
|
|
}
|
|
|
|
- (void)testSettingSelectionIndicatorColorBeforeSettingItems {
|
|
// Given
|
|
UIColor *testColor = UIColor.greenColor;
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.selectionIndicatorColor = testColor;
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(self.bottomNavBar.itemViews.firstObject.selectionIndicatorColor,
|
|
UIColor.greenColor);
|
|
}
|
|
|
|
- (void)testSettingSelectionIndicatorSize {
|
|
// Given
|
|
CGSize testSize = CGSizeMake(20, 20);
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.items = @[ item ];
|
|
self.bottomNavBar.selectionIndicatorSize = testSize;
|
|
|
|
// Then
|
|
XCTAssertTrue(
|
|
CGSizeEqualToSize(self.bottomNavBar.itemViews.firstObject.selectionIndicatorSize, testSize),
|
|
@"%@ not equal to %@",
|
|
NSStringFromCGSize(self.bottomNavBar.itemViews.firstObject.selectionIndicatorSize),
|
|
NSStringFromCGSize(testSize));
|
|
}
|
|
|
|
- (void)testSettingSelectionIndicatorSizeBeforeSettingItems {
|
|
// Given
|
|
CGSize testSize = CGSizeMake(20, 20);
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:0];
|
|
|
|
// When
|
|
self.bottomNavBar.selectionIndicatorSize = testSize;
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// Then
|
|
XCTAssertTrue(
|
|
CGSizeEqualToSize(self.bottomNavBar.itemViews.firstObject.selectionIndicatorSize, testSize),
|
|
@"%@ not equal to %@",
|
|
NSStringFromCGSize(self.bottomNavBar.itemViews.firstObject.selectionIndicatorSize),
|
|
NSStringFromCGSize(testSize));
|
|
}
|
|
|
|
#pragma mark - UILargeContentViewerItem
|
|
|
|
#if MDC_AVAILABLE_SDK_IOS(13_0)
|
|
/** Tests the large content title when the title should not contain a badge. */
|
|
- (void)testLargeContentTitle {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// When.
|
|
NSString *largeContentTitle = self.bottomNavBar.itemViews.firstObject.largeContentTitle;
|
|
|
|
// Then.
|
|
XCTAssertEqualObjects(largeContentTitle, item.title);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Tests the large content image is the @c image property when no @c largeContentImage is
|
|
specified.
|
|
*/
|
|
- (void)testLargeContentImageWithDefaultImage {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UIImage *image = [[UIImage alloc] init];
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:nil image:image tag:0];
|
|
item.largeContentSizeImage = image;
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// When.
|
|
UIImage *largeContentImage = self.bottomNavBar.itemViews.firstObject.largeContentImage;
|
|
|
|
// Then.
|
|
XCTAssertEqualObjects(largeContentImage, image);
|
|
}
|
|
}
|
|
|
|
/** Tests the large content item's image is the @c largeContentSizeImage . */
|
|
- (void)testLargeContentImageWithTabBarLargeContentImage {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UIImage *image = [[UIImage alloc] init];
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:nil image:nil tag:0];
|
|
item.largeContentSizeImage = image;
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// When.
|
|
UIImage *largeContentImage = self.bottomNavBar.itemViews.firstObject.largeContentImage;
|
|
|
|
// Then.
|
|
XCTAssertEqualObjects(largeContentImage, image);
|
|
}
|
|
}
|
|
|
|
/** Tests the large content image insets are set. */
|
|
- (void)testLargeContentImageInsets {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:nil image:nil tag:0];
|
|
item.largeContentSizeImageInsets = insets;
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// When.
|
|
UIEdgeInsets largeImageInsets = self.bottomNavBar.itemViews.firstObject.largeContentImageInsets;
|
|
|
|
// Then.
|
|
XCTAssertEqual(largeImageInsets.bottom, insets.bottom);
|
|
XCTAssertEqual(largeImageInsets.top, insets.top);
|
|
XCTAssertEqual(largeImageInsets.left, insets.left);
|
|
XCTAssertEqual(largeImageInsets.right, insets.right);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Tests the large content item's image is updated when the tab bar's @c largeContentSizeImage is
|
|
updated.
|
|
*/
|
|
- (void)testLargeContentImageUpdatedWhenTabBarPropertyUpdates {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UIImage *image = [[UIImage alloc] init];
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:nil image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// When.
|
|
item.largeContentSizeImage = image;
|
|
UIImage *largeContentImage = self.bottomNavBar.itemViews.firstObject.largeContentImage;
|
|
|
|
// Then.
|
|
XCTAssertEqualObjects(largeContentImage, image);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Tests the large content inets are update when the tab bar's @c largeContentSizeImageInsets are
|
|
updated.
|
|
*/
|
|
- (void)testLargeContentInsetUpdatedWhenTabBarPropertyUpdates {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:nil image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item ];
|
|
|
|
// When.
|
|
item.largeContentSizeImageInsets = insets;
|
|
UIEdgeInsets largeContentInsets =
|
|
self.bottomNavBar.itemViews.firstObject.largeContentImageInsets;
|
|
|
|
// Then.
|
|
XCTAssertEqual(largeContentInsets.left, insets.left);
|
|
XCTAssertEqual(largeContentInsets.bottom, insets.bottom);
|
|
XCTAssertEqual(largeContentInsets.right, insets.right);
|
|
XCTAssertEqual(largeContentInsets.top, insets.top);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Tests the last shown large content item is still returned when the interaction touch point is
|
|
still within the bounds of the navigation bar.
|
|
*/
|
|
- (void)testLargeContentViewerInteractionWhenItemIsSelectedThenDeselectedButStillInNavBarBounds {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
NSString *title1 = @"Title1";
|
|
UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:title1 image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item1 ];
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 350, 125);
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
UILargeContentViewerInteraction *interaction = [[UILargeContentViewerInteraction alloc] init];
|
|
self.continueAfterFailure = NO;
|
|
|
|
// When/Then.
|
|
XCTAssertTrue([self.bottomNavBar respondsToSelector:@selector(largeContentViewerInteraction:
|
|
itemAtPoint:)]);
|
|
CGPoint itemViewOrigin = self.bottomNavBar.itemViews.firstObject.frame.origin;
|
|
id<UILargeContentViewerItem> largeContentItem =
|
|
[self.bottomNavBar largeContentViewerInteraction:interaction itemAtPoint:itemViewOrigin];
|
|
XCTAssertEqualObjects(largeContentItem.largeContentTitle, title1);
|
|
|
|
largeContentItem = [self.bottomNavBar largeContentViewerInteraction:interaction
|
|
itemAtPoint:CGPointZero];
|
|
XCTAssertEqualObjects(largeContentItem.largeContentTitle, title1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Tests the large content item is nil when the touch point is outside the navigation bar bounds.
|
|
*/
|
|
- (void)testLargeContentViewerInteractionWhenPointIsOutSideNavBarBounds {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title1" image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item ];
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 350, 125);
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
UILargeContentViewerInteraction *interaction = [[UILargeContentViewerInteraction alloc] init];
|
|
self.continueAfterFailure = NO;
|
|
|
|
// When/Then.
|
|
XCTAssertTrue([self.bottomNavBar respondsToSelector:@selector(largeContentViewerInteraction:
|
|
itemAtPoint:)]);
|
|
CGPoint pointOutsideNavBar = CGPointMake(-1, -1);
|
|
|
|
id<UILargeContentViewerItem> largeContentItem =
|
|
[self.bottomNavBar largeContentViewerInteraction:interaction
|
|
itemAtPoint:pointOutsideNavBar];
|
|
XCTAssertNil(largeContentItem);
|
|
}
|
|
}
|
|
|
|
/** Tests the last shown large item is reset after an interaction ends. */
|
|
- (void)testLargeContentViewerInteractionResetsAfterEnding {
|
|
if (@available(iOS 13.0, *)) {
|
|
// Given.
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Title1" image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item ];
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 350, 125);
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
UILargeContentViewerInteraction *interaction = [[UILargeContentViewerInteraction alloc] init];
|
|
self.continueAfterFailure = NO;
|
|
|
|
// When/Then.
|
|
XCTAssertTrue([self.bottomNavBar respondsToSelector:@selector(largeContentViewerInteraction:
|
|
itemAtPoint:)]);
|
|
|
|
CGPoint pointInsideFirstItem = self.bottomNavBar.itemViews.firstObject.frame.origin;
|
|
id<UILargeContentViewerItem> endItem =
|
|
[self.bottomNavBar largeContentViewerInteraction:interaction
|
|
itemAtPoint:pointInsideFirstItem];
|
|
|
|
XCTAssertTrue([self.bottomNavBar
|
|
respondsToSelector:@selector(largeContentViewerInteraction:didEndOnItem:atPoint:)]);
|
|
[self.bottomNavBar largeContentViewerInteraction:interaction
|
|
didEndOnItem:endItem
|
|
atPoint:CGPointZero];
|
|
|
|
id<UILargeContentViewerItem> itemAfterReset =
|
|
[self.bottomNavBar largeContentViewerInteraction:interaction itemAtPoint:CGPointZero];
|
|
if (@available(iOS 13, *)) {
|
|
// TODO(b/184162265): Evaluate why this behavior is different on iOS 13+.
|
|
XCTAssertNotNil(itemAfterReset);
|
|
} else {
|
|
XCTAssertNil(itemAfterReset);
|
|
}
|
|
}
|
|
}
|
|
#endif // MDC_AVAILABLE_SDK_IOS(13_0)
|
|
|
|
/**
|
|
Tests the @c itemsHorizontalPadding property
|
|
*/
|
|
- (void)testItemsHorizontalPaddingProperty {
|
|
// Given
|
|
NSString *title = @"Title";
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:title image:nil tag:0];
|
|
self.bottomNavBar.items = @[ item ];
|
|
self.bottomNavBar.frame = CGRectMake(0, 0, 350, 125);
|
|
[self.bottomNavBar sizeToFit];
|
|
|
|
// When
|
|
[self.bottomNavBar setNeedsLayout];
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
|
|
MDCBottomNavigationItemView *itemView = [self.bottomNavBar.itemViews firstObject];
|
|
CGRect expectedItemViewFrameWithDefaultItemsHorizontalPadding =
|
|
CGRectInset(self.bottomNavBar.frame, 0, 0);
|
|
CGRect actualItemViewFrameWithDefaultItemsHorizontalPadding = itemView.frame;
|
|
|
|
self.bottomNavBar.itemsHorizontalPadding = 0;
|
|
[self.bottomNavBar setNeedsLayout];
|
|
[self.bottomNavBar layoutIfNeeded];
|
|
CGRect expectedItemViewFrameWithZeroItemsHorizontalPadding = self.bottomNavBar.frame;
|
|
CGRect actualItemViewFrameWithZeroItemsHorizontalPadding = itemView.frame;
|
|
|
|
// Then
|
|
XCTAssertTrue(CGRectEqualToRect(expectedItemViewFrameWithDefaultItemsHorizontalPadding,
|
|
actualItemViewFrameWithDefaultItemsHorizontalPadding));
|
|
XCTAssertTrue(CGRectEqualToRect(expectedItemViewFrameWithZeroItemsHorizontalPadding,
|
|
actualItemViewFrameWithZeroItemsHorizontalPadding));
|
|
}
|
|
|
|
#ifdef __IPHONE_13_4
|
|
/**
|
|
Verifies that MDCBottomNavigation generates a non-nil UIPointerStyle for its item views.
|
|
*/
|
|
- (void)testPointerStyleIsNonNilWithMDCBottomNavigationItemView {
|
|
if (@available(iOS 13.4, *)) {
|
|
// Given
|
|
// Pointer interactions require that the view being interacted with is in a UIWindow
|
|
[self createWindowWithView:self.bottomNavBar];
|
|
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:kTestItemTitleText image:nil tag:0];
|
|
[self.bottomNavBar setItems:@[ item ]];
|
|
|
|
MDCBottomNavigationItemView *firstItemView = self.bottomNavBar.itemViews.firstObject;
|
|
UIPointerInteraction *interaction = firstItemView.interactions.firstObject;
|
|
XCTAssertEqual(interaction.delegate, self.bottomNavBar);
|
|
UIPointerRegion *region = [UIPointerRegion regionWithRect:firstItemView.frame identifier:nil];
|
|
UIPointerStyle *pointerStyle = [self.bottomNavBar pointerInteraction:interaction
|
|
styleForRegion:region];
|
|
|
|
// Then
|
|
XCTAssertNotNil(pointerStyle);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Verifies that MDCBottomNavigation does not generate a UIPointerStyle for a non-item view.
|
|
*/
|
|
- (void)testPointerStyleIsNilWithNonMDCBottomNavigationItemView {
|
|
if (@available(iOS 13.4, *)) {
|
|
// Given
|
|
// Pointer interactions require that the view being interacted with is in a UIWindow
|
|
[self createWindowWithView:self.bottomNavBar];
|
|
UIView *nonBottomNavigationItemView = [[UIView alloc] init];
|
|
UIPointerInteraction *interaction =
|
|
[[UIPointerInteraction alloc] initWithDelegate:self.bottomNavBar];
|
|
[nonBottomNavigationItemView addInteraction:interaction];
|
|
UIPointerRegion *region = [UIPointerRegion regionWithRect:nonBottomNavigationItemView.frame
|
|
identifier:nil];
|
|
UIPointerStyle *pointerStyle = [self.bottomNavBar pointerInteraction:interaction
|
|
styleForRegion:region];
|
|
|
|
// Then
|
|
XCTAssertNil(pointerStyle);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#pragma mark - Helpers
|
|
|
|
- (void)createWindowWithView:(UIView *)view {
|
|
UIWindow *window = [[UIWindow alloc] init];
|
|
[window addSubview:view];
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|