123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- //
- // HudTests.m
- // HudTests
- //
- // Created by Matej Bukovinski on 31. 01. 16.
- // Copyright © 2016 Matej Bukovinski. All rights reserved.
- //
- #import <XCTest/XCTest.h>
- #import "MBProgressHUD.h"
- #define weakify(var) __weak typeof(var) weak_##var = var;
- #define strongify(var) \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wshadow\"") \
- __strong typeof(var) var = weak_##var; \
- _Pragma("clang diagnostic pop")
- #define MBTestHUDIsVisible(hud, rootView) \
- do { \
- XCTAssertEqualObjects(hud.superview, rootView, @"The hud should be added to the view."); \
- XCTAssertEqual(hud.alpha, 1.f, @"The HUD should be visible."); \
- XCTAssertFalse(hud.hidden, @"The HUD should be visible."); \
- XCTAssertEqual(hud.bezelView.alpha, 1.f, @"The HUD should be visible."); \
- } while (0)
- #define MBTestHUDIsHidenAndRemoved(hud, rootView) \
- do { \
- XCTAssertFalse([rootView.subviews containsObject:hud], @"The HUD should not be part of the view hierarchy."); \
- XCTAssertEqual(hud.alpha, 0.f, @"The hud should be faded out."); \
- XCTAssertNil(hud.superview, @"The HUD should not have a superview."); \
- } while (0)
- @interface HudTests : XCTestCase <MBProgressHUDDelegate>
- @property (nonatomic) XCTestExpectation *hideExpectation;
- @property (nonatomic, copy) dispatch_block_t hideChecks;
- @end
- @implementation HudTests
- #pragma mark - Convenience
- - (void)testNonAnimatedConvenienceHUDPresentation {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:rootView animated:NO];
- XCTAssertNotNil(hud, @"A HUD should be created.");
- MBTestHUDIsVisible(hud, rootView);
- XCTAssertEqual(hud.bezelView.alpha, 1.f, @"The HUD should be visible.");
- XCTAssertFalse([hud.bezelView.layer.animationKeys containsObject:@"opacity"], @"The opacity should NOT be animated.");
- XCTAssertEqualObjects([MBProgressHUD HUDForView:rootView], hud, @"The HUD should be found via the convenience operation.");
- XCTAssertTrue([MBProgressHUD hideHUDForView:rootView animated:NO], @"The HUD should be found and removed.");
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- XCTAssertFalse([MBProgressHUD hideHUDForView:rootView animated:NO], @"A subsequent HUD hide operation should fail.");
- }
- - (void)testAnimatedConvenienceHUDPresentation {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- self.hideExpectation = [self expectationWithDescription:@"The hudWasHidden: delegate should have been called."];
- MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:rootView animated:YES];
- hud.delegate = self;
- XCTAssertNotNil(hud, @"A HUD should be created.");
- MBTestHUDIsVisible(hud, rootView);
- XCTAssertEqual(hud.bezelView.alpha, 1.f, @"The HUD should be visible.");
- XCTAssertTrue([hud.bezelView.layer.animationKeys containsObject:@"opacity"], @"The opacity should be animated.");
- XCTAssertEqualObjects([MBProgressHUD HUDForView:rootView], hud, @"The HUD should be found via the convenience operation.");
- XCTAssertTrue([MBProgressHUD hideHUDForView:rootView animated:YES], @"The HUD should be found and removed.");
- XCTAssertTrue([rootView.subviews containsObject:hud], @"The HUD should still be part of the view hierarchy.");
- XCTAssertEqual(hud.alpha, 1.f, @"The hud should still be visible.");
- XCTAssertEqualObjects(hud.superview, rootView, @"The hud should be added to the view.");
- XCTAssertEqual(hud.bezelView.alpha, 0.f, @"The HUD bezel should be animated out.");
- XCTAssertTrue([hud.bezelView.layer.animationKeys containsObject:@"opacity"], @"The opacity should be animated.");
- weakify(self);
- self.hideChecks = ^{
- strongify(self);
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- XCTAssertFalse([MBProgressHUD hideHUDForView:rootView animated:YES], @"A subsequent HUD hide operation should fail.");
- };
- [self waitForExpectationsWithTimeout:5. handler:nil];
- }
- - (void)testCompletionBlock {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- self.hideExpectation = [self expectationWithDescription:@"The hudWasHidden: delegate should have been called."];
- XCTestExpectation *completionExpectation = [self expectationWithDescription:@"The completionBlock: should have been called."];
- MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:rootView animated:YES];
- hud.delegate = self;
- hud.completionBlock = ^{
- [completionExpectation fulfill];
- };
- [hud hideAnimated:YES];
- [self waitForExpectationsWithTimeout:5. handler:nil];
- }
- #pragma mark - Delay
- - (void)testDelayedHide {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- self.hideExpectation = [self expectationWithDescription:@"The hudWasHidden: delegate should have been called."];
- MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:rootView animated:NO];
- hud.delegate = self;
- XCTAssertNotNil(hud, @"A HUD should be created.");
- [hud hideAnimated:NO afterDelay:2];
- MBTestHUDIsVisible(hud, rootView);
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- MBTestHUDIsVisible(hud, rootView);
- });
- XCTestExpectation *hideCheckExpectation = [self expectationWithDescription:@"Hide check"];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // After the grace time passes, the HUD should still not be shown.
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- [hideCheckExpectation fulfill];
- });
- [self waitForExpectationsWithTimeout:5. handler:nil];
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- }
- #pragma mark - Ruse
- - (void)testNonAnimatedHudReuse {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:rootView];
- [rootView addSubview:hud];
- [hud showAnimated:NO];
- XCTAssertNotNil(hud, @"A HUD should be created.");
- [hud hideAnimated:NO];
- [hud showAnimated:NO];
- MBTestHUDIsVisible(hud, rootView);
- [hud hideAnimated:NO];
- [hud removeFromSuperview];
- }
- - (void)testUnfinishedHidingAnimation {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:rootView animated:NO];
- [hud hideAnimated:YES];
- // Cancel all animations. It will cause `UIView+animate...` to call completionBlock with `finished = NO`.
- // It's same as if you call `[hud hideAnimated:YES]` while the app is in background.
- [hud.bezelView.layer removeAllAnimations];
- [hud.backgroundView.layer removeAllAnimations];
- XCTestExpectation *hideCheckExpectation = [self expectationWithDescription:@"Hide check"];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // After the grace time passes, the HUD should still not be shown.
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- [hideCheckExpectation fulfill];
- });
- [self waitForExpectationsWithTimeout:5. handler:nil];
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- }
- - (void)testAnimatedImmediateHudReuse {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- XCTestExpectation *hideExpectation = [self expectationWithDescription:@"The hud should have been hidden."];
- MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:rootView];
- [rootView addSubview:hud];
- [hud showAnimated:YES];
- XCTAssertNotNil(hud, @"A HUD should be created.");
- [hud hideAnimated:YES];
- [hud showAnimated:YES];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- MBTestHUDIsVisible(hud, rootView);
- [hud hideAnimated:NO];
- [hud removeFromSuperview];
- [hideExpectation fulfill];
- });
- [self waitForExpectationsWithTimeout:5. handler:nil];
- }
- #pragma mark - Min show time
- - (void)testMinShowTime {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- self.hideExpectation = [self expectationWithDescription:@"The hudWasHidden: delegate should have been called."];
- MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:rootView];
- hud.delegate = self;
- hud.removeFromSuperViewOnHide = YES;
- hud.minShowTime = 2.;
- [rootView addSubview:hud];
- [hud showAnimated:YES];
- XCTAssertNotNil(hud, @"A HUD should be created.");
- [hud hideAnimated:YES];
- __block BOOL checkedAfterOneSecond = NO;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // Check that the hud is still visible
- MBTestHUDIsVisible(hud, rootView);
- checkedAfterOneSecond = YES;
- });
- weakify(self);
- self.hideChecks = ^{
- strongify(self);
- XCTAssertTrue(checkedAfterOneSecond);
- };
- [self waitForExpectationsWithTimeout:5. handler:nil];
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- }
- #pragma mark - Grace time
- - (void)testGraceTime {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- self.hideExpectation = [self expectationWithDescription:@"The hudWasHidden: delegate should have been called."];
- MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:rootView];
- hud.delegate = self;
- hud.removeFromSuperViewOnHide = YES;
- hud.graceTime = 2.;
- [rootView addSubview:hud];
- [hud showAnimated:YES];
- XCTAssertNotNil(hud, @"A HUD should be created.");
- // The HUD should be added to the view but still hidden
- XCTAssertEqualObjects(hud.superview, rootView, @"The hud should be added to the view."); \
- XCTAssertEqual(hud.alpha, 0.f, @"The HUD should not be visible."); \
- XCTAssertFalse(hud.hidden, @"The HUD should be visible."); \
- XCTAssertEqual(hud.bezelView.alpha, 0.f, @"The HUD should not be visible."); \
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // The HUD should be added to the view but still hidden
- XCTAssertEqualObjects(hud.superview, rootView, @"The hud should be added to the view."); \
- XCTAssertEqual(hud.alpha, 0.f, @"The HUD should not be visible."); \
- XCTAssertFalse(hud.hidden, @"The HUD should be visible."); \
- XCTAssertEqual(hud.bezelView.alpha, 0.f, @"The HUD should not be visible."); \
- });
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // After the grace time passes, the HUD should be shown.
- MBTestHUDIsVisible(hud, rootView);
- [hud hideAnimated:YES];
- });
- [self waitForExpectationsWithTimeout:5. handler:nil];
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- }
- - (void)testHideBeforeGraceTimeElapsed {
- UIViewController *rootViewController = UIApplication.sharedApplication.keyWindow.rootViewController;
- UIView *rootView = rootViewController.view;
- self.hideExpectation = [self expectationWithDescription:@"The hudWasHidden: delegate should have been called."];
- MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:rootView];
- hud.delegate = self;
- hud.removeFromSuperViewOnHide = YES;
- hud.graceTime = 2.;
- [rootView addSubview:hud];
- [hud showAnimated:YES];
- XCTAssertNotNil(hud, @"A HUD should be created.");
- // The HUD should be added to the view but still hidden
- XCTAssertEqualObjects(hud.superview, rootView, @"The hud should be added to the view."); \
- XCTAssertEqual(hud.alpha, 0.f, @"The HUD should not be visible."); \
- XCTAssertFalse(hud.hidden, @"The HUD should be visible."); \
- XCTAssertEqual(hud.bezelView.alpha, 0.f, @"The HUD should not be visible."); \
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // The HUD should be added to the view but still hidden
- XCTAssertEqualObjects(hud.superview, rootView, @"The hud should be added to the view."); \
- XCTAssertEqual(hud.alpha, 0.f, @"The HUD should not be visible."); \
- XCTAssertFalse(hud.hidden, @"The HUD should be visible."); \
- XCTAssertEqual(hud.bezelView.alpha, 0.f, @"The HUD should not be visible."); \
- [hud hideAnimated:YES];
- });
- XCTestExpectation *hideCheckExpectation = [self expectationWithDescription:@"Hide check"];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // After the grace time passes, the HUD should still not be shown.
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- [hideCheckExpectation fulfill];
- });
- [self waitForExpectationsWithTimeout:5. handler:nil];
- MBTestHUDIsHidenAndRemoved(hud, rootView);
- }
- #pragma mark - MBProgressHUDDelegate
- - (void)hudWasHidden:(MBProgressHUD *)hud {
- if (self.hideChecks) self.hideChecks();
- self.hideChecks = nil;
- [self.hideExpectation fulfill];
- self.hideExpectation = nil;
- }
- @end
|