blob: 4557331401ffb7f1846cc692f48debc54fa49ab8 [file] [log] [blame] [edit]
// Copyright 2019-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>
#import <CoreGraphics/CoreGraphics.h>
#import "../../src/TabBarView/MDCTabBarView.h"
#import "../../src/TabBarView/private/MDCTabBarViewItemView.h"
#import "../../src/TabBarView/private/MDCTabBarViewItemViewDelegate.h"
// Minimum width of an item view.
static const CGFloat kMinWidth = 90;
// Maximum width of an item view.
static const CGFloat kLargeWidthSize = 360;
// Minimum (expected) height of an item view with only a title or image (not both).
static const CGFloat kMinHeightOfTitleOrImageOnlyView = 48;
// Minimum (expected) height of an item view with both a title and image.
static const CGFloat kMinHeightOfTitleAndImageView = 72;
static NSString *const kLongTitle = @"12345678901234567890123456789012345678901 "
"2345678901234567890123456789012345678901234567890 "
"3456789012345678901234567890123456789012345678901 "
"4567890123456789012345678901234567890123456789012";
static UIImage *fakeImage(CGFloat width, CGFloat height) {
CGSize imageSize = CGSizeMake(width, height);
UIGraphicsBeginImageContext(imageSize);
[UIColor.whiteColor setFill];
UIRectFill(CGRectMake(0, 0, imageSize.width, imageSize.height));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
@interface MDCTabBarViewItemViewTests : XCTestCase
/** The view being tested. */
@property(nonatomic, strong) MDCTabBarViewItemView *itemView;
@end
@implementation MDCTabBarViewItemViewTests
- (void)setUp {
[super setUp];
self.itemView = [[MDCTabBarViewItemView alloc] init];
MDCTabBarView *tabBarView = [[MDCTabBarView alloc] init];
self.itemView.itemViewDelegate = (id<MDCTabBarViewItemViewDelegate>)tabBarView;
}
- (void)tearDown {
self.itemView.itemViewDelegate = nil;
self.itemView = nil;
[super tearDown];
}
#pragma mark - -intrinsicContentSize
- (void)testIntrinsicContentSizeForNoTitleNoImageIsMinimumSize {
// When
CGSize intrinsicContentSize = self.itemView.intrinsicContentSize;
// Then
XCTAssertEqualWithAccuracy(intrinsicContentSize.width, kMinWidth, 0.001);
XCTAssertEqualWithAccuracy(intrinsicContentSize.height, kMinHeightOfTitleOrImageOnlyView, 0.001);
}
- (void)testIntrinsicContentSizeForShortTitleExpectedImageLimitsHeight {
// When
self.itemView.iconImageView.image = fakeImage(24, 24);
self.itemView.titleLabel.text = @"Favorites";
CGSize intrinsicContentSize = self.itemView.intrinsicContentSize;
// Then
XCTAssertGreaterThanOrEqual(intrinsicContentSize.width, kMinWidth);
XCTAssertEqualWithAccuracy(intrinsicContentSize.height, kMinHeightOfTitleAndImageView, 0.001);
}
- (void)testIntrinsicContentSizeWhenMinItemWidthIsSetOnDelegate {
// Given
self.itemView.itemViewDelegate.minItemWidth = 150;
// When
self.itemView.iconImageView.image = fakeImage(24, 24);
self.itemView.titleLabel.text = @"Favorites";
CGSize intrinsicContentSize = self.itemView.intrinsicContentSize;
// Then
XCTAssertGreaterThanOrEqual(intrinsicContentSize.width, 150);
XCTAssertEqualWithAccuracy(intrinsicContentSize.height, kMinHeightOfTitleAndImageView, 0.001);
}
#pragma mark - -sizeThatFits:
- (void)testSizeThatFitsForNoContentWithSmallDimensionsIsMinimumSize {
// When
CGSize fitSize = [self.itemView sizeThatFits:CGSizeZero];
// Then
XCTAssertEqualWithAccuracy(fitSize.width, kMinWidth, 0.001);
XCTAssertEqualWithAccuracy(fitSize.height, kMinHeightOfTitleOrImageOnlyView, 0.001);
}
- (void)testSizeThatFitsForNoContentWithReasonableDimensionsIsMinimumSize {
// Given
CGSize requestedSize = CGSizeMake(kMinWidth * 3, kMinHeightOfTitleOrImageOnlyView + 10);
// When
CGSize fitSize = [self.itemView sizeThatFits:requestedSize];
// Then
XCTAssertEqualWithAccuracy(fitSize.width, kMinWidth, 0.001);
XCTAssertEqualWithAccuracy(fitSize.height, kMinHeightOfTitleOrImageOnlyView, 0.001);
}
- (void)testSizeThatFitsForNoContentWithLargeDimensionsIsMinimumSize {
// Given
CGSize requestedSize = CGSizeMake(kLargeWidthSize + 10, kMinHeightOfTitleOrImageOnlyView + 10);
// When
CGSize fitSize = [self.itemView sizeThatFits:requestedSize];
// Then
XCTAssertEqualWithAccuracy(fitSize.width, kMinWidth, 0.001);
XCTAssertEqualWithAccuracy(fitSize.height, kMinHeightOfTitleOrImageOnlyView, 0.001);
}
// The fit size should first make the item view wide (up to the max) and then increase the height as
// necessary. The exception would be a font that is very large.
- (void)testSizeThatFitsForShortTitleExpectedImageLargerDimensionsLimitsHeight {
// When
self.itemView.iconImageView.image = fakeImage(24, 24);
self.itemView.titleLabel.text = @"Favorites";
CGSize fitSize = [self.itemView sizeThatFits:CGSizeMake(1000, 1000)];
// Then
XCTAssertGreaterThanOrEqual(fitSize.width, kMinWidth);
XCTAssertEqualWithAccuracy(fitSize.height, kMinHeightOfTitleAndImageView, 0.001);
}
#pragma mark - -contentFrame
- (void)testContentFrameForTextOnlyViewReturnsTitleLabelFittingFrame {
// When
self.itemView.titleLabel.text = @"Favorites";
[self.itemView sizeToFit];
// Then
// Grab the `contentFrame` before layout to be sure it's calculated correctly at any time.
CGRect contentFrame = self.itemView.contentFrame;
[self.itemView layoutIfNeeded];
XCTAssertFalse(CGRectEqualToRect(contentFrame, CGRectZero), @"(%@) is equal to (%@))",
NSStringFromCGRect(contentFrame), NSStringFromCGRect(CGRectZero));
XCTAssertEqualWithAccuracy(CGRectGetHeight(contentFrame),
CGRectGetHeight(self.itemView.titleLabel.bounds), 0.001);
XCTAssertLessThanOrEqual(CGRectGetWidth(contentFrame),
CGRectGetWidth(self.itemView.titleLabel.bounds));
CGPoint itemViewTopCenter =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMinY(self.itemView.bounds));
XCTAssertFalse(CGRectContainsPoint(contentFrame, itemViewTopCenter),
@"(%@) does not contain (%@)", NSStringFromCGRect(contentFrame),
NSStringFromCGPoint(itemViewTopCenter));
CGPoint itemViewMidBounds =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMidY(self.itemView.bounds));
XCTAssertTrue(CGRectContainsPoint(contentFrame, itemViewMidBounds), @"(%@) does not contain (%@)",
NSStringFromCGRect(contentFrame), NSStringFromCGPoint(itemViewMidBounds));
CGPoint itemViewBottomCenter =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMaxY(self.itemView.bounds));
XCTAssertFalse(CGRectContainsPoint(contentFrame, itemViewBottomCenter),
@"(%@) does not contain (%@)", NSStringFromCGRect(contentFrame),
NSStringFromCGPoint(itemViewBottomCenter));
}
- (void)testContentFrameForIconOnlyViewReturnsIconImageViewFittingFrame {
// When
self.itemView.iconImageView.image = fakeImage(24, 24);
[self.itemView sizeToFit];
// Then
// Grab the `contentFrame` before layout to be sure it's calculated correctly at any time.
CGRect contentFrame = self.itemView.contentFrame;
[self.itemView layoutIfNeeded];
XCTAssertFalse(CGRectEqualToRect(contentFrame, CGRectZero), @"(%@) is equal to (%@)",
NSStringFromCGRect(contentFrame), NSStringFromCGRect(CGRectZero));
XCTAssertEqualWithAccuracy(CGRectGetHeight(contentFrame),
CGRectGetHeight(self.itemView.iconImageView.bounds), 0.001);
XCTAssertLessThanOrEqual(CGRectGetWidth(contentFrame),
CGRectGetWidth(self.itemView.iconImageView.bounds));
CGPoint itemViewTopCenter =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMinY(self.itemView.bounds));
XCTAssertFalse(CGRectContainsPoint(contentFrame, itemViewTopCenter),
@"(%@) does not contain (%@)", NSStringFromCGRect(contentFrame),
NSStringFromCGPoint(itemViewTopCenter));
CGPoint itemViewMidBounds =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMidY(self.itemView.bounds));
XCTAssertTrue(CGRectContainsPoint(contentFrame, itemViewMidBounds), @"(%@) does not contain (%@)",
NSStringFromCGRect(contentFrame), NSStringFromCGPoint(itemViewMidBounds));
CGPoint itemViewBottomCenter =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMaxY(self.itemView.bounds));
XCTAssertFalse(CGRectContainsPoint(contentFrame, itemViewBottomCenter),
@"(%@) does not contain (%@)", NSStringFromCGRect(contentFrame),
NSStringFromCGPoint(itemViewBottomCenter));
}
- (void)testContentFrameForTextAndIconViewReturnsFrameWithTitleLabelWidthAndTitleImageHeight {
// When
self.itemView.iconImageView.image = fakeImage(24, 24);
self.itemView.titleLabel.text = @"Favorites";
[self.itemView sizeToFit];
// Then
// Grab the `contentFrame` before layout to be sure it's calculated correctly at any time.
CGRect contentFrame = self.itemView.contentFrame;
[self.itemView layoutIfNeeded];
XCTAssertFalse(CGRectEqualToRect(contentFrame, CGRectZero), @"(%@) is equal to (%@)",
NSStringFromCGRect(contentFrame), NSStringFromCGRect(CGRectZero));
XCTAssertGreaterThan(CGRectGetHeight(contentFrame),
CGRectGetHeight(self.itemView.titleLabel.bounds));
XCTAssertLessThanOrEqual(CGRectGetWidth(contentFrame),
CGRectGetWidth(self.itemView.titleLabel.bounds));
CGPoint itemViewTopCenter =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMinY(self.itemView.bounds));
XCTAssertFalse(CGRectContainsPoint(contentFrame, itemViewTopCenter),
@"(%@) does not contain (%@)", NSStringFromCGRect(contentFrame),
NSStringFromCGPoint(itemViewTopCenter));
CGPoint itemViewMidBounds =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMidY(self.itemView.bounds));
XCTAssertTrue(CGRectContainsPoint(contentFrame, itemViewMidBounds), @"(%@) does not contain (%@)",
NSStringFromCGRect(contentFrame), NSStringFromCGPoint(itemViewMidBounds));
CGPoint itemViewBottomCenter =
CGPointMake(CGRectGetMidX(self.itemView.bounds), CGRectGetMaxY(self.itemView.bounds));
XCTAssertFalse(CGRectContainsPoint(contentFrame, itemViewBottomCenter),
@"(%@) does not contain (%@)", NSStringFromCGRect(contentFrame),
NSStringFromCGPoint(itemViewBottomCenter));
}
@end