Files
react-native/packages/rn-tester/RNTesterUnitTests/RCTImageLoaderTests.m
Andres Suarez 8bd3edec88 Update copyright headers from Facebook to Meta
Reviewed By: aaronabramov

Differential Revision: D33367752

fbshipit-source-id: 4ce94d184485e5ee0a62cf67ad2d3ba16e285c8f
2021-12-30 15:11:21 -08:00

234 lines
9.8 KiB
Objective-C

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <XCTest/XCTest.h>
#import <React/RCTBridge.h>
#import <React/RCTImageLoader.h>
#import "RCTImageLoaderHelpers.h"
unsigned char blackGIF[] = {0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b};
RCTDefineImageURLLoader(RCTImageLoaderTestsURLLoader1) RCTDefineImageURLLoader(RCTImageLoaderTestsURLLoader2)
RCTDefineImageDecoder(RCTImageLoaderTestsDecoder1) RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2)
@interface RCTImageLoaderTests : XCTestCase
@end
@implementation RCTImageLoaderTests {
NSURL *_bundleURL;
}
- (void)setUp
{
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
_bundleURL = [bundle URLForResource:@"RNTesterUnitTestsBundle" withExtension:@"js"];
}
- (void)testImageLoading
{
UIImage *image = [UIImage new];
id<RCTImageURLLoader> loader = [[RCTImageLoaderTestsURLLoader1 alloc] initWithPriority:1.0
canLoadImageURLHandler:^BOOL(__unused NSURL *requestURL) {
return YES;
}
loadImageURLHandler:^RCTImageLoaderCancellationBlock(
__unused NSURL *imageURL,
__unused CGSize size,
__unused CGFloat scale,
__unused RCTResizeMode resizeMode,
RCTImageLoaderProgressBlock progressHandler,
RCTImageLoaderCompletionBlock completionHandler) {
progressHandler(1, 1);
completionHandler(nil, image);
return nil;
}];
NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
moduleProvider:^{
return @[ loader ];
}
launchOptions:nil];
NSURLRequest *urlRequest =
[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://reactnative.dev/img/opengraph.png"]];
[[bridge moduleForClass:[RCTImageLoader class]] loadImageWithURLRequest:urlRequest
size:CGSizeMake(100, 100)
scale:1.0
clipped:YES
resizeMode:RCTResizeModeContain
progressBlock:^(int64_t progress, int64_t total) {
XCTAssertEqual(progress, 1);
XCTAssertEqual(total, 1);
}
partialLoadBlock:^(UIImage *loadedImage) {
}
completionBlock:^(NSError *loadError, id loadedImage) {
XCTAssertEqualObjects(loadedImage, image);
XCTAssertNil(loadError);
}];
}
- (void)testImageLoaderUsesImageURLLoaderWithHighestPriority
{
UIImage *image = [UIImage new];
id<RCTImageURLLoader> loader1 = [[RCTImageLoaderTestsURLLoader1 alloc] initWithPriority:1.0
canLoadImageURLHandler:^BOOL(__unused NSURL *requestURL) {
return YES;
}
loadImageURLHandler:^RCTImageLoaderCancellationBlock(
__unused NSURL *imageURL,
__unused CGSize size,
__unused CGFloat scale,
__unused RCTResizeMode resizeMode,
RCTImageLoaderProgressBlock progressHandler,
RCTImageLoaderCompletionBlock completionHandler) {
progressHandler(1, 1);
completionHandler(nil, image);
return nil;
}];
id<RCTImageURLLoader> loader2 = [[RCTImageLoaderTestsURLLoader2 alloc] initWithPriority:0.5
canLoadImageURLHandler:^BOOL(__unused NSURL *requestURL) {
return YES;
}
loadImageURLHandler:^RCTImageLoaderCancellationBlock(
__unused NSURL *imageURL,
__unused CGSize size,
__unused CGFloat scale,
__unused RCTResizeMode resizeMode,
__unused RCTImageLoaderProgressBlock progressHandler,
__unused RCTImageLoaderCompletionBlock completionHandler) {
XCTFail(@"Should not have used loader2");
return nil;
}];
NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
moduleProvider:^{
return @[ loader1, loader2 ];
}
launchOptions:nil];
NSURLRequest *urlRequest =
[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://reactnative.dev/img/opengraph.png"]];
[[bridge moduleForClass:[RCTImageLoader class]] loadImageWithURLRequest:urlRequest
size:CGSizeMake(100, 100)
scale:1.0
clipped:YES
resizeMode:RCTResizeModeContain
progressBlock:^(int64_t progress, int64_t total) {
XCTAssertEqual(progress, 1);
XCTAssertEqual(total, 1);
}
partialLoadBlock:^(UIImage *loadedImage) {
}
completionBlock:^(NSError *loadError, id loadedImage) {
XCTAssertEqualObjects(loadedImage, image);
XCTAssertNil(loadError);
}];
}
- (void)testImageDecoding
{
NSData *data = [NSData dataWithBytesNoCopy:blackGIF length:sizeof(blackGIF) freeWhenDone:NO];
UIImage *image = [[UIImage alloc] initWithData:data];
id<RCTImageDataDecoder> decoder = [[RCTImageLoaderTestsDecoder1 alloc] initWithPriority:1.0
canDecodeImageDataHandler:^BOOL(__unused NSData *imageData) {
return YES;
}
decodeImageDataHandler:^RCTImageLoaderCancellationBlock(
NSData *imageData,
__unused CGSize size,
__unused CGFloat scale,
__unused RCTResizeMode resizeMode,
RCTImageLoaderCompletionBlock completionHandler) {
XCTAssertEqualObjects(imageData, data);
completionHandler(nil, image);
return nil;
}];
NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
moduleProvider:^{
return @[ decoder ];
}
launchOptions:nil];
RCTImageLoaderCancellationBlock cancelBlock =
[[bridge moduleForClass:[RCTImageLoader class]] decodeImageData:data
size:CGSizeMake(1, 1)
scale:1.0
clipped:NO
resizeMode:RCTResizeModeStretch
completionBlock:^(NSError *decodeError, id decodedImage) {
XCTAssertEqualObjects(decodedImage, image);
XCTAssertNil(decodeError);
}];
XCTAssertNotNil(cancelBlock);
}
- (void)testImageLoaderUsesImageDecoderWithHighestPriority
{
NSData *data = [NSData dataWithBytesNoCopy:blackGIF length:sizeof(blackGIF) freeWhenDone:NO];
UIImage *image = [[UIImage alloc] initWithData:data];
id<RCTImageDataDecoder> decoder1 = [[RCTImageLoaderTestsDecoder1 alloc] initWithPriority:1.0
canDecodeImageDataHandler:^BOOL(__unused NSData *imageData) {
return YES;
}
decodeImageDataHandler:^RCTImageLoaderCancellationBlock(
NSData *imageData,
__unused CGSize size,
__unused CGFloat scale,
__unused RCTResizeMode resizeMode,
RCTImageLoaderCompletionBlock completionHandler) {
XCTAssertEqualObjects(imageData, data);
completionHandler(nil, image);
return nil;
}];
id<RCTImageDataDecoder> decoder2 = [[RCTImageLoaderTestsDecoder2 alloc] initWithPriority:0.5
canDecodeImageDataHandler:^BOOL(__unused NSData *imageData) {
return YES;
}
decodeImageDataHandler:^RCTImageLoaderCancellationBlock(
__unused NSData *imageData,
__unused CGSize size,
__unused CGFloat scale,
__unused RCTResizeMode resizeMode,
__unused RCTImageLoaderCompletionBlock completionHandler) {
XCTFail(@"Should not have used decoder2");
return nil;
}];
NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
moduleProvider:^{
return @[ decoder1, decoder2 ];
}
launchOptions:nil];
RCTImageLoaderCancellationBlock cancelBlock =
[[bridge moduleForClass:[RCTImageLoader class]] decodeImageData:data
size:CGSizeMake(1, 1)
scale:1.0
clipped:NO
resizeMode:RCTResizeModeStretch
completionBlock:^(NSError *decodeError, id decodedImage) {
XCTAssertEqualObjects(decodedImage, image);
XCTAssertNil(decodeError);
}];
XCTAssertNotNil(cancelBlock);
}
@end