blob: ab0352284d48b4c7ef647606b40b1fdbb8ca509b [file] [log] [blame] [edit]
// Copyright 2018-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 "../../src/private/MDCBottomDrawerContainerViewController.h"
#import "../../src/private/MDCBottomDrawerHeaderMask.h"
#import "MDCNavigationDrawerFakes.h"
@interface MDCBottomDrawerDelegateTest
: UIViewController <MDCBottomDrawerPresentationControllerDelegate>
@property(nonatomic, assign) BOOL delegateWasCalled;
@end
@implementation MDCBottomDrawerDelegateTest
- (instancetype)init {
self = [super init];
if (self) {
_delegateWasCalled = NO;
}
return self;
}
- (void)bottomDrawerWillChangeState:(MDCBottomDrawerPresentationController *)presentationController
drawerState:(MDCBottomDrawerState)drawerState {
_delegateWasCalled = YES;
}
- (void)bottomDrawerTopTransitionRatio:
(nonnull MDCBottomDrawerPresentationController *)presentationController
transitionRatio:(CGFloat)transitionRatio {
}
@end
@interface MDCBottomDrawerViewController (ScrollViewTests)
@property(nullable, nonatomic, readonly) MDCBottomDrawerHeaderMask *maskLayer;
@end
@interface MDCBottomDrawerContainerViewController (ScrollViewTests)
@property(nonatomic) BOOL scrollViewObserved;
@property(nonatomic, readonly) UIScrollView *scrollView;
@property(nonatomic, readonly) CGFloat topHeaderHeight;
@property(nonatomic, readonly) CGFloat contentHeaderHeight;
@property(nonatomic, readonly) CGFloat contentHeaderTopInset;
@property(nonatomic, readonly) CGRect presentingViewBounds;
@property(nonatomic, readonly) CGFloat contentHeightSurplus;
@property(nonatomic, readonly) BOOL contentScrollsToReveal;
@property(nonatomic) MDCBottomDrawerState drawerState;
@property(nonatomic) CGFloat initialDrawerFactor;
@property(nullable, nonatomic, readonly) UIPresentationController *presentationController;
- (void)cacheLayoutCalculations;
- (void)updateViewWithContentOffset:(CGPoint)contentOffset;
- (void)updateDrawerState:(CGFloat)transitionPercentage;
- (CGFloat)calculateInitialDrawerFactor;
@end
@interface MDCBottomDrawerPresentationController (ScrollViewTests) <
MDCBottomDrawerContainerViewControllerDelegate>
@property(nonatomic) MDCBottomDrawerContainerViewController *bottomDrawerContainerViewController;
@property(nonatomic, weak, nullable) id<MDCBottomDrawerPresentationControllerDelegate> delegate;
@property(nonatomic, strong, nullable) UIView *topHandle;
@end
@interface MDCNavigationDrawerScrollViewTests : XCTestCase
@property(nonatomic, strong, nullable) UIScrollView *fakeScrollView;
@property(nonatomic, strong, nullable) MDCBottomDrawerContainerViewController *fakeBottomDrawer;
@property(nonatomic, strong, nullable) MDCBottomDrawerViewController *drawerViewController;
@property(nonatomic, strong, nullable)
MDCBottomDrawerPresentationController *presentationController;
@property(nonatomic, strong, nullable) MDCBottomDrawerDelegateTest *delegateTest;
@end
@implementation MDCNavigationDrawerScrollViewTests
- (void)setUp {
[super setUp];
UIViewController *fakeViewController = [[UIViewController alloc] init];
fakeViewController.view.frame = CGRectMake(0, 0, 200, 500);
_fakeScrollView = [[UIScrollView alloc] init];
_fakeBottomDrawer = [[MDCBottomDrawerContainerViewController alloc]
initWithOriginalPresentingViewController:fakeViewController
trackingScrollView:_fakeScrollView];
_drawerViewController = [[MDCBottomDrawerViewController alloc] init];
_drawerViewController.contentViewController = fakeViewController;
_presentationController = [[MDCBottomDrawerPresentationController alloc]
initWithPresentedViewController:_drawerViewController
presentingViewController:nil];
_delegateTest = [[MDCBottomDrawerDelegateTest alloc] init];
MDCBottomDrawerPresentationController *presentationController =
(MDCBottomDrawerPresentationController *)self.drawerViewController.presentationController;
presentationController.bottomDrawerContainerViewController = self.fakeBottomDrawer;
self.fakeBottomDrawer.contentViewController = self.drawerViewController.contentViewController;
}
- (void)tearDown {
self.fakeScrollView = nil;
self.fakeBottomDrawer = nil;
[super tearDown];
}
- (void)setupHeaderWithPreferredContentSize:(CGSize)preferredContentSize {
MDCNavigationDrawerFakeHeaderViewController *fakeHeader =
[[MDCNavigationDrawerFakeHeaderViewController alloc] init];
self.fakeBottomDrawer.headerViewController = fakeHeader;
self.fakeBottomDrawer.headerViewController.preferredContentSize = preferredContentSize;
}
- (void)testScrollViewNotNil {
// Then
XCTAssertNotNil(self.fakeBottomDrawer.scrollView);
}
- (void)testScrollViewBeingObserved {
// When
[self.fakeBottomDrawer viewWillAppear:YES];
// Then
XCTAssertTrue(self.fakeBottomDrawer.scrollViewObserved);
}
- (void)testScrollViewNotBeingObserved {
// When
[self.fakeBottomDrawer viewWillAppear:YES];
[self.fakeBottomDrawer viewDidDisappear:YES];
// Then
XCTAssertFalse(self.fakeBottomDrawer.scrollViewObserved);
}
- (void)testPresentingViewBounds {
// Given
CGRect fakeRect = CGRectMake(0, 0, 250, 375);
// When
self.fakeBottomDrawer.originalPresentingViewController.view.bounds = fakeRect;
// Then
CGRect standardizePresentingViewBounds =
CGRectStandardize(self.fakeBottomDrawer.presentingViewBounds);
XCTAssertEqualWithAccuracy(standardizePresentingViewBounds.origin.x, fakeRect.origin.x, 0.001);
XCTAssertEqualWithAccuracy(standardizePresentingViewBounds.origin.y, fakeRect.origin.y, 0.001);
XCTAssertEqualWithAccuracy(standardizePresentingViewBounds.size.width, fakeRect.size.width,
0.001);
XCTAssertEqualWithAccuracy(standardizePresentingViewBounds.size.height, fakeRect.size.height,
0.001);
}
- (void)testContentHeaderHeightWithNoHeader {
// When
self.fakeBottomDrawer.headerViewController = nil;
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderHeight, 0, 0.001);
}
- (void)testContentHeaderHeightWithHeader {
// Given
CGSize fakePreferredContentSize = CGSizeMake(200, 300);
// When
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderHeight,
fakePreferredContentSize.height, 0.001);
}
- (void)testTopHeaderHeightWithNoHeader {
// When
self.fakeBottomDrawer.headerViewController = nil;
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.topHeaderHeight, 0, 0.001);
}
- (void)testTopHeaderHeightWithHeader {
// Given
// MDCDeviceTopSafeAreaInset adds 20 if there is no safe area and you are not in an application
CGFloat mdcDeviceTopSafeArea = 20;
CGSize fakePreferredContentSize = CGSizeMake(200, 300);
// When
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.topHeaderHeight,
mdcDeviceTopSafeArea + fakePreferredContentSize.height, 0.001);
}
- (void)testContentHeaderTopInsetWithHeaderAndContentViewController {
// Given
// Setup gives us presentingViewBounds of (0, 0, 200, 500)
CGSize fakePreferredContentSize = CGSizeMake(200, 300);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 100);
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// presentingViewBounds.size.height = 500 / 2 = 250
// The drawer should initially open to half the presentingViewBounds if there is more than
// half of the view's height worth of content
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 250, 0.001);
}
- (void)testContentHeaderTopInsetWithNoHeaderOrContentViewController {
// Given
// Setup gives us presentingViewbounds of (0, 0, 200, 500)
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// presentingViewBounds.size.height = 500, contentHeaderHeight = 0
// contentViewController.preferredContentSize.height = 0
// 500 - 0 - 0 = 500
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 500, 0.001);
}
- (void)testContentHeaderTopInsetWithHeaderAndNoContentViewController {
// Given
// Setup gives us presentingViewBounds of (0, 0, 200, 500)
CGSize fakePreferredContentSize = CGSizeMake(200, 300);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// presentingViewBounds.size.height = 500 / 2 = 250
// The drawer should initially open to half the presentingViewBounds if there is more than
// half of the view's height worth of content
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 250, 0.001);
}
- (void)testContentHeaderTopInsetWithOnlyContentViewController {
// Given
// Setup gives us presentingViewBounds of (0, 0, 200, 500)
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 100);
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// presentingViewBounds.size.height = 500, contentHeaderHeight = 0
// contentViewController.preferredContentSize.height = 100
// 500 - 0 - 100 = 400
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 400, 0.001);
}
- (void)testContentHeaderTopInsetForScrollableContentForLargeHeader {
// Given
// Setup gives us presentingViewBoudns of (0, 0, 200, 500)
CGSize fakePreferredContentSize = CGSizeMake(200, 700);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// In cacheLayoutCalculation we test if contentScrollsToReveal is true then contentHeaderTopInset
// should be initialDrawerFactor * presentingViewBounds = 500 * 0.5
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 250, 0.001);
}
- (void)testContentHeaderTopInsetForScrollableContentForLargeContent {
// Given
// Setup gives us presentingViewBounds of (0, 0, 200, 500)
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 1000);
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// In cacheLayoutCalculation we test if contentScrollsToReveal is true then contentHeaderTopInset
// should be initialDrawerFactor * presentingViewBounds = 500 * 0.5
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 250, 0.001);
}
- (void)testContentHeaderTopInsetForScrollableContent {
// Given
// Setup gives us presentingViewBounds of (0, 0, 200, 500)
CGSize fakePreferredContentSize = CGSizeMake(200, 700);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 1000);
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// In cacheLayoutCalculation we test if contentScrollsToReveal is true then contentHeaderTopInset
// should be initialDrawerFactor * presentingViewBounds = 500 * 0.5
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 250, 0.001);
}
- (void)testContentHeightSurplus {
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeightSurplus, 0, 0.001);
}
- (void)testContentHeightSurplusWithScrollabelContent {
// Given
CGSize fakePreferredContentSize = CGSizeMake(200, 1000);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 1500);
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeightSurplus, 2250, 0.001);
}
- (void)testContentScrollsToRevealFalse {
// Then
XCTAssertFalse(self.fakeBottomDrawer.contentScrollsToReveal);
}
- (void)testContentScrollsToRevealTrue {
CGSize fakePreferredContentSize = CGSizeMake(200, 1000);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 1500);
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
XCTAssertTrue(self.fakeBottomDrawer.contentScrollsToReveal);
}
- (void)testBottomDrawerStateCollapsed {
CGSize fakePreferredContentSize = CGSizeMake(200, 1000);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
// When
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 1500);
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
XCTAssertEqual(self.fakeBottomDrawer.drawerState, MDCBottomDrawerStateCollapsed);
}
- (void)testBottomDrawerStateExpanded {
CGSize fakePreferredContentSize = CGSizeMake(200, 100);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
// When
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 100);
[self.fakeBottomDrawer cacheLayoutCalculations];
// Then
// The drawer needs less than half the presentingViewBounds.height to be in an expanded state
// Unless if a user scrolls passed `initialDrawerFactor`.
XCTAssertEqual(self.fakeBottomDrawer.drawerState, MDCBottomDrawerStateExpanded);
}
- (void)testBottomDrawerStateFullScreen {
CGSize fakePreferredContentSize = CGSizeMake(200, 2000);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
// When
[self.fakeBottomDrawer cacheLayoutCalculations];
[self.fakeBottomDrawer updateDrawerState:1];
// Then
XCTAssertEqual(self.fakeBottomDrawer.drawerState, MDCBottomDrawerStateFullScreen);
}
- (void)testBottomDrawerStateCallback {
CGSize fakePreferredContentSize = CGSizeMake(200, 1000);
[self setupHeaderWithPreferredContentSize:fakePreferredContentSize];
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
// When
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 1500);
[self.fakeBottomDrawer cacheLayoutCalculations];
self.presentationController.delegate = self.delegateTest;
self.presentationController.bottomDrawerContainerViewController = self.fakeBottomDrawer;
self.fakeBottomDrawer.delegate = self.presentationController;
self.fakeBottomDrawer.drawerState = MDCBottomDrawerStateExpanded;
// Then
XCTAssertEqual(self.delegateTest.delegateWasCalled, YES);
}
- (void)testBottomDrawerCornersAPICollapsed {
// When
[self.drawerViewController setTopCornersRadius:10 forDrawerState:MDCBottomDrawerStateCollapsed];
// Then
XCTAssertEqual(self.drawerViewController.maskLayer.maximumCornerRadius, 10);
}
- (void)testBottomDrawerCornersAPIExpanded {
// When
self.drawerViewController.contentViewController.preferredContentSize = CGSizeMake(100, 100);
[self.fakeBottomDrawer cacheLayoutCalculations];
[self.drawerViewController setTopCornersRadius:5 forDrawerState:MDCBottomDrawerStateExpanded];
// Then
XCTAssertEqual(self.drawerViewController.maskLayer.minimumCornerRadius, 5);
}
- (void)testBottomDrawerCornersAPIFullScreen {
// When
self.drawerViewController.contentViewController.preferredContentSize = CGSizeMake(100, 5000);
[self.fakeBottomDrawer cacheLayoutCalculations];
[self.drawerViewController setTopCornersRadius:3 forDrawerState:MDCBottomDrawerStateFullScreen];
// Then
XCTAssertEqual(self.drawerViewController.maskLayer.minimumCornerRadius, 3);
}
- (void)testBottomDrawerDynamicSizing {
// Given
self.fakeBottomDrawer.contentViewController =
[[MDCNavigationDrawerFakeTableViewController alloc] init];
[self.fakeBottomDrawer viewDidLoad];
[self.fakeBottomDrawer cacheLayoutCalculations];
CGFloat previousContentHeaderTopInset = self.fakeBottomDrawer.contentHeaderTopInset;
// When
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(200, 200);
// Then
XCTAssertLessThan(self.fakeBottomDrawer.contentHeaderTopInset, previousContentHeaderTopInset);
}
- (void)testBottomDrawerHandle {
// When
[self.presentationController presentationTransitionWillBegin];
// Then
XCTAssertNotNil(self.presentationController.topHandle);
XCTAssertEqualWithAccuracy(CGRectGetWidth(self.presentationController.topHandle.frame),
(CGFloat)24.0, (CGFloat)0.001);
XCTAssertEqualWithAccuracy(CGRectGetHeight(self.presentationController.topHandle.frame),
(CGFloat)2.0, (CGFloat)0.001);
XCTAssertEqualWithAccuracy(self.presentationController.topHandle.layer.cornerRadius, (CGFloat)1.0,
(CGFloat)0.001);
XCTAssertEqual(self.presentationController.topHandle.hidden, YES);
}
- (void)testBottomDrawerHandleHidden {
// When
MDCBottomDrawerPresentationController *presentationController =
(MDCBottomDrawerPresentationController *)self.drawerViewController.presentationController;
presentationController.topHandle = [[UIView alloc] init];
presentationController.topHandle.hidden = YES;
self.drawerViewController.topHandleHidden = NO;
// Then
XCTAssertEqual(presentationController.topHandle.hidden, NO);
}
- (void)testBottomDrawerHandleColor {
// When
MDCBottomDrawerPresentationController *presentationController =
(MDCBottomDrawerPresentationController *)self.drawerViewController.presentationController;
presentationController.topHandle = [[UIView alloc] init];
presentationController.topHandle.backgroundColor = UIColor.blueColor;
self.drawerViewController.topHandleColor = UIColor.redColor;
// Then
XCTAssertEqualObjects(presentationController.topHandle.backgroundColor, UIColor.redColor);
}
- (void)testBottomDrawerScrollingEnabled {
// When
self.drawerViewController.trackingScrollView = self.fakeScrollView;
// Then
XCTAssertEqual(self.fakeScrollView.scrollEnabled, NO);
}
- (void)testSetTrackingScrollViewAfterSetScrimColor {
// Given
MDCBottomDrawerPresentationController *drawerPresentationController =
(MDCBottomDrawerPresentationController *)self.drawerViewController.presentationController;
// When
// Setting the scrim color before setting the tracking scroll view in some cases used to
// not set the trackingScrollView on bottomDrawerContainerViewController.
self.drawerViewController.scrimColor = UIColor.blueColor;
self.drawerViewController.trackingScrollView = self.fakeScrollView;
// Then
XCTAssertNotNil(
drawerPresentationController.bottomDrawerContainerViewController.trackingScrollView);
}
- (void)testBottomDrawerTopInset {
// Given
MDCNavigationDrawerFakeHeaderViewController *fakeHeader =
[[MDCNavigationDrawerFakeHeaderViewController alloc] init];
self.fakeBottomDrawer.headerViewController = fakeHeader;
self.drawerViewController.delegate = fakeHeader;
self.fakeBottomDrawer.delegate = self.presentationController;
[self.presentationController presentationTransitionWillBegin];
// When
[self.fakeBottomDrawer viewWillAppear:YES];
[self.fakeBottomDrawer cacheLayoutCalculations];
[self.fakeBottomDrawer.scrollView setContentOffset:CGPointMake(0, 1000)];
// Then
XCTAssertEqualWithAccuracy(fakeHeader.topInset, (CGFloat)7.0, (CGFloat)0.001);
}
- (void)testContentReachesFullscreenPresentationControllerValue {
// When
[self.presentationController presentationTransitionWillBegin];
[self.presentationController.bottomDrawerContainerViewController cacheLayoutCalculations];
// Then
XCTAssertEqual(
self.presentationController.bottomDrawerContainerViewController.contentReachesFullscreen,
self.presentationController.contentReachesFullscreen);
}
- (void)testContentOffsetY {
// When
[self.drawerViewController setContentOffsetY:0 animated:YES];
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.scrollView.contentOffset.y, 500, (CGFloat)0.001);
}
- (void)testAddedHeight {
// Given
CGFloat contentViewControllerHeight =
CGRectStandardize(self.fakeBottomDrawer.contentViewController.view.frame).size.height;
CGFloat fakeHeight = 100;
self.fakeBottomDrawer.trackingScrollView = nil;
// When
[self.fakeBottomDrawer updateViewWithContentOffset:CGPointMake(0, fakeHeight)];
// Then
CGFloat newContentViewControllerHeight =
CGRectGetHeight(self.fakeBottomDrawer.contentViewController.view.frame);
CGFloat expectedHeight = contentViewControllerHeight + fakeHeight;
XCTAssertEqualWithAccuracy(newContentViewControllerHeight, expectedHeight, 0.001);
}
- (void)testAddedHeightWithMultipleScrolls {
// Given
CGFloat contentViewControllerHeight =
CGRectStandardize(self.fakeBottomDrawer.contentViewController.view.frame).size.height;
CGFloat fakeFirstHeight = 80;
CGFloat fakeSecondHeight = 100;
self.fakeBottomDrawer.trackingScrollView = nil;
// When
[self.fakeBottomDrawer updateViewWithContentOffset:CGPointMake(0, fakeFirstHeight)];
[self.fakeBottomDrawer updateViewWithContentOffset:CGPointMake(0, fakeSecondHeight)];
// Then
CGFloat newContentViewControllerHeight =
CGRectGetHeight(self.fakeBottomDrawer.contentViewController.view.frame);
CGFloat expectedHeight = contentViewControllerHeight + fakeSecondHeight;
XCTAssertEqualWithAccuracy(newContentViewControllerHeight, expectedHeight, 0.001);
}
- (void)testAddedHeightWithTrackingScrollView {
// Given
CGFloat contentViewControllerHeight =
CGRectStandardize(self.fakeBottomDrawer.contentViewController.view.frame).size.height;
CGFloat fakeHeight = 100;
self.fakeBottomDrawer.trackingScrollView = self.fakeScrollView;
// When
[self.fakeBottomDrawer updateViewWithContentOffset:CGPointMake(0, fakeHeight)];
// Then
CGFloat newContentViewControllerHeight =
CGRectGetHeight(self.fakeBottomDrawer.contentViewController.view.frame);
XCTAssertEqualWithAccuracy(newContentViewControllerHeight, contentViewControllerHeight, 0.001);
}
- (void)testCalculateInitialDrawerFactorWithSmallHeight {
// Given
CGRect fakeRect = CGRectMake(0, 0, 250, 500);
self.fakeBottomDrawer.originalPresentingViewController.view.bounds = fakeRect;
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(250, 100);
// When
CGFloat drawerFactor = [self.fakeBottomDrawer calculateInitialDrawerFactor];
// Then
XCTAssertEqualWithAccuracy(drawerFactor, 0.2, 0.001);
}
- (void)testCalculateInitialDrawerFactorWithLargeHeight {
// Given
CGRect fakeRect = CGRectMake(0, 0, 250, 500);
self.fakeBottomDrawer.originalPresentingViewController.view.bounds = fakeRect;
self.fakeBottomDrawer.contentViewController.preferredContentSize = CGSizeMake(250, 1000);
// When
CGFloat drawerFactor = [self.fakeBottomDrawer calculateInitialDrawerFactor];
// Then
XCTAssertEqualWithAccuracy(drawerFactor, 0.5, 0.001);
}
- (void)testExpandToFullScreen {
// Given
MDCNavigationDrawerFakeHeaderViewController *fakeHeader =
[[MDCNavigationDrawerFakeHeaderViewController alloc] init];
self.fakeBottomDrawer.headerViewController = fakeHeader;
XCTestExpectation *expectation = [self expectationWithDescription:@"expand complete"];
// When
[self.drawerViewController expandToFullscreenWithDuration:(CGFloat)0.2
completion:^(BOOL completed) {
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
// Then
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.trackingScrollView.frame.origin.y, 0, 0.001);
CGFloat expectedHeight = self.fakeBottomDrawer.presentingViewBounds.size.height -
fakeHeader.preferredContentSize.height;
XCTAssertEqualWithAccuracy(
CGRectGetHeight(self.fakeBottomDrawer.contentViewController.view.frame), expectedHeight,
0.001);
XCTAssertEqualWithAccuracy(CGRectGetMinY(self.fakeBottomDrawer.scrollView.frame), 0, 0.001);
XCTAssertEqualWithAccuracy(self.fakeBottomDrawer.contentHeaderTopInset, 20, 0.01);
}
@end