blob: 599e75c7bd5be233f5889ff093b78a4bb815ba68 [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 "MaterialAvailability.h"
#import "MaterialBanner.h"
#import "MaterialBanner+Theming.h"
#import "MaterialButtons.h"
#import "UIColor+MaterialDynamic.h"
#import "MaterialMath.h"
#import "MaterialColorScheme.h"
#import "MaterialContainerScheme.h"
#import "MaterialTypographyScheme.h"
// The opacity value applied to text view.
static CGFloat const kTextViewOpacity = (CGFloat)0.87;
// The opacity value applied to divider.
static CGFloat const kDividerOpacity = (CGFloat)0.12;
/**
This class is used for creating a @UIWindow with customized size category.
*/
@interface MDCBannerViewThemingTestsDynamicTypeContentSizeCategoryOverrideWindow : UIWindow
/** Used to override the value of @c preferredContentSizeCategory. */
@property(nonatomic, copy) UIContentSizeCategory contentSizeCategoryOverride;
@end
@implementation MDCBannerViewThemingTestsDynamicTypeContentSizeCategoryOverrideWindow
- (instancetype)init {
self = [super init];
if (self) {
self.contentSizeCategoryOverride = UIContentSizeCategoryLarge;
}
return self;
}
- (instancetype)initWithContentSizeCategoryOverride:
(UIContentSizeCategory)contentSizeCategoryOverride {
self = [super init];
if (self) {
self.contentSizeCategoryOverride = contentSizeCategoryOverride;
}
return self;
}
- (UITraitCollection *)traitCollection {
UITraitCollection *traitCollection = [UITraitCollection
traitCollectionWithPreferredContentSizeCategory:self.contentSizeCategoryOverride];
return traitCollection;
}
@end
/**
This class confirms behavior of @c MDCBannerView.
*/
@interface MDCBannerViewThemingTests : XCTestCase
@property(nonatomic, strong, nullable) MDCBannerView *bannerView;
@property(nonatomic, strong, nullable) MDCContainerScheme *containerScheme;
@end
@implementation MDCBannerViewThemingTests
- (void)setUp {
[super setUp];
self.bannerView = [[MDCBannerView alloc] init];
self.containerScheme = [[MDCContainerScheme alloc] init];
}
- (void)tearDown {
self.bannerView = nil;
self.containerScheme = nil;
[super tearDown];
}
- (void)testThemingWithCustomValues {
// Given
self.containerScheme.colorScheme.surfaceColor = UIColor.yellowColor;
self.containerScheme.colorScheme.onSurfaceColor = UIColor.cyanColor;
self.containerScheme.colorScheme.primaryColor = UIColor.purpleColor;
self.containerScheme.colorScheme.secondaryColor = UIColor.redColor;
self.containerScheme.colorScheme.backgroundColor = UIColor.blueColor;
self.containerScheme.colorScheme.elevationOverlayEnabledForDarkMode = YES;
self.containerScheme.typographyScheme.body2 = [UIFont systemFontOfSize:101.0];
// When
[self.bannerView applyThemeWithScheme:self.containerScheme];
// Then
NSUInteger maximumStateValue = UIControlStateNormal | UIControlStateSelected |
UIControlStateHighlighted | UIControlStateDisabled;
// Color
XCTAssertEqualObjects(self.bannerView.backgroundColor,
self.containerScheme.colorScheme.surfaceColor);
XCTAssertEqualObjects(
self.bannerView.textView.textColor,
[self.containerScheme.colorScheme.onSurfaceColor colorWithAlphaComponent:kTextViewOpacity]);
XCTAssertEqualObjects(
self.bannerView.dividerColor,
[self.containerScheme.colorScheme.onSurfaceColor colorWithAlphaComponent:kDividerOpacity]);
XCTAssertEqualObjects(self.bannerView.imageView.tintColor,
self.containerScheme.colorScheme.primaryColor);
for (NSUInteger state = 0; state <= maximumStateValue; ++state) {
XCTAssertEqualObjects([self.bannerView.leadingButton titleColorForState:UIControlStateNormal],
self.containerScheme.colorScheme.primaryColor);
XCTAssertEqualObjects(
[self.bannerView.leadingButton imageTintColorForState:UIControlStateNormal],
self.containerScheme.colorScheme.primaryColor);
XCTAssertEqualObjects([self.bannerView.trailingButton titleColorForState:UIControlStateNormal],
self.containerScheme.colorScheme.primaryColor);
XCTAssertEqualObjects(
[self.bannerView.trailingButton imageTintColorForState:UIControlStateNormal],
self.containerScheme.colorScheme.primaryColor);
}
// Typography
XCTAssertEqualObjects(self.bannerView.textView.font, self.containerScheme.typographyScheme.body2);
for (NSUInteger state = 0; state <= maximumStateValue; ++state) {
XCTAssertEqualObjects([self.bannerView.leadingButton titleFontForState:state],
self.containerScheme.typographyScheme.button);
XCTAssertEqualObjects([self.bannerView.trailingButton titleFontForState:state],
self.containerScheme.typographyScheme.button);
}
[self assertTraitCollectionAndElevationBlockForBannerView:self.bannerView
colorScheme:self.containerScheme.colorScheme];
}
- (void)assertTraitCollectionAndElevationBlockForBannerView:(MDCBannerView *)bannerView
colorScheme:(id<MDCColorScheming>)colorScheme {
if (colorScheme.elevationOverlayEnabledForDarkMode) {
XCTAssertNotNil(bannerView.mdc_elevationDidChangeBlock);
XCTAssertNotNil(bannerView.traitCollectionDidChangeBlock);
} else {
XCTAssertNil(bannerView.mdc_elevationDidChangeBlock);
XCTAssertNil(bannerView.traitCollectionDidChangeBlock);
}
}
// TODO(https://github.com/material-components/material-components-ios/issues/8532): Replace the
// usage of this method with generic macro when available.
- (BOOL)compareColorsWithFloatPrecisionFirstColor:(UIColor *)firstColor
secondColor:(UIColor *)secondColor {
CGFloat fRed = 0.0, fGreen = 0.0, fBlue = 0.0, fAlpha = 0.0;
[firstColor getRed:&fRed green:&fGreen blue:&fBlue alpha:&fAlpha];
CGFloat sRed = 0.0, sGreen = 0.0, sBlue = 0.0, sAlpha = 0.0;
[secondColor getRed:&sRed green:&sGreen blue:&sBlue alpha:&sAlpha];
return (MDCCGFloatEqual(fRed, sRed) && MDCCGFloatEqual(fGreen, sGreen) &&
MDCCGFloatEqual(fBlue, sBlue) && MDCCGFloatEqual(fAlpha, sAlpha));
}
@end