mirror of
https://github.com/material-components/material-components-ios.git
synced 2026-02-20 08:27:32 +08:00
712 lines
24 KiB
Objective-C
712 lines
24 KiB
Objective-C
// 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 "MDCButton.h"
|
|
#import "MDCShadowElevations.h"
|
|
#import "MDCSnackbarManager.h"
|
|
#import "MDCSnackbarMessage.h"
|
|
#import "MDCSnackbarMessageView.h"
|
|
#import "MDCFakeMDCSnackbarManagerDelegate.h"
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wprivate-header"
|
|
#import "MDCSnackbarManagerInternal.h"
|
|
#import "MDCSnackbarOverlayView.h"
|
|
#pragma clang diagnostic pop
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
static const int64_t kDispatchTimeWait = (int64_t)((CGFloat)0.2 * NSEC_PER_SEC);
|
|
|
|
@interface MDCSnackbarManagerInternal (Testing)
|
|
@property(nonatomic) MDCSnackbarMessageView *currentSnackbar;
|
|
@property(nonatomic) MDCSnackbarOverlayView *overlayView;
|
|
@property(nonatomic) BOOL isVoiceOverRunningOverride;
|
|
@end
|
|
@interface MDCSnackbarManager (Testing)
|
|
@property(nonnull, nonatomic, strong) MDCSnackbarManagerInternal *internalManager;
|
|
@end
|
|
@interface MDCSnackbarMessageView (Testing)
|
|
@property(nonatomic, strong) UILabel *label;
|
|
@end
|
|
|
|
/** Fake MDCChipView for unit testing. */
|
|
@interface MDCSnackbarMessageViewTestsFakeView : MDCSnackbarMessageView
|
|
|
|
/** Used to set the value of @c traitCollection. */
|
|
@property(nonatomic, strong) UITraitCollection *traitCollectionOverride;
|
|
|
|
@end
|
|
|
|
@implementation MDCSnackbarMessageViewTestsFakeView
|
|
|
|
- (UITraitCollection *)traitCollection {
|
|
return self.traitCollectionOverride ?: [super traitCollection];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface MDCSnackbarMessageViewTests : XCTestCase
|
|
@property(nonatomic, strong, nullable) MDCSnackbarManager *manager;
|
|
@property(nonatomic, strong, nullable) FakeMDCSnackbarManagerDelegate *delegate;
|
|
@property(nonatomic, strong, nullable) MDCSnackbarMessage *message;
|
|
@end
|
|
|
|
@implementation MDCSnackbarMessageViewTests
|
|
|
|
- (void)setUp {
|
|
[super setUp];
|
|
|
|
self.manager = [[MDCSnackbarManager alloc] init];
|
|
self.delegate = [[FakeMDCSnackbarManagerDelegate alloc] init];
|
|
self.manager.delegate = self.delegate;
|
|
self.message = [MDCSnackbarMessage messageWithText:@"message text"];
|
|
}
|
|
|
|
- (void)tearDown {
|
|
[self.manager dismissAndCallCompletionBlocksWithCategory:nil];
|
|
self.message = nil;
|
|
self.manager.delegate = nil;
|
|
self.delegate = nil;
|
|
self.manager = nil;
|
|
|
|
[super tearDown];
|
|
}
|
|
|
|
- (void)testMessageDescription {
|
|
// Given
|
|
NSString *text = @"the message text";
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
|
|
// When
|
|
self.message.text = text;
|
|
self.message.action = action;
|
|
|
|
// Then
|
|
XCTAssertNotNil(self.message.description);
|
|
XCTAssertTrue([self.message.description containsString:@"text:"]);
|
|
XCTAssertTrue([self.message.description containsString:text]);
|
|
XCTAssertTrue([self.message.description containsString:@"action:"]);
|
|
XCTAssertTrue([self.message.description containsString:action.title]);
|
|
XCTAssertTrue([self.message.description containsString:@"viewClass:"]);
|
|
XCTAssertTrue([self.message.description containsString:@"MDCSnackbarMessageView"]);
|
|
}
|
|
|
|
- (void)testSettingMessageActionWithNilTitleAsserts {
|
|
// Given
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
|
|
// When/Then
|
|
XCTAssertThrows(self.message.action = action);
|
|
}
|
|
|
|
- (void)testSettingMessageActionWithEmptyTitleAsserts {
|
|
// Given
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"";
|
|
|
|
// When/Then
|
|
XCTAssertThrows(self.message.action = action);
|
|
}
|
|
|
|
- (void)testDescription {
|
|
// Given
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
MDCSnackbarMessageView *messageView = self.delegate.presentedView;
|
|
XCTAssertNotNil(messageView.description);
|
|
XCTAssertTrue([messageView.description containsString:@"message:"]);
|
|
XCTAssertTrue([messageView.description containsString:@"MDCSnackbarMessage"]);
|
|
}
|
|
|
|
- (void)testDefaultColors {
|
|
// Given
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(messageView.snackbarMessageViewBackgroundColor,
|
|
[UIColor colorWithRed:(CGFloat)(0x32 / 255.0)
|
|
green:(CGFloat)(0x32 / 255.0)
|
|
blue:(CGFloat)(0x32 / 255.0)
|
|
alpha:1]);
|
|
XCTAssertEqualObjects(messageView.snackbarMessageViewShadowColor, UIColor.blackColor);
|
|
XCTAssertEqualObjects(messageView.messageTextColor, UIColor.whiteColor);
|
|
}
|
|
|
|
- (void)testDefaultElevation {
|
|
// Then
|
|
XCTAssertEqual([[MDCSnackbarMessageView alloc] init].elevation, MDCShadowElevationSnackbar);
|
|
}
|
|
|
|
- (void)testCustomElevation {
|
|
// Given
|
|
CGFloat fakeElevation = 10;
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
|
|
// When
|
|
messageView.elevation = fakeElevation;
|
|
|
|
// Then
|
|
XCTAssertEqual(messageView.elevation, fakeElevation);
|
|
}
|
|
|
|
- (void)testAccessibilityLabelDefaultIsNil {
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
|
|
// Then
|
|
XCTAssertNil(self.delegate.presentedView.label.accessibilityLabel);
|
|
}
|
|
|
|
- (void)testAccessibilityLabelSetFromSnackbarMessageProperty {
|
|
// When
|
|
self.message.accessibilityLabel = @"not message text";
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(self.delegate.presentedView.label.accessibilityLabel,
|
|
self.message.accessibilityLabel);
|
|
}
|
|
|
|
- (void)testAccessibilityHintDefaultIsNotNil {
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertNotNil(self.delegate.presentedView.label.accessibilityHint);
|
|
}
|
|
|
|
- (void)testAccessibilityHintSetFromSnackbarMessageProperty {
|
|
// When
|
|
self.message.accessibilityHint = @"a hint";
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertEqualObjects(self.delegate.presentedView.label.accessibilityHint,
|
|
self.message.accessibilityHint);
|
|
}
|
|
|
|
- (void)testSnackbarAccessibiltyViewIsModalDefaultsToNoWithActions {
|
|
// Given
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertFalse(self.manager.internalManager.overlayView.accessibilityViewIsModal);
|
|
}
|
|
|
|
- (void)testSnackbarAccessibiltyViewIsModalDefaultsToNoWithNoActions {
|
|
// Given
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertFalse(self.manager.internalManager.overlayView.accessibilityViewIsModal);
|
|
}
|
|
|
|
- (void)testSnackbarAccessibilityViewIsModalIsYesWithActions {
|
|
// Given
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
self.manager.shouldEnableAccessibilityViewIsModal = YES;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertTrue(self.manager.internalManager.overlayView.accessibilityViewIsModal);
|
|
}
|
|
|
|
- (void)testSnackbarAccessibiltyViewIsModalIsNoWithoutActions {
|
|
// Given
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
self.manager.shouldEnableAccessibilityViewIsModal = YES;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertFalse(self.manager.internalManager.overlayView.accessibilityViewIsModal);
|
|
}
|
|
|
|
- (void)testSnackbarAccessibilityViewIsModalIsNoWithoutVoiceOverWithLegacyBehavior {
|
|
// Given
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
self.message.usesLegacyDismissalBehavior = YES;
|
|
self.manager.internalManager.isVoiceOverRunningOverride = NO;
|
|
self.manager.shouldEnableAccessibilityViewIsModal = YES;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertFalse(self.manager.internalManager.overlayView.accessibilityViewIsModal);
|
|
}
|
|
|
|
- (void)testSnackbarAccessibiltyViewIsModalWithSnackbarViewOverwriteWithActions {
|
|
// Given
|
|
self.delegate.shouldSetSnackbarViewAccessibilityViewIsModal = YES;
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertTrue(self.manager.internalManager.overlayView.accessibilityViewIsModal);
|
|
}
|
|
|
|
- (void)testSnackbarAccessibiltyViewIsModalWithSnackbarViewOverwriteWithNoActions {
|
|
// Given
|
|
self.delegate.shouldSetSnackbarViewAccessibilityViewIsModal = YES;
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertTrue(self.manager.internalManager.overlayView.accessibilityViewIsModal);
|
|
}
|
|
|
|
- (void)testSnackbarViewShowWhenShouldShowMessageWhenVoiceOverIsRunningIsYES {
|
|
// Given
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
self.manager.shouldShowMessageWhenVoiceOverIsRunning = YES;
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, kDispatchTimeWait);
|
|
dispatch_after(popTime, dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertNotNil(self.manager.internalManager.currentSnackbar);
|
|
}
|
|
|
|
- (void)testSnackbarViewNotShowWhenShouldShowMessageWhenVoiceOverIsRunningIsNO {
|
|
// Given
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
self.manager.shouldShowMessageWhenVoiceOverIsRunning = NO;
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, kDispatchTimeWait);
|
|
dispatch_after(popTime, dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertNil(self.manager.internalManager.currentSnackbar);
|
|
}
|
|
|
|
- (void)testManagerForwardsButtonProperties {
|
|
// Given
|
|
self.manager.uppercaseButtonTitle = NO;
|
|
self.manager.buttonInkColor = UIColor.redColor;
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
UIButton *actionButton = self.manager.internalManager.currentSnackbar.actionButton;
|
|
XCTAssertTrue([actionButton isKindOfClass:[MDCButton class]]);
|
|
MDCButton *button = (MDCButton *)actionButton;
|
|
XCTAssertFalse(button.uppercaseTitle);
|
|
XCTAssertEqualObjects(UIColor.redColor, button.inkColor);
|
|
}
|
|
|
|
- (void)testTraitCollectionDidChangeCalledWhenTraitCollectionChanges {
|
|
// Given
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Called traitCollectionDidChange"];
|
|
__block UITraitCollection *passedTraitCollection;
|
|
__block MDCSnackbarMessageView *passedMessageView;
|
|
messageView.traitCollectionDidChangeBlock =
|
|
^(MDCSnackbarMessageView *_Nonnull inMessageView,
|
|
UITraitCollection *_Nullable previousTraitCollection) {
|
|
passedMessageView = inMessageView;
|
|
passedTraitCollection = previousTraitCollection;
|
|
[expectation fulfill];
|
|
};
|
|
|
|
// When
|
|
UITraitCollection *testCollection = [UITraitCollection traitCollectionWithDisplayScale:77];
|
|
[messageView traitCollectionDidChange:testCollection];
|
|
|
|
// Then
|
|
[self waitForExpectations:@[ expectation ] timeout:1];
|
|
XCTAssertEqual(passedTraitCollection, testCollection);
|
|
XCTAssertEqual(passedMessageView, messageView);
|
|
}
|
|
|
|
- (void)testCurrentElevationMatchesElevationWhenElevationChanges {
|
|
// Given
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
|
|
// When
|
|
messageView.elevation = 4;
|
|
|
|
// Then
|
|
XCTAssertEqualWithAccuracy(messageView.mdc_currentElevation, messageView.elevation, 0.001);
|
|
}
|
|
|
|
- (void)testSettingOverrideBaseElevationReturnsSetValue {
|
|
// Given
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
CGFloat expectedBaseElevation = 99;
|
|
|
|
// When
|
|
messageView.mdc_overrideBaseElevation = expectedBaseElevation;
|
|
|
|
// Then
|
|
XCTAssertEqualWithAccuracy(messageView.mdc_overrideBaseElevation, expectedBaseElevation, 0.001);
|
|
}
|
|
|
|
- (void)testElevationDidChangeBlockCalledWhenElevationChangesValue {
|
|
// Given
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
messageView.elevation = 5;
|
|
__block BOOL blockCalled = NO;
|
|
messageView.mdc_elevationDidChangeBlock = ^(id<MDCElevatable> _, CGFloat elevation) {
|
|
blockCalled = YES;
|
|
};
|
|
|
|
// When
|
|
messageView.elevation = messageView.elevation + 1;
|
|
|
|
// Then
|
|
XCTAssertTrue(blockCalled);
|
|
}
|
|
|
|
- (void)testElevationDidChangeBlockNotCalledWhenElevationIsSetWithoutChangingValue {
|
|
// Given
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
messageView.elevation = 5;
|
|
__block BOOL blockCalled = NO;
|
|
messageView.mdc_elevationDidChangeBlock = ^(id<MDCElevatable> _, CGFloat elevation) {
|
|
blockCalled = YES;
|
|
};
|
|
|
|
// When
|
|
messageView.elevation = messageView.elevation;
|
|
|
|
// Then
|
|
XCTAssertFalse(blockCalled);
|
|
}
|
|
|
|
- (void)testDefaultValueForOverrideBaseElevationIsNegative {
|
|
// Given
|
|
MDCSnackbarMessageView *messageView = [[MDCSnackbarMessageView alloc] init];
|
|
|
|
// Then
|
|
XCTAssertLessThan(messageView.mdc_overrideBaseElevation, 0);
|
|
}
|
|
|
|
- (void)testMessageStaysWhenFocusOnShowIsEnabled {
|
|
// Given
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
self.message.focusOnShow = YES;
|
|
self.message.duration = 0.1;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, kDispatchTimeWait);
|
|
dispatch_after(popTime, dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertFalse(self.manager.internalManager.currentSnackbar.accessibilityElementsHidden);
|
|
}
|
|
|
|
- (void)testAccessibilityElementsVisibleWhenVoiceOverStatusEnabled {
|
|
// Given
|
|
MDCSnackbarMessageAction *action = [[MDCSnackbarMessageAction alloc] init];
|
|
action.title = @"Tap Me";
|
|
self.message.action = action;
|
|
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
// Wait for the snackbar to be displayed.
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
// Wait for the completion block to run after displaying the snackbar.
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
XCTAssertFalse(self.manager.internalManager.currentSnackbar.accessibilityElementsHidden);
|
|
// When
|
|
self.manager.internalManager.isVoiceOverRunningOverride = YES;
|
|
[[NSNotificationCenter defaultCenter]
|
|
postNotificationName:UIAccessibilityVoiceOverStatusDidChangeNotification
|
|
object:nil];
|
|
|
|
// Then
|
|
XCTAssertFalse(self.manager.internalManager.currentSnackbar.accessibilityElementsHidden);
|
|
}
|
|
|
|
- (void)testMessageCustomizationUsingWillPresentBlock {
|
|
// Given
|
|
__block BOOL blockCalled = NO;
|
|
self.message.snackbarMessageWillPresentBlock =
|
|
^(MDCSnackbarMessage *snackbarMessage, MDCSnackbarMessageView *messageView) {
|
|
blockCalled = YES;
|
|
};
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertTrue(blockCalled);
|
|
}
|
|
|
|
- (void)testMessageStaysWhenDurationIsZero {
|
|
// Given
|
|
self.message.duration = 0.1;
|
|
self.message.automaticallyDismisses = NO;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, kDispatchTimeWait);
|
|
dispatch_after(popTime, dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertNotNil(self.manager.internalManager.currentSnackbar);
|
|
}
|
|
|
|
- (void)testSnackbarDidDisappearDelegateCalled {
|
|
// Given
|
|
const CGFloat kSnackbarDuration = (CGFloat)0.1;
|
|
self.message.duration = kSnackbarDuration;
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
self.delegate.didDisappearExpectation = [self expectationWithDescription:@"didDisappear"];
|
|
// Then
|
|
// Expect 'snackbarDidDisappear' delegate method to be called.
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
}
|
|
|
|
- (void)testSnackbarWillDisappearDelegateCalled {
|
|
// Given
|
|
const CGFloat kSnackbarDuration = (CGFloat)0.1;
|
|
self.message.duration = kSnackbarDuration;
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
self.delegate.willDisappearExpectation = [self expectationWithDescription:@"willDisappear"];
|
|
// Then
|
|
// Expect 'snackbarWillDisappear' delegate method to be called.
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
}
|
|
|
|
- (void)testSettingPresentationHostViewOverrideDisplaysSnackbarInCorrectView {
|
|
// Given
|
|
UIView *customView = [[UIView alloc] init];
|
|
self.message.presentationHostViewOverride = customView;
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completed"];
|
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, kDispatchTimeWait);
|
|
dispatch_after(popTime, dispatch_get_main_queue(), ^{
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:3 handler:nil];
|
|
|
|
// Then
|
|
XCTAssertTrue([customView.subviews count] > 0);
|
|
XCTAssertEqual([customView.subviews.firstObject class], [MDCSnackbarOverlayView class]);
|
|
}
|
|
|
|
/**
|
|
* This test creates a snackbar with 'shouldDismissOnOverlayTap' enabled, presents it, waits for the
|
|
* snackbar to appear, and then taps the screen. The snackbar should dismiss at this point.
|
|
*/
|
|
- (void)testDismissOnScreenTap {
|
|
// Given
|
|
self.message.shouldDismissOnOverlayTap = YES;
|
|
self.message.duration = 0;
|
|
self.delegate.didDisappearExpectation = [self expectationWithDescription:@"didDisappear"];
|
|
self.delegate.willPresentExpectation = [self expectationWithDescription:@"willPresent"];
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
[self waitForExpectations:@[ self.delegate.willPresentExpectation ] timeout:0.5];
|
|
[self.manager.internalManager.overlayView pointInside:CGPointMake(3, 3) withEvent:nil];
|
|
|
|
// Then
|
|
[self waitForExpectationsWithTimeout:0.5 handler:nil];
|
|
}
|
|
|
|
/**
|
|
* This test is identical to the one above, but we do *not* tap the screen, and check to make sure
|
|
* the snackbar has *not* been dismissed.
|
|
*/
|
|
- (void)testDismissOnScreenTap_NoTap {
|
|
// Given
|
|
self.message.shouldDismissOnOverlayTap = YES;
|
|
self.message.duration = 0;
|
|
self.delegate.willPresentExpectation = [self expectationWithDescription:@"willPresent"];
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
[self waitForExpectationsWithTimeout:0.5 handler:nil];
|
|
|
|
// Then
|
|
[NSThread sleepForTimeInterval:0.5];
|
|
// Unfortunately, there is no way to to assert an expectation has *not* fired after a time
|
|
// interval. Instead we rely on 'internalManager.currentSnackbar' to be nil iff the snackbar is
|
|
// dismissed.
|
|
XCTAssertNotNil(self.manager.internalManager.currentSnackbar);
|
|
}
|
|
|
|
/**
|
|
* In a similar vein to the tests above, this test ensures the snackbar does *not* dismiss on tap if
|
|
* the user doesn't enable shouldDismissOnScreenTap.
|
|
*/
|
|
- (void)testNotDismissedOnScreenTap {
|
|
// Given
|
|
self.message.duration = 0;
|
|
self.delegate.willPresentExpectation = [self expectationWithDescription:@"willPresent"];
|
|
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
[self waitForExpectationsWithTimeout:0.5 handler:nil];
|
|
|
|
// Then
|
|
[NSThread sleepForTimeInterval:0.5];
|
|
// Unfortunately, there is no way to to assert an expectation has *not* fired after a time
|
|
// interval. Instead we rely on 'internalManager.currentSnackbar' to be nil iff the snackbar is
|
|
// dismissed.
|
|
XCTAssertNotNil(self.manager.internalManager.currentSnackbar);
|
|
}
|
|
|
|
- (void)testsnackbarIsPresentingDelegateCalled {
|
|
// Given
|
|
self.delegate.willPresentExpectation = [self expectationWithDescription:@"willPresent"];
|
|
self.delegate.isPresentingExpectation = [self expectationWithDescription:@"isPresenting"];
|
|
// When
|
|
[self.manager showMessage:self.message];
|
|
// Then
|
|
[self waitForExpectationsWithTimeout:0.2 handler:nil];
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|