diff --git a/Examples/SDWebImage Demo/MasterViewController.m b/Examples/SDWebImage Demo/MasterViewController.m index 9044cc46..29c31e9d 100644 --- a/Examples/SDWebImage Demo/MasterViewController.m +++ b/Examples/SDWebImage Demo/MasterViewController.m @@ -76,6 +76,7 @@ @"http://littlesvr.ca/apng/images/world-cup-2014-42.webp", @"https://isparta.github.io/compare-webp/image/gif_webp/webp/2.webp", @"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png", + @"http://via.placeholder.com/200x200.jpg", nil]; for (int i=0; i<100; i++) { diff --git a/Tests/Podfile b/Tests/Podfile index 02553ebb..6610b613 100644 --- a/Tests/Podfile +++ b/Tests/Podfile @@ -2,7 +2,7 @@ source 'https://github.com/CocoaPods/Specs.git' use_frameworks! -xcodeproj 'SDWebImage Tests' +project 'SDWebImage Tests' workspace '../SDWebImage' target 'Tests' do diff --git a/Tests/Tests/SDCategoriesTests.m b/Tests/Tests/SDCategoriesTests.m index fb969425..982e89d5 100644 --- a/Tests/Tests/SDCategoriesTests.m +++ b/Tests/Tests/SDCategoriesTests.m @@ -26,7 +26,7 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setImageWithURL"]; UIImageView *imageView = [[UIImageView alloc] init]; - NSURL *originalImageURL = [NSURL URLWithString:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage050.jpg"]; + 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(); @@ -42,7 +42,7 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setHighlightedImageWithURL"]; UIImageView *imageView = [[UIImageView alloc] init]; - NSURL *originalImageURL = [NSURL URLWithString:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage051.jpg"]; + 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(); @@ -58,7 +58,7 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"MKAnnotationView setImageWithURL"]; MKAnnotationView *annotationView = [[MKAnnotationView alloc] init]; - NSURL *originalImageURL = [NSURL URLWithString:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage052.jpg"]; + 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(); @@ -74,7 +74,7 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"UIButton setImageWithURL normalState"]; UIButton *button = [[UIButton alloc] init]; - NSURL *originalImageURL = [NSURL URLWithString:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage053.jpg"]; + NSURL *originalImageURL = [NSURL URLWithString:kTestJpegURL]; [button sd_setImageWithURL:originalImageURL forState:UIControlStateNormal completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { @@ -91,7 +91,7 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"UIButton setImageWithURL highlightedState"]; UIButton *button = [[UIButton alloc] init]; - NSURL *originalImageURL = [NSURL URLWithString:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage054.jpg"]; + NSURL *originalImageURL = [NSURL URLWithString:kTestJpegURL]; [button sd_setImageWithURL:originalImageURL forState:UIControlStateHighlighted completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { @@ -108,7 +108,7 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"UIButton setBackgroundImageWithURL normalState"]; UIButton *button = [[UIButton alloc] init]; - NSURL *originalImageURL = [NSURL URLWithString:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage055.jpg"]; + NSURL *originalImageURL = [NSURL URLWithString:kTestJpegURL]; [button sd_setBackgroundImageWithURL:originalImageURL forState:UIControlStateNormal completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { diff --git a/Tests/Tests/SDImageCacheTests.m b/Tests/Tests/SDImageCacheTests.m index 756dfd8a..eeab0d39 100644 --- a/Tests/Tests/SDImageCacheTests.m +++ b/Tests/Tests/SDImageCacheTests.m @@ -14,24 +14,16 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; @interface SDImageCacheTests : SDTestCase -@property (strong, nonatomic) SDImageCache *sharedImageCache; @end @implementation SDImageCacheTests -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. - self.sharedImageCache = [SDImageCache sharedImageCache]; - [self clearAllCaches]; -} - - (void)test01SharedImageCache { - expect(self.sharedImageCache).toNot.beNil(); + expect([SDImageCache sharedImageCache]).toNot.beNil(); } - (void)test02Singleton{ - expect(self.sharedImageCache).to.equal([SDImageCache sharedImageCache]); + expect([SDImageCache sharedImageCache]).to.equal([SDImageCache sharedImageCache]); } - (void)test03ImageCacheCanBeInstantiated { @@ -42,16 +34,21 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; - (void)test04ClearDiskCache{ XCTestExpectation *expectation = [self expectationWithDescription:@"Clear disk cache"]; - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - [self.sharedImageCache clearDiskOnCompletion:^{ - [self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { + [[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; + [[SDImageCache sharedImageCache] clearDiskOnCompletion:^{ + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.equal([self imageForTesting]); + [[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { if (!isInCache) { - [expectation fulfill]; + [[SDImageCache sharedImageCache] calculateSizeWithCompletionBlock:^(NSUInteger fileCount, NSUInteger totalSize) { + expect(fileCount).to.equal(0); + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + [expectation fulfill]; + }]; + }]; } else { XCTFail(@"Image should not be in cache"); } }]; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.equal([self imageForTesting]); }]; [self waitForExpectationsWithCommonTimeout]; } @@ -59,15 +56,18 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; - (void)test05ClearMemoryCache{ XCTestExpectation *expectation = [self expectationWithDescription:@"Clear memory cache"]; - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - [self.sharedImageCache clearMemory]; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; - [self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { - if (isInCache) { - [expectation fulfill]; - } else { - XCTFail(@"Image should be in cache"); - } + [[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{ + [[SDImageCache sharedImageCache] clearMemory]; + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; + [[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { + if (isInCache) { + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + [expectation fulfill]; + }]; + } else { + XCTFail(@"Image should be in cache"); + } + }]; }]; [self waitForExpectationsWithCommonTimeout]; } @@ -77,11 +77,13 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; XCTestExpectation *expectation = [self expectationWithDescription:@"storeImage forKey"]; UIImage *image = [self imageForTesting]; - [self.sharedImageCache storeImage:image forKey:kImageTestKey completion:nil]; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.equal(image); - [self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { + [[SDImageCache sharedImageCache] storeImage:image forKey:kImageTestKey completion:nil]; + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.equal(image); + [[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { if (isInCache) { - [expectation fulfill]; + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + [expectation fulfill]; + }]; } else { XCTFail(@"Image should be in cache"); } @@ -90,15 +92,17 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; } // Testing storeImage:forKey:toDisk:YES -- (void)test07InsertionOfImageForcingDiskStorage{ +- (void)test07InsertionOfImageForcingDiskStorage { XCTestExpectation *expectation = [self expectationWithDescription:@"storeImage forKey toDisk=YES"]; UIImage *image = [self imageForTesting]; - [self.sharedImageCache storeImage:image forKey:kImageTestKey toDisk:YES completion:nil]; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.equal(image); - [self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { + [[SDImageCache sharedImageCache] storeImage:image forKey:kImageTestKey toDisk:YES completion:nil]; + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.equal(image); + [[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { if (isInCache) { - [expectation fulfill]; + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + [expectation fulfill]; + }]; } else { XCTFail(@"Image should be in cache"); } @@ -110,121 +114,129 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; - (void)test08InsertionOfImageOnlyInMemory { XCTestExpectation *expectation = [self expectationWithDescription:@"storeImage forKey toDisk=NO"]; UIImage *image = [self imageForTesting]; - [self.sharedImageCache storeImage:image forKey:kImageTestKey toDisk:NO completion:nil]; + [[SDImageCache sharedImageCache] storeImage:image forKey:kImageTestKey toDisk:NO completion:nil]; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.equal([self imageForTesting]); - [self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.equal([self imageForTesting]); + [[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { if (!isInCache) { [expectation fulfill]; } else { XCTFail(@"Image should not be in cache"); } }]; - [self.sharedImageCache clearMemory]; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil(); + [[SDImageCache sharedImageCache] clearMemory]; + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.beNil(); [self waitForExpectationsWithCommonTimeout]; } -- (void)test09RetrieveImageThroughNSOperation{ - //- (NSOperation *)queryCacheOperationForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock; +- (void)test09RetrieveImageThroughNSOperation { + XCTestExpectation *expectation = [self expectationWithDescription:@"queryCacheOperationForKey"]; UIImage *imageForTesting = [self imageForTesting]; - [self.sharedImageCache storeImage:imageForTesting forKey:kImageTestKey completion:nil]; - NSOperation *operation = [self.sharedImageCache queryCacheOperationForKey:kImageTestKey done:^(UIImage *image, NSData *data, SDImageCacheType cacheType) { + [[SDImageCache sharedImageCache] storeImage:imageForTesting forKey:kImageTestKey completion:nil]; + NSOperation *operation = [[SDImageCache sharedImageCache] queryCacheOperationForKey:kImageTestKey done:^(UIImage *image, NSData *data, SDImageCacheType cacheType) { expect(image).to.equal(imageForTesting); + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + [expectation fulfill]; + }]; }]; expect(operation).toNot.beNil; + [operation start]; + [self waitForExpectationsWithCommonTimeout]; } -- (void)test10RemoveImageForKeyWithCompletion{ - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - [self.sharedImageCache removeImageForKey:kImageTestKey withCompletion:^{ - expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).to.beNil; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; +- (void)test10RemoveImageForKeyWithCompletion { + XCTestExpectation *expectation = [self expectationWithDescription:@"removeImageForKey"]; + [[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + expect([[SDImageCache sharedImageCache] imageFromDiskCacheForKey:kImageTestKey]).to.beNil; + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; + [expectation fulfill]; }]; + [self waitForExpectationsWithCommonTimeout]; } - (void)test11RemoveImageforKeyNotFromDiskWithCompletion{ - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - [self.sharedImageCache removeImageForKey:kImageTestKey fromDisk:NO withCompletion:^{ - expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).toNot.beNil; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; + XCTestExpectation *expectation = [self expectationWithDescription:@"removeImageForKey fromDisk:NO"]; + [[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey fromDisk:NO withCompletion:^{ + expect([[SDImageCache sharedImageCache] imageFromDiskCacheForKey:kImageTestKey]).toNot.beNil; + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; + [expectation fulfill]; }]; + [self waitForExpectationsWithCommonTimeout]; } - (void)test12RemoveImageforKeyFromDiskWithCompletion{ - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - [self.sharedImageCache removeImageForKey:kImageTestKey fromDisk:YES withCompletion:^{ - expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).to.beNil; - expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; + XCTestExpectation *expectation = [self expectationWithDescription:@"removeImageForKey fromDisk:YES"]; + [[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey fromDisk:YES withCompletion:^{ + expect([[SDImageCache sharedImageCache] imageFromDiskCacheForKey:kImageTestKey]).to.beNil; + expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.beNil; + [expectation fulfill]; }]; + [self waitForExpectationsWithCommonTimeout]; } - (void)test20InitialCacheSize{ - expect([self.sharedImageCache getSize]).to.equal(0); + expect([[SDImageCache sharedImageCache] getSize]).to.equal(0); } - (void)test21InitialDiskCount{ - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - expect([self.sharedImageCache getDiskCount]).to.equal(1); -} - -- (void)test22DiskCountAfterInsertion{ - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - expect([self.sharedImageCache getDiskCount]).to.equal(1); + XCTestExpectation *expectation = [self expectationWithDescription:@"getDiskCount"]; + [[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{ + expect([[SDImageCache sharedImageCache] getDiskCount]).to.equal(1); + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + [expectation fulfill]; + }]; + }]; + [self waitForExpectationsWithCommonTimeout]; } - (void)test31DefaultCachePathForAnyKey{ - NSString *path = [self.sharedImageCache defaultCachePathForKey:kImageTestKey]; + NSString *path = [[SDImageCache sharedImageCache] defaultCachePathForKey:kImageTestKey]; expect(path).toNot.beNil; } - (void)test32CachePathForNonExistingKey{ - NSString *path = [self.sharedImageCache cachePathForKey:kImageTestKey inPath:[self.sharedImageCache defaultCachePathForKey:kImageTestKey]]; + NSString *path = [[SDImageCache sharedImageCache] cachePathForKey:kImageTestKey inPath:[[SDImageCache sharedImageCache] defaultCachePathForKey:kImageTestKey]]; expect(path).to.beNil; } - (void)test33CachePathForExistingKey{ - [self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey completion:nil]; - NSString *path = [self.sharedImageCache cachePathForKey:kImageTestKey inPath:[self.sharedImageCache defaultCachePathForKey:kImageTestKey]]; - expect(path).notTo.beNil; + XCTestExpectation *expectation = [self expectationWithDescription:@"cachePathForKey inPath"]; + [[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{ + NSString *path = [[SDImageCache sharedImageCache] cachePathForKey:kImageTestKey inPath:[[SDImageCache sharedImageCache] defaultCachePathForKey:kImageTestKey]]; + expect(path).notTo.beNil; + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ + [expectation fulfill]; + }]; + }]; + [self waitForExpectationsWithCommonTimeout]; } -// TODO -- Testing image data insertion - -// TODO -- this test is driving me crazy keeps failing for unknown reasons, sometimes the image data is not written to disk - disabling the test for now -- (void)a40InsertionOfImageData { +- (void)test40InsertionOfImageData { XCTestExpectation *expectation = [self expectationWithDescription:@"Insertion of image data works"]; UIImage *image = [UIImage imageWithContentsOfFile:[self testImagePath]]; NSData *imageData = UIImageJPEGRepresentation(image, 1.0); - [self.sharedImageCache storeImageDataToDisk:imageData forKey:kImageTestKey]; + [[SDImageCache sharedImageCache] storeImageDataToDisk:imageData forKey:kImageTestKey]; - UIImage *storedImageFromMemory = [self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]; + UIImage *storedImageFromMemory = [[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]; expect(storedImageFromMemory).to.equal(nil); - NSString *cachePath = [self.sharedImageCache defaultCachePathForKey:kImageTestKey]; + NSString *cachePath = [[SDImageCache sharedImageCache] defaultCachePathForKey:kImageTestKey]; UIImage *cachedImage = [UIImage imageWithContentsOfFile:cachePath]; NSData *storedImageData = UIImageJPEGRepresentation(cachedImage, 1.0); expect(storedImageData.length).to.beGreaterThan(0); expect(cachedImage.size).to.equal(image.size); // can't directly compare image and cachedImage because apparently there are some slight differences, even though the image is the same - __block int blocksCalled = 0; - - [self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { + [[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { expect(isInCache).to.equal(YES); - blocksCalled += 1; - if (blocksCalled == 2) { + + [[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{ [expectation fulfill]; - } - }]; - - [self.sharedImageCache calculateSizeWithCompletionBlock:^(NSUInteger fileCount, NSUInteger totalSize) { - expect(fileCount).to.beLessThan(100); - blocksCalled += 1; - if (blocksCalled == 2) { - [expectation fulfill]; - } + }]; }]; [self waitForExpectationsWithCommonTimeout]; @@ -269,7 +281,10 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; } [[SDWebImageCodersManager sharedInstance] removeCoder:testDecoder]; - [expectation fulfill]; + + [[SDImageCache sharedImageCache] removeImageForKey:key withCompletion:^{ + [expectation fulfill]; + }]; }]; [self waitForExpectationsWithCommonTimeout]; @@ -277,14 +292,6 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; #pragma mark Helper methods -- (void)clearAllCaches{ - [self.sharedImageCache deleteOldFilesWithCompletionBlock:nil]; - - // TODO: this is not ok, clearDiskOnCompletion will clear async, this means that when we execute the tests, the cache might not be cleared - [self.sharedImageCache clearDiskOnCompletion:nil]; - [self.sharedImageCache clearMemory]; -} - - (UIImage *)imageForTesting{ static UIImage *reusableImage = nil; if (!reusableImage) { diff --git a/Tests/Tests/SDTestCase.h b/Tests/Tests/SDTestCase.h index 2eab1f97..7deb9850 100644 --- a/Tests/Tests/SDTestCase.h +++ b/Tests/Tests/SDTestCase.h @@ -13,11 +13,13 @@ #import #import -extern const int64_t kAsyncTestTimeout; +FOUNDATION_EXPORT const int64_t kAsyncTestTimeout; +FOUNDATION_EXPORT NSString * _Nonnull const kTestJpegURL; +FOUNDATION_EXPORT NSString * _Nonnull const kTestPNGURL; @interface SDTestCase : XCTestCase - (void)waitForExpectationsWithCommonTimeout; -- (void)waitForExpectationsWithCommonTimeoutUsingHandler:(XCWaitCompletionHandler)handler; +- (void)waitForExpectationsWithCommonTimeoutUsingHandler:(nullable XCWaitCompletionHandler)handler; @end diff --git a/Tests/Tests/SDTestCase.m b/Tests/Tests/SDTestCase.m index 7029e9d4..ffd9cf61 100644 --- a/Tests/Tests/SDTestCase.m +++ b/Tests/Tests/SDTestCase.m @@ -10,6 +10,8 @@ #import "SDTestCase.h" const int64_t kAsyncTestTimeout = 5; +NSString *const kTestJpegURL = @"http://via.placeholder.com/50x50.jpg"; +NSString *const kTestPNGURL = @"http://via.placeholder.com/50x50.png"; @implementation SDTestCase diff --git a/Tests/Tests/SDWebImageDecoderTests.m b/Tests/Tests/SDWebImageDecoderTests.m index 53fac045..0ceaff3d 100644 --- a/Tests/Tests/SDWebImageDecoderTests.m +++ b/Tests/Tests/SDWebImageDecoderTests.m @@ -11,6 +11,8 @@ #import #import #import +#import +#import @interface SDWebImageDecoderTests : SDTestCase @@ -96,32 +98,63 @@ - (void)test09ThatStaticWebPCoderWorks { NSURL *staticWebPURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageStatic" withExtension:@"webp"]; - NSData *staticWebPData = [NSData dataWithContentsOfURL:staticWebPURL]; - UIImage *staticWebPImage = [[SDWebImageWebPCoder sharedCoder] decodedImageWithData:staticWebPData]; - expect(staticWebPImage).toNot.beNil(); - - NSData *outputData = [[SDWebImageWebPCoder sharedCoder] encodedDataWithImage:staticWebPImage format:SDImageFormatWebP]; - expect(outputData).toNot.beNil(); + [self verifyCoder:[SDWebImageWebPCoder sharedCoder] + withLocalImageURL:staticWebPURL + isAnimatedImage:NO]; } - (void)test10ThatAnimatedWebPCoderWorks { NSURL *animatedWebPURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageAnimated" withExtension:@"webp"]; - NSData *animatedWebPData = [NSData dataWithContentsOfURL:animatedWebPURL]; - UIImage *animatedWebPImage = [[SDWebImageWebPCoder sharedCoder] decodedImageWithData:animatedWebPData]; - expect(animatedWebPImage).toNot.beNil(); - expect(animatedWebPImage.images.count).to.beGreaterThan(0); - CGSize imageSize = animatedWebPImage.size; - CGFloat imageScale = animatedWebPImage.scale; - [animatedWebPImage.images enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) { - CGSize size = image.size; - CGFloat scale = image.scale; - expect(imageSize.width).to.equal(size.width); - expect(imageSize.height).to.equal(size.height); - expect(imageScale).to.equal(scale); - }]; + [self verifyCoder:[SDWebImageWebPCoder sharedCoder] + withLocalImageURL:animatedWebPURL + isAnimatedImage:YES]; +} + +- (void)test20ThatOurGIFCoderWorksNotFLAnimatedImage { + NSURL *gifURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImage" withExtension:@"gif"]; + [self verifyCoder:[SDWebImageGIFCoder sharedCoder] + withLocalImageURL:gifURL + isAnimatedImage:YES]; +} + +- (void)verifyCoder:(id)coder + withLocalImageURL:(NSURL *)imageUrl + isAnimatedImage:(BOOL)isAnimated { + NSData *inputImageData = [NSData dataWithContentsOfURL:imageUrl]; + expect(inputImageData).toNot.beNil(); + SDImageFormat inputImageFormat = [NSData sd_imageFormatForImageData:inputImageData]; + expect(inputImageFormat).toNot.equal(SDImageFormatUndefined); - NSData *outputData = [[SDWebImageWebPCoder sharedCoder] encodedDataWithImage:animatedWebPImage format:SDImageFormatWebP]; - expect(outputData).toNot.beNil(); + // 1 - check if we can decode - should be true + expect([coder canDecodeFromData:inputImageData]).to.beTruthy(); + + // 2 - decode from NSData to UIImage and check it + UIImage *inputImage = [coder decodedImageWithData:inputImageData]; + expect(inputImage).toNot.beNil(); + + if (isAnimated) { + // 2a - check images count > 0 (only for animated images) + expect(inputImage.images.count).to.beGreaterThan(0); + + // 2b - check image size and scale for each frameImage (only for animated images) + CGSize imageSize = inputImage.size; + CGFloat imageScale = inputImage.scale; + [inputImage.images enumerateObjectsUsingBlock:^(UIImage * frameImage, NSUInteger idx, BOOL * stop) { + expect(imageSize).to.equal(frameImage.size); + expect(imageScale).to.equal(frameImage.scale); + }]; + } + + // 3 - check if we can encode to the original format + expect([coder canEncodeToFormat:inputImageFormat]).to.beTruthy(); + + // 4 - encode from UIImage to NSData using the inputImageFormat and check it + NSData *outputImageData = [coder encodedDataWithImage:inputImage format:inputImageFormat]; + expect(outputImageData).toNot.beNil(); + UIImage *outputImage = [coder decodedImageWithData:outputImageData]; + expect(outputImage.size).to.equal(inputImage.size); + expect(outputImage.scale).to.equal(inputImage.scale); + expect(outputImage.images.count).to.equal(inputImage.images.count); } @end diff --git a/Tests/Tests/SDWebImageDownloaderTests.m b/Tests/Tests/SDWebImageDownloaderTests.m index e1b10e37..04b78214 100644 --- a/Tests/Tests/SDWebImageDownloaderTests.m +++ b/Tests/Tests/SDWebImageDownloaderTests.m @@ -80,7 +80,7 @@ - (void)test04ThatASimpleDownloadWorks { XCTestExpectation *expectation = [self expectationWithDescription:@"Simple download"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage004.jpg"]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { if (image && data && !error && finished) { [expectation fulfill]; @@ -145,7 +145,7 @@ - (void)test09ThatProgressiveJPEGWorks { XCTestExpectation *expectation = [self expectationWithDescription:@"Progressive JPEG download"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage009.jpg"]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:SDWebImageDownloaderProgressiveDownload progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { if (image && data && !error && finished) { [expectation fulfill]; @@ -175,7 +175,7 @@ - (void)test11ThatCancelWorks { XCTestExpectation *expectation = [self expectationWithDescription:@"Cancel"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage011.jpg"]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; SDWebImageDownloadToken *token = [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { XCTFail(@"Should not get here"); @@ -195,7 +195,7 @@ - (void)test12ThatWeCanUseAnotherSessionForEachDownloadOperation { XCTestExpectation *expectation = [self expectationWithDescription:@"Owned session"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage012.jpg"]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:imageURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15]; request.HTTPShouldUsePipelining = YES; @@ -221,7 +221,7 @@ - (void)test13ThatDownloadCanContinueWhenTheAppEntersBackground { XCTestExpectation *expectation = [self expectationWithDescription:@"Simple download"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage013.jpg"]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:SDWebImageDownloaderContinueInBackground progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { if (image && data && !error && finished) { [expectation fulfill]; @@ -233,8 +233,8 @@ } - (void)test14ThatPNGWorks { - XCTestExpectation *expectation = [self expectationWithDescription:@"WEBP"]; - NSURL *imageURL = [NSURL URLWithString:@"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png"]; + XCTestExpectation *expectation = [self expectationWithDescription:@"PNG"]; + NSURL *imageURL = [NSURL URLWithString:kTestPNGURL]; [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { if (image && data && !error && finished) { [expectation fulfill]; @@ -282,7 +282,7 @@ - (void)test20ThatDownloadingSameURLTwiceAndCancellingFirstWorks { XCTestExpectation *expectation = [self expectationWithDescription:@"Correct image downloads"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage020.jpg"]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; SDWebImageDownloadToken *token1 = [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL @@ -320,7 +320,7 @@ - (void)test21ThatCancelingDownloadThenRequestingAgainWorks { XCTestExpectation *expectation = [self expectationWithDescription:@"Correct image downloads"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage021.jpg"]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; SDWebImageDownloadToken *token1 = [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL diff --git a/Tests/Tests/SDWebImageManagerTests.m b/Tests/Tests/SDWebImageManagerTests.m index 87a0ccb1..423b0f44 100644 --- a/Tests/Tests/SDWebImageManagerTests.m +++ b/Tests/Tests/SDWebImageManagerTests.m @@ -9,8 +9,6 @@ #import "SDTestCase.h" #import -NSString *workingImageURL = @"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage001.jpg"; - @interface SDWebImageManagerTests : SDTestCase @end @@ -25,7 +23,7 @@ NSString *workingImageURL = @"http://s3.amazonaws.com/fast-image-cache/demo-imag - (void)test02ThatDownloadInvokesCompletionBlockWithCorrectParamsAsync { __block XCTestExpectation *expectation = [self expectationWithDescription:@"Image download completes"]; - NSURL *originalImageURL = [NSURL URLWithString:workingImageURL]; + NSURL *originalImageURL = [NSURL URLWithString:kTestJpegURL]; [[SDWebImageManager sharedManager] loadImageWithURL:originalImageURL options:SDWebImageRefreshCached @@ -65,7 +63,7 @@ NSString *workingImageURL = @"http://s3.amazonaws.com/fast-image-cache/demo-imag - (void)test04CachedImageExistsForURL { __block XCTestExpectation *expectation = [self expectationWithDescription:@"Image exists in cache"]; - NSURL *imageURL = [NSURL URLWithString:workingImageURL]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; [[SDWebImageManager sharedManager] cachedImageExistsForURL:imageURL completion:^(BOOL isInCache) { if (isInCache) { [expectation fulfill]; @@ -78,7 +76,7 @@ NSString *workingImageURL = @"http://s3.amazonaws.com/fast-image-cache/demo-imag - (void)test05DiskImageExistsForURL { __block XCTestExpectation *expectation = [self expectationWithDescription:@"Image exists in disk cache"]; - NSURL *imageURL = [NSURL URLWithString:workingImageURL]; + NSURL *imageURL = [NSURL URLWithString:kTestJpegURL]; [[SDWebImageManager sharedManager] diskImageExistsForURL:imageURL completion:^(BOOL isInCache) { if (isInCache) { [expectation fulfill]; @@ -92,7 +90,9 @@ NSString *workingImageURL = @"http://s3.amazonaws.com/fast-image-cache/demo-imag - (void)test06CancellAll { XCTestExpectation *expectation = [self expectationWithDescription:@"Cancel"]; - NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage006.jpg"]; + // need a bigger image here, that is why we don't use kTestJpegURL + // if the image is too small, it will get downloaded before we can cancel :) + NSURL *imageURL = [NSURL URLWithString:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage001.jpg"]; [[SDWebImageManager sharedManager] loadImageWithURL:imageURL options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { XCTFail(@"Should not get here"); }]; @@ -110,7 +110,7 @@ NSString *workingImageURL = @"http://s3.amazonaws.com/fast-image-cache/demo-imag - (void)test07ThatLoadImageWithSDWebImageRefreshCachedWorks { XCTestExpectation *expectation = [self expectationWithDescription:@"Image download twice with SDWebImageRefresh failed"]; - NSURL *originalImageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage007.jpg"]; + NSURL *originalImageURL = [NSURL URLWithString:kTestJpegURL]; [[SDImageCache sharedImageCache] clearDiskOnCompletion:nil]; [[SDWebImageManager sharedManager] loadImageWithURL:originalImageURL options:SDWebImageRefreshCached progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { diff --git a/Tests/Tests/SDWebImagePrefetcherTests.m b/Tests/Tests/SDWebImagePrefetcherTests.m index ea18f5b0..66600add 100644 --- a/Tests/Tests/SDWebImagePrefetcherTests.m +++ b/Tests/Tests/SDWebImagePrefetcherTests.m @@ -24,13 +24,9 @@ - (void)test02PrefetchMultipleImages { XCTestExpectation *expectation = [self expectationWithDescription:@"Correct prefetch of multiple images"]; - NSMutableArray *imageURLs = [NSMutableArray array]; - - for (int i=40; i<43; i++) { - NSString *imageURLString = [NSString stringWithFormat:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage%03d.jpg", i]; - NSURL *imageURL = [NSURL URLWithString:imageURLString]; - [imageURLs addObject:imageURL]; - } + NSArray *imageURLs = @[@"http://via.placeholder.com/20x20.jpg", + @"http://via.placeholder.com/30x30.jpg", + @"http://via.placeholder.com/40x40.jpg"]; __block int numberOfPrefetched = 0;