// Copyright 2016-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 "MaterialButtons.h"
#import "MaterialShadowElevations.h"
#import "MaterialShadowLayer.h"
#import "MaterialShapeLibrary.h"
#import "MaterialShapes.h"
#import "MaterialTypography.h"

static const CGFloat kEpsilonAccuracy = (CGFloat)0.001;
// A value greater than the largest value created by combining normal values of UIControlState.
// This is a complete hack, but UIControlState doesn't expose anything useful here.
// This assumes that UIControlState is actually a set of bitfields and ignores application-specific
// values.
static const UIControlState kNumUIControlStates = 2 * UIControlStateSelected - 1;
static const UIControlState kUIControlStateDisabledHighlighted =
    UIControlStateHighlighted | UIControlStateDisabled;

static CGFloat randomNumber(void) { return arc4random_uniform(100) / (CGFloat)10; }

static CGFloat randomNumberNotEqualTo(const CGFloat targetNumber) {
  while (1) {
    CGFloat number = randomNumber();
    if (number != targetNumber) {
      return number;
    }
  }
}

static UIColor *randomColor(void) {
  switch (arc4random_uniform(5)) {
    case 0:
      return [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
      break;
    case 1:
      return [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
      break;
    case 2:
      return [UIColor redColor];
      break;
    case 3:
      return [UIColor orangeColor];
      break;
    case 4:
      return [UIColor greenColor];
      break;
    default:
      return [UIColor blueColor];
      break;
  }
}

static NSString *controlStateDescription(UIControlState controlState) {
  if (controlState == UIControlStateNormal) {
    return @"Normal";
  }
  NSMutableString *string = [NSMutableString string];
  if ((UIControlStateHighlighted & controlState) == UIControlStateHighlighted) {
    [string appendString:@"Highlighted "];
  }
  if ((UIControlStateDisabled & controlState) == UIControlStateDisabled) {
    [string appendString:@"Disabled "];
  }
  if ((UIControlStateSelected & controlState) == UIControlStateSelected) {
    [string appendString:@"Selected "];
  }
  return [string copy];
}

@interface FakeShadowLayer : MDCShapedShadowLayer
@property(nonatomic, assign) NSInteger elevationAssignmentCount;
@end

@implementation FakeShadowLayer

- (void)setElevation:(MDCShadowElevation)elevation {
  ++self.elevationAssignmentCount;
  [super setElevation:elevation];
}
@end

@interface TestButton : MDCButton
@property(nonatomic, strong) FakeShadowLayer *shadowLayer;
@property(nonatomic, strong) UITraitCollection *traitCollectionOverride;
@end

@implementation TestButton
+ (Class)layerClass {
  return [FakeShadowLayer class];
}

- (instancetype)initWithFrame:(CGRect)frame {
  self = [super initWithFrame:frame];
  if (self) {
    _shadowLayer = (FakeShadowLayer *)self.layer;
  }
  return self;
}

- (UITraitCollection *)traitCollection {
  return self.traitCollectionOverride ?: [super traitCollection];
}

@end

@interface MDCButtonTests : XCTestCase
@property(nonatomic, strong, nullable) MDCButton *button;
@end

@implementation MDCButtonTests

- (void)setUp {
  [super setUp];

  self.button = [[MDCButton alloc] init];
}

- (void)tearDown {
  self.button = nil;

  [super tearDown];
}

- (void)testUppercaseTitleYes {
  // Given
  NSString *originalTitle = @"some Text";

  // When
  self.button.uppercaseTitle = YES;
  [self.button setTitle:originalTitle forState:UIControlStateNormal];

  // Then
  XCTAssertEqualObjects(self.button.currentTitle,
                        [originalTitle uppercaseStringWithLocale:[NSLocale currentLocale]]);
}

- (void)testUppercaseAttributedTitleYes {
  // Given
  NSAttributedString *originalAttributedTitle =
      [[NSAttributedString alloc] initWithString:@"some Text"];

  // When
  self.button.uppercaseTitle = YES;
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateNormal];

  // Then
  NSString *uppercaseString =
      [originalAttributedTitle.string uppercaseStringWithLocale:[NSLocale currentLocale]];
  NSAttributedString *uppercaseAttributedTitle =
      [[NSAttributedString alloc] initWithString:uppercaseString];
  XCTAssertEqualObjects(self.button.currentAttributedTitle, uppercaseAttributedTitle);
}

- (void)testUppercaseTitleNo {
  // Given
  NSString *originalTitle = @"some Text";

  // When
  self.button.uppercaseTitle = NO;
  [self.button setTitle:originalTitle forState:UIControlStateNormal];

  // Then
  XCTAssertEqualObjects(self.button.currentTitle, originalTitle);
}

- (void)testUppercaseAttributedTitleNo {
  // Given
  NSAttributedString *originalAttributedTitle =
      [[NSAttributedString alloc] initWithString:@"some Text"];

  // When
  self.button.uppercaseTitle = NO;
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateNormal];

  // Then
  XCTAssertEqualObjects(self.button.currentAttributedTitle, originalAttributedTitle);
}

- (void)testUppercaseTitleNoChangedToYes {
  // Given
  NSString *originalTitle = @"some Text";

  // When
  self.button.uppercaseTitle = NO;
  [self.button setTitle:originalTitle forState:UIControlStateNormal];
  [self.button setTitle:originalTitle forState:UIControlStateHighlighted];
  [self.button setTitle:originalTitle forState:UIControlStateDisabled];
  self.button.uppercaseTitle = YES;

  // Then
  XCTAssertEqualObjects(self.button.currentTitle,
                        [originalTitle uppercaseStringWithLocale:[NSLocale currentLocale]]);
}

- (void)testUppercaseAttributedTitleNoChangedToYes {
  // Given
  NSAttributedString *originalAttributedTitle =
      [[NSAttributedString alloc] initWithString:@"some Text"];

  // When
  self.button.uppercaseTitle = NO;
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateNormal];
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateHighlighted];
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateDisabled];
  self.button.uppercaseTitle = YES;

  // Then
  NSString *uppercaseString =
      [originalAttributedTitle.string uppercaseStringWithLocale:[NSLocale currentLocale]];
  NSAttributedString *uppercaseAttributedTitle =
      [[NSAttributedString alloc] initWithString:uppercaseString];
  XCTAssertEqualObjects(self.button.currentAttributedTitle, uppercaseAttributedTitle);
}

- (void)testUppercaseTitleYesChangedToNo {
  // Given
  NSString *originalTitle = @"some Text";

  // When
  self.button.uppercaseTitle = YES;
  [self.button setTitle:originalTitle forState:UIControlStateNormal];
  [self.button setTitle:originalTitle forState:UIControlStateHighlighted];
  [self.button setTitle:originalTitle forState:UIControlStateDisabled];
  self.button.uppercaseTitle = NO;

  // Then
  XCTAssertEqualObjects(self.button.currentTitle, originalTitle);
}

- (void)testUppercaseAttributedTitleYesChangedToNo {
  // Given
  NSAttributedString *originalAttributedTitle =
      [[NSAttributedString alloc] initWithString:@"some Text"];

  // When
  self.button.uppercaseTitle = YES;
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateNormal];
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateHighlighted];
  [self.button setAttributedTitle:originalAttributedTitle forState:UIControlStateDisabled];
  self.button.uppercaseTitle = NO;

  // Then
  XCTAssertEqualObjects(self.button.currentAttributedTitle, originalAttributedTitle);
}

- (void)testSetEnabledAnimated {
  // Given
  NSArray *boolValues = @[ @YES, @NO ];
  for (id enabled in boolValues) {
    for (id animated in boolValues) {
      // When
      [self.button setEnabled:[enabled boolValue] animated:[animated boolValue]];

      // Then
      XCTAssertEqual(self.button.enabled, [enabled boolValue]);
    }
  }
}

- (void)testElevationForState {
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    // Given
    CGFloat elevation = randomNumber();

    // When
    [self.button setElevation:elevation forState:controlState];

    // Then
    XCTAssertEqual([self.button elevationForState:controlState], elevation);
  }
}

- (void)testSetElevationOnlyUpdatesCurrentState {
  // Given
  TestButton *selectedButton = [[TestButton alloc] init];
  TestButton *highlightedButton = [[TestButton alloc] init];

  XCTAssertEqualWithAccuracy([selectedButton elevationForState:UIControlStateNormal],
                             [selectedButton elevationForState:UIControlStateHighlighted], 0.0001,
                             @"This test assumes that .normal and .highlighted start with the same "
                              "elevation values.");

  [selectedButton setSelected:YES];
  [highlightedButton setHighlighted:YES];
  NSInteger selectedButtonElevationCount = selectedButton.shadowLayer.elevationAssignmentCount;
  NSInteger highlightedButtonElevationCount =
      highlightedButton.shadowLayer.elevationAssignmentCount;

  // When
  [selectedButton setElevation:77 forState:UIControlStateHighlighted];
  [highlightedButton setElevation:75 forState:UIControlStateNormal];

  // Then
  XCTAssertEqual(selectedButton.shadowLayer.elevationAssignmentCount, selectedButtonElevationCount,
                 @"Updating an unrelated elevation should not update the layer elevation.");
  XCTAssertEqual(highlightedButtonElevationCount + 1,
                 highlightedButton.shadowLayer.elevationAssignmentCount,
                 @"Updating the current elevation should cause one elevation update.");
}

- (void)testElevationNormal {
  // Given
  CGFloat normalElevation = randomNumberNotEqualTo(0);

  // When
  [self.button setElevation:normalElevation forState:UIControlStateNormal];

  // Then
  XCTAssertEqual([self.button elevationForState:UIControlStateNormal], normalElevation);
  XCTAssertEqual([self.button elevationForState:UIControlStateHighlighted], normalElevation);
  XCTAssertEqual([self.button elevationForState:UIControlStateDisabled], normalElevation);
  XCTAssertEqual([self.button elevationForState:UIControlStateSelected], normalElevation);
}

- (void)testElevationNormalZeroElevation {
  // When
  [self.button setElevation:0 forState:UIControlStateNormal];

  // Then
  XCTAssertEqual([self.button elevationForState:UIControlStateNormal], 0);
}

- (void)testDefaultBorderWidth {
  // Then
  for (NSUInteger controlState = 0; controlState <= kNumUIControlStates; ++controlState) {
    XCTAssertEqualWithAccuracy([self.button borderWidthForState:controlState], 0, 0.001);
  }
}

- (void)testBorderWidthForStateWithDifferentValues {
  for (NSUInteger controlState = 0; controlState <= kNumUIControlStates; ++controlState) {
    // Given
    CGFloat width = (CGFloat)controlState;

    // When
    [self.button setBorderWidth:width forState:controlState];

    // Then
    if (controlState == (UIControlStateHighlighted | UIControlStateDisabled)) {
      XCTAssertEqualWithAccuracy([self.button borderWidthForState:controlState],
                                 [self.button borderWidthForState:UIControlStateHighlighted],
                                 0.001);
    } else if (controlState ==
               (UIControlStateHighlighted | UIControlStateDisabled | UIControlStateSelected)) {
      XCTAssertNotEqualWithAccuracy([self.button borderWidthForState:controlState],
                                    [self.button borderWidthForState:UIControlStateNormal], 0.001);
    } else {
      XCTAssertEqualWithAccuracy([self.button borderWidthForState:controlState], width, 0.001);
    }
  }
}

- (void)testBorderWidthFallbackBehavior {
  // Given
  CGFloat fakeBorderWidth = 99;

  // When
  [self.button setBorderWidth:fakeBorderWidth forState:UIControlStateNormal];

  // Then
  for (NSUInteger controlState = 0; controlState <= kNumUIControlStates; ++controlState) {
    XCTAssertEqualWithAccuracy([self.button borderWidthForState:controlState], fakeBorderWidth,
                               0.001);
  }
}

- (void)testBorderColorForState {
  for (NSUInteger state = 0; state <= kNumUIControlStates; ++state) {
    // Given
    UIColor *color = randomColor();

    // When
    [self.button setBorderColor:color forState:state];

    // Then
    XCTAssertEqualObjects([self.button borderColorForState:state], color);
  }
}

- (void)testBorderColorForStateFallbackBehavior {
  // When
  [self.button setBorderColor:UIColor.redColor forState:UIControlStateNormal];

  // Then
  for (NSUInteger state = 0; state <= kNumUIControlStates; ++state) {
    XCTAssertEqualObjects([self.button borderColorForState:state], UIColor.redColor);
  }
}

- (void)testBorderColorForStateBehaviorMatchesTitleColorForStateForward {
  // Given
  MDCButton *testButton = [[MDCButton alloc] init];
  UIButton *uiButton = [[UIButton alloc] init];

  // When
  UIControlState maxState = UIControlStateNormal | UIControlStateHighlighted |
                            UIControlStateDisabled | UIControlStateSelected;
  for (UIControlState state = 0; state <= maxState; ++state) {
    UIColor *color = [UIColor colorWithWhite:0 alpha:(CGFloat)(state / (CGFloat)maxState)];
    [testButton setBorderColor:color forState:state];
    [uiButton setTitleColor:color forState:state];
  }

  // Then
  for (UIControlState state = 0; state <= maxState; ++state) {
    XCTAssertEqualObjects([testButton borderColorForState:state],
                          [uiButton titleColorForState:state], @" for state (%lu)",
                          (unsigned long)state);
  }
}

- (void)testBorderColorForStateBehaviorMatchesTitleColorForStateBackward {
  // Given
  MDCButton *testButton = [[MDCButton alloc] init];
  UIButton *uiButton = [[UIButton alloc] init];

  // When
  UIControlState maxState = UIControlStateNormal | UIControlStateHighlighted |
                            UIControlStateDisabled | UIControlStateSelected;
  for (NSInteger state = maxState; state >= 0; --state) {
    UIColor *color = [UIColor colorWithWhite:0 alpha:(CGFloat)(state / (CGFloat)maxState)];
    [testButton setBorderColor:color forState:state];
    [uiButton setTitleColor:color forState:state];
  }

  // Then
  for (UIControlState state = 0; state <= maxState; ++state) {
    XCTAssertEqualObjects([testButton borderColorForState:state],
                          [uiButton titleColorForState:state], @" for state (%lu)",
                          (unsigned long)state);
  }
}

- (void)testBackgroundColorForState {
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    // Given
    UIColor *color = randomColor();

    // When
    [self.button setBackgroundColor:color forState:controlState];

    // Then
    XCTAssertEqualObjects([self.button backgroundColorForState:controlState], color);
  }
}

- (void)testBackgroundColorForStateFallbackBehavior {
  // When
  [self.button setBackgroundColor:UIColor.purpleColor forState:UIControlStateNormal];

  // Then
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    XCTAssertEqualObjects([self.button backgroundColorForState:controlState], UIColor.purpleColor);
  }
}

- (void)testBackgroundColorForStateUpdatesBackgroundColor {
  // Given
  for (NSUInteger controlState = 0; controlState <= kNumUIControlStates; ++controlState) {
    // Disabling the button removes any highlighted state
    UIControlState testState = controlState;
    if ((testState & UIControlStateDisabled) == UIControlStateDisabled) {
      testState &= ~UIControlStateHighlighted;
    }
    BOOL isDisabled = (testState & UIControlStateDisabled) == UIControlStateDisabled;
    BOOL isSelected = (testState & UIControlStateSelected) == UIControlStateSelected;
    BOOL isHighlighted = (testState & UIControlStateHighlighted) == UIControlStateHighlighted;

    // Also given
    UIColor *color = randomColor();
    [self.button setBackgroundColor:color forState:testState];

    // When
    self.button.enabled = !isDisabled;
    self.button.selected = isSelected;
    self.button.highlighted = isHighlighted;

    XCTAssertEqualObjects(self.button.backgroundColor, color, @"for state (%lu).",
                          (unsigned long)testState);
  }
}

- (void)testBackgroundColorForStateUpdatesBackgroundColorWithFallback {
  // Given
  [self.button setBackgroundColor:UIColor.magentaColor forState:UIControlStateNormal];

  for (NSUInteger controlState = 0; controlState <= kNumUIControlStates; ++controlState) {
    BOOL isDisabled = (controlState & UIControlStateDisabled) == UIControlStateDisabled;
    BOOL isSelected = (controlState & UIControlStateSelected) == UIControlStateSelected;
    BOOL isHighlighted = (controlState & UIControlStateHighlighted) == UIControlStateHighlighted;

    // When
    self.button.enabled = !isDisabled;
    self.button.selected = isSelected;
    self.button.highlighted = isHighlighted;

    XCTAssertEqualObjects(self.button.backgroundColor,
                          [self.button backgroundColorForState:UIControlStateNormal],
                          @"for state (%lu).", (unsigned long)controlState);
  }
}

// Behavioral test to verify that MDCButton's `backgroundColor:forState:` matches the behavior of
// UIButton's `titleColor:forState:`.  Specifically, to ensure that the special handling of
// (UIControlStateDisabled | UIControlStateHighlighted) is identical.
//
// This test is valuable because clients who are familiar with the fallback behavior of
// `titleColor:forState:` may be surprised if the MDCButton APIs don't match. For example, setting
// the titleColor for (UIControlStateDisabled | UIControlStateHighlighted) will actually update the
// value assigned for UIControlStateHighlighted, but ONLY if it has already been assigned. Otherwise
// no update will take place.
- (void)testBackgroundColorForStateBehaviorMatchesTitleColorForStateWithoutFallbackForward {
  // Given
  UIButton *uiButton = [[UIButton alloc] init];

  // When
  UIControlState maxState = UIControlStateNormal | UIControlStateHighlighted |
                            UIControlStateDisabled | UIControlStateSelected;
  for (UIControlState state = 0; state <= maxState; ++state) {
    UIColor *color = [UIColor colorWithWhite:0 alpha:(CGFloat)(state / (CGFloat)maxState)];
    [self.button setBackgroundColor:color forState:state];
    [uiButton setTitleColor:color forState:state];
  }

  // Then
  for (UIControlState state = 0; state <= maxState; ++state) {
    XCTAssertEqualObjects([self.button backgroundColorForState:state],
                          [uiButton titleColorForState:state], @" for state (%lu)",
                          (unsigned long)state);
  }
}

- (void)testBackgroundColorForStateBehaviorMatchesTitleColorForStateWithoutFallbackBackward {
  // Given
  UIButton *uiButton = [[UIButton alloc] init];

  // When
  UIControlState maxState = UIControlStateNormal | UIControlStateHighlighted |
                            UIControlStateDisabled | UIControlStateSelected;
  for (NSInteger state = maxState; state >= 0; --state) {
    UIColor *color = [UIColor colorWithWhite:0 alpha:(CGFloat)(state / (CGFloat)maxState)];
    [self.button setBackgroundColor:color forState:(UIControlState)state];
    [uiButton setTitleColor:color forState:(UIControlState)state];
  }

  // Then
  for (UIControlState state = 0; state <= maxState; ++state) {
    XCTAssertEqualObjects([self.button backgroundColorForState:state],
                          [uiButton titleColorForState:state], @" for state (%lu)",
                          (unsigned long)state);
  }
}

#pragma mark - titleFont:forState:

- (void)testTitleFontForState {
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    // Given
    UIFont *randomFont = [UIFont systemFontOfSize:arc4random_uniform(100)];

    // When
    [self.button setTitleFont:randomFont forState:controlState];

    // Then
    XCTAssertEqualObjects([self.button titleFontForState:controlState], randomFont);
  }
}

- (void)testTitleFontForStateFallbackBehavior {
  // Given
  UIFont *fakeFont = [UIFont systemFontOfSize:25];
  // When
  [self.button setTitleFont:fakeFont forState:UIControlStateNormal];

  // Then
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    XCTAssertEqualObjects([self.button titleFontForState:controlState], fakeFont);
  }
}

- (void)testTitleFontForStateFallbackBehaviorWithLegacyDynamicType {
  // When
  self.button.mdc_adjustsFontForContentSizeCategory = YES;

  // Then
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    XCTAssertTrue(
        [[self.button titleFontForState:controlState]
            mdc_isSimplyEqual:[[MDCTypography buttonFont]
                                  mdc_fontSizedForMaterialTextStyle:MDCFontTextStyleButton
                                               scaledForDynamicType:YES]],
        @"(%@) is not equal to (%@)", [self.button titleFontForState:UIControlStateNormal],
        [[MDCTypography buttonFont] mdc_fontSizedForMaterialTextStyle:MDCFontTextStyleButton
                                                 scaledForDynamicType:YES]);
  }
}

- (void)testTitleFontForStateWithLegacyDynamicTypeReturnsRenderedFonts {
  // Given
  UIFont *userFont = [UIFont systemFontOfSize:99];
  [self.button setTitleFont:userFont forState:UIControlStateNormal];

  // When
  self.button.mdc_adjustsFontForContentSizeCategory = YES;

  // Then
  XCTAssertFalse([[self.button titleFontForState:UIControlStateNormal] mdc_isSimplyEqual:userFont],
                 @"(%@) is equal to (%@)", [self.button titleFontForState:UIControlStateNormal],
                 userFont);
  XCTAssertFalse([self.button.titleLabel.font mdc_isSimplyEqual:userFont], @"(%@) is equal to (%@)",
                 self.button.titleLabel.font, userFont);
  XCTAssertTrue([[self.button titleFontForState:UIControlStateNormal]
                    mdc_isSimplyEqual:self.button.titleLabel.font],
                @"(%@) is not equal to (%@)", [self.button titleFontForState:UIControlStateNormal],
                self.button.titleLabel.font);
}

- (void)testTitleFontForStateWithLegacyDynamicTypeRestoresUserFonts {
  // Given
  UIFont *userFont = [UIFont systemFontOfSize:99];
  [self.button setTitleFont:userFont forState:UIControlStateNormal];
  self.button.mdc_adjustsFontForContentSizeCategory = YES;

  // When
  self.button.mdc_adjustsFontForContentSizeCategory = NO;

  // Then
  XCTAssertTrue([[self.button titleFontForState:UIControlStateNormal] mdc_isSimplyEqual:userFont],
                @"(%@) is not equal to (%@)", [self.button titleFontForState:UIControlStateNormal],
                userFont);
  XCTAssertTrue([self.button.titleLabel.font mdc_isSimplyEqual:userFont],
                @"(%@) is not equal to (%@)", self.button.titleLabel.font, userFont);
  XCTAssertTrue([[self.button titleFontForState:UIControlStateNormal]
                    mdc_isSimplyEqual:self.button.titleLabel.font],
                @"(%@) is not equal to (%@)", [self.button titleFontForState:UIControlStateNormal],
                self.button.titleLabel.font);
}

/**
 Verifies that disabling the @c titleFont:forState: APIs after setting fonts preserves the
 directly-assigned font on the button's @c titleLabel.
 */
- (void)testTitleFontForStateDisabledAfterSettingFontsPreventsFontChange {
  // Given
  UIFont *normalFont = [UIFont systemFontOfSize:10];
  UIFont *selectedFont = [UIFont systemFontOfSize:40];
  UIFont *directlyAssignedFont = [UIFont systemFontOfSize:25];
  [self.button setTitleFont:normalFont forState:UIControlStateNormal];
  [self.button setTitleFont:selectedFont forState:UIControlStateSelected];

  // When
  self.button.enableTitleFontForState = NO;
  self.button.titleLabel.font = directlyAssignedFont;
  self.button.selected = YES;

  // Then
  XCTAssertEqualObjects(self.button.titleLabel.font, directlyAssignedFont);
}

/**
 Verifies that disabling @c titleFont:forState: APIs before setting fonts preserves the
 directly-assigned font on the button's @c titleLabel.
 */
- (void)testTitleFontForStateDisabledBeforeSettingFontsPreventsFontChange {
  // Given
  UIFont *normalFont = [UIFont systemFontOfSize:10];
  UIFont *selectedFont = [UIFont systemFontOfSize:40];
  UIFont *directlyAssignedFont = [UIFont systemFontOfSize:25];
  self.button.enableTitleFontForState = NO;
  self.button.titleLabel.font = directlyAssignedFont;

  // When
  [self.button setTitleFont:normalFont forState:UIControlStateNormal];
  [self.button setTitleFont:selectedFont forState:UIControlStateSelected];
  self.button.selected = YES;

  // Then
  XCTAssertEqualObjects(self.button.titleLabel.font, directlyAssignedFont);
}

/**
 Verifies that after enabling @c titleFont:forState: APIs, that @c titleLabel.font will be
 replaced by the next time the state is changed.
 */
- (void)testTitleFontForStateReenabledUpdatesFontsOnNextStateChange {
  // Given
  UIFont *normalFont = [UIFont systemFontOfSize:10];
  UIFont *selectedFont = [UIFont systemFontOfSize:40];
  UIFont *directlyAssignedFont = [UIFont systemFontOfSize:25];
  self.button.enableTitleFontForState = NO;
  [self.button setTitleFont:normalFont forState:UIControlStateNormal];
  [self.button setTitleFont:selectedFont forState:UIControlStateSelected];
  self.button.titleLabel.font = directlyAssignedFont;
  self.button.selected = YES;

  // When
  self.button.enableTitleFontForState = YES;
  self.button.selected = NO;

  // Then
  XCTAssertEqualObjects(self.button.titleLabel.font, normalFont);
}

#pragma mark - shadowColor:forState:

- (void)testRemovedShadowColorForState {
  // When
  [self.button setShadowColor:nil forState:UIControlStateNormal];

  // Then
  XCTAssertNil([self.button shadowColorForState:UIControlStateNormal]);
  XCTAssertNil([self.button shadowColorForState:UIControlStateHighlighted]);
}

- (void)testDefaultShadowColorForState {
  // Then
  XCTAssertNotNil([self.button shadowColorForState:UIControlStateSelected]);
}

- (void)testShadowColorForUnspecifiedStateEqualsNormalState {
  // Given
  UIColor *color = randomColor();

  // When
  [self.button setShadowColor:color forState:UIControlStateNormal];

  XCTAssertEqual([self.button shadowColorForState:UIControlStateHighlighted], color);
}

- (void)testShadowColorForState {
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    // Given
    UIColor *color = randomColor();

    // When
    [self.button setShadowColor:color forState:controlState];

    // Then
    XCTAssertEqualObjects([self.button shadowColorForState:controlState], color);
  }
}

- (void)testLayerShadowColorForState {
  for (NSUInteger controlState = 0; controlState <= kNumUIControlStates; ++controlState) {
    // Given
    NSUInteger effectiveControlState = controlState;
    UIColor *color = randomColor();

    // When
    [self.button setShadowColor:color forState:controlState];
    if ((effectiveControlState & UIControlStateHighlighted) == UIControlStateHighlighted) {
      self.button.highlighted = YES;
    } else {
      self.button.highlighted = NO;
    }

    if ((effectiveControlState & UIControlStateDisabled) == UIControlStateDisabled) {
      self.button.enabled = NO;
      // Disabling a button turns off "highlighted"
      effectiveControlState = (effectiveControlState & ~UIControlStateHighlighted);
    } else {
      self.button.enabled = YES;
    }

    if ((effectiveControlState & UIControlStateSelected) == UIControlStateSelected) {
      self.button.selected = YES;
    } else {
      self.button.selected = NO;
    }

    // Then
    UIColor *layerShadowColor = [UIColor colorWithCGColor:self.button.layer.shadowColor];
    XCTAssertEqualObjects([self.button shadowColorForState:effectiveControlState],
                          layerShadowColor);
  }
}

#pragma mark - imageTintColor:forState:

- (void)testRemovedImageTintColorForState {
  // When
  [self.button setImageTintColor:nil forState:UIControlStateNormal];

  // Then
  XCTAssertNil([self.button imageTintColorForState:UIControlStateNormal]);
  XCTAssertNil([self.button imageTintColorForState:UIControlStateHighlighted]);
}

- (void)testDefaultImageTintColorForState {
  // Then
  XCTAssertNil([self.button imageTintColorForState:UIControlStateSelected]);
}

- (void)testImageTintForUnspecifiedStateEqualsNormalState {
  // Given
  UIColor *color = randomColor();

  // When
  [self.button setImageTintColor:color forState:UIControlStateNormal];

  XCTAssertEqual([self.button imageTintColorForState:UIControlStateHighlighted], color);
}

- (void)testImageTintColorForState {
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    // Given
    UIColor *color = randomColor();

    // When
    [self.button setImageTintColor:color forState:controlState];

    // Then
    XCTAssertEqualObjects([self.button imageTintColorForState:controlState], color);
  }
}

- (void)testImageTintColorForStateFallsBackToDefault {
  // Given
  UIColor *normalTint = [UIColor yellowColor];
  UIColor *selectedTint = [UIColor redColor];

  // When
  [self.button setImageTintColor:normalTint forState:UIControlStateNormal];
  [self.button setImageTintColor:selectedTint forState:UIControlStateSelected];

  // Then
  XCTAssertEqualObjects([self.button imageTintColorForState:UIControlStateNormal], normalTint);
  XCTAssertEqualObjects([self.button imageTintColorForState:UIControlStateSelected], selectedTint);
  XCTAssertEqualObjects([self.button imageTintColorForState:UIControlStateHighlighted], normalTint);
}

- (void)testImageTintColorForStateSetsImageViewTintColor {
  // Given
  UIColor *normalTint = [UIColor yellowColor];
  UIColor *selectedTint = [UIColor redColor];

  // When
  [self.button setImageTintColor:normalTint forState:UIControlStateNormal];
  [self.button setImageTintColor:selectedTint forState:UIControlStateSelected];

  // Then
  XCTAssertEqualObjects(self.button.imageView.tintColor, normalTint);

  // When
  self.button.selected = YES;

  // Then
  XCTAssertEqualObjects(self.button.imageView.tintColor, selectedTint);
}

#pragma mark - backgroundColor:forState:

- (void)testCurrentBackgroundColorNormal {
  // Given
  UIColor *normalColor = [UIColor redColor];
  [self.button setBackgroundColor:normalColor forState:UIControlStateNormal];

  // Then
  XCTAssertEqualObjects([self.button backgroundColor], normalColor);
}

- (void)testCurrentBackgroundColorHighlighted {
  // Given
  UIColor *normalColor = [UIColor redColor];
  UIColor *color = [UIColor orangeColor];
  [self.button setBackgroundColor:normalColor forState:UIControlStateNormal];
  [self.button setBackgroundColor:color forState:UIControlStateHighlighted];

  // When
  self.button.highlighted = YES;

  // Then
  XCTAssertEqualObjects([self.button backgroundColor], color);
}

- (void)testCurrentBackgroundColorDisabled {
  // Given
  UIColor *normalColor = [UIColor redColor];
  UIColor *color = [UIColor orangeColor];
  [self.button setBackgroundColor:normalColor forState:UIControlStateNormal];
  [self.button setBackgroundColor:color forState:UIControlStateDisabled];

  // When
  self.button.enabled = NO;

  // Then
  XCTAssertEqualObjects([self.button backgroundColor], color);
}

- (void)testCurrentBackgroundColorSelected {
  // Given
  UIColor *normalColor = [UIColor redColor];
  UIColor *color = [UIColor orangeColor];
  [self.button setBackgroundColor:normalColor forState:UIControlStateNormal];
  [self.button setBackgroundColor:color forState:UIControlStateSelected];

  // When
  self.button.selected = YES;

  // Then
  XCTAssertEqualObjects([self.button backgroundColor], color);
}

#pragma mark - elevation:forState:

- (void)testCurrentElevationNormal {
  // Given
  CGFloat normalElevation = 10;
  [self.button setElevation:normalElevation forState:UIControlStateNormal];

  // Then
  XCTAssertEqualWithAccuracy([self.button elevationForState:self.button.state], normalElevation,
                             kEpsilonAccuracy);
}

- (void)testCurrentElevationHighlighted {
  // Given
  CGFloat normalElevation = 10;
  CGFloat elevation = 40;
  [self.button setElevation:normalElevation forState:UIControlStateNormal];
  [self.button setElevation:elevation forState:UIControlStateHighlighted];

  // When
  self.button.highlighted = YES;

  // Then
  XCTAssertEqualWithAccuracy([self.button elevationForState:self.button.state], elevation,
                             kEpsilonAccuracy);
}

- (void)testCurrentElevationDisabled {
  // Given
  CGFloat normalElevation = 10;
  CGFloat elevation = 40;
  [self.button setElevation:normalElevation forState:UIControlStateNormal];
  [self.button setElevation:elevation forState:UIControlStateDisabled];

  // When
  self.button.enabled = NO;

  // Then
  XCTAssertEqualWithAccuracy([self.button elevationForState:self.button.state], elevation,
                             kEpsilonAccuracy);
}

- (void)testCurrentElevationSelected {
  // Given
  CGFloat normalElevation = 10;
  CGFloat elevation = 40;
  [self.button setElevation:normalElevation forState:UIControlStateNormal];
  [self.button setElevation:elevation forState:UIControlStateSelected];

  // When
  self.button.selected = YES;

  // Then
  XCTAssertEqualWithAccuracy([self.button elevationForState:self.button.state], elevation,
                             kEpsilonAccuracy);
}

#pragma mark - Ink Color

- (void)testInkColors {
  // Given
  UIColor *color = randomColor();

  // When
  self.button.inkColor = color;

  // Then
  XCTAssertEqualObjects(self.button.inkColor, color);
}

- (void)testRippleColors {
  // Given
  UIColor *color = randomColor();

  // When
  self.button.rippleColor = color;

  // Then
  XCTAssertEqualObjects(self.button.rippleColor, color);
}

/*
 TODO: things to unit test
 (should these even be a thing?)
 - hitAreaInset
 - underlyingColor (text color)
 */

- (void)testPointInsideWithoutHitAreaInsets {
  // Given
  self.button.frame = CGRectMake(0, 0, 80, 50);

  CGPoint touchPointInsideBoundsTopLeft = CGPointMake(0, 0);
  CGPoint touchPointInsideBoundsTopRight = CGPointMake((CGFloat)79.9, 0);
  CGPoint touchPointInsideBoundsBottomRight = CGPointMake((CGFloat)79.9, (CGFloat)49.9);
  CGPoint touchPointInsideBoundsBottomLeft = CGPointMake(0, (CGFloat)49.9);

  CGPoint touchPointOutsideBoundsTopLeft = CGPointMake(0, (CGFloat)-0.1);
  CGPoint touchPointOutsideBoundsTopRight = CGPointMake(80, 0);
  CGPoint touchPointOutsideBoundsBottomRight = CGPointMake(80, 50);
  CGPoint touchPointOutsideBoundsBottomLeft = CGPointMake(0, 50);

  // Then
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsTopLeft withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsTopRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsBottomRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsBottomLeft withEvent:nil]);

  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsTopLeft withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsTopRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsBottomRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsBottomLeft withEvent:nil]);
}

- (void)testPointInsideWithoutHitAreaInsetsTooSmall {
  // Given
  self.button.frame = CGRectMake(0, 0, 10, 10);

  CGPoint touchPointInsideBoundsTopLeft = CGPointMake(0, 0);
  CGPoint touchPointInsideBoundsTopRight = CGPointMake((CGFloat)9.9, 0);
  CGPoint touchPointInsideBoundsBottomRight = CGPointMake((CGFloat)9.9, (CGFloat)9.9);
  CGPoint touchPointInsideBoundsBottomLeft = CGPointMake(0, (CGFloat)9.9);

  CGPoint touchPointOutsideBoundsTopLeft = CGPointMake(0, (CGFloat)-0.1);
  CGPoint touchPointOutsideBoundsTopRight = CGPointMake(10, 0);
  CGPoint touchPointOutsideBoundsBottomRight = CGPointMake(10, 10);
  CGPoint touchPointOutsideBoundsBottomLeft = CGPointMake(0, 10);

  // Then
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsTopLeft withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsTopRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsBottomRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideBoundsBottomLeft withEvent:nil]);

  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsTopLeft withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsTopRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsBottomRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideBoundsBottomLeft withEvent:nil]);
}

- (void)testPointInsideWithCustomHitAreaInsets {
  // Given
  self.button.frame = CGRectMake(0, 0, 10, 10);

  CGPoint touchPointInsideHitAreaTopLeft = CGPointMake(-5, -5);
  CGPoint touchPointInsideHitAreaTopRight = CGPointMake(-5, (CGFloat)14.9);
  CGPoint touchPointInsideHitAreaBottomRight = CGPointMake((CGFloat)14.9, (CGFloat)14.9);
  CGPoint touchPointInsideHitAreaBottomLeft = CGPointMake((CGFloat)14.9, -5);

  CGPoint touchPointOutsideHitAreaTopLeft = CGPointMake((CGFloat)-5.1, -5);
  CGPoint touchPointOutsideHitAreaTopRight = CGPointMake(-5, 15);
  CGPoint touchPointOutsideHitAreaBottomRight = CGPointMake(15, 15);
  CGPoint touchPointOutsideHitAreaBottomLeft = CGPointMake(15, -5);

  // When
  self.button.hitAreaInsets = UIEdgeInsetsMake(-5, -5, -5, -5);

  // Then
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaTopLeft withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaTopRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaBottomRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaBottomLeft withEvent:nil]);

  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaTopLeft withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaTopRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaBottomRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaBottomLeft withEvent:nil]);
}

- (void)testPointInsideWithNonStandardizedBounds {
  // Given
  // This is (-10, -10, 20, 20) in standardized form
  CGRect bounds = CGRectMake(10, 10, -20, -20);
  // Once applied, these insets should increase the hitArea to (-15, -20, 30, 40)
  UIEdgeInsets insets = UIEdgeInsetsMake(-10, -5, -10, -5);

  CGPoint touchPointInsideHitAreaTopLeft = CGPointMake(-15, -20);
  CGPoint touchPointInsideHitAreaTopRight = CGPointMake((CGFloat)14.9, -20);
  CGPoint touchPointInsideHitAreaBottomRight = CGPointMake((CGFloat)14.9, (CGFloat)19.9);
  CGPoint touchPointInsideHitAreaBottomLeft = CGPointMake(-15, (CGFloat)19.9);

  CGPoint touchPointOutsideHitAreaTopLeft = CGPointMake((CGFloat)-15.1, -20);
  CGPoint touchPointOutsideHitAreaTopRight = CGPointMake(20, -20);
  CGPoint touchPointOutsideHitAreaBottomRight = CGPointMake(15, 20);
  CGPoint touchPointOutsideHitAreaBottomLeft = CGPointMake(-15, 20);

  // When
  self.button.bounds = bounds;
  self.button.hitAreaInsets = insets;

  // Then
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaTopLeft withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaTopRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaBottomRight withEvent:nil]);
  XCTAssertTrue([self.button pointInside:touchPointInsideHitAreaBottomLeft withEvent:nil]);

  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaTopLeft withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaTopRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaBottomRight withEvent:nil]);
  XCTAssertFalse([self.button pointInside:touchPointOutsideHitAreaBottomLeft withEvent:nil]);
}

#pragma mark - UIButton strangeness

- (void)testTitleColorForState {
  for (NSUInteger controlState = 0; controlState < kNumUIControlStates; ++controlState) {
    if (controlState & kUIControlStateDisabledHighlighted) {
      // We skip the Disabled Highlighted state because UIButton titleColorForState ignores it.
      continue;
    }
    // Given
    UIColor *color = [UIColor blueColor];

    // When
    [self.button setTitleColor:color forState:controlState];

    // Then
    XCTAssertEqualObjects([self.button titleColorForState:controlState], color,
                          @"for control state:%@ ", controlStateDescription(controlState));
  }
}
- (void)testTitleColorForStateDisabledHighlight {
  // This is strange that setting the color for a state does not return the value of that state.
  // It turns out that it returns the value set to the normal state.

  // Given
  UIControlState controlState = kUIControlStateDisabledHighlighted;
  UIColor *color = [UIColor blueColor];
  UIColor *normalColor = [UIColor greenColor];
  [self.button setTitleColor:normalColor forState:UIControlStateNormal];

  // When
  [self.button setTitleColor:color forState:controlState];

  // Then
  XCTAssertEqualObjects([self.button titleColorForState:controlState], normalColor,
                        @"for control state:%@ ", controlStateDescription(controlState));
  XCTAssertNotEqualObjects([self.button titleColorForState:controlState], color,
                           @"for control state:%@ ", controlStateDescription(controlState));
}

#pragma mark - UIButton state changes

- (void)testEnabled {
  // Given
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.highlighted = (BOOL)arc4random_uniform(2);
  button.selected = (BOOL)arc4random_uniform(2);
  button.enabled = (BOOL)arc4random_uniform(2);

  // When
  button.enabled = YES;

  // Then
  XCTAssertTrue(button.enabled);
  XCTAssertFalse(button.state & UIControlStateDisabled);
}

- (void)testDisabled {
  // Given
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.highlighted = (BOOL)arc4random_uniform(2);
  button.selected = (BOOL)arc4random_uniform(2);
  button.enabled = (BOOL)arc4random_uniform(2);

  // When
  button.enabled = NO;

  // Then
  XCTAssertFalse(button.enabled);
  XCTAssertTrue(button.state & UIControlStateDisabled);
}

- (void)testHighlighted {
  // Given
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.highlighted = NO;
  button.selected = (BOOL)arc4random_uniform(2);

  // For some reason we can only set the highlighted state to YES if its enabled is also YES.
  button.enabled = YES;

  UIControlState oldState = button.state;
  XCTAssertFalse(button.highlighted);

  // When
  button.highlighted = YES;

  // Then
  XCTAssertTrue(button.highlighted);
  XCTAssertTrue(button.state & UIControlStateHighlighted);
  XCTAssertEqual(button.state, (oldState | UIControlStateHighlighted));
}

- (void)testUnhighlighted {
  // Given
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.highlighted = YES;
  button.selected = (BOOL)arc4random_uniform(2);
  button.enabled = (BOOL)arc4random_uniform(2);
  UIControlState oldState = button.state;
  XCTAssertTrue(button.highlighted);

  // When
  button.highlighted = NO;

  // Then
  XCTAssertFalse(button.highlighted);
  XCTAssertFalse(button.state & UIControlStateHighlighted);
  XCTAssertEqual(button.state, (oldState & ~UIControlStateHighlighted));
}

- (void)testSelected {
  // Given
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.highlighted = (BOOL)arc4random_uniform(2);
  button.selected = NO;
  button.enabled = (BOOL)arc4random_uniform(2);
  UIControlState oldState = button.state;

  // When
  button.selected = YES;

  // Then
  XCTAssertTrue(button.selected);
  XCTAssertTrue(button.state & UIControlStateSelected);
  XCTAssertEqual(button.state, (oldState | UIControlStateSelected));
}

- (void)testUnselected {
  // Given
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.highlighted = (BOOL)arc4random_uniform(2);
  button.selected = YES;
  button.enabled = (BOOL)arc4random_uniform(2);

  // When
  button.selected = NO;

  // Then
  XCTAssertFalse(button.selected);
  XCTAssertFalse(button.state & UIControlStateSelected);
}

- (void)testDefaultFont {
  // Then
  XCTAssertEqualObjects(self.button.titleLabel.font, [MDCTypography buttonFont]);
}

- (void)testDefaultAdjustsFontProperty {
  // Then
  XCTAssertFalse(self.button.mdc_adjustsFontForContentSizeCategory);
}

- (void)testAdjustsFontProperty {
  UIFont *preferredFont = [UIFont mdc_preferredFontForMaterialTextStyle:MDCFontTextStyleButton];

  // When
  self.button.mdc_adjustsFontForContentSizeCategory = YES;

  // Then
  XCTAssertTrue(self.button.mdc_adjustsFontForContentSizeCategory);
  XCTAssertEqualWithAccuracy(self.button.titleLabel.font.pointSize, preferredFont.pointSize,
                             kEpsilonAccuracy,
                             @"Font size should be equal to MDCFontTextStyleButton's.");
}

/**
 Test legacy dynamic type impacts a @c MDCButton when @c
 mdc_adjustsFontForContentSizeCategory is set to @c YES that the font changes.
 */
- (void)testLegacyDynamicTypeEnabled {
  // Given
  UIFont *fakeFont = [UIFont systemFontOfSize:55];
  [self.button setTitleFont:fakeFont forState:UIControlStateNormal];
  UIFont *originalFont = self.button.titleLabel.font;
  self.button.mdc_adjustsFontForContentSizeCategory = YES;

  // Then
  XCTAssertFalse([self.button.titleLabel.font mdc_isSimplyEqual:originalFont], @"%@ is equal to %@",
                 self.button.titleLabel.font, originalFont);
}

#pragma mark - Size-related tests

- (void)testSizeThatFitsWithMinimumOnly {
  // Given
  [self.button sizeToFit];
  CGRect expectedFrame = CGRectMake(0, 0, CGRectGetWidth(self.button.frame) + 15,
                                    CGRectGetHeight(self.button.frame) + 21);

  // When
  self.button.minimumSize = expectedFrame.size;
  [self.button sizeToFit];

  // Then
  XCTAssertTrue(CGRectEqualToRect(expectedFrame, self.button.frame), @"\nE: %@\nA: %@",
                NSStringFromCGRect(expectedFrame), NSStringFromCGRect(self.button.frame));
}

- (void)testSizeThatFitsWithMaximumOnly {
  // Given
  [self.button sizeToFit];
  CGRect expectedFrame = CGRectMake(0, 0, CGRectGetWidth(self.button.frame) - 7,
                                    CGRectGetHeight(self.button.frame) - 3);

  // When
  self.button.maximumSize = expectedFrame.size;
  [self.button sizeToFit];

  // Then
  XCTAssertTrue(CGRectEqualToRect(expectedFrame, self.button.frame), @"\nE: %@\nA: %@",
                NSStringFromCGRect(expectedFrame), NSStringFromCGRect(self.button.frame));
}

- (void)testSizeThatFitsWithMinimumAndMaximum {
  // Given
  [self.button sizeToFit];
  CGRect expectedFrame = CGRectMake(0, 0, CGRectGetWidth(self.button.frame) + 21,
                                    CGRectGetHeight(self.button.frame) - 4);

  // When
  self.button.maximumSize = CGSizeMake(0, CGRectGetHeight(expectedFrame));  // Only bound max height
  self.button.minimumSize = CGSizeMake(CGRectGetWidth(expectedFrame), 0);   // Only bound min width
  [self.button sizeToFit];

  // Then
  XCTAssertTrue(CGRectEqualToRect(expectedFrame, self.button.frame), @"\nE: %@\nA: %@",
                NSStringFromCGRect(expectedFrame), NSStringFromCGRect(self.button.frame));
}

- (void)testIntrinsicContentSizeWithMinimumSizeIncreasesSize {
  // Given
  CGSize originalSize = self.button.intrinsicContentSize;
  CGSize expectedSize = CGSizeMake(originalSize.width + 10, originalSize.height + 10);

  // When
  self.button.minimumSize = expectedSize;

  // Then
  XCTAssertTrue(CGSizeEqualToSize(expectedSize, self.button.intrinsicContentSize));
}

- (void)testIntrinsicContentSizeWithMaximumDecreasesSize {
  // Given
  CGSize originalSize = self.button.intrinsicContentSize;
  CGSize expectedSize = CGSizeMake(originalSize.width - 5, originalSize.height - 5);

  // When
  self.button.maximumSize = expectedSize;

  // Then
  XCTAssertTrue(CGSizeEqualToSize(expectedSize, self.button.intrinsicContentSize));
}

- (void)testIntrinsicContentSizeWithMaximumAndMinimumSizeBehavior {
  // Given
  CGSize originalSize = self.button.intrinsicContentSize;
  CGSize expectedSize = CGSizeMake(originalSize.width + 5, originalSize.height - 5);

  // When
  self.button.maximumSize = CGSizeMake(0, expectedSize.height);
  self.button.minimumSize = CGSizeMake(expectedSize.width, 0);

  // Then
  XCTAssertTrue(CGSizeEqualToSize(expectedSize, self.button.intrinsicContentSize));
}

#pragma mark - UIAccessibility

- (void)testAccessibilityTraitsDefault {
  // Then
  XCTAssertEqual(self.button.accessibilityTraits, UIAccessibilityTraitButton);
}

- (void)testAccessibilityTraitsDefaultIncludesButtonExplicitlyTrue {
  // When
  self.button.accessibilityTraitsIncludesButton = YES;

  // Then
  XCTAssertEqual(self.button.accessibilityTraits, UIAccessibilityTraitButton);
}

- (void)testAccessibilityTraitsDefaultIncludesButtonExplicitlyFalse {
  // Given
  UIButton *referenceButton = [[UIButton alloc] init];
  [referenceButton setTitle:@"title" forState:UIControlStateNormal];

  // When
  self.button.accessibilityTraitsIncludesButton = NO;

  // Then
  // UIButton does not return `.button` in unit tests, but will in a simulator. The best this test
  // can do is confirm the behavior matches UIButton.
  XCTAssertEqual(self.button.accessibilityTraits, referenceButton.accessibilityTraits);
}

- (void)testSetAccessibilityTraitsIncludesButtonByDefault {
  // When
  self.button.accessibilityTraits = UIAccessibilityTraitLink;

  // Then
  XCTAssertEqual(self.button.accessibilityTraits,
                 UIAccessibilityTraitLink | UIAccessibilityTraitButton);
}

- (void)testSetAccessibilityTraitsExcludesButtonExplicitly {
  // When
  self.button.accessibilityTraitsIncludesButton = NO;
  self.button.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction;

  // Then
  XCTAssertEqual(self.button.accessibilityTraits, UIAccessibilityTraitAllowsDirectInteraction);
}

- (void)testSetAccessibilityTraitsIncludesButtonExplicitly {
  // When
  self.button.accessibilityTraitsIncludesButton = YES;
  self.button.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction;

  // Then
  XCTAssertEqual(self.button.accessibilityTraits,
                 UIAccessibilityTraitAllowsDirectInteraction | UIAccessibilityTraitButton);
}

#pragma mark - UITraitCollection

- (void)testTraitCollectionDidChangeBlockCalledWhenTraitCollectionChanges {
  // Given
  MDCButton *button = [[MDCButton alloc] init];
  XCTestExpectation *expectation =
      [self expectationWithDescription:@"Called traitCollectionDidChange"];

  __block MDCButton *passedButton;
  button.traitCollectionDidChangeBlock =
      ^(MDCButton *_Nonnull buttonInBlock, UITraitCollection *_Nullable previousTraitCollection) {
        passedButton = buttonInBlock;
        [expectation fulfill];
      };

  // When
  [button traitCollectionDidChange:nil];

  // Then
  [self waitForExpectations:@[ expectation ] timeout:1];
  XCTAssertEqual(passedButton, button);
}

#pragma mark - MaterialElevation

- (void)testDefaultValueForOverrideBaseElevationIsNegative {
  // Given
  MDCButton *button = [[MDCButton alloc] init];

  // Then
  XCTAssertLessThan(button.mdc_overrideBaseElevation, 0);
}

- (void)testCurrentElevationMatchesElevationForState {
  // Given
  MDCButton *button = [[MDCButton alloc] init];

  // When
  UIControlState allStatesCombined = UIControlStateNormal | UIControlStateDisabled |
                                     UIControlStateSelected | UIControlStateHighlighted;
  MDCShadowElevation startingElevation = 100;

  for (NSUInteger state = 0; state <= allStatesCombined; ++state) {
    [button setElevation:startingElevation + state forState:state];
  }

  // Then
  for (NSUInteger state = 0; state <= allStatesCombined; ++state) {
    if (state & (UIControlStateDisabled | UIControlStateHighlighted)) {
      continue;
    }
    button.enabled = (state & UIControlStateDisabled) == UIControlStateDisabled ? NO : YES;
    button.selected = (state & UIControlStateSelected) == UIControlStateSelected ? YES : NO;
    button.highlighted =
        (state & UIControlStateHighlighted) == UIControlStateHighlighted ? YES : NO;
    XCTAssertEqualWithAccuracy(button.mdc_currentElevation, [button elevationForState:state],
                               0.001);
  }
}

- (void)testElevationDidChangeBlockCalledWhenStateChangeCausesElevationChange {
  // Given
  MDCButton *button = [[MDCButton alloc] init];
  [button setElevation:1 forState:UIControlStateNormal];
  [button setElevation:9 forState:UIControlStateSelected];
  __block CGFloat newElevation = 0;
  button.mdc_elevationDidChangeBlock = ^(id<MDCElevatable> _, CGFloat elevation) {
    newElevation = elevation;
  };

  // When
  button.selected = YES;

  // Then
  XCTAssertEqualWithAccuracy(newElevation, [button elevationForState:UIControlStateSelected],
                             0.001);
}

- (void)testElevationDidChangeBlockNotCalledWhenStateChangeDoesNotCauseElevationChange {
  // Given
  MDCButton *button = [[MDCButton alloc] init];
  [button setElevation:1 forState:UIControlStateNormal];
  [button setElevation:1 forState:UIControlStateHighlighted];
  __block BOOL blockCalled = NO;
  button.mdc_elevationDidChangeBlock = ^(id<MDCElevatable> _, CGFloat elevation) {
    blockCalled = YES;
  };

  // When
  button.highlighted = YES;

  // Then
  XCTAssertFalse(blockCalled);
}

- (void)testElevationDidChangeBlockCalledWhenElevationChangesForCurrentState {
  // Given
  MDCButton *button = [[MDCButton alloc] init];
  button.selected = YES;
  __block CGFloat newElevation = 0;
  button.mdc_elevationDidChangeBlock = ^(id<MDCElevatable> _, CGFloat elevation) {
    newElevation = elevation;
  };

  // When
  [button setElevation:99 forState:button.state];

  // Then
  XCTAssertEqualWithAccuracy(newElevation, [button elevationForState:button.state], 0.001);
}

- (void)testDefaultVisibleAreaInsetAndShapeGeneratorValues {
  // Then
  XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.button.visibleAreaInsets, UIEdgeInsetsZero));
  XCTAssertNil(self.button.shapeGenerator);
}

- (void)testSettingVisibleAreaInsetCreatesCorrectShape {
  // Given
  CGFloat cornerRadius = 5;
  UIEdgeInsets visibleAreaInsets = UIEdgeInsetsMake(1, 2, 3, 4);
  MDCRectangleShapeGenerator *rectangleShapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
  MDCCornerTreatment *cornerTreatment =
      [[MDCRoundedCornerTreatment alloc] initWithRadius:cornerRadius];
  [rectangleShapeGenerator setCorners:cornerTreatment];
  rectangleShapeGenerator.topLeftCornerOffset =
      CGPointMake(visibleAreaInsets.left, visibleAreaInsets.top);
  rectangleShapeGenerator.topRightCornerOffset =
      CGPointMake(-visibleAreaInsets.right, visibleAreaInsets.top);
  rectangleShapeGenerator.bottomLeftCornerOffset =
      CGPointMake(visibleAreaInsets.left, -visibleAreaInsets.bottom);
  rectangleShapeGenerator.bottomRightCornerOffset =
      CGPointMake(-visibleAreaInsets.right, -visibleAreaInsets.bottom);
  self.button.layer.cornerRadius = cornerRadius;
  [self.button sizeToFit];

  // When
  self.button.visibleAreaInsets = visibleAreaInsets;

  // Then
  XCTAssertTrue(CGPathEqualToPath([self.button.shapeGenerator pathForSize:CGSizeMake(100, 100)],
                                  [rectangleShapeGenerator pathForSize:CGSizeMake(100, 100)]));
}

- (void)testSettingVisibleAreaInsetAndAfterCornerRadiusCreatesCorrectShape {
  // Given
  CGFloat cornerRadius = 12;
  UIEdgeInsets visibleAreaInsets = UIEdgeInsetsMake(1, 2, 3, 4);
  MDCRectangleShapeGenerator *rectangleShapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
  MDCCornerTreatment *cornerTreatment =
      [[MDCRoundedCornerTreatment alloc] initWithRadius:cornerRadius];
  [rectangleShapeGenerator setCorners:cornerTreatment];
  rectangleShapeGenerator.topLeftCornerOffset =
      CGPointMake(visibleAreaInsets.left, visibleAreaInsets.top);
  rectangleShapeGenerator.topRightCornerOffset =
      CGPointMake(-visibleAreaInsets.right, visibleAreaInsets.top);
  rectangleShapeGenerator.bottomLeftCornerOffset =
      CGPointMake(visibleAreaInsets.left, -visibleAreaInsets.bottom);
  rectangleShapeGenerator.bottomRightCornerOffset =
      CGPointMake(-visibleAreaInsets.right, -visibleAreaInsets.bottom);
  self.button.layer.cornerRadius = 5;
  [self.button sizeToFit];

  // When
  self.button.visibleAreaInsets = visibleAreaInsets;
  self.button.layer.cornerRadius = cornerRadius;

  // Then
  XCTAssertTrue(CGPathEqualToPath([self.button.shapeGenerator pathForSize:CGSizeMake(100, 100)],
                                  [rectangleShapeGenerator pathForSize:CGSizeMake(100, 100)]));
}

- (void)testSettingVisibleAreaInsetAndThenResetingItAndCheckingCorrectShapeGeneratorValue {
  // Given
  UIEdgeInsets visibleAreaInsets = UIEdgeInsetsMake(1, 2, 3, 4);
  [self.button sizeToFit];
  self.button.visibleAreaInsets = visibleAreaInsets;

  // When
  self.button.visibleAreaInsets = UIEdgeInsetsZero;

  // Then
  XCTAssertNil(self.button.shapeGenerator);
  XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.button.visibleAreaInsets, UIEdgeInsetsZero));
}

- (void)testSettingVisibleAreaInsetsProvidesCorrectSizeThatFitsAndIntrinsicContentSize {
  // Given
  CGSize buttonSize = CGSizeMake(32, 33);
  UIEdgeInsets visibleAreaInsets = UIEdgeInsetsMake(1, 2, 3, 4);
  [self.button sizeToFit];
  CGRect beforeButtonFrame = self.button.frame;
  CGSize beforeInsetsSize = [self.button intrinsicContentSize];

  // When
  self.button.visibleAreaInsets = visibleAreaInsets;
  [self.button sizeToFit];
  CGRect afterButtonFrame = self.button.frame;
  CGSize afterInsetsSize = [self.button intrinsicContentSize];

  // Then
  XCTAssertTrue(CGSizeEqualToSize(beforeInsetsSize, buttonSize));
  XCTAssertTrue(CGSizeEqualToSize(beforeButtonFrame.size, buttonSize));
  XCTAssertTrue(CGSizeEqualToSize(
      afterInsetsSize,
      CGSizeMake(buttonSize.width + visibleAreaInsets.left + visibleAreaInsets.right,
                 buttonSize.height + visibleAreaInsets.top + visibleAreaInsets.bottom)));
  XCTAssertTrue(CGSizeEqualToSize(
      afterButtonFrame.size,
      CGSizeMake(buttonSize.width + visibleAreaInsets.left + visibleAreaInsets.right,
                 buttonSize.height + visibleAreaInsets.top + visibleAreaInsets.bottom)));
}

@end
