ComponentKitApplicationTests/CKNetworkImageComponentTests.mm (161 lines of code) (raw):

/* * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import <ComponentSnapshotTestCase/CKComponentSnapshotTestCase.h> #import <ComponentKit/CKNetworkImageComponent.h> #pragma mark - Helpers static UIImage *ck_fakeImage(UIColor *imageBackgroundColor, CGSize size) { size_t bytesPerRow = ((((size_t)size.width * 4)+31)&~0x1f); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); CGColorSpaceRelease(colorSpace); CGContextSetAllowsAntialiasing(context, YES); CGContextSetInterpolationQuality(context, kCGInterpolationHigh); CGContextSetFillColorWithColor(context, [imageBackgroundColor CGColor]); CGContextFillRect(context, {{0,0}, size}); CGImageRef imageRef = CGBitmapContextCreateImage(context); CGContextRelease(context); UIImage *image = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp]; CGImageRelease(imageRef); return image; } typedef id (^CKTestImageDownloaderDownloadImageBlock)(NSURL *url, id caller, dispatch_queue_t callbackQueue, void (^downloadProgressBlock)(CGFloat), void (^completion)(CGImageRef, NSError *)); @interface CKTestImageDownloader : NSObject <CKNetworkImageDownloading> @end @implementation CKTestImageDownloader { CKTestImageDownloaderDownloadImageBlock _downloadImageBlock; } - (instancetype)initWithDownloadImageBlock:(CKTestImageDownloaderDownloadImageBlock)downloadImageBlock { self = [super init]; if (self) { _downloadImageBlock = [downloadImageBlock copy]; } return self; } - (id)downloadImageWithURL:(NSURL *)URL caller:(id)caller callbackQueue:(dispatch_queue_t)callbackQueue downloadProgressBlock:(void (^)(CGFloat))downloadProgressBlock completion:(void (^)(CGImageRef, NSError *))completion { return _downloadImageBlock(URL, caller, callbackQueue, downloadProgressBlock, completion); } - (void)cancelImageDownload:(id)download { /* no-op */ } @end #pragma mark - Tests @interface CKNetworkImageComponentTests : CKComponentSnapshotTestCase @end @implementation CKNetworkImageComponentTests - (void)setUp { [super setUp]; self.recordMode = NO; } - (void)testWhenNoDefaultImageIsGivenImageViewImageIsNotSetToDefaultImage { CKNetworkImageComponent *c = [CKNetworkImageComponent newWithURL:nil imageDownloader:nil size:{} options:{} attributes:{ {{@selector(setBackgroundColor:), [UIColor redColor]}}, }]; static CKSizeRange kSize = {{50, 50}, {50, 50}}; CKSnapshotVerifyComponent(c, kSize, nil); } - (void)testWhenDefaultImageIsGivenImageViewImageIsSetToDefaultImage { CKNetworkImageComponent *c = [CKNetworkImageComponent newWithURL:nil imageDownloader:nil size:{} options:{ .defaultImage = ck_fakeImage([UIColor greenColor], CGSizeMake(50, 50)), } attributes:{ {{@selector(setBackgroundColor:), [UIColor redColor]}}, }]; static CKSizeRange kSize = {{50, 50}, {50, 50}}; CKSnapshotVerifyComponent(c, kSize, nil); } - (void)testWhenURLIsNilImageDownloaderIsNotCalled { CKTestImageDownloader *imageDownloader = [[CKTestImageDownloader alloc] initWithDownloadImageBlock:^id(NSURL *url, id caller, dispatch_queue_t callbackQueue, void (^downloadProgressBlock)(CGFloat), void (^completion)(CGImageRef, NSError *)) { // Fake image downloader immediately returns a blue image, but since component // URL is nil, this image will never be used. completion(ck_fakeImage([UIColor blueColor], CGSizeMake(50, 50)).CGImage, nil); return nil; }]; CKNetworkImageComponent *c = [CKNetworkImageComponent newWithURL:nil imageDownloader:imageDownloader size:{} options:{} attributes:{ // Snapshot will show a red image, not the purple image provided by the image downloader. {{@selector(setBackgroundColor:), [UIColor redColor]}}, }]; static CKSizeRange kSize = {{50, 50}, {50, 50}}; CKSnapshotVerifyComponent(c, kSize, nil); } - (void)testWhenURLIsNotNilAndImageDownloaderCallsCompletionBlockWithImageThatImageIsSetAsTheImageViewImageInsteadOfTheDefaultImage { CKTestImageDownloader *imageDownloader = [[CKTestImageDownloader alloc] initWithDownloadImageBlock:^id(NSURL *url, id caller, dispatch_queue_t callbackQueue, void (^downloadProgressBlock)(CGFloat), void (^completion)(CGImageRef, NSError *)) { // This half-transparent blue image will be overlaid on top of the red background image. UIImage *blueImage = ck_fakeImage([UIColor colorWithRed:0 green:0 blue:1 alpha:.5], CGSizeMake(50, 50)); completion(blueImage.CGImage, nil); return nil; }]; CKNetworkImageComponent *c = [CKNetworkImageComponent newWithURL:[NSURL URLWithString:@"http://literally-any-non-nil-url-can-be-used-here.com"] imageDownloader:imageDownloader size:{} options:{ // This opaque green default image will be replaced in favor of the image provided by the image downloader. .defaultImage = ck_fakeImage([UIColor greenColor], CGSizeMake(50, 50)), } attributes:{ {{@selector(setBackgroundColor:), [UIColor redColor]}}, }]; static CKSizeRange kSize = {{50, 50}, {50, 50}}; CKSnapshotVerifyComponent(c, kSize, nil); } - (void)testCropRectLimitsTheSizeOfTheImageToTheSpecifiedRect { CKNetworkImageComponent *c = [CKNetworkImageComponent newWithURL:nil imageDownloader:nil size:{} options:{ .cropRect = CGRectMake(0, 0, 40, 40), .defaultImage = ck_fakeImage([UIColor greenColor], CGSizeMake(50, 50)), } attributes:{ {{@selector(setBackgroundColor:), [UIColor redColor]}}, }]; static CKSizeRange kSize = {{50, 50}, {50, 50}}; CKSnapshotVerifyComponent(c, kSize, nil); } @end