378 lines
19 KiB
Objective-C
378 lines
19 KiB
Objective-C
/*
|
|
* This file is part of the SDWebImage package.
|
|
* (c) Olivier Poitrey <rs@dailymotion.com>
|
|
* (c) Matt Galloway
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
#import "SDTestCase.h"
|
|
#import <KVOController/KVOController.h>
|
|
|
|
@interface SDWebCacheCategoriesTests : SDTestCase
|
|
|
|
@property (nonatomic, strong) UIWindow *window;
|
|
|
|
@end
|
|
|
|
@implementation SDWebCacheCategoriesTests
|
|
|
|
- (void)testUIImageViewSetImageWithURL {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setImageWithURL"];
|
|
|
|
UIImageView *imageView = [[UIImageView alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[imageView sd_setImageWithURL:originalImageURL
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect(imageView.image).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
expect(imageView.sd_imageURL).equal(originalImageURL);
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
#if SD_UIKIT
|
|
- (void)testUIImageViewSetHighlightedImageWithURL {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setHighlightedImageWithURL"];
|
|
|
|
UIImageView *imageView = [[UIImageView alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[imageView sd_setHighlightedImageWithURL:originalImageURL
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect(imageView.highlightedImage).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
#endif
|
|
|
|
- (void)testMKAnnotationViewSetImageWithURL {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"MKAnnotationView setImageWithURL"];
|
|
|
|
MKAnnotationView *annotationView = [[MKAnnotationView alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[annotationView sd_setImageWithURL:originalImageURL
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect(annotationView.image).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
#if SD_UIKIT
|
|
- (void)testUIButtonSetImageWithURLNormalState {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIButton setImageWithURL normalState"];
|
|
|
|
UIButton *button = [[UIButton alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[button sd_setImageWithURL:originalImageURL
|
|
forState:UIControlStateNormal
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect([button imageForState:UIControlStateNormal]).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testUIButtonSetImageWithURLHighlightedState {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIButton setImageWithURL highlightedState"];
|
|
|
|
UIButton *button = [[UIButton alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[button sd_setImageWithURL:originalImageURL
|
|
forState:UIControlStateHighlighted
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect([button imageForState:UIControlStateHighlighted]).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testUIButtonSetBackgroundImageWithURLNormalState {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIButton setBackgroundImageWithURL normalState"];
|
|
|
|
UIButton *button = [[UIButton alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[button sd_setBackgroundImageWithURL:originalImageURL
|
|
forState:UIControlStateNormal
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect([button backgroundImageForState:UIControlStateNormal]).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testUIButtonBackgroundImageCancelCurrentImageLoad {
|
|
UIButton *button = [[UIButton alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[button sd_setBackgroundImageWithURL:originalImageURL forState:UIControlStateNormal];
|
|
[button sd_cancelBackgroundImageLoadForState:UIControlStateNormal];
|
|
NSString *backgroundImageOperationKey = [self testBackgroundImageOperationKeyForState:UIControlStateNormal];
|
|
expect([button sd_imageLoadOperationForKey:backgroundImageOperationKey]).beNil();
|
|
}
|
|
|
|
#endif
|
|
|
|
#if SD_MAC
|
|
- (void)testNSButtonSetImageWithURL {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"NSButton setImageWithURL"];
|
|
|
|
NSButton *button = [[NSButton alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[button sd_setImageWithURL:originalImageURL
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect(button.image).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testNSButtonSetAlternateImageWithURL {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"NSButton setAlternateImageWithURL"];
|
|
|
|
NSButton *button = [[NSButton alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[button sd_setAlternateImageWithURL:originalImageURL
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect(button.alternateImage).to.equal(image);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
#endif
|
|
|
|
- (void)testUIViewInternalSetImageWithURL {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIView internalSetImageWithURL"];
|
|
|
|
UIView *view = [[UIView alloc] init];
|
|
#if SD_MAC
|
|
view.wantsLayer = YES;
|
|
#endif
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
UIImage *placeholder = [[UIImage alloc] initWithContentsOfFile:[self testJPEGPath]];
|
|
[view sd_internalSetImageWithURL:originalImageURL
|
|
placeholderImage:placeholder
|
|
options:0
|
|
context:nil
|
|
setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
if (!imageData && cacheType == SDImageCacheTypeNone) {
|
|
// placeholder
|
|
expect(image).to.equal(placeholder);
|
|
} else {
|
|
// cache or download
|
|
expect(image).toNot.beNil();
|
|
}
|
|
view.layer.contents = (__bridge id _Nullable)(image.CGImage);
|
|
}
|
|
progress:nil
|
|
completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
|
expect(image).toNot.beNil();
|
|
expect(error).to.beNil();
|
|
expect(originalImageURL).to.equal(imageURL);
|
|
expect((__bridge CGImageRef)view.layer.contents == image.CGImage).to.beTruthy();
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testUIViewCancelCurrentImageLoad {
|
|
UIView *imageView = [[UIView alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[SDImageCache.sharedImageCache removeImageFromDiskForKey:kTestJPEGURL];
|
|
[SDImageCache.sharedImageCache removeImageFromMemoryForKey:kTestJPEGURL];
|
|
[imageView sd_internalSetImageWithURL:originalImageURL placeholderImage:nil options:0 context:nil setImageBlock:nil progress:nil completed:nil];
|
|
[imageView sd_cancelCurrentImageLoad];
|
|
NSString *operationKey = NSStringFromClass(UIView.class);
|
|
expect([imageView sd_imageLoadOperationForKey:operationKey]).beNil();
|
|
}
|
|
|
|
- (void)testUIViewCancelCallbackWithError {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIView internalSetImageWithURL cancel callback error"];
|
|
|
|
UIView *imageView = [[UIView alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
[SDImageCache.sharedImageCache removeImageFromDiskForKey:kTestJPEGURL];
|
|
[SDImageCache.sharedImageCache removeImageFromMemoryForKey:kTestJPEGURL];
|
|
[imageView sd_internalSetImageWithURL:originalImageURL placeholderImage:nil options:0 context:nil setImageBlock:nil progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
|
expect(error).notTo.beNil();
|
|
expect(error.code).equal(SDWebImageErrorCancelled);
|
|
[expectation fulfill];
|
|
}];
|
|
[imageView sd_cancelCurrentImageLoad];
|
|
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testUIViewImageProgressKVOWork {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIView imageProgressKVO failed"];
|
|
UIView *view = [[UIView alloc] init];
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
|
|
[self.KVOController observe:view.sd_imageProgress keyPath:NSStringFromSelector(@selector(fractionCompleted)) options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
|
|
NSProgress *progress = object;
|
|
NSNumber *completedValue = change[NSKeyValueChangeNewKey];
|
|
expect(progress.fractionCompleted).equal(completedValue.doubleValue);
|
|
// mark that KVO is called
|
|
[progress setUserInfoObject:@(YES) forKey:NSStringFromSelector(@selector(testUIViewImageProgressKVOWork))];
|
|
}];
|
|
|
|
// Clear the disk cache to force download from network
|
|
[[SDImageCache sharedImageCache] removeImageForKey:kTestJPEGURL withCompletion:^{
|
|
[view sd_internalSetImageWithURL:originalImageURL placeholderImage:nil options:0 context:nil setImageBlock:nil progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
|
expect(view.sd_imageProgress.fractionCompleted).equal(1.0);
|
|
expect([view.sd_imageProgress.userInfo[NSStringFromSelector(_cmd)] boolValue]).equal(YES);
|
|
[expectation fulfill];
|
|
}];
|
|
}];
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testUIViewTransitionWork {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIView transition does not work"];
|
|
|
|
// Attach a window, or CALayer will not submit drawing
|
|
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
|
|
// Cover each convenience method
|
|
imageView.sd_imageTransition = SDWebImageTransition.fadeTransition;
|
|
imageView.sd_imageTransition = SDWebImageTransition.flipFromTopTransition;
|
|
imageView.sd_imageTransition = SDWebImageTransition.flipFromLeftTransition;
|
|
imageView.sd_imageTransition = SDWebImageTransition.flipFromBottomTransition;
|
|
imageView.sd_imageTransition = SDWebImageTransition.flipFromRightTransition;
|
|
imageView.sd_imageTransition = SDWebImageTransition.curlUpTransition;
|
|
imageView.sd_imageTransition = SDWebImageTransition.curlDownTransition;
|
|
imageView.sd_imageTransition.duration = 1;
|
|
|
|
#if SD_UIKIT
|
|
[self.window addSubview:imageView];
|
|
#else
|
|
imageView.wantsLayer = YES;
|
|
[self.window.contentView addSubview:imageView];
|
|
#endif
|
|
|
|
UIImage *placeholder = [[UIImage alloc] initWithContentsOfFile:[self testJPEGPath]];
|
|
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
__weak typeof(imageView) wimageView = imageView;
|
|
[imageView sd_setImageWithURL:originalImageURL
|
|
placeholderImage:placeholder
|
|
options:SDWebImageForceTransition
|
|
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
__strong typeof(wimageView) simageView = imageView;
|
|
// Delay to let CALayer commit the transition in next runloop
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, kMinDelayNanosecond), dispatch_get_main_queue(), ^{
|
|
// Check current view contains layer animation
|
|
NSArray *animationKeys = simageView.layer.animationKeys;
|
|
expect(animationKeys.count).beGreaterThan(0);
|
|
[expectation fulfill];
|
|
});
|
|
}];
|
|
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
- (void)testUIViewIndicatorWork {
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"UIView indicator does not work"];
|
|
|
|
UIImageView *imageView = [[UIImageView alloc] init];
|
|
imageView.sd_imageIndicator = SDWebImageActivityIndicator.grayIndicator;
|
|
// Cover each convience method, finally use progress indicator for test
|
|
imageView.sd_imageIndicator = SDWebImageActivityIndicator.grayLargeIndicator;
|
|
imageView.sd_imageIndicator = SDWebImageActivityIndicator.whiteIndicator;
|
|
imageView.sd_imageIndicator = SDWebImageActivityIndicator.whiteLargeIndicator;
|
|
#if SD_IOS
|
|
imageView.sd_imageIndicator = SDWebImageProgressIndicator.barIndicator;
|
|
#endif
|
|
imageView.sd_imageIndicator = SDWebImageProgressIndicator.defaultIndicator;
|
|
// Test setter trigger removeFromSuperView
|
|
expect(imageView.subviews.count).equal(1);
|
|
|
|
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
|
__weak typeof(imageView) wimageView = imageView;
|
|
[imageView sd_setImageWithURL:originalImageURL
|
|
placeholderImage:nil options:SDWebImageFromLoaderOnly progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
__strong typeof(wimageView) simageView = imageView;
|
|
UIView *indicatorView = simageView.subviews.firstObject;
|
|
expect(indicatorView).equal(simageView.sd_imageIndicator.indicatorView);
|
|
|
|
if (receivedSize <= 0 || expectedSize <= 0) {
|
|
return;
|
|
}
|
|
|
|
// Base on current implementation, since we dispatch the progressBlock to main queue, the indicator's progress state should be synchonized
|
|
double progress = 0;
|
|
double imageProgress = (double)receivedSize / (double)expectedSize;
|
|
#if SD_UIKIT
|
|
progress = ((UIProgressView *)simageView.sd_imageIndicator.indicatorView).progress;
|
|
#else
|
|
progress = ((NSProgressIndicator *)simageView.sd_imageIndicator.indicatorView).doubleValue / 100;
|
|
#endif
|
|
expect(progress).equal(imageProgress);
|
|
});
|
|
} completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
|
__strong typeof(wimageView) simageView = imageView;
|
|
double progress = 0;
|
|
#if SD_UIKIT
|
|
progress = ((UIProgressView *)simageView.sd_imageIndicator.indicatorView).progress;
|
|
#else
|
|
progress = ((NSProgressIndicator *)simageView.sd_imageIndicator.indicatorView).doubleValue / 100;
|
|
#endif
|
|
// Finish progress is 1
|
|
expect(progress).equal(1);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectationsWithCommonTimeout];
|
|
}
|
|
|
|
#pragma mark - Helper
|
|
- (UIWindow *)window {
|
|
if (!_window) {
|
|
UIScreen *mainScreen = [UIScreen mainScreen];
|
|
#if SD_UIKIT
|
|
_window = [[UIWindow alloc] initWithFrame:mainScreen.bounds];
|
|
#else
|
|
_window = [[NSWindow alloc] initWithContentRect:mainScreen.frame styleMask:0 backing:NSBackingStoreBuffered defer:NO screen:mainScreen];
|
|
#endif
|
|
}
|
|
return _window;
|
|
}
|
|
|
|
- (NSString *)testJPEGPath {
|
|
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
|
|
return [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
|
|
}
|
|
|
|
#if SD_UIKIT
|
|
- (NSString *)testBackgroundImageOperationKeyForState:(UIControlState)state {
|
|
return [NSString stringWithFormat:@"UIButtonBackgroundImageOperation%lu", (unsigned long)state];
|
|
}
|
|
#endif
|
|
|
|
@end
|