Do not opt-out fbsource/xplat/js/react-native-github/packages from CLANGFORMAT
Summary: As we're working on C++ code for RNTester to integrate Fabric, we should enable CLANGFORMAT for the files over there. Changelog: [Internal] [Changed] - Enable CLANGFORMAT on fbsource/xplat/js/react-native-github/packages Reviewed By: ShikaSD Differential Revision: D32493605 fbshipit-source-id: 7b5d63f6d2fae1a1aa1e782738953c8cd2cdbe4b
This commit is contained in:
Родитель
8ace78c082
Коммит
aa4da248c1
|
@ -9,6 +9,6 @@
|
|||
|
||||
// TODO: Import every prop and event to asset they're generated
|
||||
|
||||
int main(){
|
||||
return 0;
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <FBReactNativeTestSpec/FBReactNativeTestSpec.h>
|
||||
#import <react/renderer/components/codegen_tests/ComponentDescriptors.h>
|
||||
#import <react/renderer/components/codegen_tests/ComponentViewHelpers.h>
|
||||
#import <FBReactNativeTestSpec/FBReactNativeTestSpec.h>
|
||||
#import <FBReactNativeTestSpec/FBReactNativeTestSpec-generated.mm>
|
||||
|
||||
// TODO: Import every prop and event to asset they're generated
|
||||
|
||||
int main(){
|
||||
return 0;
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <React/RCTViewComponentView.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface RNTMyNativeViewComponentView : RCTViewComponentView
|
||||
|
||||
- (UIColor *)UIColorFromHexString: (const std::string)hexString;
|
||||
- (UIColor *)UIColorFromHexString:(const std::string)hexString;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#import "RNTMyNativeViewComponentView.h"
|
||||
|
||||
#import <react/renderer/components/MyNativeViewSpec/ComponentDescriptors.h>
|
||||
#import <react/renderer/components/MyNativeViewSpec/Props.h>
|
||||
#import <react/renderer/components/MyNativeViewSpec/EventEmitters.h>
|
||||
#import <react/renderer/components/MyNativeViewSpec/Props.h>
|
||||
#import <react/renderer/components/MyNativeViewSpec/RCTComponentViewHelpers.h>
|
||||
|
||||
#import "RCTFabricComponentsPlugins.h"
|
||||
|
@ -20,7 +20,7 @@ using namespace facebook::react;
|
|||
@end
|
||||
|
||||
@implementation RNTMyNativeViewComponentView {
|
||||
UIView *_view;
|
||||
UIView *_view;
|
||||
}
|
||||
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
|
@ -35,7 +35,7 @@ using namespace facebook::react;
|
|||
_props = defaultProps;
|
||||
|
||||
_view = [[UIView alloc] init];
|
||||
_view.backgroundColor = [UIColor redColor];
|
||||
_view.backgroundColor = [UIColor redColor];
|
||||
|
||||
self.contentView = _view;
|
||||
}
|
||||
|
@ -43,33 +43,36 @@ using namespace facebook::react;
|
|||
return self;
|
||||
}
|
||||
|
||||
- (UIColor *)UIColorFromHexString:(const std::string)hexString {
|
||||
unsigned rgbValue = 0;
|
||||
NSString *colorString = [NSString stringWithCString:hexString.c_str()
|
||||
encoding:[NSString defaultCStringEncoding]];
|
||||
NSScanner *scanner = [NSScanner scannerWithString:colorString];
|
||||
[scanner setScanLocation:1]; // bypass '#' character
|
||||
[scanner scanHexInt:&rgbValue];
|
||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
|
||||
- (UIColor *)UIColorFromHexString:(const std::string)hexString
|
||||
{
|
||||
unsigned rgbValue = 0;
|
||||
NSString *colorString = [NSString stringWithCString:hexString.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
NSScanner *scanner = [NSScanner scannerWithString:colorString];
|
||||
[scanner setScanLocation:1]; // bypass '#' character
|
||||
[scanner scanHexInt:&rgbValue];
|
||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0
|
||||
green:((rgbValue & 0xFF00) >> 8) / 255.0
|
||||
blue:(rgbValue & 0xFF) / 255.0
|
||||
alpha:1.0];
|
||||
}
|
||||
|
||||
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
|
||||
{
|
||||
[super updateProps:props oldProps:oldProps];
|
||||
[super updateProps:props oldProps:oldProps];
|
||||
}
|
||||
|
||||
- (void)onChange:(UIView *)sender
|
||||
{
|
||||
// No-op
|
||||
// std::dynamic_pointer_cast<const ViewEventEmitter>(_eventEmitter)
|
||||
// ->onChange(ViewEventEmitter::OnChange{.value = static_cast<bool>(sender.on)});
|
||||
// No-op
|
||||
// std::dynamic_pointer_cast<const ViewEventEmitter>(_eventEmitter)
|
||||
// ->onChange(ViewEventEmitter::OnChange{.value = static_cast<bool>(sender.on)});
|
||||
}
|
||||
|
||||
#pragma mark - Native Commands
|
||||
|
||||
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
|
||||
{
|
||||
RCTRNTMyNativeViewHandleCommand(self, commandName, args);
|
||||
RCTRNTMyNativeViewHandleCommand(self, commandName, args);
|
||||
}
|
||||
|
||||
- (void)callNativeMethodToChangeBackgroundColor:(NSString *)colorString
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTViewManager.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTViewManager.h>
|
||||
|
||||
@interface RNTMyNativeViewManager : RCTViewManager
|
||||
@end
|
||||
|
@ -18,15 +18,14 @@ RCT_EXPORT_MODULE(RNTMyNativeView)
|
|||
|
||||
RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
|
||||
|
||||
RCT_EXPORT_METHOD(callNativeMethodToChangeBackgroundColor:(nonnull NSNumber *)reactTag
|
||||
color:(NSString *)color
|
||||
) {
|
||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
|
||||
UIView *view = viewRegistry[reactTag];
|
||||
if (!view || ![view isKindOfClass:[UIView class]]) {
|
||||
RCTLogError(@"Cannot find NativeView with tag #%@", reactTag);
|
||||
return;
|
||||
}
|
||||
RCT_EXPORT_METHOD(callNativeMethodToChangeBackgroundColor : (nonnull NSNumber *)reactTag color : (NSString *)color)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
UIView *view = viewRegistry[reactTag];
|
||||
if (!view || ![view isKindOfClass:[UIView class]]) {
|
||||
RCTLogError(@"Cannot find NativeView with tag #%@", reactTag);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned rgbValue = 0;
|
||||
NSString *colorString = [NSString stringWithCString:std::string([color UTF8String]).c_str()
|
||||
|
@ -35,9 +34,11 @@ RCT_EXPORT_METHOD(callNativeMethodToChangeBackgroundColor:(nonnull NSNumber *)re
|
|||
[scanner setScanLocation:1]; // bypass '#' character
|
||||
[scanner scanHexInt:&rgbValue];
|
||||
|
||||
view.backgroundColor = [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
|
||||
}];
|
||||
|
||||
view.backgroundColor = [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0
|
||||
green:((rgbValue & 0xFF00) >> 8) / 255.0
|
||||
blue:(rgbValue & 0xFF) / 255.0
|
||||
alpha:1.0];
|
||||
}];
|
||||
}
|
||||
|
||||
- (UIView *)view
|
||||
|
|
|
@ -13,71 +13,71 @@
|
|||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_EXPORT_METHOD(takeScreenshot:(id /* NSString or NSNumber */)target
|
||||
withOptions:(NSDictionary *)options
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
RCT_EXPORT_METHOD(takeScreenshot
|
||||
: (id /* NSString or NSNumber */)target withOptions
|
||||
: (NSDictionary *)options resolve
|
||||
: (RCTPromiseResolveBlock)resolve reject
|
||||
: (RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
[self.bridge.uiManager
|
||||
addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
// Get view
|
||||
UIView *view;
|
||||
if (target == nil || [target isEqual:@"window"]) {
|
||||
view = RCTKeyWindow();
|
||||
} else if ([target isKindOfClass:[NSNumber class]]) {
|
||||
view = viewRegistry[target];
|
||||
if (!view) {
|
||||
RCTLogError(@"No view found with reactTag: %@", target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get view
|
||||
UIView *view;
|
||||
if (target == nil || [target isEqual:@"window"]) {
|
||||
view = RCTKeyWindow();
|
||||
} else if ([target isKindOfClass:[NSNumber class]]) {
|
||||
view = viewRegistry[target];
|
||||
if (!view) {
|
||||
RCTLogError(@"No view found with reactTag: %@", target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Get options
|
||||
CGSize size = [RCTConvert CGSize:options];
|
||||
NSString *format = [RCTConvert NSString:options[@"format"] ?: @"png"];
|
||||
|
||||
// Get options
|
||||
CGSize size = [RCTConvert CGSize:options];
|
||||
NSString *format = [RCTConvert NSString:options[@"format"] ?: @"png"];
|
||||
// Capture image
|
||||
if (size.width < 0.1 || size.height < 0.1) {
|
||||
size = view.bounds.size;
|
||||
}
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
|
||||
BOOL success = [view drawViewHierarchyInRect:(CGRect){CGPointZero, size} afterScreenUpdates:YES];
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
// Capture image
|
||||
if (size.width < 0.1 || size.height < 0.1) {
|
||||
size = view.bounds.size;
|
||||
}
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
|
||||
BOOL success = [view drawViewHierarchyInRect:(CGRect){CGPointZero, size} afterScreenUpdates:YES];
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
if (!success || !image) {
|
||||
reject(RCTErrorUnspecified, @"Failed to capture view snapshot.", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert image to data (on a background thread)
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
NSData *data;
|
||||
if ([format isEqualToString:@"png"]) {
|
||||
data = UIImagePNGRepresentation(image);
|
||||
} else if ([format isEqualToString:@"jpeg"]) {
|
||||
CGFloat quality = [RCTConvert CGFloat:options[@"quality"] ?: @1];
|
||||
data = UIImageJPEGRepresentation(image, quality);
|
||||
} else {
|
||||
RCTLogError(@"Unsupported image format: %@", format);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save to a temp file
|
||||
NSError *error = nil;
|
||||
NSString *tempFilePath = RCTTempFilePath(format, &error);
|
||||
if (tempFilePath) {
|
||||
if ([data writeToFile:tempFilePath options:(NSDataWritingOptions)0 error:&error]) {
|
||||
resolve(tempFilePath);
|
||||
if (!success || !image) {
|
||||
reject(RCTErrorUnspecified, @"Failed to capture view snapshot.", nil);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached here, something went wrong
|
||||
reject(RCTErrorUnspecified, error.localizedDescription, error);
|
||||
});
|
||||
}];
|
||||
// Convert image to data (on a background thread)
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSData *data;
|
||||
if ([format isEqualToString:@"png"]) {
|
||||
data = UIImagePNGRepresentation(image);
|
||||
} else if ([format isEqualToString:@"jpeg"]) {
|
||||
CGFloat quality = [RCTConvert CGFloat:options[@"quality"] ?: @1];
|
||||
data = UIImageJPEGRepresentation(image, quality);
|
||||
} else {
|
||||
RCTLogError(@"Unsupported image format: %@", format);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save to a temp file
|
||||
NSError *error = nil;
|
||||
NSString *tempFilePath = RCTTempFilePath(format, &error);
|
||||
if (tempFilePath) {
|
||||
if ([data writeToFile:tempFilePath options:(NSDataWritingOptions)0 error:&error]) {
|
||||
resolve(tempFilePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached here, something went wrong
|
||||
reject(RCTErrorUnspecified, error.localizedDescription, error);
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -35,7 +35,7 @@ extern NSString *const FBReferenceImageFilePathKey;
|
|||
/**
|
||||
Record snapshots.
|
||||
**/
|
||||
@property(readwrite, nonatomic, assign) BOOL recordMode;
|
||||
@property (readwrite, nonatomic, assign) BOOL recordMode;
|
||||
|
||||
/**
|
||||
@param testClass The subclass of FBSnapshotTestCase that is using this controller.
|
||||
|
@ -55,7 +55,8 @@ extern NSString *const FBReferenceImageFilePathKey;
|
|||
@param view The view to snapshot.
|
||||
@param selector selector
|
||||
@param identifier An optional identifier, used is there are multiple snapshot tests in a given -test method.
|
||||
@param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc).
|
||||
@param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ,
|
||||
etc).
|
||||
@returns YES if the comparison (or saving of the reference image) succeeded.
|
||||
*/
|
||||
- (BOOL)compareSnapshotOfView:(UIView *)view
|
||||
|
@ -75,9 +76,7 @@ extern NSString *const FBReferenceImageFilePathKey;
|
|||
@param error An error, if this methods returns nil, the error will be something useful.
|
||||
@returns An image.
|
||||
*/
|
||||
- (UIImage *)referenceImageForSelector:(SEL)selector
|
||||
identifier:(NSString *)identifier
|
||||
error:(NSError **)error;
|
||||
- (UIImage *)referenceImageForSelector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)error;
|
||||
|
||||
/**
|
||||
Saves a reference image.
|
||||
|
@ -98,9 +97,7 @@ extern NSString *const FBReferenceImageFilePathKey;
|
|||
@param errorPtr An error that indicates why the comparison failed if it does.
|
||||
@returns YES if the comparison succeeded and the images are the same.
|
||||
*/
|
||||
- (BOOL)compareReferenceImage:(UIImage *)referenceImage
|
||||
toImage:(UIImage *)image
|
||||
error:(NSError **)errorPtr;
|
||||
- (BOOL)compareReferenceImage:(UIImage *)referenceImage toImage:(UIImage *)image error:(NSError **)errorPtr;
|
||||
|
||||
/**
|
||||
Saves the reference image and the test image to `failedOutputDirectory`.
|
||||
|
|
|
@ -31,8 +31,7 @@ typedef struct RGBAPixel {
|
|||
|
||||
@end
|
||||
|
||||
@implementation FBSnapshotTestController
|
||||
{
|
||||
@implementation FBSnapshotTestController {
|
||||
NSFileManager *_fileManager;
|
||||
}
|
||||
|
||||
|
@ -40,16 +39,16 @@ typedef struct RGBAPixel {
|
|||
|
||||
- (instancetype)initWithTestClass:(Class)testClass
|
||||
{
|
||||
return [self initWithTestName:NSStringFromClass(testClass)];
|
||||
return [self initWithTestName:NSStringFromClass(testClass)];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTestName:(NSString *)testName
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_testName = [testName copy];
|
||||
_fileManager = [NSFileManager new];
|
||||
}
|
||||
return self;
|
||||
if ((self = [super init])) {
|
||||
_testName = [testName copy];
|
||||
_fileManager = [NSFileManager new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
@ -61,9 +60,7 @@ typedef struct RGBAPixel {
|
|||
|
||||
#pragma mark - Public API
|
||||
|
||||
- (UIImage *)referenceImageForSelector:(SEL)selector
|
||||
identifier:(NSString *)identifier
|
||||
error:(NSError **)errorPtr
|
||||
- (UIImage *)referenceImageForSelector:(SEL)selector identifier:(NSString *)identifier error:(NSError **)errorPtr
|
||||
{
|
||||
NSString *filePath = [self _referenceFilePathForSelector:selector identifier:identifier];
|
||||
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
|
||||
|
@ -73,10 +70,11 @@ typedef struct RGBAPixel {
|
|||
*errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain
|
||||
code:FBSnapshotTestControllerErrorCodeNeedsRecord
|
||||
userInfo:@{
|
||||
FBReferenceImageFilePathKey: filePath,
|
||||
NSLocalizedDescriptionKey: @"Unable to load reference image.",
|
||||
NSLocalizedFailureReasonErrorKey: @"Reference image not found. You need to run the test in record mode",
|
||||
}];
|
||||
FBReferenceImageFilePathKey : filePath,
|
||||
NSLocalizedDescriptionKey : @"Unable to load reference image.",
|
||||
NSLocalizedFailureReasonErrorKey :
|
||||
@"Reference image not found. You need to run the test in record mode",
|
||||
}];
|
||||
} else {
|
||||
*errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain
|
||||
code:FBSnapshotTestControllerErrorCodeUnknown
|
||||
|
@ -116,8 +114,8 @@ typedef struct RGBAPixel {
|
|||
*errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain
|
||||
code:FBSnapshotTestControllerErrorCodePNGCreationFailed
|
||||
userInfo:@{
|
||||
FBReferenceImageFilePathKey: filePath,
|
||||
}];
|
||||
FBReferenceImageFilePathKey : filePath,
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,8 +160,8 @@ typedef struct RGBAPixel {
|
|||
}
|
||||
|
||||
NSString *diffPath = [self _failedFilePathForSelector:selector
|
||||
identifier:identifier
|
||||
fileNameType:FBTestSnapshotFileNameTypeFailedTestDiff];
|
||||
identifier:identifier
|
||||
fileNameType:FBTestSnapshotFileNameTypeFailedTestDiff];
|
||||
|
||||
UIImage *diffImage = [referenceImage diffWithImage:testImage];
|
||||
NSData *diffImageData = UIImagePNGRepresentation(diffImage);
|
||||
|
@ -172,8 +170,11 @@ typedef struct RGBAPixel {
|
|||
return NO;
|
||||
}
|
||||
|
||||
NSLog(@"If you have Kaleidoscope installed you can run this command to see an image diff:\n"
|
||||
@"ksdiff \"%@\" \"%@\"", referencePath, testPath);
|
||||
NSLog(
|
||||
@"If you have Kaleidoscope installed you can run this command to see an image diff:\n"
|
||||
@"ksdiff \"%@\" \"%@\"",
|
||||
referencePath,
|
||||
testPath);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
@ -181,26 +182,26 @@ typedef struct RGBAPixel {
|
|||
- (BOOL)compareReferenceImage:(UIImage *)referenceImage toImage:(UIImage *)image error:(NSError **)errorPtr
|
||||
{
|
||||
if (CGSizeEqualToSize(referenceImage.size, image.size)) {
|
||||
|
||||
BOOL imagesEqual = [referenceImage compareWithImage:image];
|
||||
if (NULL != errorPtr) {
|
||||
*errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain
|
||||
code:FBSnapshotTestControllerErrorCodeImagesDifferent
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: @"Images different",
|
||||
}];
|
||||
NSLocalizedDescriptionKey : @"Images different",
|
||||
}];
|
||||
}
|
||||
return imagesEqual;
|
||||
}
|
||||
if (NULL != errorPtr) {
|
||||
*errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain
|
||||
code:FBSnapshotTestControllerErrorCodeImagesDifferentSizes
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey: @"Images different sizes",
|
||||
NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"referenceImage:%@, image:%@",
|
||||
NSStringFromCGSize(referenceImage.size),
|
||||
NSStringFromCGSize(image.size)],
|
||||
}];
|
||||
*errorPtr = [NSError
|
||||
errorWithDomain:FBSnapshotTestControllerErrorDomain
|
||||
code:FBSnapshotTestControllerErrorCodeImagesDifferentSizes
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey : @"Images different sizes",
|
||||
NSLocalizedFailureReasonErrorKey : [NSString stringWithFormat:@"referenceImage:%@, image:%@",
|
||||
NSStringFromCGSize(referenceImage.size),
|
||||
NSStringFromCGSize(image.size)],
|
||||
}];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
@ -261,9 +262,7 @@ typedef NS_ENUM(NSUInteger, FBTestSnapshotFileNameType) {
|
|||
identifier:(NSString *)identifier
|
||||
fileNameType:(FBTestSnapshotFileNameType)fileNameType
|
||||
{
|
||||
NSString *fileName = [self _fileNameForSelector:selector
|
||||
identifier:identifier
|
||||
fileNameType:fileNameType];
|
||||
NSString *fileName = [self _fileNameForSelector:selector identifier:identifier fileNameType:fileNameType];
|
||||
NSString *folderPath = NSTemporaryDirectory();
|
||||
if (getenv("IMAGE_DIFF_DIR")) {
|
||||
folderPath = @(getenv("IMAGE_DIFF_DIR"));
|
||||
|
|
|
@ -25,22 +25,22 @@
|
|||
return NO;
|
||||
}
|
||||
|
||||
CGContextRef referenceImageContext = CGBitmapContextCreate(referenceImagePixels,
|
||||
CGImageGetWidth(self.CGImage),
|
||||
CGImageGetHeight(self.CGImage),
|
||||
CGImageGetBitsPerComponent(self.CGImage),
|
||||
minBytesPerRow,
|
||||
CGImageGetColorSpace(self.CGImage),
|
||||
(CGBitmapInfo)kCGImageAlphaPremultipliedLast
|
||||
);
|
||||
CGContextRef imageContext = CGBitmapContextCreate(imagePixels,
|
||||
CGImageGetWidth(image.CGImage),
|
||||
CGImageGetHeight(image.CGImage),
|
||||
CGImageGetBitsPerComponent(image.CGImage),
|
||||
minBytesPerRow,
|
||||
CGImageGetColorSpace(image.CGImage),
|
||||
(CGBitmapInfo)kCGImageAlphaPremultipliedLast
|
||||
);
|
||||
CGContextRef referenceImageContext = CGBitmapContextCreate(
|
||||
referenceImagePixels,
|
||||
CGImageGetWidth(self.CGImage),
|
||||
CGImageGetHeight(self.CGImage),
|
||||
CGImageGetBitsPerComponent(self.CGImage),
|
||||
minBytesPerRow,
|
||||
CGImageGetColorSpace(self.CGImage),
|
||||
(CGBitmapInfo)kCGImageAlphaPremultipliedLast);
|
||||
CGContextRef imageContext = CGBitmapContextCreate(
|
||||
imagePixels,
|
||||
CGImageGetWidth(image.CGImage),
|
||||
CGImageGetHeight(image.CGImage),
|
||||
CGImageGetBitsPerComponent(image.CGImage),
|
||||
minBytesPerRow,
|
||||
CGImageGetColorSpace(image.CGImage),
|
||||
(CGBitmapInfo)kCGImageAlphaPremultipliedLast);
|
||||
|
||||
CGFloat scaleFactor = [UIScreen mainScreen].scale;
|
||||
CGContextScaleCTM(referenceImageContext, scaleFactor, scaleFactor);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
CGContextBeginTransparencyLayer(context, NULL);
|
||||
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
|
||||
CGContextSetBlendMode(context, kCGBlendModeDifference);
|
||||
CGContextSetFillColorWithColor(context,[UIColor whiteColor].CGColor);
|
||||
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
|
||||
CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height));
|
||||
CGContextEndTransparencyLayer(context);
|
||||
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@implementation RCTSnapshotManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
|
|
@ -10,11 +10,7 @@
|
|||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, RCTTestStatus) {
|
||||
RCTTestStatusPending = 0,
|
||||
RCTTestStatusPassed,
|
||||
RCTTestStatusFailed
|
||||
};
|
||||
typedef NS_ENUM(NSInteger, RCTTestStatus) { RCTTestStatusPending = 0, RCTTestStatusPassed, RCTTestStatusFailed };
|
||||
|
||||
@class FBSnapshotTestController;
|
||||
|
||||
|
|
|
@ -26,52 +26,64 @@
|
|||
@end
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'TestModule'
|
||||
*/
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'TestModule'
|
||||
*/
|
||||
|
||||
class JSI_EXPORT NativeTestModuleSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativeTestModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms);
|
||||
|
||||
};
|
||||
} // namespace react
|
||||
class JSI_EXPORT NativeTestModuleSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativeTestModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
namespace react {
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_markTestCompleted(
|
||||
facebook::jsi::Runtime &rt,
|
||||
TurboModule &turboModule,
|
||||
const facebook::jsi::Value *args,
|
||||
size_t count)
|
||||
{
|
||||
return static_cast<ObjCTurboModule &>(turboModule)
|
||||
.invokeObjCMethod(rt, VoidKind, "markTestCompleted", @selector(markTestCompleted), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_markTestCompleted(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "markTestCompleted", @selector(markTestCompleted), args, count);
|
||||
}
|
||||
static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_markTestPassed(
|
||||
facebook::jsi::Runtime &rt,
|
||||
TurboModule &turboModule,
|
||||
const facebook::jsi::Value *args,
|
||||
size_t count)
|
||||
{
|
||||
return static_cast<ObjCTurboModule &>(turboModule)
|
||||
.invokeObjCMethod(rt, VoidKind, "markTestPassed", @selector(markTestPassed:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_markTestPassed(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "markTestPassed", @selector(markTestPassed:), args, count);
|
||||
}
|
||||
static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_verifySnapshot(
|
||||
facebook::jsi::Runtime &rt,
|
||||
TurboModule &turboModule,
|
||||
const facebook::jsi::Value *args,
|
||||
size_t count)
|
||||
{
|
||||
return static_cast<ObjCTurboModule &>(turboModule)
|
||||
.invokeObjCMethod(rt, VoidKind, "verifySnapshot", @selector(verifySnapshot:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_verifySnapshot(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "verifySnapshot", @selector(verifySnapshot:), args, count);
|
||||
}
|
||||
NativeTestModuleSpecJSI::NativeTestModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params)
|
||||
{
|
||||
methodMap_["markTestCompleted"] = MethodMetadata{0, __hostFunction_NativeTestModuleSpecJSI_markTestCompleted};
|
||||
|
||||
methodMap_["markTestPassed"] = MethodMetadata{1, __hostFunction_NativeTestModuleSpecJSI_markTestPassed};
|
||||
|
||||
NativeTestModuleSpecJSI::NativeTestModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms)
|
||||
: ObjCTurboModule(params) {
|
||||
methodMap_["verifySnapshot"] = MethodMetadata{1, __hostFunction_NativeTestModuleSpecJSI_verifySnapshot};
|
||||
}
|
||||
|
||||
methodMap_["markTestCompleted"] = MethodMetadata {0, __hostFunction_NativeTestModuleSpecJSI_markTestCompleted};
|
||||
|
||||
|
||||
methodMap_["markTestPassed"] = MethodMetadata {1, __hostFunction_NativeTestModuleSpecJSI_markTestPassed};
|
||||
|
||||
|
||||
methodMap_["verifySnapshot"] = MethodMetadata {1, __hostFunction_NativeTestModuleSpecJSI_verifySnapshot};
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
@interface RCTTestModule() <NativeTestModuleSpec>
|
||||
@interface RCTTestModule () <NativeTestModuleSpec>
|
||||
@end
|
||||
|
||||
@implementation RCTTestModule {
|
||||
|
@ -88,7 +100,7 @@ RCT_EXPORT_MODULE()
|
|||
return _bridge.uiManager.methodQueue;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback)
|
||||
RCT_EXPORT_METHOD(verifySnapshot : (RCTResponseSenderBlock)callback)
|
||||
{
|
||||
RCTAssert(_controller != nil, @"No snapshot controller configured.");
|
||||
|
||||
|
@ -113,11 +125,11 @@ RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback)
|
|||
if (!success) {
|
||||
RCTLogInfo(@"Failed to verify snapshot %@ (error: %@)", identifier, error);
|
||||
}
|
||||
callback(@[@(success)]);
|
||||
callback(@[ @(success) ]);
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(sendAppEvent:(NSString *)name body:(nullable id)body)
|
||||
RCT_EXPORT_METHOD(sendAppEvent : (NSString *)name body : (nullable id)body)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
@ -125,12 +137,16 @@ RCT_EXPORT_METHOD(sendAppEvent:(NSString *)name body:(nullable id)body)
|
|||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
RCT_REMAP_METHOD(shouldResolve, shouldResolve_resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
|
||||
RCT_REMAP_METHOD(shouldResolve, shouldResolve_resolve
|
||||
: (RCTPromiseResolveBlock)resolve reject
|
||||
: (RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
resolve(@1);
|
||||
}
|
||||
|
||||
RCT_REMAP_METHOD(shouldReject, shouldReject_resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
|
||||
RCT_REMAP_METHOD(shouldReject, shouldReject_resolve
|
||||
: (RCTPromiseResolveBlock)resolve reject
|
||||
: (RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
reject(nil, nil, nil);
|
||||
}
|
||||
|
@ -140,20 +156,23 @@ RCT_EXPORT_METHOD(markTestCompleted)
|
|||
[self markTestPassed:YES];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(markTestPassed:(BOOL)success)
|
||||
RCT_EXPORT_METHOD(markTestPassed : (BOOL)success)
|
||||
{
|
||||
[_bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
self->_status = success ? RCTTestStatusPassed : RCTTestStatusFailed;
|
||||
}];
|
||||
[_bridge.uiManager
|
||||
addUIBlock:^(__unused RCTUIManager *uiManager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
self->_status = success ? RCTTestStatusPassed : RCTTestStatusFailed;
|
||||
}];
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return std::make_shared<facebook::react::NativeTestModuleSpecJSI>(params);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Class RCTTestModuleCls(void) {
|
||||
Class RCTTestModuleCls(void)
|
||||
{
|
||||
return RCTTestModule.class;
|
||||
}
|
||||
|
|
|
@ -13,33 +13,32 @@
|
|||
#define FB_REFERENCE_IMAGE_DIR ""
|
||||
#endif
|
||||
|
||||
#define RCT_RUN_RUNLOOP_WHILE(CONDITION) \
|
||||
{ \
|
||||
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:30]; \
|
||||
NSRunLoop *runloop = [NSRunLoop mainRunLoop]; \
|
||||
while ((CONDITION)) { \
|
||||
[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; \
|
||||
if ([timeout timeIntervalSinceNow] <= 0) { \
|
||||
XCTFail(@"Runloop timed out before condition was met"); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#define RCT_RUN_RUNLOOP_WHILE(CONDITION) \
|
||||
{ \
|
||||
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:30]; \
|
||||
NSRunLoop *runloop = [NSRunLoop mainRunLoop]; \
|
||||
while ((CONDITION)) { \
|
||||
[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; \
|
||||
if ([timeout timeIntervalSinceNow] <= 0) { \
|
||||
XCTFail(@"Runloop timed out before condition was met"); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the RCTInitRunnerForApp macro for typical usage. See FBSnapshotTestCase.h for more information
|
||||
* on how to configure the snapshotting system.
|
||||
*/
|
||||
#define RCTInitRunnerForApp(app__, moduleProvider__, scriptURL__) \
|
||||
[[RCTTestRunner alloc] initWithApp:(app__) \
|
||||
referenceDirectory:@FB_REFERENCE_IMAGE_DIR \
|
||||
moduleProvider:(moduleProvider__) \
|
||||
scriptURL: scriptURL__]
|
||||
[[RCTTestRunner alloc] initWithApp:(app__) \
|
||||
referenceDirectory:@FB_REFERENCE_IMAGE_DIR \
|
||||
moduleProvider:(moduleProvider__)scriptURL:scriptURL__]
|
||||
|
||||
#define RCTInitRunnerForAppWithDelegate(app__, bridgeDelegate__) \
|
||||
[[RCTTestRunner alloc] initWithApp:(app__) \
|
||||
referenceDirectory:@FB_REFERENCE_IMAGE_DIR \
|
||||
bridgeDelegate:(bridgeDelegate__)]
|
||||
[[RCTTestRunner alloc] initWithApp:(app__) \
|
||||
referenceDirectory:@FB_REFERENCE_IMAGE_DIR \
|
||||
bridgeDelegate:(bridgeDelegate__)]
|
||||
|
||||
@protocol RCTBridgeModule;
|
||||
@class RCTBridge;
|
||||
|
@ -113,11 +112,13 @@
|
|||
* @param test Selector of the test, usually just `_cmd`.
|
||||
* @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS.
|
||||
* @param initialProps props that are passed into the component when rendered.
|
||||
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its creation.
|
||||
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its
|
||||
* creation.
|
||||
*/
|
||||
- (void)runTest:(SEL)test module:(NSString *)moduleName
|
||||
initialProps:(NSDictionary<NSString *, id> *)initialProps
|
||||
configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock;
|
||||
- (void)runTest:(SEL)test
|
||||
module:(NSString *)moduleName
|
||||
initialProps:(NSDictionary<NSString *, id> *)initialProps
|
||||
configurationBlock:(void (^)(RCTRootView *rootView))configurationBlock;
|
||||
|
||||
/**
|
||||
* Same as runTest:, but allows for passing initialProps for providing mock data
|
||||
|
@ -127,13 +128,15 @@ configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock;
|
|||
* @param test Selector of the test, usually just `_cmd`.
|
||||
* @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS.
|
||||
* @param initialProps props that are passed into the component when rendered.
|
||||
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its creation.
|
||||
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its
|
||||
* creation.
|
||||
* @param expectErrorRegex A regex that must match the error thrown. If no error is thrown, the test fails.
|
||||
*/
|
||||
- (void)runTest:(SEL)test module:(NSString *)moduleName
|
||||
initialProps:(NSDictionary<NSString *, id> *)initialProps
|
||||
configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock
|
||||
expectErrorRegex:(NSString *)expectErrorRegex;
|
||||
- (void)runTest:(SEL)test
|
||||
module:(NSString *)moduleName
|
||||
initialProps:(NSDictionary<NSString *, id> *)initialProps
|
||||
configurationBlock:(void (^)(RCTRootView *rootView))configurationBlock
|
||||
expectErrorRegex:(NSString *)expectErrorRegex;
|
||||
|
||||
/**
|
||||
* Same as runTest:, but allows for passing initialProps for providing mock data
|
||||
|
@ -144,12 +147,14 @@ expectErrorRegex:(NSString *)expectErrorRegex;
|
|||
* @param test Selector of the test, usually just `_cmd`.
|
||||
* @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS.
|
||||
* @param initialProps props that are passed into the component when rendered.
|
||||
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its creation.
|
||||
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its
|
||||
* creation.
|
||||
* @param expectErrorBlock A block that takes the error message and returns NO to fail the test.
|
||||
*/
|
||||
- (void)runTest:(SEL)test module:(NSString *)moduleName
|
||||
initialProps:(NSDictionary<NSString *, id> *)initialProps
|
||||
configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock
|
||||
expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock;
|
||||
- (void)runTest:(SEL)test
|
||||
module:(NSString *)moduleName
|
||||
initialProps:(NSDictionary<NSString *, id> *)initialProps
|
||||
configurationBlock:(void (^)(RCTRootView *rootView))configurationBlock
|
||||
expectErrorBlock:(BOOL (^)(NSString *error))expectErrorBlock;
|
||||
|
||||
@end
|
||||
|
|
|
@ -209,20 +209,21 @@
|
|||
// Set up the default RCTImageLoader and RCTNetworking modules.
|
||||
if (moduleClass == RCTImageLoader.class) {
|
||||
return [[moduleClass alloc] initWithRedirectDelegate:nil
|
||||
loadersProvider:^NSArray<id<RCTImageURLLoader>> *(RCTModuleRegistry * moduleRegistry) {
|
||||
return @ [[RCTLocalAssetImageLoader new]];
|
||||
loadersProvider:^NSArray<id<RCTImageURLLoader>> *(RCTModuleRegistry *moduleRegistry) {
|
||||
return @[ [RCTLocalAssetImageLoader new] ];
|
||||
}
|
||||
decodersProvider:^NSArray<id<RCTImageDataDecoder>> *(RCTModuleRegistry * moduleRegistry) {
|
||||
return @ [[RCTGIFImageDecoder new]];
|
||||
decodersProvider:^NSArray<id<RCTImageDataDecoder>> *(RCTModuleRegistry *moduleRegistry) {
|
||||
return @[ [RCTGIFImageDecoder new] ];
|
||||
}];
|
||||
} else if (moduleClass == RCTNetworking.class) {
|
||||
return [[moduleClass alloc] initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(RCTModuleRegistry * moduleRegistry) {
|
||||
return @[
|
||||
[RCTHTTPRequestHandler new],
|
||||
[RCTDataRequestHandler new],
|
||||
[RCTFileRequestHandler new],
|
||||
];
|
||||
}];
|
||||
return [[moduleClass alloc]
|
||||
initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(RCTModuleRegistry *moduleRegistry) {
|
||||
return @[
|
||||
[RCTHTTPRequestHandler new],
|
||||
[RCTDataRequestHandler new],
|
||||
[RCTFileRequestHandler new],
|
||||
];
|
||||
}];
|
||||
}
|
||||
// No custom initializer here.
|
||||
return [moduleClass new];
|
||||
|
|
|
@ -29,14 +29,11 @@ RCT_EXPORT_MODULE();
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface FlexibleSizeExampleView () <RCTRootViewDelegate>
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation FlexibleSizeExampleView
|
||||
{
|
||||
@implementation FlexibleSizeExampleView {
|
||||
RCTRootView *_resizableRootView;
|
||||
UITextView *_currentSizeTextView;
|
||||
BOOL _sizeUpdated;
|
||||
|
@ -76,11 +73,12 @@ RCT_EXPORT_MODULE();
|
|||
{
|
||||
float textViewHeight = 60;
|
||||
float spacingHeight = 10;
|
||||
[_resizableRootView setFrame:CGRectMake(0, textViewHeight + spacingHeight, self.frame.size.width, _resizableRootView.frame.size.height)];
|
||||
[_resizableRootView
|
||||
setFrame:CGRectMake(
|
||||
0, textViewHeight + spacingHeight, self.frame.size.width, _resizableRootView.frame.size.height)];
|
||||
[_currentSizeTextView setFrame:CGRectMake(0, 0, self.frame.size.width, textViewHeight)];
|
||||
}
|
||||
|
||||
|
||||
- (NSArray<UIView<RCTComponent> *> *)reactSubviews
|
||||
{
|
||||
// this is to avoid unregistering our RCTRootView when the component is removed from RN hierarchy
|
||||
|
@ -88,7 +86,6 @@ RCT_EXPORT_MODULE();
|
|||
return @[];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - RCTRootViewDelegate
|
||||
|
||||
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView
|
||||
|
@ -98,13 +95,16 @@ RCT_EXPORT_MODULE();
|
|||
|
||||
if (!_sizeUpdated) {
|
||||
_sizeUpdated = TRUE;
|
||||
_currentSizeTextView.text = [NSString stringWithFormat:@"RCTRootViewDelegate: content with initially unknown size has appeared, updating root view's size so the content fits."];
|
||||
_currentSizeTextView.text = [NSString
|
||||
stringWithFormat:
|
||||
@"RCTRootViewDelegate: content with initially unknown size has appeared, updating root view's size so the content fits."];
|
||||
|
||||
} else {
|
||||
_currentSizeTextView.text = [NSString stringWithFormat:@"RCTRootViewDelegate: content size has been changed to (%ld, %ld), updating root view's size.",
|
||||
(long)newFrame.size.width,
|
||||
(long)newFrame.size.height];
|
||||
|
||||
_currentSizeTextView.text =
|
||||
[NSString stringWithFormat:
|
||||
@"RCTRootViewDelegate: content size has been changed to (%ld, %ld), updating root view's size.",
|
||||
(long)newFrame.size.width,
|
||||
(long)newFrame.size.height];
|
||||
}
|
||||
|
||||
rootView.frame = newFrame;
|
||||
|
|
|
@ -27,8 +27,7 @@ RCT_EXPORT_MODULE();
|
|||
|
||||
@end
|
||||
|
||||
@implementation UpdatePropertiesExampleView
|
||||
{
|
||||
@implementation UpdatePropertiesExampleView {
|
||||
RCTRootView *_rootView;
|
||||
UIButton *_button;
|
||||
BOOL _beige;
|
||||
|
@ -44,16 +43,14 @@ RCT_EXPORT_MODULE();
|
|||
|
||||
_rootView = [[RCTRootView alloc] initWithBridge:appDelegate.bridge
|
||||
moduleName:@"SetPropertiesExampleApp"
|
||||
initialProperties:@{@"color":@"beige"}];
|
||||
initialProperties:@{@"color" : @"beige"}];
|
||||
|
||||
_button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
[_button setTitle:@"Native Button" forState:UIControlStateNormal];
|
||||
[_button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
[_button setBackgroundColor:[UIColor grayColor]];
|
||||
|
||||
[_button addTarget:self
|
||||
action:@selector(changeColor)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
[_button addTarget:self action:@selector(changeColor) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[self addSubview:_button];
|
||||
[self addSubview:_rootView];
|
||||
|
@ -75,7 +72,7 @@ RCT_EXPORT_MODULE();
|
|||
- (void)changeColor
|
||||
{
|
||||
_beige = !_beige;
|
||||
[_rootView setAppProperties:@{@"color":_beige ? @"beige" : @"purple"}];
|
||||
[_rootView setAppProperties:@{@"color" : _beige ? @"beige" : @"purple"}];
|
||||
}
|
||||
|
||||
- (NSArray<UIView<RCTComponent> *> *)reactSubviews
|
||||
|
|
|
@ -18,7 +18,9 @@ Class RNTesterTurboModuleClassProvider(const char *name);
|
|||
/**
|
||||
* Provide a pure C++ instance of a TurboModule, specific to this app.
|
||||
*/
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleProvider(const std::string &name, std::shared_ptr<CallInvoker> jsInvoker);
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleProvider(
|
||||
const std::string &name,
|
||||
std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
|
|
@ -8,19 +8,23 @@
|
|||
#import "RNTesterTurboModuleProvider.h"
|
||||
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <ReactCommon/SampleTurboCxxModule.h>
|
||||
#import <ReactCommon/RCTSampleTurboModule.h>
|
||||
#import <ReactCommon/SampleTurboCxxModule.h>
|
||||
|
||||
// NOTE: This entire file should be codegen'ed.
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
Class RNTesterTurboModuleClassProvider(const char *name) {
|
||||
Class RNTesterTurboModuleClassProvider(const char *name)
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleProvider(const std::string &name, std::shared_ptr<CallInvoker> jsInvoker) {
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleProvider(
|
||||
const std::string &name,
|
||||
std::shared_ptr<CallInvoker> jsInvoker)
|
||||
{
|
||||
if (name == "SampleTurboCxxModule") {
|
||||
return std::make_shared<SampleTurboCxxModule>(jsInvoker);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
|
|
|
@ -13,32 +13,26 @@
|
|||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTRootViewDelegate.h>
|
||||
|
||||
#define RCT_TEST_DATA_CONFIGURATION_BLOCK(appName, testType, input, block) \
|
||||
- (void)DISABLED_test##appName##_##testType##_##input \
|
||||
{ \
|
||||
[_runner runTest:_cmd \
|
||||
module:@#appName \
|
||||
initialProps:@{@#input:@YES} \
|
||||
configurationBlock:block]; \
|
||||
}
|
||||
#define RCT_TEST_DATA_CONFIGURATION_BLOCK(appName, testType, input, block) \
|
||||
-(void)DISABLED_test##appName##_##testType##_##input \
|
||||
{ \
|
||||
[_runner runTest:_cmd module:@ #appName initialProps:@{@ #input : @YES} configurationBlock:block]; \
|
||||
}
|
||||
|
||||
#define RCT_TEST_CONFIGURATION_BLOCK(appName, block) \
|
||||
- (void)DISABLED_test##appName \
|
||||
{ \
|
||||
[_runner runTest:_cmd \
|
||||
module:@#appName \
|
||||
initialProps:nil \
|
||||
configurationBlock:block]; \
|
||||
}
|
||||
#define RCT_TEST_CONFIGURATION_BLOCK(appName, block) \
|
||||
-(void)DISABLED_test##appName \
|
||||
{ \
|
||||
[_runner runTest:_cmd module:@ #appName initialProps:nil configurationBlock:block]; \
|
||||
}
|
||||
|
||||
#define RCTNone RCTRootViewSizeFlexibilityNone
|
||||
#define RCTNone RCTRootViewSizeFlexibilityNone
|
||||
#define RCTHeight RCTRootViewSizeFlexibilityHeight
|
||||
#define RCTWidth RCTRootViewSizeFlexibilityWidth
|
||||
#define RCTBoth RCTRootViewSizeFlexibilityWidthAndHeight
|
||||
#define RCTWidth RCTRootViewSizeFlexibilityWidth
|
||||
#define RCTBoth RCTRootViewSizeFlexibilityWidthAndHeight
|
||||
|
||||
typedef void (^ControlBlock)(RCTRootView*);
|
||||
typedef void (^ControlBlock)(RCTRootView *);
|
||||
|
||||
@interface SizeFlexibilityTestDelegate : NSObject<RCTRootViewDelegate>
|
||||
@interface SizeFlexibilityTestDelegate : NSObject <RCTRootViewDelegate>
|
||||
@end
|
||||
|
||||
@implementation SizeFlexibilityTestDelegate
|
||||
|
@ -48,9 +42,9 @@ typedef void (^ControlBlock)(RCTRootView*);
|
|||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
[rootView.eventDispatcher sendAppEventWithName:@"rootViewDidChangeIntrinsicSize"
|
||||
body:@{@"width": @(rootView.intrinsicSize.width),
|
||||
@"height": @(rootView.intrinsicSize.height)}];
|
||||
[rootView.eventDispatcher
|
||||
sendAppEventWithName:@"rootViewDidChangeIntrinsicSize"
|
||||
body:@{@"width" : @(rootView.intrinsicSize.width), @"height" : @(rootView.intrinsicSize.height)}];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
|
@ -68,7 +62,7 @@ static SizeFlexibilityTestDelegate *sizeFlexibilityDelegate()
|
|||
|
||||
static ControlBlock simpleSizeFlexibilityBlock(RCTRootViewSizeFlexibility sizeFlexibility)
|
||||
{
|
||||
return ^(RCTRootView *rootView){
|
||||
return ^(RCTRootView *rootView) {
|
||||
rootView.delegate = sizeFlexibilityDelegate();
|
||||
rootView.sizeFlexibility = sizeFlexibility;
|
||||
};
|
||||
|
@ -76,12 +70,8 @@ static ControlBlock simpleSizeFlexibilityBlock(RCTRootViewSizeFlexibility sizeFl
|
|||
|
||||
static ControlBlock multipleSizeFlexibilityUpdatesBlock(RCTRootViewSizeFlexibility finalSizeFlexibility)
|
||||
{
|
||||
return ^(RCTRootView *rootView){
|
||||
|
||||
NSInteger arr[4] = {RCTNone,
|
||||
RCTHeight,
|
||||
RCTWidth,
|
||||
RCTBoth};
|
||||
return ^(RCTRootView *rootView) {
|
||||
NSInteger arr[4] = {RCTNone, RCTHeight, RCTWidth, RCTBoth};
|
||||
|
||||
rootView.delegate = sizeFlexibilityDelegate();
|
||||
|
||||
|
@ -97,7 +87,7 @@ static ControlBlock multipleSizeFlexibilityUpdatesBlock(RCTRootViewSizeFlexibili
|
|||
|
||||
static ControlBlock reactContentSizeUpdateBlock(RCTRootViewSizeFlexibility sizeFlexibility)
|
||||
{
|
||||
return ^(RCTRootView *rootView){
|
||||
return ^(RCTRootView *rootView) {
|
||||
rootView.delegate = sizeFlexibilityDelegate();
|
||||
rootView.sizeFlexibility = sizeFlexibility;
|
||||
};
|
||||
|
@ -107,8 +97,7 @@ static ControlBlock reactContentSizeUpdateBlock(RCTRootViewSizeFlexibility sizeF
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTRootViewIntegrationTests
|
||||
{
|
||||
@implementation RCTRootViewIntegrationTests {
|
||||
RCTTestRunner *_runner;
|
||||
}
|
||||
|
||||
|
@ -123,22 +112,43 @@ static ControlBlock reactContentSizeUpdateBlock(RCTRootViewSizeFlexibility sizeF
|
|||
|
||||
// Simple size flexibility tests - test if the content is measured properly
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, SingleUpdate, none, simpleSizeFlexibilityBlock(RCTNone));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, SingleUpdate, height, simpleSizeFlexibilityBlock(RCTHeight));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(
|
||||
SizeFlexibilityUpdateTest,
|
||||
SingleUpdate,
|
||||
height,
|
||||
simpleSizeFlexibilityBlock(RCTHeight));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, SingleUpdate, width, simpleSizeFlexibilityBlock(RCTWidth));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, SingleUpdate, both, simpleSizeFlexibilityBlock(RCTBoth));
|
||||
|
||||
// Consider multiple size flexibility updates in a row. Test if the view's flexibility mode eventually is set to the expected value
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, MultipleUpdates, none, multipleSizeFlexibilityUpdatesBlock(RCTNone));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, MultipleUpdates, height, multipleSizeFlexibilityUpdatesBlock(RCTHeight));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, MultipleUpdates, width, multipleSizeFlexibilityUpdatesBlock(RCTWidth));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(SizeFlexibilityUpdateTest, MultipleUpdates, both, multipleSizeFlexibilityUpdatesBlock(RCTBoth));
|
||||
// Consider multiple size flexibility updates in a row. Test if the view's flexibility mode eventually is set to the
|
||||
// expected value
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(
|
||||
SizeFlexibilityUpdateTest,
|
||||
MultipleUpdates,
|
||||
none,
|
||||
multipleSizeFlexibilityUpdatesBlock(RCTNone));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(
|
||||
SizeFlexibilityUpdateTest,
|
||||
MultipleUpdates,
|
||||
height,
|
||||
multipleSizeFlexibilityUpdatesBlock(RCTHeight));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(
|
||||
SizeFlexibilityUpdateTest,
|
||||
MultipleUpdates,
|
||||
width,
|
||||
multipleSizeFlexibilityUpdatesBlock(RCTWidth));
|
||||
RCT_TEST_DATA_CONFIGURATION_BLOCK(
|
||||
SizeFlexibilityUpdateTest,
|
||||
MultipleUpdates,
|
||||
both,
|
||||
multipleSizeFlexibilityUpdatesBlock(RCTBoth));
|
||||
|
||||
// Test if the 'rootViewDidChangeIntrinsicSize' delegate method is called after the RN app decides internally to resize
|
||||
RCT_TEST_CONFIGURATION_BLOCK(ReactContentSizeUpdateTest, reactContentSizeUpdateBlock(RCTBoth))
|
||||
|
||||
// Test if setting 'appProperties' property updates the RN app
|
||||
RCT_TEST_CONFIGURATION_BLOCK(PropertiesUpdateTest, ^(RCTRootView *rootView) {
|
||||
rootView.appProperties = @{@"markTestPassed":@YES};
|
||||
rootView.appProperties = @{@"markTestPassed" : @YES};
|
||||
})
|
||||
|
||||
@end
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
UIView *containerView = _uiManager.viewRegistry[@20];
|
||||
NSMutableArray *addedViews = [NSMutableArray array];
|
||||
|
||||
NSArray *tagsToAdd = @[@1, @2, @3, @4, @5];
|
||||
NSArray *addAtIndices = @[@0, @1, @2, @3, @4];
|
||||
NSArray *tagsToAdd = @[ @1, @2, @3, @4, @5 ];
|
||||
NSArray *addAtIndices = @[ @0, @1, @2, @3, @4 ];
|
||||
for (NSNumber *tag in tagsToAdd) {
|
||||
[addedViews addObject:_uiManager.viewRegistry[tag]];
|
||||
}
|
||||
|
@ -69,12 +69,13 @@
|
|||
|
||||
[_uiManager.viewRegistry[@20] didUpdateReactSubviews];
|
||||
|
||||
XCTAssertTrue([[containerView reactSubviews] count] == 5,
|
||||
@"Expect to have 5 react subviews after calling manage children \
|
||||
with 5 tags to add, instead have %lu", (unsigned long)[[containerView reactSubviews] count]);
|
||||
XCTAssertTrue(
|
||||
[[containerView reactSubviews] count] == 5,
|
||||
@"Expect to have 5 react subviews after calling manage children \
|
||||
with 5 tags to add, instead have %lu",
|
||||
(unsigned long)[[containerView reactSubviews] count]);
|
||||
for (UIView *view in addedViews) {
|
||||
XCTAssertTrue([view superview] == containerView,
|
||||
@"Expected to have manage children successfully add children");
|
||||
XCTAssertTrue([view superview] == containerView, @"Expected to have manage children successfully add children");
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +85,7 @@
|
|||
UIView *containerView = _uiManager.viewRegistry[@20];
|
||||
NSMutableArray *removedViews = [NSMutableArray array];
|
||||
|
||||
NSArray *removeAtIndices = @[@0, @4, @8, @12, @16];
|
||||
NSArray *removeAtIndices = @[ @0, @4, @8, @12, @16 ];
|
||||
for (NSNumber *index in removeAtIndices) {
|
||||
NSNumber *reactTag = @(index.integerValue + 2);
|
||||
[removedViews addObject:_uiManager.viewRegistry[reactTag]];
|
||||
|
@ -103,23 +104,26 @@
|
|||
removeAtIndices:removeAtIndices
|
||||
registry:(NSMutableDictionary<NSNumber *, id<RCTComponent>> *)_uiManager.viewRegistry];
|
||||
|
||||
[_uiManager.viewRegistry[@20] didUpdateReactSubviews];
|
||||
[_uiManager.viewRegistry[@20] didUpdateReactSubviews];
|
||||
|
||||
XCTAssertEqual(containerView.reactSubviews.count, (NSUInteger)13,
|
||||
@"Expect to have 13 react subviews after calling manage children\
|
||||
XCTAssertEqual(
|
||||
containerView.reactSubviews.count,
|
||||
(NSUInteger)13,
|
||||
@"Expect to have 13 react subviews after calling manage children\
|
||||
with 5 tags to remove and 18 prior children, instead have %zd",
|
||||
containerView.reactSubviews.count);
|
||||
containerView.reactSubviews.count);
|
||||
for (UIView *view in removedViews) {
|
||||
XCTAssertTrue([view superview] == nil,
|
||||
@"Expected to have manage children successfully remove children");
|
||||
XCTAssertTrue([view superview] == nil, @"Expected to have manage children successfully remove children");
|
||||
// After removing views are unregistered - we need to reregister
|
||||
_uiManager.viewRegistry[view.reactTag] = view;
|
||||
}
|
||||
for (NSInteger i = 2; i < 20; i++) {
|
||||
UIView *view = _uiManager.viewRegistry[@(i)];
|
||||
if (![removedViews containsObject:view]) {
|
||||
XCTAssertTrue([view superview] == containerView,
|
||||
@"Should not have removed view with react tag %ld during delete but did", (long)i);
|
||||
XCTAssertTrue(
|
||||
[view superview] == containerView,
|
||||
@"Should not have removed view with react tag %ld during delete but did",
|
||||
(long)i);
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
@ -137,11 +141,11 @@
|
|||
{
|
||||
UIView *containerView = _uiManager.viewRegistry[@20];
|
||||
|
||||
NSArray *removeAtIndices = @[@2, @3, @5, @8];
|
||||
NSArray *addAtIndices = @[@0, @6];
|
||||
NSArray *tagsToAdd = @[@11, @12];
|
||||
NSArray *moveFromIndices = @[@4, @9];
|
||||
NSArray *moveToIndices = @[@1, @7];
|
||||
NSArray *removeAtIndices = @[ @2, @3, @5, @8 ];
|
||||
NSArray *addAtIndices = @[ @0, @6 ];
|
||||
NSArray *tagsToAdd = @[ @11, @12 ];
|
||||
NSArray *moveFromIndices = @[ @4, @9 ];
|
||||
NSArray *moveToIndices = @[ @1, @7 ];
|
||||
|
||||
// We need to keep these in array to keep them around
|
||||
NSMutableArray *viewsToRemove = [NSMutableArray array];
|
||||
|
@ -164,15 +168,21 @@
|
|||
removeAtIndices:removeAtIndices
|
||||
registry:(NSMutableDictionary<NSNumber *, id<RCTComponent>> *)_uiManager.viewRegistry];
|
||||
|
||||
XCTAssertTrue([[containerView reactSubviews] count] == 8,
|
||||
@"Expect to have 8 react subviews after calling manage children,\
|
||||
instead have the following subviews %@", [containerView reactSubviews]);
|
||||
XCTAssertTrue(
|
||||
[[containerView reactSubviews] count] == 8,
|
||||
@"Expect to have 8 react subviews after calling manage children,\
|
||||
instead have the following subviews %@",
|
||||
[containerView reactSubviews]);
|
||||
|
||||
NSArray *expectedReactTags = @[@11, @5, @1, @2, @7, @8, @12, @10];
|
||||
NSArray *expectedReactTags = @[ @11, @5, @1, @2, @7, @8, @12, @10 ];
|
||||
for (NSUInteger i = 0; i < containerView.subviews.count; i++) {
|
||||
XCTAssertEqualObjects([[containerView reactSubviews][i] reactTag], expectedReactTags[i],
|
||||
@"Expected subview at index %ld to have react tag #%@ but has tag #%@",
|
||||
(long)i, expectedReactTags[i], [[containerView reactSubviews][i] reactTag]);
|
||||
XCTAssertEqualObjects(
|
||||
[[containerView reactSubviews][i] reactTag],
|
||||
expectedReactTags[i],
|
||||
@"Expected subview at index %ld to have react tag #%@ but has tag #%@",
|
||||
(long)i,
|
||||
expectedReactTags[i],
|
||||
[[containerView reactSubviews][i] reactTag]);
|
||||
}
|
||||
|
||||
// Clean up after ourselves
|
||||
|
|
|
@ -10,26 +10,25 @@
|
|||
|
||||
#import <RCTTest/RCTTestRunner.h>
|
||||
|
||||
#define RCT_TEST(name) \
|
||||
- (void)test##name \
|
||||
{ \
|
||||
[_runner runTest:_cmd module:@#name]; \
|
||||
}
|
||||
#define RCT_TEST(name) \
|
||||
-(void)test##name \
|
||||
{ \
|
||||
[_runner runTest:_cmd module:@ #name]; \
|
||||
}
|
||||
|
||||
#define RCT_TEST_ONLY_WITH_PACKAGER(name) \
|
||||
- (void)test##name \
|
||||
{ \
|
||||
if (getenv("CI_USE_PACKAGER")) { \
|
||||
[_runner runTest:_cmd module:@#name]; \
|
||||
} \
|
||||
}
|
||||
#define RCT_TEST_ONLY_WITH_PACKAGER(name) \
|
||||
-(void)test##name \
|
||||
{ \
|
||||
if (getenv("CI_USE_PACKAGER")) { \
|
||||
[_runner runTest:_cmd module:@ #name]; \
|
||||
} \
|
||||
}
|
||||
|
||||
@interface RNTesterIntegrationTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNTesterIntegrationTests
|
||||
{
|
||||
@implementation RNTesterIntegrationTests {
|
||||
RCTTestRunner *_runner;
|
||||
}
|
||||
|
||||
|
@ -44,9 +43,9 @@
|
|||
- (void)testTheTester_waitOneFrame
|
||||
{
|
||||
[_runner runTest:_cmd
|
||||
module:@"IntegrationTestHarnessTest"
|
||||
initialProps:@{@"waitOneFrame": @YES}
|
||||
configurationBlock:nil];
|
||||
module:@"IntegrationTestHarnessTest"
|
||||
initialProps:@{@"waitOneFrame" : @YES}
|
||||
configurationBlock:nil];
|
||||
}
|
||||
|
||||
// Disabled
|
||||
|
@ -55,7 +54,7 @@ configurationBlock:nil];
|
|||
// [_runner runTest:_cmd
|
||||
// module:@"IntegrationTestHarnessTest"
|
||||
// initialProps:@{@"shouldThrow": @YES}
|
||||
//configurationBlock:nil
|
||||
// configurationBlock:nil
|
||||
// expectErrorRegex:@"because shouldThrow"];
|
||||
//}
|
||||
|
||||
|
@ -66,9 +65,9 @@ RCT_TEST(IntegrationTestHarnessTest)
|
|||
// RCT_TEST(TimersTest) // Disabled due to issue introduced in 61346d3
|
||||
// TODO(TD15973709) RCT_TEST(AsyncStorageTest)
|
||||
RCT_TEST(AppEventsTest)
|
||||
//RCT_TEST(ImageCachePolicyTest) // This test never passed.
|
||||
// RCT_TEST(ImageCachePolicyTest) // This test never passed.
|
||||
RCT_TEST(ImageSnapshotTest)
|
||||
//RCT_TEST(LayoutEventsTest) // Disabled due to flakiness: #8686784
|
||||
// RCT_TEST(LayoutEventsTest) // Disabled due to flakiness: #8686784
|
||||
RCT_TEST(SimpleSnapshotTest)
|
||||
RCT_TEST(SyncMethodTest)
|
||||
RCT_TEST(PromiseTest)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
RCT_EXPORT_MODULE(RNTesterTestModule)
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(echoString:(NSString *)input)
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(echoString : (NSString *)input)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
@ -27,9 +27,11 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(methodThatReturnsNil)
|
|||
return nil;
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(methodThatCallsCallbackWithString:(NSString *)input callback:(RCTResponseSenderBlock)callback)
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(methodThatCallsCallbackWithString
|
||||
: (NSString *)input callback
|
||||
: (RCTResponseSenderBlock)callback)
|
||||
{
|
||||
callback(@[input]);
|
||||
callback(@[ input ]);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
|
||||
@class OCObserverMockObject;
|
||||
|
||||
@interface NSNotificationCenter (OCMAdditions)
|
||||
|
||||
@interface NSNotificationCenter(OCMAdditions)
|
||||
|
||||
- (void)addMockObserver:(OCObserverMockObject *)notificationObserver name:(NSString *)notificationName object:(id)notificationSender;
|
||||
- (void)addMockObserver:(OCObserverMockObject *)notificationObserver
|
||||
name:(NSString *)notificationName
|
||||
object:(id)notificationSender;
|
||||
|
||||
@end
|
||||
|
|
|
@ -46,8 +46,11 @@
|
|||
#define OCMOCK_ANY [OCMArg any]
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define OCMOCK_VALUE(variable) \
|
||||
({ __typeof__(variable) __v = (variable); [NSValue value:&__v withObjCType:@encode(__typeof__(__v))]; })
|
||||
#define OCMOCK_VALUE(variable) \
|
||||
({ \
|
||||
__typeof__(variable) __v = (variable); \
|
||||
[NSValue value:&__v withObjCType:@encode(__typeof__(__v))]; \
|
||||
})
|
||||
#else
|
||||
#define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof__(variable))]
|
||||
#define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof__(variable))]
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface OCMConstraint : NSObject
|
||||
|
||||
+ (instancetype)constraint;
|
||||
|
@ -29,7 +28,6 @@
|
|||
+ (instancetype)constraintWithSelector:(SEL)aSelector onObject:(id)anObject;
|
||||
+ (instancetype)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)aValue;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@interface OCMAnyConstraint : OCMConstraint
|
||||
|
@ -41,31 +39,27 @@
|
|||
@interface OCMIsNotNilConstraint : OCMConstraint
|
||||
@end
|
||||
|
||||
@interface OCMIsNotEqualConstraint : OCMConstraint
|
||||
{
|
||||
@public
|
||||
id testValue;
|
||||
@interface OCMIsNotEqualConstraint : OCMConstraint {
|
||||
@public
|
||||
id testValue;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface OCMInvocationConstraint : OCMConstraint
|
||||
{
|
||||
@public
|
||||
NSInvocation *invocation;
|
||||
@interface OCMInvocationConstraint : OCMConstraint {
|
||||
@public
|
||||
NSInvocation *invocation;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface OCMBlockConstraint : OCMConstraint
|
||||
{
|
||||
BOOL (^block)(id);
|
||||
@interface OCMBlockConstraint : OCMConstraint {
|
||||
BOOL (^block)(id);
|
||||
}
|
||||
|
||||
- (instancetype)initWithConstraintBlock:(BOOL (^)(id))block;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#define CONSTRAINT(aSelector) [OCMConstraint constraintWithSelector:aSelector onObject:self]
|
||||
#define CONSTRAINTV(aSelector, aValue) [OCMConstraint constraintWithSelector:aSelector onObject:self withValue:(aValue)]
|
||||
|
|
|
@ -16,11 +16,10 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface OCMLocation : NSObject
|
||||
{
|
||||
id testCase;
|
||||
NSString *file;
|
||||
NSUInteger line;
|
||||
@interface OCMLocation : NSObject {
|
||||
id testCase;
|
||||
NSString *file;
|
||||
NSUInteger line;
|
||||
}
|
||||
|
||||
+ (instancetype)locationWithTestCase:(id)aTestCase file:(NSString *)aFile line:(NSUInteger)aLine;
|
||||
|
|
|
@ -21,10 +21,8 @@
|
|||
@class OCMStubRecorder;
|
||||
@class OCMockObject;
|
||||
|
||||
|
||||
@interface OCMMacroState : NSObject
|
||||
{
|
||||
OCMRecorder *recorder;
|
||||
@interface OCMMacroState : NSObject {
|
||||
OCMRecorder *recorder;
|
||||
}
|
||||
|
||||
+ (void)beginStubMacro;
|
||||
|
|
|
@ -19,11 +19,9 @@
|
|||
@class OCMockObject;
|
||||
@class OCMInvocationMatcher;
|
||||
|
||||
|
||||
@interface OCMRecorder : NSProxy
|
||||
{
|
||||
OCMockObject *mockObject;
|
||||
OCMInvocationMatcher *invocationMatcher;
|
||||
@interface OCMRecorder : NSProxy {
|
||||
OCMockObject *mockObject;
|
||||
OCMInvocationMatcher *invocationMatcher;
|
||||
}
|
||||
|
||||
- (instancetype)init;
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#import "OCMRecorder.h"
|
||||
|
||||
|
||||
@interface OCMStubRecorder : OCMRecorder
|
||||
|
||||
- (id)andReturn:(id)anObject;
|
||||
|
@ -29,25 +28,28 @@
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface OCMStubRecorder (Properties)
|
||||
|
||||
#define andReturn(aValue) _andReturn(({ __typeof__(aValue) _v = (aValue); [NSValue value:&_v withObjCType:@encode(__typeof__(_v))]; }))
|
||||
@property (nonatomic, readonly) OCMStubRecorder *(^ _andReturn)(NSValue *);
|
||||
#define andReturn(aValue) \
|
||||
_andReturn(({ \
|
||||
__typeof__(aValue) _v = (aValue); \
|
||||
[NSValue value:&_v withObjCType:@encode(__typeof__(_v))]; \
|
||||
}))
|
||||
@property (nonatomic, readonly) OCMStubRecorder * (^_andReturn)(NSValue *);
|
||||
|
||||
#define andThrow(anException) _andThrow(anException)
|
||||
@property (nonatomic, readonly) OCMStubRecorder *(^ _andThrow)(NSException *);
|
||||
@property (nonatomic, readonly) OCMStubRecorder * (^_andThrow)(NSException *);
|
||||
|
||||
#define andPost(aNotification) _andPost(aNotification)
|
||||
@property (nonatomic, readonly) OCMStubRecorder *(^ _andPost)(NSNotification *);
|
||||
@property (nonatomic, readonly) OCMStubRecorder * (^_andPost)(NSNotification *);
|
||||
|
||||
#define andCall(anObject, aSelector) _andCall(anObject, aSelector)
|
||||
@property (nonatomic, readonly) OCMStubRecorder *(^ _andCall)(id, SEL);
|
||||
@property (nonatomic, readonly) OCMStubRecorder * (^_andCall)(id, SEL);
|
||||
|
||||
#define andDo(aBlock) _andDo(aBlock)
|
||||
@property (nonatomic, readonly) OCMStubRecorder *(^ _andDo)(void (^)(NSInvocation *));
|
||||
@property (nonatomic, readonly) OCMStubRecorder * (^_andDo)(void (^)(NSInvocation *));
|
||||
|
||||
#define andForwardToRealObject() _andForwardToRealObject()
|
||||
@property (nonatomic, readonly) OCMStubRecorder *(^ _andForwardToRealObject)(void);
|
||||
@property (nonatomic, readonly) OCMStubRecorder * (^_andForwardToRealObject)(void);
|
||||
|
||||
@end
|
||||
|
|
|
@ -14,15 +14,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
#import "OCMockObject.h"
|
||||
#import "OCMRecorder.h"
|
||||
#import "OCMStubRecorder.h"
|
||||
#import "OCMConstraint.h"
|
||||
#import "NSNotificationCenter+OCMAdditions.h"
|
||||
#import "OCMArg.h"
|
||||
#import "OCMConstraint.h"
|
||||
#import "OCMLocation.h"
|
||||
#import "OCMMacroState.h"
|
||||
#import "NSNotificationCenter+OCMAdditions.h"
|
||||
|
||||
#import "OCMRecorder.h"
|
||||
#import "OCMStubRecorder.h"
|
||||
#import "OCMockObject.h"
|
||||
|
||||
#define OCMClassMock(cls) [OCMockObject niceMockForClass:cls]
|
||||
|
||||
|
@ -36,49 +35,26 @@
|
|||
|
||||
#define OCMObserverMock() [OCMockObject observerMock]
|
||||
|
||||
|
||||
#define OCMStub(invocation) \
|
||||
({ \
|
||||
_OCMSilenceWarnings( \
|
||||
[OCMMacroState beginStubMacro]; \
|
||||
invocation; \
|
||||
[OCMMacroState endStubMacro]; \
|
||||
); \
|
||||
})
|
||||
({ _OCMSilenceWarnings([OCMMacroState beginStubMacro]; invocation;[OCMMacroState endStubMacro];); })
|
||||
|
||||
#define OCMExpect(invocation) \
|
||||
({ \
|
||||
_OCMSilenceWarnings( \
|
||||
[OCMMacroState beginExpectMacro]; \
|
||||
invocation; \
|
||||
[OCMMacroState endExpectMacro]; \
|
||||
); \
|
||||
})
|
||||
|
||||
#define ClassMethod(invocation) \
|
||||
_OCMSilenceWarnings( \
|
||||
[[OCMMacroState globalState] switchToClassMethod]; \
|
||||
invocation; \
|
||||
);
|
||||
({ _OCMSilenceWarnings([OCMMacroState beginExpectMacro]; invocation;[OCMMacroState endExpectMacro];); })
|
||||
|
||||
#define ClassMethod(invocation) _OCMSilenceWarnings([[OCMMacroState globalState] switchToClassMethod]; invocation;);
|
||||
|
||||
#define OCMVerifyAll(mock) [mock verifyAtLocation:OCMMakeLocation(self, __FILE__, __LINE__)]
|
||||
|
||||
#define OCMVerifyAllWithDelay(mock, delay) [mock verifyWithDelay:delay atLocation:OCMMakeLocation(self, __FILE__, __LINE__)]
|
||||
#define OCMVerifyAllWithDelay(mock, delay) \
|
||||
[mock verifyWithDelay:delay atLocation:OCMMakeLocation(self, __FILE__, __LINE__)]
|
||||
|
||||
#define OCMVerify(invocation) \
|
||||
({ \
|
||||
_OCMSilenceWarnings( \
|
||||
[OCMMacroState beginVerifyMacroAtLocation:OCMMakeLocation(self, __FILE__, __LINE__)]; \
|
||||
invocation; \
|
||||
[OCMMacroState endVerifyMacro]; \
|
||||
); \
|
||||
})
|
||||
#define OCMVerify(invocation) \
|
||||
({ \
|
||||
_OCMSilenceWarnings([OCMMacroState beginVerifyMacroAtLocation:OCMMakeLocation(self, __FILE__, __LINE__)]; \
|
||||
invocation; \
|
||||
[OCMMacroState endVerifyMacro];); \
|
||||
})
|
||||
|
||||
#define _OCMSilenceWarnings(macro) \
|
||||
({ \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wunused-value\"") \
|
||||
macro \
|
||||
_Pragma("clang diagnostic pop") \
|
||||
})
|
||||
#define _OCMSilenceWarnings(macro) \
|
||||
({_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunused-value\"") \
|
||||
macro _Pragma("clang diagnostic pop")})
|
||||
|
|
|
@ -22,15 +22,13 @@
|
|||
@class OCMInvocationMatcher;
|
||||
@class OCMInvocationExpectation;
|
||||
|
||||
|
||||
@interface OCMockObject : NSProxy
|
||||
{
|
||||
BOOL isNice;
|
||||
BOOL expectationOrderMatters;
|
||||
NSMutableArray *stubs;
|
||||
NSMutableArray *expectations;
|
||||
NSMutableArray *exceptions;
|
||||
NSMutableArray *invocations;
|
||||
@interface OCMockObject : NSProxy {
|
||||
BOOL isNice;
|
||||
BOOL expectationOrderMatters;
|
||||
NSMutableArray *stubs;
|
||||
NSMutableArray *expectations;
|
||||
NSMutableArray *exceptions;
|
||||
NSMutableArray *invocations;
|
||||
}
|
||||
|
||||
+ (id)mockForClass:(Class)aClass;
|
||||
|
@ -71,4 +69,3 @@
|
|||
- (void)verifyInvocation:(OCMInvocationMatcher *)matcher atLocation:(OCMLocation *)location;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#import <React/RCTModuleMethod.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@interface AllocationTestModule : NSObject<RCTBridgeModule, RCTInvalidating>
|
||||
@interface AllocationTestModule : NSObject <RCTBridgeModule, RCTInvalidating>
|
||||
|
||||
@property (nonatomic, assign, getter=isValid) BOOL valid;
|
||||
|
||||
|
@ -37,10 +37,13 @@ RCT_EXPORT_MODULE();
|
|||
_valid = NO;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
:(__unused NSNumber *)b
|
||||
:(__unused RCTResponseSenderBlock)c
|
||||
:(__unused RCTResponseErrorBlock)d) {}
|
||||
RCT_EXPORT_METHOD(test
|
||||
: (__unused NSString *)a
|
||||
: (__unused NSNumber *)b
|
||||
: (__unused RCTResponseSenderBlock)c
|
||||
: (__unused RCTResponseErrorBlock)d)
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
@ -56,14 +59,17 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
|||
[super setUp];
|
||||
|
||||
NSString *bundleContents =
|
||||
@"var __fbBatchedBridge = {"
|
||||
" callFunctionReturnFlushedQueue: function() { return null; },"
|
||||
" invokeCallbackAndReturnFlushedQueue: function() { return null; },"
|
||||
" flushedQueue: function() { return null; },"
|
||||
"};";
|
||||
@"var __fbBatchedBridge = {"
|
||||
" callFunctionReturnFlushedQueue: function() { return null; },"
|
||||
" invokeCallbackAndReturnFlushedQueue: function() { return null; },"
|
||||
" flushedQueue: function() { return null; },"
|
||||
"};";
|
||||
|
||||
NSURL *tempDir = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
|
||||
[[NSFileManager defaultManager] createDirectoryAtURL:tempDir withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
[[NSFileManager defaultManager] createDirectoryAtURL:tempDir
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:NULL];
|
||||
NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString];
|
||||
NSString *fileName = [NSString stringWithFormat:@"rctallocationtests-bundle-%@.js", guid];
|
||||
|
||||
|
@ -102,7 +108,9 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
|||
AllocationTestModule *module = [AllocationTestModule new];
|
||||
@autoreleasepool {
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:^{ return @[module]; }
|
||||
moduleProvider:^{
|
||||
return @[ module ];
|
||||
}
|
||||
launchOptions:nil];
|
||||
XCTAssertTrue(module.isValid, @"AllocationTestModule should be valid");
|
||||
(void)bridge;
|
||||
|
@ -118,7 +126,9 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
|||
@autoreleasepool {
|
||||
AllocationTestModule *module = [AllocationTestModule new];
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:^{ return @[module]; }
|
||||
moduleProvider:^{
|
||||
return @[ module ];
|
||||
}
|
||||
launchOptions:nil];
|
||||
XCTAssertNotNil(module, @"AllocationTestModule should have been created");
|
||||
weakModule = module;
|
||||
|
@ -132,15 +142,14 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
|||
- (void)testModuleMethodsAreDeallocated
|
||||
{
|
||||
static RCTMethodInfo methodInfo = {
|
||||
.objcName = "test:(NSString *)a :(nonnull NSNumber *)b :(RCTResponseSenderBlock)c :(RCTResponseErrorBlock)d",
|
||||
.jsName = "",
|
||||
.isSync = false
|
||||
};
|
||||
.objcName = "test:(NSString *)a :(nonnull NSNumber *)b :(RCTResponseSenderBlock)c :(RCTResponseErrorBlock)d",
|
||||
.jsName = "",
|
||||
.isSync = false};
|
||||
|
||||
__weak RCTModuleMethod *weakMethod;
|
||||
@autoreleasepool {
|
||||
__autoreleasing RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithExportedMethod:&methodInfo
|
||||
moduleClass:[AllocationTestModule class]];
|
||||
__autoreleasing RCTModuleMethod *method =
|
||||
[[RCTModuleMethod alloc] initWithExportedMethod:&methodInfo moduleClass:[AllocationTestModule class]];
|
||||
XCTAssertNotNil(method, @"RCTModuleMethod should have been created");
|
||||
weakMethod = method;
|
||||
}
|
||||
|
@ -151,9 +160,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
|||
|
||||
- (void)testContentViewIsInvalidated
|
||||
{
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:nil
|
||||
launchOptions:nil];
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:nil launchOptions:nil];
|
||||
__weak UIView *rootContentView;
|
||||
@autoreleasepool {
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"" initialProperties:nil];
|
||||
|
|
|
@ -13,12 +13,9 @@
|
|||
|
||||
@end
|
||||
|
||||
static CGFloat RCTSimpleInterpolation(CGFloat value, NSArray<NSNumber *> *inputRange, NSArray<NSNumber *> *outputRange) {
|
||||
return RCTInterpolateValueInRange(value,
|
||||
inputRange,
|
||||
outputRange,
|
||||
EXTRAPOLATE_TYPE_EXTEND,
|
||||
EXTRAPOLATE_TYPE_EXTEND);
|
||||
static CGFloat RCTSimpleInterpolation(CGFloat value, NSArray<NSNumber *> *inputRange, NSArray<NSNumber *> *outputRange)
|
||||
{
|
||||
return RCTInterpolateValueInRange(value, inputRange, outputRange, EXTRAPOLATE_TYPE_EXTEND, EXTRAPOLATE_TYPE_EXTEND);
|
||||
}
|
||||
|
||||
@implementation RCTAnimationUtilsTests
|
||||
|
@ -27,8 +24,8 @@ static CGFloat RCTSimpleInterpolation(CGFloat value, NSArray<NSNumber *> *inputR
|
|||
|
||||
- (void)testSimpleOneToOneMapping
|
||||
{
|
||||
NSArray<NSNumber *> *input = @[@0, @1];
|
||||
NSArray<NSNumber *> *output = @[@0, @1];
|
||||
NSArray<NSNumber *> *input = @[ @0, @1 ];
|
||||
NSArray<NSNumber *> *output = @[ @0, @1 ];
|
||||
XCTAssertEqual(RCTSimpleInterpolation(0, input, output), 0);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(0.5, input, output), 0.5);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(0.8, input, output), 0.8);
|
||||
|
@ -37,8 +34,8 @@ static CGFloat RCTSimpleInterpolation(CGFloat value, NSArray<NSNumber *> *inputR
|
|||
|
||||
- (void)testWiderOutputRange
|
||||
{
|
||||
NSArray<NSNumber *> *input = @[@0, @1];
|
||||
NSArray<NSNumber *> *output = @[@100, @200];
|
||||
NSArray<NSNumber *> *input = @[ @0, @1 ];
|
||||
NSArray<NSNumber *> *output = @[ @100, @200 ];
|
||||
XCTAssertEqual(RCTSimpleInterpolation(0, input, output), 100);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(0.5, input, output), 150);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(0.8, input, output), 180);
|
||||
|
@ -47,8 +44,8 @@ static CGFloat RCTSimpleInterpolation(CGFloat value, NSArray<NSNumber *> *inputR
|
|||
|
||||
- (void)testWiderInputRange
|
||||
{
|
||||
NSArray<NSNumber *> *input = @[@2000, @3000];
|
||||
NSArray<NSNumber *> *output = @[@1, @2];
|
||||
NSArray<NSNumber *> *input = @[ @2000, @3000 ];
|
||||
NSArray<NSNumber *> *output = @[ @1, @2 ];
|
||||
XCTAssertEqual(RCTSimpleInterpolation(2000, input, output), 1);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(2250, input, output), 1.25);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(2800, input, output), 1.8);
|
||||
|
@ -57,8 +54,8 @@ static CGFloat RCTSimpleInterpolation(CGFloat value, NSArray<NSNumber *> *inputR
|
|||
|
||||
- (void)testManySegments
|
||||
{
|
||||
NSArray<NSNumber *> *input = @[@-1, @1, @5];
|
||||
NSArray<NSNumber *> *output = @[@0, @10, @20];
|
||||
NSArray<NSNumber *> *input = @[ @-1, @1, @5 ];
|
||||
NSArray<NSNumber *> *output = @[ @0, @10, @20 ];
|
||||
XCTAssertEqual(RCTSimpleInterpolation(-1, input, output), 0);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(0, input, output), 5);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(1, input, output), 10);
|
||||
|
@ -68,47 +65,31 @@ static CGFloat RCTSimpleInterpolation(CGFloat value, NSArray<NSNumber *> *inputR
|
|||
|
||||
- (void)testExtendExtrapolate
|
||||
{
|
||||
NSArray<NSNumber *> *input = @[@10, @20];
|
||||
NSArray<NSNumber *> *output = @[@0, @1];
|
||||
NSArray<NSNumber *> *input = @[ @10, @20 ];
|
||||
NSArray<NSNumber *> *output = @[ @0, @1 ];
|
||||
XCTAssertEqual(RCTSimpleInterpolation(30, input, output), 2);
|
||||
XCTAssertEqual(RCTSimpleInterpolation(5, input, output), -0.5);
|
||||
}
|
||||
|
||||
- (void)testClampExtrapolate
|
||||
{
|
||||
NSArray<NSNumber *> *input = @[@10, @20];
|
||||
NSArray<NSNumber *> *output = @[@0, @1];
|
||||
NSArray<NSNumber *> *input = @[ @10, @20 ];
|
||||
NSArray<NSNumber *> *output = @[ @0, @1 ];
|
||||
CGFloat value;
|
||||
value = RCTInterpolateValueInRange(30,
|
||||
input,
|
||||
output,
|
||||
EXTRAPOLATE_TYPE_CLAMP,
|
||||
EXTRAPOLATE_TYPE_CLAMP);
|
||||
value = RCTInterpolateValueInRange(30, input, output, EXTRAPOLATE_TYPE_CLAMP, EXTRAPOLATE_TYPE_CLAMP);
|
||||
XCTAssertEqual(value, 1);
|
||||
value = RCTInterpolateValueInRange(5,
|
||||
input,
|
||||
output,
|
||||
EXTRAPOLATE_TYPE_CLAMP,
|
||||
EXTRAPOLATE_TYPE_CLAMP);
|
||||
value = RCTInterpolateValueInRange(5, input, output, EXTRAPOLATE_TYPE_CLAMP, EXTRAPOLATE_TYPE_CLAMP);
|
||||
XCTAssertEqual(value, 0);
|
||||
}
|
||||
|
||||
- (void)testIdentityExtrapolate
|
||||
{
|
||||
NSArray<NSNumber *> *input = @[@10, @20];
|
||||
NSArray<NSNumber *> *output = @[@0, @1];
|
||||
NSArray<NSNumber *> *input = @[ @10, @20 ];
|
||||
NSArray<NSNumber *> *output = @[ @0, @1 ];
|
||||
CGFloat value;
|
||||
value = RCTInterpolateValueInRange(30,
|
||||
input,
|
||||
output,
|
||||
EXTRAPOLATE_TYPE_IDENTITY,
|
||||
EXTRAPOLATE_TYPE_IDENTITY);
|
||||
value = RCTInterpolateValueInRange(30, input, output, EXTRAPOLATE_TYPE_IDENTITY, EXTRAPOLATE_TYPE_IDENTITY);
|
||||
XCTAssertEqual(value, 30);
|
||||
value = RCTInterpolateValueInRange(5,
|
||||
input,
|
||||
output,
|
||||
EXTRAPOLATE_TYPE_IDENTITY,
|
||||
EXTRAPOLATE_TYPE_IDENTITY);
|
||||
value = RCTInterpolateValueInRange(5, input, output, EXTRAPOLATE_TYPE_IDENTITY, EXTRAPOLATE_TYPE_IDENTITY);
|
||||
XCTAssertEqual(value, 5);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTBlobManagerTests
|
||||
{
|
||||
@implementation RCTBlobManagerTests {
|
||||
RCTBlobManager *_module;
|
||||
NSMutableData *_data;
|
||||
NSString *_blobId;
|
||||
|
@ -47,9 +46,9 @@
|
|||
- (void)testResolveMap
|
||||
{
|
||||
NSDictionary<NSString *, id> *map = @{
|
||||
@"blobId": _blobId,
|
||||
@"size": @(_data.length),
|
||||
@"offset": @0,
|
||||
@"blobId" : _blobId,
|
||||
@"size" : @(_data.length),
|
||||
@"offset" : @0,
|
||||
};
|
||||
XCTAssertTrue([_data isEqualToData:[_module resolve:map]]);
|
||||
}
|
||||
|
@ -72,21 +71,21 @@
|
|||
- (void)testCreateFromParts
|
||||
{
|
||||
NSDictionary<NSString *, id> *blobData = @{
|
||||
@"blobId": _blobId,
|
||||
@"offset": @0,
|
||||
@"size": @(_data.length),
|
||||
@"blobId" : _blobId,
|
||||
@"offset" : @0,
|
||||
@"size" : @(_data.length),
|
||||
};
|
||||
NSDictionary<NSString *, id> *blob = @{
|
||||
@"data": blobData,
|
||||
@"type": @"blob",
|
||||
@"data" : blobData,
|
||||
@"type" : @"blob",
|
||||
};
|
||||
NSString *stringData = @"i \u2665 dogs";
|
||||
NSDictionary<NSString *, id> *string = @{
|
||||
@"data": stringData,
|
||||
@"type": @"string",
|
||||
@"data" : stringData,
|
||||
@"type" : @"string",
|
||||
};
|
||||
NSString *resultId = [NSUUID UUID].UUIDString;
|
||||
NSArray<id> *parts = @[blob, string];
|
||||
NSArray<id> *parts = @[ blob, string ];
|
||||
|
||||
[_module createFromParts:parts withId:resultId];
|
||||
|
||||
|
|
|
@ -21,9 +21,7 @@
|
|||
rootTag:(NSNumber *)rootTag
|
||||
props:(NSDictionary *)props;
|
||||
|
||||
- (void)updateView:(nonnull NSNumber *)reactTag
|
||||
viewName:(NSString *)viewName
|
||||
props:(NSDictionary *)props;
|
||||
- (void)updateView:(nonnull NSNumber *)reactTag viewName:(NSString *)viewName props:(NSDictionary *)props;
|
||||
|
||||
@property (nonatomic, copy, readonly) NSMutableDictionary<NSNumber *, RCTShadowView *> *shadowViewRegistry;
|
||||
|
||||
|
@ -72,8 +70,7 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTComponentPropsTests
|
||||
{
|
||||
@implementation RCTComponentPropsTests {
|
||||
RCTBridge *_bridge;
|
||||
NSNumber *_rootViewReactTag;
|
||||
}
|
||||
|
@ -103,10 +100,8 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
|||
{
|
||||
__block RCTPropsTestView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
NSDictionary *props = @{@"integerProp": @58,
|
||||
@"objectProp": @10,
|
||||
@"structProp": @{@"x": @7, @"y": @8},
|
||||
@"customProp": @"Goodbye"};
|
||||
NSDictionary *props =
|
||||
@{@"integerProp" : @58, @"objectProp" : @10, @"structProp" : @{@"x" : @7, @"y" : @8}, @"customProp" : @"Goodbye"};
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTPropsTestView" rootTag:self->_rootViewReactTag props:props];
|
||||
|
@ -127,10 +122,10 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
|||
{
|
||||
__block RCTPropsTestView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
|
||||
|
||||
XCTestExpectation *initialExpectation = [self expectationWithDescription:@"initial expectation"];
|
||||
XCTestExpectation *updateExpectation = [self expectationWithDescription:@"second expectation"];
|
||||
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTPropsTestView" rootTag:self->_rootViewReactTag props:@{}];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
|
@ -138,7 +133,7 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
|||
XCTAssertEqual(view.layer.allowsGroupOpacity, TRUE);
|
||||
[initialExpectation fulfill];
|
||||
}];
|
||||
[uiManager updateView:@2 viewName:@"RCTPropsTestView" props:@{@"needsOffscreenAlphaCompositing": @NO}];
|
||||
[uiManager updateView:@2 viewName:@"RCTPropsTestView" props:@{@"needsOffscreenAlphaCompositing" : @NO}];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
view = (RCTPropsTestView *)viewRegistry[@2];
|
||||
XCTAssertEqual(view.layer.allowsGroupOpacity, FALSE);
|
||||
|
@ -146,23 +141,23 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
|||
}];
|
||||
[uiManager setNeedsLayout];
|
||||
});
|
||||
|
||||
[self waitForExpectations:@[initialExpectation, updateExpectation] timeout:0.1];
|
||||
|
||||
[self waitForExpectations:@[ initialExpectation, updateExpectation ] timeout:0.1];
|
||||
}
|
||||
|
||||
- (void)testResetProps
|
||||
{
|
||||
__block RCTPropsTestView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
NSDictionary *props = @{@"integerProp": @58,
|
||||
@"objectProp": @10,
|
||||
@"structProp": @{@"x": @7, @"y": @8},
|
||||
@"customProp": @"Goodbye"};
|
||||
NSDictionary *props =
|
||||
@{@"integerProp" : @58, @"objectProp" : @10, @"structProp" : @{@"x" : @7, @"y" : @8}, @"customProp" : @"Goodbye"};
|
||||
|
||||
NSDictionary *resetProps = @{@"integerProp": [NSNull null],
|
||||
@"objectProp": [NSNull null],
|
||||
@"structProp": [NSNull null],
|
||||
@"customProp": [NSNull null]};
|
||||
NSDictionary *resetProps = @{
|
||||
@"integerProp" : [NSNull null],
|
||||
@"objectProp" : [NSNull null],
|
||||
@"structProp" : [NSNull null],
|
||||
@"customProp" : [NSNull null]
|
||||
};
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTPropsTestView" rootTag:self->_rootViewReactTag props:props];
|
||||
|
@ -184,8 +179,8 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
|||
{
|
||||
__block RCTView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
NSDictionary *props = @{@"backgroundColor": @0xffffffff};
|
||||
NSDictionary *resetProps = @{@"backgroundColor": [NSNull null]};
|
||||
NSDictionary *props = @{@"backgroundColor" : @0xffffffff};
|
||||
NSDictionary *resetProps = @{@"backgroundColor" : [NSNull null]};
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTView" rootTag:self->_rootViewReactTag props:props];
|
||||
|
@ -194,10 +189,11 @@ RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
|||
XCTAssertEqualObjects(view.backgroundColor, [RCTConvert UIColor:@0xffffffff]);
|
||||
}];
|
||||
[uiManager updateView:@2 viewName:@"RCTView" props:resetProps];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, __unused NSDictionary<NSNumber *,UIView *> *viewRegistry) {
|
||||
view = (RCTView *)viewRegistry[@2];
|
||||
XCTAssertNil(view.backgroundColor);
|
||||
}];
|
||||
[uiManager
|
||||
addUIBlock:^(__unused RCTUIManager *_uiManager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
view = (RCTView *)viewRegistry[@2];
|
||||
XCTAssertNil(view.backgroundColor);
|
||||
}];
|
||||
[uiManager setNeedsLayout];
|
||||
});
|
||||
|
||||
|
|
|
@ -16,20 +16,22 @@
|
|||
|
||||
@implementation RCTConvert_NSURLTests
|
||||
|
||||
#define TEST_URL(name, _input, _expectedURL) \
|
||||
- (void)test_##name { \
|
||||
NSURL *result = [RCTConvert NSURL:_input]; \
|
||||
XCTAssertEqualObjects(result.absoluteString, _expectedURL); \
|
||||
} \
|
||||
#define TEST_URL(name, _input, _expectedURL) \
|
||||
-(void)test_##name \
|
||||
{ \
|
||||
NSURL *result = [RCTConvert NSURL:_input]; \
|
||||
XCTAssertEqualObjects(result.absoluteString, _expectedURL); \
|
||||
}
|
||||
|
||||
#define TEST_PATH(name, _input, _expectedPath) \
|
||||
- (void)test_##name { \
|
||||
NSURL *result = [RCTConvert NSURL:_input]; \
|
||||
XCTAssertEqualObjects(result.path, _expectedPath); \
|
||||
} \
|
||||
#define TEST_PATH(name, _input, _expectedPath) \
|
||||
-(void)test_##name \
|
||||
{ \
|
||||
NSURL *result = [RCTConvert NSURL:_input]; \
|
||||
XCTAssertEqualObjects(result.path, _expectedPath); \
|
||||
}
|
||||
|
||||
#define TEST_BUNDLE_PATH(name, _input, _expectedPath) \
|
||||
TEST_PATH(name, _input, [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:_expectedPath])
|
||||
TEST_PATH(name, _input, [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:_expectedPath])
|
||||
|
||||
// Basic tests
|
||||
TEST_URL(basic, @"http://example.com", @"http://example.com")
|
||||
|
@ -40,27 +42,29 @@ TEST_PATH(fileURL, @"file:///blah/hello.jsbundle", @"/blah/hello.jsbundle")
|
|||
TEST_BUNDLE_PATH(filePath, @"blah/hello.jsbundle", @"blah/hello.jsbundle")
|
||||
TEST_BUNDLE_PATH(filePathWithSpaces, @"blah blah/hello.jsbundle", @"blah blah/hello.jsbundle")
|
||||
TEST_BUNDLE_PATH(filePathWithEncodedSpaces, @"blah%20blah/hello.jsbundle", @"blah blah/hello.jsbundle")
|
||||
TEST_BUNDLE_PATH(imageAt2XPath, @"images/foo@2x.jpg", @"images/foo@2x.jpg")
|
||||
TEST_BUNDLE_PATH(imageFile, @"foo.jpg", @"foo.jpg")
|
||||
TEST_BUNDLE_PATH(imageAt2XPath, @"images/foo@2x.jpg", @"images/foo@2x.jpg")
|
||||
TEST_BUNDLE_PATH(imageFile, @"foo.jpg", @"foo.jpg")
|
||||
|
||||
// User documents
|
||||
TEST_PATH(documentsFolder, @"~/Documents",
|
||||
[NSSearchPathForDirectoriesInDomains
|
||||
(NSDocumentDirectory, NSUserDomainMask, YES) firstObject])
|
||||
TEST_PATH(
|
||||
documentsFolder,
|
||||
@"~/Documents",
|
||||
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject])
|
||||
|
||||
// Remote files
|
||||
TEST_URL(fullURL, @"http://example.com/blah/hello.jsbundle", @"http://example.com/blah/hello.jsbundle")
|
||||
TEST_URL(urlWithSpaces, @"http://example.com/blah blah/foo", @"http://example.com/blah%20blah/foo")
|
||||
TEST_URL(urlWithEncodedSpaces, @"http://example.com/blah%20blah/foo", @"http://example.com/blah%20blah/foo")
|
||||
TEST_URL(imageURL, @"http://example.com/foo@2x.jpg", @"http://example.com/foo@2x.jpg")
|
||||
TEST_URL(imageURLWithSpaces, @"http://example.com/blah foo@2x.jpg", @"http://example.com/blah%20foo@2x.jpg")
|
||||
TEST_URL(imageURL, @"http://example.com/foo@2x.jpg", @"http://example.com/foo@2x.jpg")
|
||||
TEST_URL(imageURLWithSpaces, @"http://example.com/blah foo@2x.jpg", @"http://example.com/blah%20foo@2x.jpg")
|
||||
|
||||
// Unicode
|
||||
TEST_URL(unicodeURL,
|
||||
@"https://ru.wikipedia.org/wiki/\u0417\u0430\u0433\u043B\u0430\u0432"
|
||||
"\u043D\u0430\u044F_\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430",
|
||||
@"https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2"
|
||||
"%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0")
|
||||
TEST_URL(
|
||||
unicodeURL,
|
||||
@"https://ru.wikipedia.org/wiki/\u0417\u0430\u0433\u043B\u0430\u0432"
|
||||
"\u043D\u0430\u044F_\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430",
|
||||
@"https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2"
|
||||
"%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0")
|
||||
|
||||
// Data URLs
|
||||
- (void)testDataURL
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
@end
|
||||
|
||||
static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
||||
static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2)
|
||||
{
|
||||
CGFloat rgba1[4];
|
||||
CGFloat rgba2[4];
|
||||
RCTGetRGBAColorComponents(color1, rgba1);
|
||||
|
@ -41,16 +42,22 @@ static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
|||
|
||||
__block NSString *errorMessage = nil;
|
||||
RCTLogFunction defaultLogFunction = RCTGetLogFunction();
|
||||
RCTSetLogFunction(^(__unused RCTLogLevel level, __unused RCTLogSource source, __unused NSString *fileName, __unused NSNumber *lineNumber, NSString *message) {
|
||||
errorMessage = message;
|
||||
});
|
||||
RCTSetLogFunction(
|
||||
^(__unused RCTLogLevel level,
|
||||
__unused RCTLogSource source,
|
||||
__unused NSString *fileName,
|
||||
__unused NSNumber *lineNumber,
|
||||
NSString *message) {
|
||||
errorMessage = message;
|
||||
});
|
||||
|
||||
UIColor *value = [RCTConvert UIColor:json];
|
||||
|
||||
RCTSetLogFunction(defaultLogFunction);
|
||||
|
||||
XCTAssertEqualObjects(value, nil);
|
||||
XCTAssertTrue([errorMessage containsString:@"labelColor"]); // the RedBox message will contain a list of the valid color names.
|
||||
XCTAssertTrue(
|
||||
[errorMessage containsString:@"labelColor"]); // the RedBox message will contain a list of the valid color names.
|
||||
}
|
||||
|
||||
- (void)testFallbackColor
|
||||
|
@ -72,7 +79,8 @@ static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
|||
if (@available(iOS 13.0, *)) {
|
||||
id savedTraitCollection = [UITraitCollection currentTraitCollection];
|
||||
|
||||
[UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
|
||||
[UITraitCollection
|
||||
setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
|
||||
CGFloat rgba[4];
|
||||
RCTGetRGBAColorComponents([value CGColor], rgba);
|
||||
XCTAssertEqual(rgba[0], 0);
|
||||
|
@ -80,7 +88,8 @@ static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
|||
XCTAssertEqual(rgba[2], 0);
|
||||
XCTAssertEqual(rgba[3], 0);
|
||||
|
||||
[UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]];
|
||||
[UITraitCollection
|
||||
setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]];
|
||||
RCTGetRGBAColorComponents([value CGColor], rgba);
|
||||
XCTAssertEqual(rgba[0], 1);
|
||||
XCTAssertEqual(rgba[1], 1);
|
||||
|
@ -94,7 +103,9 @@ static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
|||
|
||||
- (void)testCompositeDynamicColor
|
||||
{
|
||||
id json = RCTJSONParse(@"{ \"dynamic\": { \"light\": { \"semantic\": \"systemRedColor\" }, \"dark\":{ \"semantic\": \"systemBlueColor\" } } }", nil);
|
||||
id json = RCTJSONParse(
|
||||
@"{ \"dynamic\": { \"light\": { \"semantic\": \"systemRedColor\" }, \"dark\":{ \"semantic\": \"systemBlueColor\" } } }",
|
||||
nil);
|
||||
UIColor *value = [RCTConvert UIColor:json];
|
||||
XCTAssertNotNil(value);
|
||||
|
||||
|
@ -102,11 +113,13 @@ static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
|||
if (@available(iOS 13.0, *)) {
|
||||
id savedTraitCollection = [UITraitCollection currentTraitCollection];
|
||||
|
||||
[UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
|
||||
[UITraitCollection
|
||||
setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
|
||||
|
||||
XCTAssertTrue(CGColorsAreEqual([value CGColor], [[UIColor systemRedColor] CGColor]));
|
||||
|
||||
[UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]];
|
||||
[UITraitCollection
|
||||
setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]];
|
||||
|
||||
XCTAssertTrue(CGColorsAreEqual([value CGColor], [[UIColor systemBlueColor] CGColor]));
|
||||
|
||||
|
@ -117,45 +130,45 @@ static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
|||
|
||||
- (void)testGenerateFallbacks
|
||||
{
|
||||
NSDictionary<NSString *, NSNumber*>* semanticColors = @{
|
||||
NSDictionary<NSString *, NSNumber *> *semanticColors = @{
|
||||
// https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors
|
||||
// Label Colors
|
||||
@"labelColor": @(0xFF000000),
|
||||
@"secondaryLabelColor": @(0x993c3c43),
|
||||
@"tertiaryLabelColor": @(0x4c3c3c43),
|
||||
@"quaternaryLabelColor": @(0x2d3c3c43),
|
||||
@"labelColor" : @(0xFF000000),
|
||||
@"secondaryLabelColor" : @(0x993c3c43),
|
||||
@"tertiaryLabelColor" : @(0x4c3c3c43),
|
||||
@"quaternaryLabelColor" : @(0x2d3c3c43),
|
||||
// Fill Colors
|
||||
@"systemFillColor": @(0x33787880),
|
||||
@"secondarySystemFillColor": @(0x28787880),
|
||||
@"tertiarySystemFillColor": @(0x1e767680),
|
||||
@"quaternarySystemFillColor": @(0x14747480),
|
||||
@"systemFillColor" : @(0x33787880),
|
||||
@"secondarySystemFillColor" : @(0x28787880),
|
||||
@"tertiarySystemFillColor" : @(0x1e767680),
|
||||
@"quaternarySystemFillColor" : @(0x14747480),
|
||||
// Text Colors
|
||||
@"placeholderTextColor": @(0x4c3c3c43),
|
||||
@"placeholderTextColor" : @(0x4c3c3c43),
|
||||
// Standard Content Background Colors
|
||||
@"systemBackgroundColor": @(0xFFffffff),
|
||||
@"secondarySystemBackgroundColor": @(0xFFf2f2f7),
|
||||
@"tertiarySystemBackgroundColor": @(0xFFffffff),
|
||||
@"systemBackgroundColor" : @(0xFFffffff),
|
||||
@"secondarySystemBackgroundColor" : @(0xFFf2f2f7),
|
||||
@"tertiarySystemBackgroundColor" : @(0xFFffffff),
|
||||
// Grouped Content Background Colors
|
||||
@"systemGroupedBackgroundColor": @(0xFFf2f2f7),
|
||||
@"secondarySystemGroupedBackgroundColor": @(0xFFffffff),
|
||||
@"tertiarySystemGroupedBackgroundColor": @(0xFFf2f2f7),
|
||||
@"systemGroupedBackgroundColor" : @(0xFFf2f2f7),
|
||||
@"secondarySystemGroupedBackgroundColor" : @(0xFFffffff),
|
||||
@"tertiarySystemGroupedBackgroundColor" : @(0xFFf2f2f7),
|
||||
// Separator Colors
|
||||
@"separatorColor": @(0x493c3c43),
|
||||
@"opaqueSeparatorColor": @(0xFFc6c6c8),
|
||||
@"separatorColor" : @(0x493c3c43),
|
||||
@"opaqueSeparatorColor" : @(0xFFc6c6c8),
|
||||
// Link Color
|
||||
@"linkColor": @(0xFF007aff),
|
||||
@"linkColor" : @(0xFF007aff),
|
||||
// https://developer.apple.com/documentation/uikit/uicolor/standard_colors
|
||||
// Adaptable Colors
|
||||
@"systemBrownColor": @(0xFFa2845e),
|
||||
@"systemIndigoColor": @(0xFF5856d6),
|
||||
@"systemBrownColor" : @(0xFFa2845e),
|
||||
@"systemIndigoColor" : @(0xFF5856d6),
|
||||
// Adaptable Gray Colors
|
||||
@"systemGray2Color": @(0xFFaeaeb2),
|
||||
@"systemGray3Color": @(0xFFc7c7cc),
|
||||
@"systemGray4Color": @(0xFFd1d1d6),
|
||||
@"systemGray5Color": @(0xFFe5e5ea),
|
||||
@"systemGray6Color": @(0xFFf2f2f7),
|
||||
@"systemGray2Color" : @(0xFFaeaeb2),
|
||||
@"systemGray3Color" : @(0xFFc7c7cc),
|
||||
@"systemGray4Color" : @(0xFFd1d1d6),
|
||||
@"systemGray5Color" : @(0xFFe5e5ea),
|
||||
@"systemGray6Color" : @(0xFFf2f2f7),
|
||||
// Clear Color
|
||||
@"clearColor": @(0x00000000),
|
||||
@"clearColor" : @(0x00000000),
|
||||
};
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
|
@ -163,7 +176,8 @@ static BOOL CGColorsAreEqual(CGColorRef color1, CGColorRef color2) {
|
|||
if (@available(iOS 13.0, *)) {
|
||||
savedTraitCollection = [UITraitCollection currentTraitCollection];
|
||||
|
||||
[UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
|
||||
[UITraitCollection
|
||||
setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTDevMenu.h>
|
||||
|
||||
typedef void(^RCTDevMenuAlertActionHandler)(UIAlertAction *action);
|
||||
typedef void (^RCTDevMenuAlertActionHandler)(UIAlertAction *action);
|
||||
|
||||
@interface RCTDevMenu ()
|
||||
|
||||
|
@ -23,8 +23,7 @@ typedef void(^RCTDevMenuAlertActionHandler)(UIAlertAction *action);
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTDevMenuTests
|
||||
{
|
||||
@implementation RCTDevMenuTests {
|
||||
RCTBridge *_bridge;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
@property (atomic, assign, readwrite) BOOL canCoalesce;
|
||||
@end
|
||||
|
||||
@implementation RCTTestEvent
|
||||
{
|
||||
@implementation RCTTestEvent {
|
||||
NSDictionary<NSString *, id> *_body;
|
||||
}
|
||||
|
||||
|
@ -52,27 +51,25 @@
|
|||
|
||||
- (NSArray *)arguments
|
||||
{
|
||||
return @[_eventName, _body];
|
||||
return @[ _eventName, _body ];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTDummyBridge : RCTBridge
|
||||
- (void)dispatchBlock:(dispatch_block_t)block
|
||||
queue:(dispatch_queue_t)queue;
|
||||
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;
|
||||
@end
|
||||
|
||||
@implementation RCTDummyBridge
|
||||
- (void)dispatchBlock:(dispatch_block_t __unused)block
|
||||
queue:(dispatch_queue_t __unused)queue
|
||||
{}
|
||||
- (void)dispatchBlock:(dispatch_block_t __unused)block queue:(dispatch_queue_t __unused)queue
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@interface RCTEventDispatcherTests : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation RCTEventDispatcherTests
|
||||
{
|
||||
@implementation RCTEventDispatcherTests {
|
||||
id _bridge;
|
||||
RCTEventDispatcher *_eventDispatcher;
|
||||
RCTCallableJSModules *_callableJSModules;
|
||||
|
@ -83,7 +80,6 @@
|
|||
NSString *_JSMethod;
|
||||
}
|
||||
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
@ -99,21 +95,15 @@
|
|||
[_eventDispatcher initialize];
|
||||
|
||||
_eventName = RCTNormalizeInputEventName(@"sampleEvent");
|
||||
_body = @{ @"foo": @"bar" };
|
||||
_testEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:_eventName
|
||||
body:_body
|
||||
coalescingKey:0];
|
||||
_body = @{@"foo" : @"bar"};
|
||||
_testEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:_eventName body:_body coalescingKey:0];
|
||||
|
||||
_JSMethod = [[_testEvent class] moduleDotMethod];
|
||||
}
|
||||
|
||||
- (void)testLegacyEventsAreImmediatelyDispatched
|
||||
{
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter"
|
||||
method:@"emit"
|
||||
args:[_testEvent arguments]
|
||||
completion:NULL];
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter" method:@"emit" args:[_testEvent arguments] completion:NULL];
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
@ -160,19 +150,18 @@
|
|||
{
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}]
|
||||
queue:RCTJSThread];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_bridge verify];
|
||||
|
||||
// eventsEmittingBlock would be called when js is no longer busy, which will result in emitting events
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod]
|
||||
args:[_testEvent arguments]];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] args:[_testEvent arguments]];
|
||||
eventsEmittingBlock();
|
||||
[_bridge verify];
|
||||
|
||||
|
||||
[[_bridge expect] dispatchBlock:OCMOCK_ANY queue:RCTJSThread];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_bridge verify];
|
||||
|
@ -182,15 +171,15 @@
|
|||
{
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod]
|
||||
args:[_testEvent arguments]];
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}]
|
||||
queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] args:[_testEvent arguments]];
|
||||
|
||||
RCTTestEvent *ignoredEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:_eventName
|
||||
body:@{ @"other": @"body" }
|
||||
body:@{@"other" : @"body"}
|
||||
coalescingKey:0];
|
||||
[_eventDispatcher sendEvent:ignoredEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
|
@ -209,14 +198,12 @@
|
|||
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod]
|
||||
args:[firstEvent arguments]];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod]
|
||||
args:[_testEvent arguments]];
|
||||
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}]
|
||||
queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] args:[firstEvent arguments]];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] args:[_testEvent arguments]];
|
||||
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
|
@ -238,14 +225,12 @@
|
|||
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[firstEvent class] moduleDotMethod]
|
||||
args:[firstEvent arguments]];
|
||||
[self _expectBridgeJSCall:[[secondEvent class] moduleDotMethod]
|
||||
args:[secondEvent arguments]];
|
||||
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}]
|
||||
queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[firstEvent class] moduleDotMethod] args:[firstEvent arguments]];
|
||||
[self _expectBridgeJSCall:[[secondEvent class] moduleDotMethod] args:[secondEvent arguments]];
|
||||
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
[_eventDispatcher sendEvent:secondEvent];
|
||||
|
@ -257,25 +242,17 @@
|
|||
- (void)testSameEventTypesWithDifferentCoalesceKeysDontCoalesce
|
||||
{
|
||||
NSString *eventName = RCTNormalizeInputEventName(@"firstEvent");
|
||||
RCTTestEvent *firstEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:eventName
|
||||
body:_body
|
||||
coalescingKey:0];
|
||||
RCTTestEvent *secondEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:eventName
|
||||
body:_body
|
||||
coalescingKey:1];
|
||||
RCTTestEvent *firstEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:eventName body:_body coalescingKey:0];
|
||||
RCTTestEvent *secondEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:eventName body:_body coalescingKey:1];
|
||||
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod]
|
||||
args:[firstEvent arguments]];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod]
|
||||
args:[secondEvent arguments]];
|
||||
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}]
|
||||
queue:RCTJSThread];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] args:[firstEvent arguments]];
|
||||
[self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] args:[secondEvent arguments]];
|
||||
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
[_eventDispatcher sendEvent:secondEvent];
|
||||
|
@ -290,15 +267,12 @@
|
|||
[_bridge verify];
|
||||
}
|
||||
|
||||
-(void)_expectBridgeJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
|
||||
- (void)_expectBridgeJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
|
||||
{
|
||||
NSArray<NSString *> *const components = [moduleDotMethod componentsSeparatedByString:@"."];
|
||||
NSString *const moduleName = components[0];
|
||||
NSString *const methodName = components[1];
|
||||
[[_bridge expect] enqueueJSCall:moduleName
|
||||
method:methodName
|
||||
args:args
|
||||
completion:NULL];
|
||||
[[_bridge expect] enqueueJSCall:moduleName method:methodName args:args completion:NULL];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -19,31 +19,32 @@
|
|||
// It can happen (particularly in tvOS simulator) that expected and result font objects
|
||||
// will be different objects, but the same font, so this macro now explicitly
|
||||
// checks that fontName (which includes the style) and pointSize are equal.
|
||||
#define RCTAssertEqualFonts(font1, font2) { \
|
||||
XCTAssertEqualObjects(font1.fontName, font2.fontName); \
|
||||
XCTAssertEqual(font1.pointSize,font2.pointSize); \
|
||||
}
|
||||
#define RCTAssertEqualFonts(font1, font2) \
|
||||
{ \
|
||||
XCTAssertEqualObjects(font1.fontName, font2.fontName); \
|
||||
XCTAssertEqual(font1.pointSize, font2.pointSize); \
|
||||
}
|
||||
|
||||
- (void)testWeight
|
||||
{
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:14 weight:UIFontWeightBold];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight": @"bold"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight" : @"bold"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight": @"500"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight" : @"500"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:14 weight:UIFontWeightUltraLight];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight": @"100"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight" : @"100"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:14 weight:UIFontWeightRegular];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight": @"normal"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontWeight" : @"normal"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +53,7 @@
|
|||
{
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:18.5];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontSize": @18.5}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontSize" : @18.5}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -62,18 +63,18 @@
|
|||
#if !TARGET_OS_TV
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"Cochin" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Cochin"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"Cochin"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"Helvetica Neue"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-Italic" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"HelveticaNeue-Italic"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"HelveticaNeue-Italic"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -87,12 +88,12 @@
|
|||
symbolicTraits |= UIFontDescriptorTraitItalic;
|
||||
fontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:symbolicTraits];
|
||||
UIFont *expected = [UIFont fontWithDescriptor:fontDescriptor size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle": @"italic"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle" : @"italic"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle": @"normal"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle" : @"normal"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +107,7 @@
|
|||
symbolicTraits |= UIFontDescriptorTraitItalic;
|
||||
fontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:symbolicTraits];
|
||||
UIFont *expected = [UIFont fontWithDescriptor:fontDescriptor size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle": @"italic", @"fontWeight": @"100"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle" : @"italic", @"fontWeight" : @"100"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
|
@ -116,7 +117,7 @@
|
|||
symbolicTraits |= UIFontDescriptorTraitItalic;
|
||||
fontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:symbolicTraits];
|
||||
UIFont *expected = [UIFont fontWithDescriptor:fontDescriptor size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle": @"italic", @"fontWeight": @"bold"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontStyle" : @"italic", @"fontWeight" : @"bold"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -125,23 +126,23 @@
|
|||
{
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-Bold" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue", @"fontWeight": @"bold"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"Helvetica Neue", @"fontWeight" : @"bold"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"HelveticaNeue-Bold", @"fontWeight": @"normal"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"HelveticaNeue-Bold", @"fontWeight" : @"normal"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"Cochin-Bold" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Cochin", @"fontWeight": @"700"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"Cochin", @"fontWeight" : @"700"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"Cochin" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Cochin", @"fontWeight": @"100"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"Cochin", @"fontWeight" : @"100"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
#endif
|
||||
|
@ -151,12 +152,12 @@
|
|||
{
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-Italic" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue", @"fontStyle": @"italic"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"Helvetica Neue", @"fontStyle" : @"italic"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"HelveticaNeue-Italic", @"fontStyle": @"normal"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"HelveticaNeue-Italic", @"fontStyle" : @"normal"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -165,17 +166,20 @@
|
|||
{
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-LightItalic" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue", @"fontStyle": @"italic", @"fontWeight": @"300"}];
|
||||
UIFont *result =
|
||||
[RCTConvert UIFont:@{@"fontFamily" : @"Helvetica Neue", @"fontStyle" : @"italic", @"fontWeight" : @"300"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-Bold" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"HelveticaNeue-Italic", @"fontStyle": @"normal", @"fontWeight": @"bold"}];
|
||||
UIFont *result = [RCTConvert
|
||||
UIFont:@{@"fontFamily" : @"HelveticaNeue-Italic", @"fontStyle" : @"normal", @"fontWeight" : @"bold"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"HelveticaNeue-Italic", @"fontStyle": @"normal", @"fontWeight": @"normal"}];
|
||||
UIFont *result = [RCTConvert
|
||||
UIFont:@{@"fontFamily" : @"HelveticaNeue-Italic", @"fontStyle" : @"normal", @"fontWeight" : @"normal"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -184,19 +188,19 @@
|
|||
{
|
||||
{
|
||||
UIFont *expected = [UIFont monospacedDigitSystemFontOfSize:14 weight:UIFontWeightRegular];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontVariant": @[@"tabular-nums"]}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontVariant" : @[ @"tabular-nums" ]}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *monospaceFont = [UIFont monospacedDigitSystemFontOfSize:14 weight:UIFontWeightRegular];
|
||||
UIFontDescriptor *fontDescriptor = [monospaceFont.fontDescriptor fontDescriptorByAddingAttributes:@{
|
||||
UIFontDescriptorFeatureSettingsAttribute: @[@{
|
||||
UIFontFeatureTypeIdentifierKey: @(kLowerCaseType),
|
||||
UIFontFeatureSelectorIdentifierKey: @(kLowerCaseSmallCapsSelector),
|
||||
}]
|
||||
UIFontDescriptorFeatureSettingsAttribute : @[ @{
|
||||
UIFontFeatureTypeIdentifierKey : @(kLowerCaseType),
|
||||
UIFontFeatureSelectorIdentifierKey : @(kLowerCaseSmallCapsSelector),
|
||||
} ]
|
||||
}];
|
||||
UIFont *expected = [UIFont fontWithDescriptor:fontDescriptor size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontVariant": @[@"tabular-nums", @"small-caps"]}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontVariant" : @[ @"tabular-nums", @"small-caps" ]}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
@ -205,12 +209,12 @@
|
|||
{
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"foobar"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"foobar"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
UIFont *expected = [UIFont systemFontOfSize:14 weight:UIFontWeightBold];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"foobar", @"fontWeight": @"bold"}];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily" : @"foobar", @"fontWeight" : @"bold"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,25 +15,43 @@
|
|||
|
||||
@implementation RCTFormatErrorTests
|
||||
|
||||
- (void)testSymbolication {
|
||||
- (void)testSymbolication
|
||||
{
|
||||
NSArray<NSDictionary<NSString *, id> *> *stackTrace = @[
|
||||
@{@"methodName": @"method_from_bundle", @"column": @11, @"lineNumber": @7, @"file": @"Fb4aBundle.js"},
|
||||
@{@"methodName": @"method_from_ram_bundle", @"column": @13, @"lineNumber": @18, @"file": @"199.js"},
|
||||
@{@"methodName": @"method_from_ram_bundle_with_address", @"column": @13, @"lineNumber": @18, @"file": @"address at 199.js"},
|
||||
@{@"methodName": @"method_from_segment", @"column": @18, @"lineNumber": @9, @"file": @"seg-1.js"},
|
||||
@{@"methodName": @"method_from_segment_with_address", @"column": @18, @"lineNumber": @9, @"file": @"address at seg-1.js"},
|
||||
@{@"methodName": @"method_from_ram_segment", @"column": @20, @"lineNumber": @10, @"file": @"seg-3_198.js"},
|
||||
@{@"methodName": @"method_from_ram_segment_with_address", @"column": @20, @"lineNumber": @10, @"file": @"address at seg-3_198.js"}
|
||||
@{@"methodName" : @"method_from_bundle", @"column" : @11, @"lineNumber" : @7, @"file" : @"Fb4aBundle.js"},
|
||||
@{@"methodName" : @"method_from_ram_bundle", @"column" : @13, @"lineNumber" : @18, @"file" : @"199.js"},
|
||||
@{
|
||||
@"methodName" : @"method_from_ram_bundle_with_address",
|
||||
@"column" : @13,
|
||||
@"lineNumber" : @18,
|
||||
@"file" : @"address at 199.js"
|
||||
},
|
||||
@{@"methodName" : @"method_from_segment", @"column" : @18, @"lineNumber" : @9, @"file" : @"seg-1.js"},
|
||||
@{
|
||||
@"methodName" : @"method_from_segment_with_address",
|
||||
@"column" : @18,
|
||||
@"lineNumber" : @9,
|
||||
@"file" : @"address at seg-1.js"
|
||||
},
|
||||
@{@"methodName" : @"method_from_ram_segment", @"column" : @20, @"lineNumber" : @10, @"file" : @"seg-3_198.js"},
|
||||
@{
|
||||
@"methodName" : @"method_from_ram_segment_with_address",
|
||||
@"column" : @20,
|
||||
@"lineNumber" : @10,
|
||||
@"file" : @"address at seg-3_198.js"
|
||||
}
|
||||
];
|
||||
NSString *message = RCTFormatError(@"Error", stackTrace, 0);
|
||||
XCTAssertEqualObjects(message, @"Error, stack:\n"
|
||||
"method_from_bundle@7:11\n"
|
||||
"method_from_ram_bundle@199.js:18:13\n"
|
||||
"method_from_ram_bundle_with_address@199.js:18:13\n"
|
||||
"method_from_segment@seg-1.js:9:18\n"
|
||||
"method_from_segment_with_address@seg-1.js:9:18\n"
|
||||
"method_from_ram_segment@seg-3_198.js:10:20\n"
|
||||
"method_from_ram_segment_with_address@seg-3_198.js:10:20\n");
|
||||
XCTAssertEqualObjects(
|
||||
message,
|
||||
@"Error, stack:\n"
|
||||
"method_from_bundle@7:11\n"
|
||||
"method_from_ram_bundle@199.js:18:13\n"
|
||||
"method_from_ram_bundle_with_address@199.js:18:13\n"
|
||||
"method_from_segment@seg-1.js:9:18\n"
|
||||
"method_from_segment_with_address@seg-1.js:9:18\n"
|
||||
"method_from_ram_segment@seg-3_198.js:10:20\n"
|
||||
"method_from_ram_segment_with_address@seg-3_198.js:10:20\n");
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -15,8 +15,7 @@ extern BOOL RCTIsGzippedData(NSData *data);
|
|||
|
||||
@interface RCTNetworking (Private)
|
||||
|
||||
- (void)buildRequest:(NSDictionary<NSString *, id> *)query
|
||||
completionBlock:(void (^)(NSURLRequest *request))block;
|
||||
- (void)buildRequest:(NSDictionary<NSString *, id> *)query completionBlock:(void (^)(NSURLRequest *request))block;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -28,26 +27,26 @@ extern BOOL RCTIsGzippedData(NSData *data);
|
|||
|
||||
- (void)testGzip
|
||||
{
|
||||
//set up data
|
||||
// set up data
|
||||
NSString *inputString = @"Hello World!";
|
||||
NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
//compress
|
||||
// compress
|
||||
NSData *outputData = RCTGzipData(inputData, -1);
|
||||
XCTAssertTrue(RCTIsGzippedData(outputData));
|
||||
}
|
||||
|
||||
- (void)testDontRezipZippedData
|
||||
{
|
||||
//set up data
|
||||
// set up data
|
||||
NSString *inputString = @"Hello World!";
|
||||
NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
//compress
|
||||
// compress
|
||||
NSData *compressedData = RCTGzipData(inputData, -1);
|
||||
inputString = [[NSString alloc] initWithData:compressedData encoding:NSUTF8StringEncoding];
|
||||
|
||||
//compress again
|
||||
// compress again
|
||||
NSData *outputData = RCTGzipData(inputData, -1);
|
||||
NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
|
||||
XCTAssertEqualObjects(outputString, inputString);
|
||||
|
@ -56,18 +55,19 @@ extern BOOL RCTIsGzippedData(NSData *data);
|
|||
- (void)testRequestBodyEncoding
|
||||
{
|
||||
NSDictionary *query = @{
|
||||
@"url": @"http://example.com",
|
||||
@"method": @"POST",
|
||||
@"data": @{@"string": @"Hello World"},
|
||||
@"headers": @{@"Content-Encoding": @"gzip"},
|
||||
@"url" : @"http://example.com",
|
||||
@"method" : @"POST",
|
||||
@"data" : @{@"string" : @"Hello World"},
|
||||
@"headers" : @{@"Content-Encoding" : @"gzip"},
|
||||
};
|
||||
|
||||
RCTNetworking *networker = [RCTNetworking new];
|
||||
[networker setValue:dispatch_get_main_queue() forKey:@"methodQueue"];
|
||||
__block NSURLRequest *request = nil;
|
||||
[networker buildRequest:query completionBlock:^(NSURLRequest *_request) {
|
||||
request = _request;
|
||||
}];
|
||||
[networker buildRequest:query
|
||||
completionBlock:^(NSURLRequest *_request) {
|
||||
request = _request;
|
||||
}];
|
||||
|
||||
RCT_RUN_RUNLOOP_WHILE(request == nil);
|
||||
|
||||
|
|
|
@ -8,7 +8,13 @@
|
|||
#import <React/RCTImageLoader.h>
|
||||
|
||||
typedef BOOL (^RCTImageURLLoaderCanLoadImageURLHandler)(NSURL *requestURL);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageURLLoaderLoadImageURLHandler)(NSURL *imageURL, CGSize size, CGFloat scale, RCTResizeMode resizeMode, RCTImageLoaderProgressBlock progressHandler, RCTImageLoaderCompletionBlock completionHandler);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageURLLoaderLoadImageURLHandler)(
|
||||
NSURL *imageURL,
|
||||
CGSize size,
|
||||
CGFloat scale,
|
||||
RCTResizeMode resizeMode,
|
||||
RCTImageLoaderProgressBlock progressHandler,
|
||||
RCTImageLoaderCompletionBlock completionHandler);
|
||||
|
||||
@interface RCTConcreteImageURLLoader : NSObject <RCTImageURLLoader>
|
||||
|
||||
|
@ -19,7 +25,12 @@ typedef RCTImageLoaderCancellationBlock (^RCTImageURLLoaderLoadImageURLHandler)(
|
|||
@end
|
||||
|
||||
typedef BOOL (^RCTImageDataDecoderCanDecodeImageDataHandler)(NSData *imageData);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageDataDecoderDecodeImageDataHandler)(NSData *imageData, CGSize size, CGFloat scale, RCTResizeMode resizeMode, RCTImageLoaderCompletionBlock completionHandler);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageDataDecoderDecodeImageDataHandler)(
|
||||
NSData *imageData,
|
||||
CGSize size,
|
||||
CGFloat scale,
|
||||
RCTResizeMode resizeMode,
|
||||
RCTImageLoaderCompletionBlock completionHandler);
|
||||
|
||||
@interface RCTConcreteImageDecoder : NSObject <RCTImageDataDecoder>
|
||||
|
||||
|
@ -30,11 +41,11 @@ typedef RCTImageLoaderCancellationBlock (^RCTImageDataDecoderDecodeImageDataHand
|
|||
@end
|
||||
|
||||
#define _RCTDefineImageHandler(SUPERCLASS, CLASS_NAME) \
|
||||
@interface CLASS_NAME : SUPERCLASS @end \
|
||||
@implementation CLASS_NAME RCT_EXPORT_MODULE() @end
|
||||
@interface CLASS_NAME : SUPERCLASS \
|
||||
@end \
|
||||
@implementation CLASS_NAME \
|
||||
RCT_EXPORT_MODULE() @end
|
||||
|
||||
#define RCTDefineImageURLLoader(CLASS_NAME) \
|
||||
_RCTDefineImageHandler(RCTConcreteImageURLLoader, CLASS_NAME)
|
||||
#define RCTDefineImageURLLoader(CLASS_NAME) _RCTDefineImageHandler(RCTConcreteImageURLLoader, CLASS_NAME)
|
||||
|
||||
#define RCTDefineImageDecoder(CLASS_NAME) \
|
||||
_RCTDefineImageHandler(RCTConcreteImageDecoder, CLASS_NAME)
|
||||
#define RCTDefineImageDecoder(CLASS_NAME) _RCTDefineImageHandler(RCTConcreteImageDecoder, CLASS_NAME)
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
#import "RCTImageLoaderHelpers.h"
|
||||
|
||||
@implementation RCTConcreteImageURLLoader
|
||||
{
|
||||
@implementation RCTConcreteImageURLLoader {
|
||||
RCTImageURLLoaderCanLoadImageURLHandler _canLoadImageURLHandler;
|
||||
RCTImageURLLoaderLoadImageURLHandler _loadImageURLHandler;
|
||||
float _priority;
|
||||
|
@ -24,7 +23,9 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPriority:(float)priority canLoadImageURLHandler:(RCTImageURLLoaderCanLoadImageURLHandler)canLoadImageURLHandler loadImageURLHandler:(RCTImageURLLoaderLoadImageURLHandler)loadImageURLHandler
|
||||
- (instancetype)initWithPriority:(float)priority
|
||||
canLoadImageURLHandler:(RCTImageURLLoaderCanLoadImageURLHandler)canLoadImageURLHandler
|
||||
loadImageURLHandler:(RCTImageURLLoaderLoadImageURLHandler)loadImageURLHandler
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_canLoadImageURLHandler = [canLoadImageURLHandler copy];
|
||||
|
@ -58,8 +59,7 @@
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTConcreteImageDecoder
|
||||
{
|
||||
@implementation RCTConcreteImageDecoder {
|
||||
RCTImageDataDecoderCanDecodeImageDataHandler _canDecodeImageDataHandler;
|
||||
RCTImageDataDecoderDecodeImageDataHandler _decodeImageDataHandler;
|
||||
float _priority;
|
||||
|
@ -75,7 +75,9 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPriority:(float)priority canDecodeImageDataHandler:(RCTImageDataDecoderCanDecodeImageDataHandler)canDecodeImageDataHandler decodeImageDataHandler:(RCTImageDataDecoderDecodeImageDataHandler)decodeImageDataHandler
|
||||
- (instancetype)initWithPriority:(float)priority
|
||||
canDecodeImageDataHandler:(RCTImageDataDecoderCanDecodeImageDataHandler)canDecodeImageDataHandler
|
||||
decodeImageDataHandler:(RCTImageDataDecoderDecodeImageDataHandler)decodeImageDataHandler
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_canDecodeImageDataHandler = [canDecodeImageDataHandler copy];
|
||||
|
@ -91,7 +93,11 @@
|
|||
return _canDecodeImageDataHandler(imageData);
|
||||
}
|
||||
|
||||
- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData size:(CGSize)size scale:(CGFloat)scale resizeMode:(RCTResizeMode)resizeMode completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
|
||||
- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData
|
||||
size:(CGSize)size
|
||||
scale:(CGFloat)scale
|
||||
resizeMode:(RCTResizeMode)resizeMode
|
||||
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
|
||||
{
|
||||
return _decodeImageDataHandler(imageData, size, scale, resizeMode, completionHandler);
|
||||
}
|
||||
|
|
|
@ -12,18 +12,14 @@
|
|||
|
||||
#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
|
||||
};
|
||||
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)
|
||||
RCTDefineImageURLLoader(RCTImageLoaderTestsURLLoader1) RCTDefineImageURLLoader(RCTImageLoaderTestsURLLoader2)
|
||||
RCTDefineImageDecoder(RCTImageLoaderTestsDecoder1) RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2)
|
||||
|
||||
@interface RCTImageLoaderTests : XCTestCase
|
||||
@interface RCTImageLoaderTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
|
@ -41,69 +37,103 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2)
|
|||
{
|
||||
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;
|
||||
}];
|
||||
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];
|
||||
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:nil completionBlock:^(NSError *loadError, id loadedImage) {
|
||||
XCTAssertEqualObjects(loadedImage, image);
|
||||
XCTAssertNil(loadError);
|
||||
}];
|
||||
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:nil
|
||||
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> 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;
|
||||
}];
|
||||
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];
|
||||
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:nil completionBlock:^(NSError *loadError, id loadedImage) {
|
||||
XCTAssertEqualObjects(loadedImage, image);
|
||||
XCTAssertNil(loadError);
|
||||
}];
|
||||
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:nil
|
||||
completionBlock:^(NSError *loadError, id loadedImage) {
|
||||
XCTAssertEqualObjects(loadedImage, image);
|
||||
XCTAssertNil(loadError);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)testImageDecoding
|
||||
|
@ -111,27 +141,37 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2)
|
|||
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;
|
||||
}];
|
||||
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];
|
||||
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);
|
||||
}];
|
||||
[[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);
|
||||
}
|
||||
|
||||
|
@ -140,34 +180,51 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2)
|
|||
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> 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;
|
||||
}];
|
||||
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];
|
||||
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);
|
||||
}];
|
||||
[[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);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,20 +12,23 @@
|
|||
|
||||
#import <React/RCTImageUtils.h>
|
||||
|
||||
#define RCTAssertEqualPoints(a, b) { \
|
||||
XCTAssertEqual(a.x, b.x); \
|
||||
XCTAssertEqual(a.y, b.y); \
|
||||
}
|
||||
#define RCTAssertEqualPoints(a, b) \
|
||||
{ \
|
||||
XCTAssertEqual(a.x, b.x); \
|
||||
XCTAssertEqual(a.y, b.y); \
|
||||
}
|
||||
|
||||
#define RCTAssertEqualSizes(a, b) { \
|
||||
XCTAssertEqual(a.width, b.width); \
|
||||
XCTAssertEqual(a.height, b.height); \
|
||||
}
|
||||
#define RCTAssertEqualSizes(a, b) \
|
||||
{ \
|
||||
XCTAssertEqual(a.width, b.width); \
|
||||
XCTAssertEqual(a.height, b.height); \
|
||||
}
|
||||
|
||||
#define RCTAssertEqualRects(a, b) { \
|
||||
RCTAssertEqualPoints(a.origin, b.origin); \
|
||||
RCTAssertEqualSizes(a.size, b.size); \
|
||||
}
|
||||
#define RCTAssertEqualRects(a, b) \
|
||||
{ \
|
||||
RCTAssertEqualPoints(a.origin, b.origin); \
|
||||
RCTAssertEqualSizes(a.size, b.size); \
|
||||
}
|
||||
|
||||
@interface RCTImageUtilTests : XCTestCase
|
||||
|
||||
|
@ -93,7 +96,7 @@ RCTAssertEqualSizes(a.size, b.size); \
|
|||
}
|
||||
|
||||
{
|
||||
CGRect expected = {{7,0}, {5, 50}};
|
||||
CGRect expected = {{7, 0}, {5, 50}};
|
||||
CGRect result = RCTTargetRect(content, target, 1, RCTResizeModeContain);
|
||||
RCTAssertEqualRects(expected, result);
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
|
||||
- (void)testEncodingObject
|
||||
{
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo": @"bar"};
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo" : @"bar"};
|
||||
NSString *json = @"{\"foo\":\"bar\"}";
|
||||
XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL));
|
||||
}
|
||||
|
||||
- (void)testEncodingArray
|
||||
{
|
||||
NSArray<id> *array = @[@"foo", @"bar"];
|
||||
NSArray<id> *array = @[ @"foo", @"bar" ];
|
||||
NSString *json = @"[\"foo\",\"bar\"]";
|
||||
XCTAssertEqualObjects(json, RCTJSONStringify(array, NULL));
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
|||
- (void)testEncodingNSError
|
||||
{
|
||||
NSError *underlyingError = [NSError errorWithDomain:@"underlyingDomain" code:421 userInfo:nil];
|
||||
NSError *err = [NSError errorWithDomain:@"domain" code:68 userInfo:@{@"NSUnderlyingError": underlyingError}];
|
||||
NSError *err = [NSError errorWithDomain:@"domain" code:68 userInfo:@{@"NSUnderlyingError" : underlyingError}];
|
||||
|
||||
// An assertion on the full object would be too brittle since it contains an iOS stack trace
|
||||
// so we are relying on the behavior of RCTJSONParse, which is tested below.
|
||||
|
@ -54,17 +54,16 @@
|
|||
XCTAssertEqualObjects(json[@"userInfo"][@"NSUnderlyingError"][@"domain"], @"underlyingDomain");
|
||||
}
|
||||
|
||||
|
||||
- (void)testDecodingObject
|
||||
{
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo": @"bar"};
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo" : @"bar"};
|
||||
NSString *json = @"{\"foo\":\"bar\"}";
|
||||
XCTAssertEqualObjects(obj, RCTJSONParse(json, NULL));
|
||||
}
|
||||
|
||||
- (void)testDecodingArray
|
||||
{
|
||||
NSArray<id> *array = @[@"foo", @"bar"];
|
||||
NSArray<id> *array = @[ @"foo", @"bar" ];
|
||||
NSString *json = @"[\"foo\",\"bar\"]";
|
||||
XCTAssertEqualObjects(array, RCTJSONParse(json, NULL));
|
||||
}
|
||||
|
@ -81,42 +80,42 @@
|
|||
NSString *json = @"[1,2,3]";
|
||||
NSMutableArray<id> *array = RCTJSONParseMutable(json, NULL);
|
||||
XCTAssertNoThrow([array addObject:@4]);
|
||||
XCTAssertEqualObjects(array, (@[@1, @2, @3, @4]));
|
||||
XCTAssertEqualObjects(array, (@[ @1, @2, @3, @4 ]));
|
||||
}
|
||||
|
||||
- (void)testLeadingWhitespace
|
||||
{
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo": @"bar"};
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo" : @"bar"};
|
||||
NSString *json = @" \r\n\t{\"foo\":\"bar\"}";
|
||||
XCTAssertEqualObjects(obj, RCTJSONParse(json, NULL));
|
||||
}
|
||||
|
||||
- (void)testNotJSONSerializable
|
||||
{
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo": [NSDate date]};
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo" : [NSDate date]};
|
||||
NSString *json = @"{\"foo\":null}";
|
||||
XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL));
|
||||
}
|
||||
|
||||
- (void)testNaN
|
||||
{
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo": @(NAN)};
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo" : @(NAN)};
|
||||
NSString *json = @"{\"foo\":0}";
|
||||
XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL));
|
||||
}
|
||||
|
||||
- (void)testNotUTF8Convertible
|
||||
{
|
||||
//see https://gist.github.com/0xced/56035d2f57254cf518b5
|
||||
// see https://gist.github.com/0xced/56035d2f57254cf518b5
|
||||
NSString *string = [[NSString alloc] initWithBytes:"\xd8\x00" length:2 encoding:NSUTF16StringEncoding];
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo": string};
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo" : string};
|
||||
NSString *json = @"{\"foo\":null}";
|
||||
XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL));
|
||||
}
|
||||
|
||||
- (void)testErrorPointer
|
||||
{
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo": [NSDate date]};
|
||||
NSDictionary<NSString *, id> *obj = @{@"foo" : [NSDate date]};
|
||||
NSError *error;
|
||||
XCTAssertNil(RCTJSONStringify(obj, &error));
|
||||
XCTAssertNotNil(error);
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTInitializing.h>
|
||||
#import <React/RCTJavaScriptExecutor.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTViewManager.h>
|
||||
#import <React/RCTInitializing.h>
|
||||
|
||||
@interface RCTTestViewManager : RCTViewManager
|
||||
@end
|
||||
|
@ -29,14 +29,13 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (NSArray<NSString *> *)customBubblingEventTypes
|
||||
{
|
||||
return @[@"foo"];
|
||||
return @[ @"foo" ];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface RCTNotificationObserverModule : NSObject <RCTBridgeModule, RCTInitializing>
|
||||
|
||||
@property (nonatomic, assign) BOOL didDetectViewManagerInit;
|
||||
|
@ -51,7 +50,10 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (void)initialize
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didInitViewManager:) name:RCTDidInitializeModuleNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(didInitViewManager:)
|
||||
name:RCTDidInitializeModuleNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)didInitViewManager:(NSNotification *)note
|
||||
|
@ -64,8 +66,7 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
@end
|
||||
|
||||
@interface RCTModuleInitNotificationRaceTests : XCTestCase <RCTBridgeDelegate>
|
||||
{
|
||||
@interface RCTModuleInitNotificationRaceTests : XCTestCase <RCTBridgeDelegate> {
|
||||
RCTBridge *_bridge;
|
||||
RCTNotificationObserverModule *_notificationObserver;
|
||||
}
|
||||
|
@ -81,7 +82,7 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (NSArray *)extraModulesForBridge:(__unused RCTBridge *)bridge
|
||||
{
|
||||
return @[[RCTTestViewManager new], _notificationObserver];
|
||||
return @[ [RCTTestViewManager new], _notificationObserver ];
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
#import <React/RCTBridge+Private.h>
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTInitializing.h>
|
||||
#import <React/RCTJavaScriptExecutor.h>
|
||||
#import <React/RCTUtils.h>
|
||||
#import <React/RCTInitializing.h>
|
||||
|
||||
@interface RCTTestInjectedModule : NSObject <RCTBridgeModule>
|
||||
@end
|
||||
|
@ -28,7 +28,6 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface RCTTestCustomInitModule : NSObject <RCTBridgeModule>
|
||||
|
||||
@property (nonatomic, assign) BOOL initializedOnMainQueue;
|
||||
|
@ -52,7 +51,6 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface RCTTestCustomSetBridgeModule : NSObject <RCTBridgeModule, RCTInitializing>
|
||||
|
||||
@property (nonatomic, assign) BOOL setBridgeOnMainQueue;
|
||||
|
@ -73,7 +71,6 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface RCTTestExportConstantsModule : NSObject <RCTBridgeModule>
|
||||
|
||||
@property (nonatomic, assign) BOOL exportedConstants;
|
||||
|
@ -97,12 +94,11 @@ RCT_EXPORT_MODULE()
|
|||
{
|
||||
_exportedConstants = YES;
|
||||
_exportedConstantsOnMainQueue = RCTIsMainQueue();
|
||||
return @{ @"foo": @"bar" };
|
||||
return @{@"foo" : @"bar"};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface RCTLazyInitModule : NSObject <RCTBridgeModule>
|
||||
@end
|
||||
|
||||
|
@ -115,9 +111,7 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface RCTModuleInitTests : XCTestCase <RCTBridgeDelegate>
|
||||
{
|
||||
@interface RCTModuleInitTests : XCTestCase <RCTBridgeDelegate> {
|
||||
RCTBridge *_bridge;
|
||||
BOOL _injectedModuleInitNotificationSent;
|
||||
BOOL _customInitModuleNotificationSent;
|
||||
|
@ -140,14 +134,17 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (NSArray *)extraModulesForBridge:(__unused RCTBridge *)bridge
|
||||
{
|
||||
return @[_injectedModule];
|
||||
return @[ _injectedModule ];
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moduleDidInit:) name:RCTDidInitializeModuleNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(moduleDidInit:)
|
||||
name:RCTDidInitializeModuleNotification
|
||||
object:nil];
|
||||
|
||||
_injectedModuleInitNotificationSent = NO;
|
||||
_customInitModuleNotificationSent = NO;
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
static BOOL RCTLogsError(void (^block)(void))
|
||||
{
|
||||
__block BOOL loggedError = NO;
|
||||
RCTPerformBlockWithLogFunction(block, ^(RCTLogLevel level,
|
||||
__unused RCTLogSource source,
|
||||
__unused NSString *fileName,
|
||||
__unused NSNumber *lineNumber,
|
||||
__unused NSString *message) {
|
||||
loggedError = (level == RCTLogLevelError);
|
||||
});
|
||||
RCTPerformBlockWithLogFunction(
|
||||
block,
|
||||
^(RCTLogLevel level,
|
||||
__unused RCTLogSource source,
|
||||
__unused NSString *fileName,
|
||||
__unused NSNumber *lineNumber,
|
||||
__unused NSString *message) {
|
||||
loggedError = (level == RCTLogLevelError);
|
||||
});
|
||||
return loggedError;
|
||||
}
|
||||
|
||||
|
@ -29,56 +31,87 @@ static BOOL RCTLogsError(void (^block)(void))
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTModuleMethodTests
|
||||
{
|
||||
@implementation RCTModuleMethodTests {
|
||||
CGRect _s;
|
||||
}
|
||||
|
||||
static RCTModuleMethod *buildDefaultMethodWithMethodSignature(const char *methodSignature)
|
||||
{
|
||||
// This leaks a RCTMethodInfo, but it's a test, so...
|
||||
RCTMethodInfo *methodInfo = new RCTMethodInfo {.objcName = methodSignature, .isSync = NO};
|
||||
RCTMethodInfo *methodInfo = new RCTMethodInfo{.objcName = methodSignature, .isSync = NO};
|
||||
return [[RCTModuleMethod alloc] initWithExportedMethod:methodInfo moduleClass:[RCTModuleMethodTests class]];
|
||||
}
|
||||
|
||||
static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSignature)
|
||||
{
|
||||
// This leaks a RCTMethodInfo, but it's a test, so...
|
||||
RCTMethodInfo *methodInfo = new RCTMethodInfo {.objcName = methodSignature, .isSync = YES};
|
||||
RCTMethodInfo *methodInfo = new RCTMethodInfo{.objcName = methodSignature, .isSync = YES};
|
||||
return [[RCTModuleMethod alloc] initWithExportedMethod:methodInfo moduleClass:[RCTModuleMethodTests class]];
|
||||
}
|
||||
|
||||
+ (NSString *)moduleName { return nil; }
|
||||
+ (NSString *)moduleName
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)doFoo { }
|
||||
- (void)doFoo
|
||||
{
|
||||
}
|
||||
|
||||
- (void)doFooWithBar:(__unused NSString *)bar { }
|
||||
- (void)doFooWithBar:(__unused NSString *)bar
|
||||
{
|
||||
}
|
||||
|
||||
- (id)echoString:(NSString *)input { return input; }
|
||||
- (id)methodThatReturnsNil { return nil; }
|
||||
- (void)openURL:(NSURL *)URL resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {}
|
||||
- (void)openURL:(NSURL *)URL callback:(RCTResponseSenderBlock)callback {}
|
||||
- (id)methodThatCallsCallbackWithArg:(NSString *)input callback:(RCTResponseSenderBlock)callback { callback(@[input]); return nil; }
|
||||
- (id)echoString:(NSString *)input
|
||||
{
|
||||
return input;
|
||||
}
|
||||
- (id)methodThatReturnsNil
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
- (void)openURL:(NSURL *)URL resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject
|
||||
{
|
||||
}
|
||||
- (void)openURL:(NSURL *)URL callback:(RCTResponseSenderBlock)callback
|
||||
{
|
||||
}
|
||||
- (id)methodThatCallsCallbackWithArg:(NSString *)input callback:(RCTResponseSenderBlock)callback
|
||||
{
|
||||
callback(@[ input ]);
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)testNonnull
|
||||
{
|
||||
const char *methodSignature = "doFooWithBar:(nonnull NSString *)bar";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[@"Hello World"]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ @"Hello World" ]];
|
||||
}));
|
||||
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ [NSNull null] ]];
|
||||
}));
|
||||
}
|
||||
|
||||
- (void)doFooWithNumber:(__unused NSNumber *)n { }
|
||||
- (void)doFooWithDouble:(__unused double)n { }
|
||||
- (void)doFooWithInteger:(__unused NSInteger)n { }
|
||||
- (void)doFooWithCGRect:(CGRect)s { _s = s; }
|
||||
- (void)doFooWithNumber:(__unused NSNumber *)n
|
||||
{
|
||||
}
|
||||
- (void)doFooWithDouble:(__unused double)n
|
||||
{
|
||||
}
|
||||
- (void)doFooWithInteger:(__unused NSInteger)n
|
||||
{
|
||||
}
|
||||
- (void)doFooWithCGRect:(CGRect)s
|
||||
{
|
||||
_s = s;
|
||||
}
|
||||
|
||||
- (void)doFoo : (__unused NSString *)foo { }
|
||||
- (void)doFoo:(__unused NSString *)foo
|
||||
{
|
||||
}
|
||||
|
||||
- (void)testNumbersNonnull
|
||||
{
|
||||
|
@ -88,7 +121,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
const char *methodSignature = "doFooWithNumber:(NSNumber *)n";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
// Invoke method to trigger parsing
|
||||
[method invokeWithBridge:nil module:self arguments:@[@1]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ @1 ]];
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -96,7 +129,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
const char *methodSignature = "doFooWithNumber:(nonnull NSNumber *)n";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ [NSNull null] ]];
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -104,7 +137,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
const char *methodSignature = "doFooWithDouble:(double)n";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ [NSNull null] ]];
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -112,7 +145,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
const char *methodSignature = "doFooWithInteger:(NSInteger)n";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ [NSNull null] ]];
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +156,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
|
||||
CGRect r = CGRectMake(10, 20, 30, 40);
|
||||
[method invokeWithBridge:nil module:self arguments:@[@[@10, @20, @30, @40]]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ @[ @10, @20, @30, @40 ] ]];
|
||||
XCTAssertTrue(CGRectEqualToRect(r, _s));
|
||||
}
|
||||
|
||||
|
@ -139,7 +172,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
XCTAssertEqualObjects(@(method.JSMethodName), @"doFoo");
|
||||
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[@"bar"]];
|
||||
[method invokeWithBridge:nil module:self arguments:@[ @"bar" ]];
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -149,50 +182,62 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
const char *methodSignature = "doFoo";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(method.functionType == RCTFunctionTypeNormal);
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}), @"Unexpected error when parsing normal function");
|
||||
XCTAssertFalse(
|
||||
RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}),
|
||||
@"Unexpected error when parsing normal function");
|
||||
}
|
||||
|
||||
{
|
||||
const char *methodSignature = "openURL:(NSURL *)URL callback:(RCTResponseSenderBlock)callBack";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(method.functionType == RCTFunctionTypeNormal);
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}), @"Unexpected error when parsing normal function with callback");
|
||||
XCTAssertFalse(
|
||||
RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}),
|
||||
@"Unexpected error when parsing normal function with callback");
|
||||
}
|
||||
|
||||
{
|
||||
const char *methodSignature = "openURL:(NSURL *)URL resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject";
|
||||
const char *methodSignature =
|
||||
"openURL:(NSURL *)URL resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject";
|
||||
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(method.functionType == RCTFunctionTypePromise);
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}), @"Unexpected error when parsing promise function");
|
||||
XCTAssertFalse(
|
||||
RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}),
|
||||
@"Unexpected error when parsing promise function");
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
const char *methodSignature = "echoString:(NSString *)input";
|
||||
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(method.functionType == RCTFunctionTypeSync);
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}), @"Unexpected error when parsing sync function");
|
||||
XCTAssertFalse(
|
||||
RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}),
|
||||
@"Unexpected error when parsing sync function");
|
||||
}
|
||||
|
||||
{
|
||||
const char *methodSignature = "methodThatCallsCallbackWithArg:(NSString *)input callback:(RCTResponseSenderBlock)callback";
|
||||
const char *methodSignature =
|
||||
"methodThatCallsCallbackWithArg:(NSString *)input callback:(RCTResponseSenderBlock)callback";
|
||||
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(method.functionType == RCTFunctionTypeSync);
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}), @"Unexpected error when parsing sync function with callback");
|
||||
XCTAssertFalse(
|
||||
RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}),
|
||||
@"Unexpected error when parsing sync function with callback");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +246,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
{
|
||||
const char *methodSignature = "echoString:(NSString *)input";
|
||||
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
|
||||
id result = [method invokeWithBridge:nil module:self arguments:@[@"Test String Value"]];
|
||||
id result = [method invokeWithBridge:nil module:self arguments:@[ @"Test String Value" ]];
|
||||
XCTAssertEqualObjects(result, @"Test String Value");
|
||||
}
|
||||
|
||||
|
@ -226,19 +271,23 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSig
|
|||
{
|
||||
const char *methodSignature = "methodThatReturnsNil";
|
||||
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}), @"Unexpected error when parsing sync function with (id) return type");
|
||||
XCTAssertFalse(
|
||||
RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}),
|
||||
@"Unexpected error when parsing sync function with (id) return type");
|
||||
}
|
||||
|
||||
{
|
||||
const char *methodSignature = "doFoo";
|
||||
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}), @"Failed to trigger an error when parsing sync function with non-(id) return type");
|
||||
XCTAssertTrue(
|
||||
RCTLogsError(^{
|
||||
// Invoke method to trigger parsing
|
||||
__unused SEL selector = method.selector;
|
||||
}),
|
||||
@"Failed to trigger an error when parsing sync function with non-(id) return type");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#import "OCMock/OCMock.h"
|
||||
|
||||
#import <React/RCTNativeAnimatedNodesManager.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
|
||||
static const NSTimeInterval FRAME_LENGTH = 1.0 / 60.0;
|
||||
|
||||
|
@ -19,8 +19,7 @@ static const NSTimeInterval FRAME_LENGTH = 1.0 / 60.0;
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTFakeDisplayLink
|
||||
{
|
||||
@implementation RCTFakeDisplayLink {
|
||||
NSTimeInterval _timestamp;
|
||||
}
|
||||
|
||||
|
@ -41,7 +40,7 @@ static const NSTimeInterval FRAME_LENGTH = 1.0 / 60.0;
|
|||
|
||||
@end
|
||||
|
||||
@interface RCTFakeValueObserver : NSObject<RCTValueAnimatedNodeObserver>
|
||||
@interface RCTFakeValueObserver : NSObject <RCTValueAnimatedNodeObserver>
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray<NSNumber *> *calls;
|
||||
|
||||
|
@ -65,12 +64,11 @@ static const NSTimeInterval FRAME_LENGTH = 1.0 / 60.0;
|
|||
|
||||
@end
|
||||
|
||||
@interface RCTFakeEvent : NSObject<RCTEvent>
|
||||
@interface RCTFakeEvent : NSObject <RCTEvent>
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTFakeEvent
|
||||
{
|
||||
@implementation RCTFakeEvent {
|
||||
NSArray *_arguments;
|
||||
}
|
||||
|
||||
|
@ -94,9 +92,9 @@ static const NSTimeInterval FRAME_LENGTH = 1.0 / 60.0;
|
|||
return _arguments;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(+ (NSString *)moduleDotMethod);
|
||||
RCT_NOT_IMPLEMENTED(- (BOOL)canCoalesce);
|
||||
RCT_NOT_IMPLEMENTED(- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent);
|
||||
RCT_NOT_IMPLEMENTED(+(NSString *)moduleDotMethod);
|
||||
RCT_NOT_IMPLEMENTED(-(BOOL)canCoalesce);
|
||||
RCT_NOT_IMPLEMENTED(-(id<RCTEvent>)coalesceWithEvent : (id<RCTEvent>)newEvent);
|
||||
|
||||
@end
|
||||
|
||||
|
@ -115,8 +113,7 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
|
||||
@end
|
||||
|
||||
@implementation RCTNativeAnimatedNodesManagerTests
|
||||
{
|
||||
@implementation RCTNativeAnimatedNodesManagerTests {
|
||||
id _uiManager;
|
||||
RCTNativeAnimatedNodesManager *_nodesManager;
|
||||
RCTFakeDisplayLink *_displayLink;
|
||||
|
@ -129,7 +126,8 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
RCTBridge *bridge = [OCMockObject niceMockForClass:[RCTBridge class]];
|
||||
_uiManager = [OCMockObject niceMockForClass:[RCTUIManager class]];
|
||||
OCMStub([bridge uiManager]).andReturn(_uiManager);
|
||||
_nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithBridge:bridge surfacePresenter:bridge.surfacePresenter];
|
||||
_nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithBridge:bridge
|
||||
surfacePresenter:bridge.surfacePresenter];
|
||||
_displayLink = [RCTFakeDisplayLink new];
|
||||
}
|
||||
|
||||
|
@ -142,12 +140,9 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
*/
|
||||
- (void)createSimpleAnimatedView:(NSNumber *)viewTag withOpacity:(CGFloat)opacity
|
||||
{
|
||||
[_nodesManager createAnimatedNode:@101
|
||||
config:@{@"type": @"value", @"value": @(opacity), @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@201
|
||||
config:@{@"type": @"style", @"style": @{@"opacity": @101}}];
|
||||
[_nodesManager createAnimatedNode:@301
|
||||
config:@{@"type": @"props", @"props": @{@"style": @201}}];
|
||||
[_nodesManager createAnimatedNode:@101 config:@{@"type" : @"value", @"value" : @(opacity), @"offset" : @0}];
|
||||
[_nodesManager createAnimatedNode:@201 config:@{@"type" : @"style", @"style" : @{@"opacity" : @101}}];
|
||||
[_nodesManager createAnimatedNode:@301 config:@{@"type" : @"props", @"props" : @{@"style" : @201}}];
|
||||
|
||||
[_nodesManager connectAnimatedNodes:@101 childTag:@201];
|
||||
[_nodesManager connectAnimatedNodes:@201 childTag:@301];
|
||||
|
@ -157,10 +152,10 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (void)testFramesAnimation
|
||||
{
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
NSArray<NSNumber *> *frames = @[@0, @0.2, @0.4, @0.6, @0.8, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @0.2, @0.4, @0.6, @0.8, @1 ];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @1}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @1}
|
||||
endCallback:nil];
|
||||
|
||||
for (NSNumber *frame in frames) {
|
||||
|
@ -171,9 +166,7 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
[_uiManager verify];
|
||||
}
|
||||
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:@1001
|
||||
viewName:@"UIView"
|
||||
props:RCTPropChecker(@"opacity", @1)];
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:@1001 viewName:@"UIView" props:RCTPropChecker(@"opacity", @1)];
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
[_uiManager verify];
|
||||
|
||||
|
@ -185,10 +178,10 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (void)testFramesAnimationLoop
|
||||
{
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
NSArray<NSNumber *> *frames = @[@0, @0.2, @0.4, @0.6, @0.8, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @0.2, @0.4, @0.6, @0.8, @1 ];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @1, @"iterations": @5}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @1, @"iterations" : @5}
|
||||
endCallback:nil];
|
||||
|
||||
for (NSUInteger it = 0; it < 5; it++) {
|
||||
|
@ -201,9 +194,7 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
}
|
||||
}
|
||||
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:@1001
|
||||
viewName:@"UIView"
|
||||
props:RCTPropChecker(@"opacity", @1)];
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:@1001 viewName:@"UIView" props:RCTPropChecker(@"opacity", @1)];
|
||||
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
[_uiManager verify];
|
||||
|
@ -217,14 +208,14 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
{
|
||||
NSNumber *nodeId = @101;
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
NSArray<NSNumber *> *frames = @[@0, @0.2, @0.4, @0.6, @0.8, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @0.2, @0.4, @0.6, @0.8, @1 ];
|
||||
|
||||
RCTFakeValueObserver *observer = [RCTFakeValueObserver new];
|
||||
[_nodesManager startListeningToAnimatedNodeValue:nodeId valueObserver:observer];
|
||||
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:nodeId
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @1}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @1}
|
||||
endCallback:nil];
|
||||
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
|
@ -241,14 +232,14 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
{
|
||||
NSNumber *nodeId = @101;
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
NSArray<NSNumber *> *frames = @[@0, @0.2, @0.4, @0.6, @0.8, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @0.2, @0.4, @0.6, @0.8, @1 ];
|
||||
|
||||
RCTFakeValueObserver *observer = [RCTFakeValueObserver new];
|
||||
[_nodesManager startListeningToAnimatedNodeValue:nodeId valueObserver:observer];
|
||||
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:nodeId
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @1}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @1}
|
||||
endCallback:nil];
|
||||
|
||||
for (NSUInteger i = 0; i < frames.count; i++) {
|
||||
|
@ -265,13 +256,10 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
XCTAssertEqual(observer.calls.count, 7UL);
|
||||
}
|
||||
|
||||
- (void)performSpringAnimationTestWithConfig:(NSDictionary*)config isCriticallyDamped:(BOOL)testForCriticallyDamped
|
||||
- (void)performSpringAnimationTestWithConfig:(NSDictionary *)config isCriticallyDamped:(BOOL)testForCriticallyDamped
|
||||
{
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:config
|
||||
endCallback:nil];
|
||||
[_nodesManager startAnimatingNode:@1 nodeTag:@101 config:config endCallback:nil];
|
||||
|
||||
BOOL wasGreaterThanOne = NO;
|
||||
CGFloat previousValue = 0;
|
||||
|
@ -313,29 +301,33 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
|
||||
- (void)testUnderdampedSpringAnimation
|
||||
{
|
||||
[self performSpringAnimationTestWithConfig:@{@"type": @"spring",
|
||||
@"stiffness": @230.3,
|
||||
@"damping": @22,
|
||||
@"mass": @1,
|
||||
@"initialVelocity": @0,
|
||||
@"toValue": @1,
|
||||
@"restSpeedThreshold": @0.001,
|
||||
@"restDisplacementThreshold": @0.001,
|
||||
@"overshootClamping": @NO}
|
||||
[self performSpringAnimationTestWithConfig:@{
|
||||
@"type" : @"spring",
|
||||
@"stiffness" : @230.3,
|
||||
@"damping" : @22,
|
||||
@"mass" : @1,
|
||||
@"initialVelocity" : @0,
|
||||
@"toValue" : @1,
|
||||
@"restSpeedThreshold" : @0.001,
|
||||
@"restDisplacementThreshold" : @0.001,
|
||||
@"overshootClamping" : @NO
|
||||
}
|
||||
isCriticallyDamped:NO];
|
||||
}
|
||||
|
||||
- (void)testCritcallyDampedSpringAnimation
|
||||
{
|
||||
[self performSpringAnimationTestWithConfig:@{@"type": @"spring",
|
||||
@"stiffness": @1000,
|
||||
@"damping": @500,
|
||||
@"mass": @3,
|
||||
@"initialVelocity": @0,
|
||||
@"toValue": @1,
|
||||
@"restSpeedThreshold": @0.001,
|
||||
@"restDisplacementThreshold": @0.001,
|
||||
@"overshootClamping": @NO}
|
||||
[self performSpringAnimationTestWithConfig:@{
|
||||
@"type" : @"spring",
|
||||
@"stiffness" : @1000,
|
||||
@"damping" : @500,
|
||||
@"mass" : @3,
|
||||
@"initialVelocity" : @0,
|
||||
@"toValue" : @1,
|
||||
@"restSpeedThreshold" : @0.001,
|
||||
@"restDisplacementThreshold" : @0.001,
|
||||
@"overshootClamping" : @NO
|
||||
}
|
||||
isCriticallyDamped:YES];
|
||||
}
|
||||
|
||||
|
@ -344,12 +336,9 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"decay",
|
||||
@"velocity": @0.5,
|
||||
@"deceleration": @0.998}
|
||||
config:@{@"type" : @"decay", @"velocity" : @0.5, @"deceleration" : @0.998}
|
||||
endCallback:nil];
|
||||
|
||||
|
||||
__block CGFloat previousValue;
|
||||
__block CGFloat currentValue;
|
||||
CGFloat previousDiff = CGFLOAT_MAX;
|
||||
|
@ -384,14 +373,11 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (void)testDecayAnimationLoop
|
||||
{
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"decay",
|
||||
@"velocity": @0.5,
|
||||
@"deceleration": @0.998,
|
||||
@"iterations": @5}
|
||||
endCallback:nil];
|
||||
|
||||
[_nodesManager
|
||||
startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type" : @"decay", @"velocity" : @0.5, @"deceleration" : @0.998, @"iterations" : @5}
|
||||
endCallback:nil];
|
||||
|
||||
__block CGFloat previousValue;
|
||||
__block CGFloat currentValue;
|
||||
|
@ -437,18 +423,20 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"spring",
|
||||
@"iterations": @5,
|
||||
@"stiffness": @230.2,
|
||||
@"damping": @22,
|
||||
@"mass": @1,
|
||||
@"initialVelocity": @0,
|
||||
@"toValue": @1,
|
||||
@"restSpeedThreshold": @0.001,
|
||||
@"restDisplacementThreshold": @0.001,
|
||||
@"overshootClamping": @NO}
|
||||
config:@{
|
||||
@"type" : @"spring",
|
||||
@"iterations" : @5,
|
||||
@"stiffness" : @230.2,
|
||||
@"damping" : @22,
|
||||
@"mass" : @1,
|
||||
@"initialVelocity" : @0,
|
||||
@"toValue" : @1,
|
||||
@"restSpeedThreshold" : @0.001,
|
||||
@"restDisplacementThreshold" : @0.001,
|
||||
@"overshootClamping" : @NO
|
||||
}
|
||||
endCallback:nil];
|
||||
|
||||
|
||||
BOOL didComeToRest = NO;
|
||||
CGFloat previousValue = 0;
|
||||
NSUInteger numberOfResets = 0;
|
||||
|
@ -458,32 +446,32 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
[invocation getArgument:&props atIndex:4];
|
||||
currentValue = props[@"opacity"].doubleValue;
|
||||
}] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
|
||||
|
||||
// Run for 3 seconds five times.
|
||||
for (NSUInteger i = 0; i < 3 * 60 * 5; i++) {
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
|
||||
|
||||
if (!didComeToRest) {
|
||||
// Verify that animation step is relatively small.
|
||||
XCTAssertLessThan(fabs(currentValue - previousValue), 0.12);
|
||||
}
|
||||
|
||||
|
||||
// Test to see if it reset after coming to rest
|
||||
if (didComeToRest && currentValue == 0) {
|
||||
didComeToRest = NO;
|
||||
numberOfResets++;
|
||||
}
|
||||
|
||||
|
||||
// Record that the animation did come to rest when it rests on toValue.
|
||||
didComeToRest = fabs(currentValue - 1) < 0.001 && fabs(currentValue - previousValue) < 0.001;
|
||||
|
||||
|
||||
previousValue = currentValue;
|
||||
}
|
||||
|
||||
|
||||
// Verify that value reset 4 times after finishing a full animation and is currently resting.
|
||||
XCTAssertEqual(numberOfResets, 4u);
|
||||
XCTAssertTrue(didComeToRest);
|
||||
|
||||
|
||||
[[_uiManager reject] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
[_uiManager verify];
|
||||
|
@ -492,18 +480,18 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (void)testAnimationCallbackFinish
|
||||
{
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
NSArray<NSNumber *> *frames = @[@0, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @1 ];
|
||||
|
||||
__block NSInteger endCallbackCalls = 0;
|
||||
|
||||
RCTResponseSenderBlock endCallback = ^(NSArray *response) {
|
||||
endCallbackCalls++;
|
||||
XCTAssertEqualObjects(response, @[@{@"finished": @YES}]);
|
||||
XCTAssertEqualObjects(response, @[ @{@"finished" : @YES} ]);
|
||||
};
|
||||
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @1}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @1}
|
||||
endCallback:endCallback];
|
||||
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
|
@ -527,16 +515,11 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
firstValue:(CGFloat)firstValue
|
||||
secondValue:(CGFloat)secondValue
|
||||
{
|
||||
[_nodesManager createAnimatedNode:@101
|
||||
config:@{@"type": @"value", @"value": @(firstValue), @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@201
|
||||
config:@{@"type": @"value", @"value": @(secondValue), @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@301
|
||||
config:@{@"type": @"addition", @"input": @[@101, @201]}];
|
||||
[_nodesManager createAnimatedNode:@401
|
||||
config:@{@"type": @"style", @"style": @{@"translateX": @301}}];
|
||||
[_nodesManager createAnimatedNode:@501
|
||||
config:@{@"type": @"props", @"props": @{@"style": @401}}];
|
||||
[_nodesManager createAnimatedNode:@101 config:@{@"type" : @"value", @"value" : @(firstValue), @"offset" : @0}];
|
||||
[_nodesManager createAnimatedNode:@201 config:@{@"type" : @"value", @"value" : @(secondValue), @"offset" : @0}];
|
||||
[_nodesManager createAnimatedNode:@301 config:@{@"type" : @"addition", @"input" : @[ @101, @201 ]}];
|
||||
[_nodesManager createAnimatedNode:@401 config:@{@"type" : @"style", @"style" : @{@"translateX" : @301}}];
|
||||
[_nodesManager createAnimatedNode:@501 config:@{@"type" : @"props", @"props" : @{@"style" : @401}}];
|
||||
|
||||
[_nodesManager connectAnimatedNodes:@101 childTag:@301];
|
||||
[_nodesManager connectAnimatedNodes:@201 childTag:@301];
|
||||
|
@ -550,14 +533,14 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
NSNumber *viewTag = @51;
|
||||
[self createAnimatedGraphWithAdditionNode:viewTag firstValue:100 secondValue:1000];
|
||||
|
||||
NSArray<NSNumber *> *frames = @[@0, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @1 ];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @101}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @101}
|
||||
endCallback:nil];
|
||||
[_nodesManager startAnimatingNode:@2
|
||||
nodeTag:@201
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @1010}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @1010}
|
||||
endCallback:nil];
|
||||
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:viewTag
|
||||
|
@ -595,10 +578,10 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
NSNumber *viewTag = @51;
|
||||
[self createAnimatedGraphWithAdditionNode:viewTag firstValue:100 secondValue:1000];
|
||||
|
||||
NSArray<NSNumber *> *frames = @[@0, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @1 ];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @101}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @101}
|
||||
endCallback:nil];
|
||||
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:viewTag
|
||||
|
@ -637,15 +620,15 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
NSNumber *viewTag = @51;
|
||||
[self createAnimatedGraphWithAdditionNode:viewTag firstValue:100 secondValue:1000];
|
||||
|
||||
NSArray<NSNumber *> *firstFrames = @[@0, @1];
|
||||
NSArray<NSNumber *> *firstFrames = @[ @0, @1 ];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": firstFrames, @"toValue": @200}
|
||||
config:@{@"type" : @"frames", @"frames" : firstFrames, @"toValue" : @200}
|
||||
endCallback:nil];
|
||||
NSArray<NSNumber *> *secondFrames = @[@0, @0.2, @0.4, @0.6, @0.8, @1];
|
||||
NSArray<NSNumber *> *secondFrames = @[ @0, @0.2, @0.4, @0.6, @0.8, @1 ];
|
||||
[_nodesManager startAnimatingNode:@2
|
||||
nodeTag:@201
|
||||
config:@{@"type": @"frames", @"frames": secondFrames, @"toValue": @1010}
|
||||
config:@{@"type" : @"frames", @"frames" : secondFrames, @"toValue" : @1010}
|
||||
endCallback:nil];
|
||||
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:viewTag
|
||||
|
@ -677,16 +660,11 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (void)testMultiplicationNode
|
||||
{
|
||||
NSNumber *viewTag = @51;
|
||||
[_nodesManager createAnimatedNode:@101
|
||||
config:@{@"type": @"value", @"value": @1, @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@201
|
||||
config:@{@"type": @"value", @"value": @5, @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@301
|
||||
config:@{@"type": @"multiplication", @"input": @[@101, @201]}];
|
||||
[_nodesManager createAnimatedNode:@401
|
||||
config:@{@"type": @"style", @"style": @{@"translateX": @301}}];
|
||||
[_nodesManager createAnimatedNode:@501
|
||||
config:@{@"type": @"props", @"props": @{@"style": @401}}];
|
||||
[_nodesManager createAnimatedNode:@101 config:@{@"type" : @"value", @"value" : @1, @"offset" : @0}];
|
||||
[_nodesManager createAnimatedNode:@201 config:@{@"type" : @"value", @"value" : @5, @"offset" : @0}];
|
||||
[_nodesManager createAnimatedNode:@301 config:@{@"type" : @"multiplication", @"input" : @[ @101, @201 ]}];
|
||||
[_nodesManager createAnimatedNode:@401 config:@{@"type" : @"style", @"style" : @{@"translateX" : @301}}];
|
||||
[_nodesManager createAnimatedNode:@501 config:@{@"type" : @"props", @"props" : @{@"style" : @401}}];
|
||||
|
||||
[_nodesManager connectAnimatedNodes:@101 childTag:@301];
|
||||
[_nodesManager connectAnimatedNodes:@201 childTag:@301];
|
||||
|
@ -694,14 +672,14 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
[_nodesManager connectAnimatedNodes:@401 childTag:@501];
|
||||
[_nodesManager connectAnimatedNodeToView:@501 viewTag:viewTag viewName:@"UIView"];
|
||||
|
||||
NSArray<NSNumber *> *frames = @[@0, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @1 ];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @2}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @2}
|
||||
endCallback:nil];
|
||||
[_nodesManager startAnimatingNode:@2
|
||||
nodeTag:@201
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @10}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @10}
|
||||
endCallback:nil];
|
||||
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:viewTag
|
||||
|
@ -730,18 +708,18 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (void)testHandleStoppingAnimation
|
||||
{
|
||||
[self createSimpleAnimatedView:@1001 withOpacity:0];
|
||||
NSArray<NSNumber *> *frames = @[@0, @0.2, @0.4, @0.6, @0.8, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @0.2, @0.4, @0.6, @0.8, @1 ];
|
||||
|
||||
__block BOOL endCallbackCalled = NO;
|
||||
|
||||
RCTResponseSenderBlock endCallback = ^(NSArray *response) {
|
||||
endCallbackCalled = YES;
|
||||
XCTAssertEqualObjects(response, @[@{@"finished": @NO}]);
|
||||
XCTAssertEqualObjects(response, @[ @{@"finished" : @NO} ]);
|
||||
};
|
||||
|
||||
[_nodesManager startAnimatingNode:@404
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @1}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @1}
|
||||
endCallback:endCallback];
|
||||
|
||||
[[_uiManager expect] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
|
@ -766,28 +744,27 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (void)testInterpolationNode
|
||||
{
|
||||
NSNumber *viewTag = @51;
|
||||
[_nodesManager createAnimatedNode:@101
|
||||
config:@{@"type": @"value", @"value": @10, @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@101 config:@{@"type" : @"value", @"value" : @10, @"offset" : @0}];
|
||||
[_nodesManager createAnimatedNode:@201
|
||||
config:@{@"type": @"interpolation",
|
||||
@"inputRange": @[@10, @20],
|
||||
@"outputRange": @[@0, @1],
|
||||
@"extrapolateLeft": @"extend",
|
||||
@"extrapolateRight": @"extend"}];
|
||||
[_nodesManager createAnimatedNode:@301
|
||||
config:@{@"type": @"style", @"style": @{@"opacity": @201}}];
|
||||
[_nodesManager createAnimatedNode:@401
|
||||
config:@{@"type": @"props", @"props": @{@"style": @301}}];
|
||||
config:@{
|
||||
@"type" : @"interpolation",
|
||||
@"inputRange" : @[ @10, @20 ],
|
||||
@"outputRange" : @[ @0, @1 ],
|
||||
@"extrapolateLeft" : @"extend",
|
||||
@"extrapolateRight" : @"extend"
|
||||
}];
|
||||
[_nodesManager createAnimatedNode:@301 config:@{@"type" : @"style", @"style" : @{@"opacity" : @201}}];
|
||||
[_nodesManager createAnimatedNode:@401 config:@{@"type" : @"props", @"props" : @{@"style" : @301}}];
|
||||
|
||||
[_nodesManager connectAnimatedNodes:@101 childTag:@201];
|
||||
[_nodesManager connectAnimatedNodes:@201 childTag:@301];
|
||||
[_nodesManager connectAnimatedNodes:@301 childTag:@401];
|
||||
[_nodesManager connectAnimatedNodeToView:@401 viewTag:viewTag viewName:@"UIView"];
|
||||
|
||||
NSArray<NSNumber *> *frames = @[@0, @0.2, @0.4, @0.6, @0.8, @1];
|
||||
NSArray<NSNumber *> *frames = @[ @0, @0.2, @0.4, @0.6, @0.8, @1 ];
|
||||
[_nodesManager startAnimatingNode:@1
|
||||
nodeTag:@101
|
||||
config:@{@"type": @"frames", @"frames": frames, @"toValue": @20}
|
||||
config:@{@"type" : @"frames", @"frames" : frames, @"toValue" : @20}
|
||||
endCallback:nil];
|
||||
|
||||
for (NSNumber *frame in frames) {
|
||||
|
@ -804,7 +781,6 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
[_nodesManager stepAnimations:_displayLink];
|
||||
[_uiManager verify];
|
||||
|
||||
|
||||
[[_uiManager reject] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
[_uiManager verify];
|
||||
|
@ -813,10 +789,8 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
- (id<RCTEvent>)createScrollEventWithTag:(NSNumber *)viewTag value:(CGFloat)value
|
||||
{
|
||||
// The event value is the 3rd argument.
|
||||
NSArray *arguments = @[@1, @1, @{@"contentOffset": @{@"y": @(value)}}];
|
||||
return [[RCTFakeEvent alloc] initWithName:@"topScroll"
|
||||
viewTag:viewTag
|
||||
arguments:arguments];
|
||||
NSArray *arguments = @[ @1, @1, @{@"contentOffset" : @{@"y" : @(value)}} ];
|
||||
return [[RCTFakeEvent alloc] initWithName:@"topScroll" viewTag:viewTag arguments:arguments];
|
||||
}
|
||||
|
||||
- (void)testNativeAnimatedEventDoUpdate
|
||||
|
@ -824,12 +798,10 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
NSNumber *viewTag = @1001;
|
||||
[self createSimpleAnimatedView:viewTag withOpacity:0];
|
||||
|
||||
[_nodesManager addAnimatedEventToView:viewTag
|
||||
eventName:@"topScroll"
|
||||
eventMapping:@{@"animatedValueTag": @101,
|
||||
@"nativeEventPath": @[@"contentOffset", @"y"]}];
|
||||
|
||||
|
||||
[_nodesManager
|
||||
addAnimatedEventToView:viewTag
|
||||
eventName:@"topScroll"
|
||||
eventMapping:@{@"animatedValueTag" : @101, @"nativeEventPath" : @[ @"contentOffset", @"y" ]}];
|
||||
|
||||
// Make sure that the update actually happened synchronously in `handleAnimatedEvent` and does
|
||||
// not wait for the next animation loop.
|
||||
|
@ -849,34 +821,33 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
NSNumber *viewTag = @1001;
|
||||
[self createSimpleAnimatedView:viewTag withOpacity:0];
|
||||
|
||||
[_nodesManager addAnimatedEventToView:viewTag
|
||||
eventName:@"otherEvent"
|
||||
eventMapping:@{@"animatedValueTag": @101,
|
||||
@"nativeEventPath": @[@"contentOffset", @"y"]}];
|
||||
[_nodesManager
|
||||
addAnimatedEventToView:viewTag
|
||||
eventName:@"otherEvent"
|
||||
eventMapping:@{@"animatedValueTag" : @101, @"nativeEventPath" : @[ @"contentOffset", @"y" ]}];
|
||||
|
||||
[_nodesManager addAnimatedEventToView:@999
|
||||
eventName:@"topScroll"
|
||||
eventMapping:@{@"animatedValueTag": @101,
|
||||
@"nativeEventPath": @[@"contentOffset", @"y"]}];
|
||||
[_nodesManager
|
||||
addAnimatedEventToView:@999
|
||||
eventName:@"topScroll"
|
||||
eventMapping:@{@"animatedValueTag" : @101, @"nativeEventPath" : @[ @"contentOffset", @"y" ]}];
|
||||
|
||||
[[_uiManager reject] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
[_nodesManager handleAnimatedEvent:[self createScrollEventWithTag:viewTag value:10]];
|
||||
[_uiManager verify];
|
||||
}
|
||||
|
||||
- (void) testGetValue
|
||||
- (void)testGetValue
|
||||
{
|
||||
__block NSInteger saveValueCallbackCalls = 0;
|
||||
NSNumber *nodeTag = @100;
|
||||
[_nodesManager createAnimatedNode:nodeTag
|
||||
config:@{@"type": @"value", @"value": @1, @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:nodeTag config:@{@"type" : @"value", @"value" : @1, @"offset" : @0}];
|
||||
RCTResponseSenderBlock saveValueCallback = ^(NSArray *response) {
|
||||
saveValueCallbackCalls++;
|
||||
XCTAssertEqualObjects(response, @[@1]);
|
||||
XCTAssertEqualObjects(response, @[ @1 ]);
|
||||
};
|
||||
|
||||
|
||||
XCTAssertEqual(saveValueCallbackCalls, 0);
|
||||
|
||||
|
||||
[_nodesManager getValue:nodeTag saveCallback:saveValueCallback];
|
||||
XCTAssertEqual(saveValueCallbackCalls, 1);
|
||||
}
|
||||
|
@ -891,21 +862,19 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
initialValue:(CGFloat)initialValue
|
||||
animationConfig:(NSDictionary *)animationConfig
|
||||
{
|
||||
[_nodesManager createAnimatedNode:@101
|
||||
config:@{@"type": @"value", @"value": @(initialValue), @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@301
|
||||
config:@{@"type": @"value", @"value": @(initialValue), @"offset": @0}];
|
||||
[_nodesManager createAnimatedNode:@101 config:@{@"type" : @"value", @"value" : @(initialValue), @"offset" : @0}];
|
||||
[_nodesManager createAnimatedNode:@301 config:@{@"type" : @"value", @"value" : @(initialValue), @"offset" : @0}];
|
||||
|
||||
[_nodesManager createAnimatedNode:@201
|
||||
config:@{@"type": @"tracking",
|
||||
@"animationId": @70,
|
||||
@"value": @301,
|
||||
@"toValue": @101,
|
||||
@"animationConfig": animationConfig}];
|
||||
[_nodesManager createAnimatedNode:@401
|
||||
config:@{@"type": @"style", @"style": @{@"translateX": @301}}];
|
||||
[_nodesManager createAnimatedNode:@501
|
||||
config:@{@"type": @"props", @"props": @{@"style": @401}}];
|
||||
config:@{
|
||||
@"type" : @"tracking",
|
||||
@"animationId" : @70,
|
||||
@"value" : @301,
|
||||
@"toValue" : @101,
|
||||
@"animationConfig" : animationConfig
|
||||
}];
|
||||
[_nodesManager createAnimatedNode:@401 config:@{@"type" : @"style", @"style" : @{@"translateX" : @301}}];
|
||||
[_nodesManager createAnimatedNode:@501 config:@{@"type" : @"props", @"props" : @{@"style" : @401}}];
|
||||
|
||||
[_nodesManager connectAnimatedNodes:@101 childTag:@201];
|
||||
[_nodesManager connectAnimatedNodes:@301 childTag:@401];
|
||||
|
@ -920,8 +889,8 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
*/
|
||||
- (void)testTracking
|
||||
{
|
||||
NSArray *frames = @[@0, @0.25, @0.5, @0.75, @1];
|
||||
NSDictionary *animationConfig = @{@"type": @"frames", @"frames": frames};
|
||||
NSArray *frames = @[ @0, @0.25, @0.5, @0.75, @1 ];
|
||||
NSDictionary *animationConfig = @{@"type" : @"frames", @"frames" : frames};
|
||||
[self createAnimatedGraphWithTrackingNode:@1001 initialValue:0 animationConfig:animationConfig];
|
||||
[_nodesManager stepAnimations:_displayLink]; // kick off the tracking
|
||||
|
||||
|
@ -986,17 +955,17 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
* end.
|
||||
*/
|
||||
|
||||
- (void)testTrackingPausesWhenEndValueIsReached
|
||||
- (void)testTrackingPausesWhenEndValueIsReached
|
||||
{
|
||||
NSArray *frames = @[@0, @0.5, @1];
|
||||
NSDictionary *animationConfig = @{@"type": @"frames", @"frames": frames};
|
||||
NSArray *frames = @[ @0, @0.5, @1 ];
|
||||
NSDictionary *animationConfig = @{@"type" : @"frames", @"frames" : frames};
|
||||
[self createAnimatedGraphWithTrackingNode:@1001 initialValue:0 animationConfig:animationConfig];
|
||||
|
||||
[_nodesManager setAnimatedNodeValue:@101 value:@100];
|
||||
[_nodesManager stepAnimations:_displayLink]; // kick off the tracking
|
||||
|
||||
__block int callCount = 0;
|
||||
[[[_uiManager stub] andDo:^(NSInvocation* __unused invocation) {
|
||||
[[[_uiManager stub] andDo:^(NSInvocation *__unused invocation) {
|
||||
callCount++;
|
||||
}] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
|
||||
|
@ -1007,7 +976,7 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
XCTAssertEqual(callCount, 4);
|
||||
|
||||
// the animation has completed, we expect no updates to be done
|
||||
[[[_uiManager stub] andDo:^(NSInvocation* __unused invocation) {
|
||||
[[[_uiManager stub] andDo:^(NSInvocation *__unused invocation) {
|
||||
XCTFail("Expected not to be called");
|
||||
}] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
[_nodesManager stepAnimations:_displayLink];
|
||||
|
@ -1015,7 +984,7 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
|
||||
// restore rejected method, we will use it later on
|
||||
callCount = 0;
|
||||
[[[_uiManager stub] andDo:^(NSInvocation* __unused invocation) {
|
||||
[[[_uiManager stub] andDo:^(NSInvocation *__unused invocation) {
|
||||
callCount++;
|
||||
}] synchronouslyUpdateViewOnUIThread:OCMOCK_ANY viewName:OCMOCK_ANY props:OCMOCK_ANY];
|
||||
|
||||
|
@ -1040,18 +1009,20 @@ static id RCTPropChecker(NSString *prop, NSNumber *value)
|
|||
* destination value updates the current speed of the animated value will be taken into account
|
||||
* while updating the spring animation and it will smoothly transition to the new end value.
|
||||
*/
|
||||
- (void) testSpringTrackingRetainsSpeed
|
||||
- (void)testSpringTrackingRetainsSpeed
|
||||
{
|
||||
// this spring config corresponds to tension 20 and friction 0.5 which makes the spring settle
|
||||
// very slowly
|
||||
NSDictionary *springConfig = @{@"type": @"spring",
|
||||
@"restSpeedThreshold": @0.001,
|
||||
@"mass": @1,
|
||||
@"restDisplacementThreshold": @0.001,
|
||||
@"initialVelocity": @0.5,
|
||||
@"damping": @2.5,
|
||||
@"stiffness": @157.8,
|
||||
@"overshootClamping": @NO};
|
||||
NSDictionary *springConfig = @{
|
||||
@"type" : @"spring",
|
||||
@"restSpeedThreshold" : @0.001,
|
||||
@"mass" : @1,
|
||||
@"restDisplacementThreshold" : @0.001,
|
||||
@"initialVelocity" : @0.5,
|
||||
@"damping" : @2.5,
|
||||
@"stiffness" : @157.8,
|
||||
@"overshootClamping" : @NO
|
||||
};
|
||||
[self createAnimatedGraphWithTrackingNode:@1001 initialValue:0 animationConfig:springConfig];
|
||||
|
||||
__block CGFloat lastTranslateX = 0;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#import <React/RCTShadowView+Layout.h>
|
||||
#import <React/RCTShadowView.h>
|
||||
|
||||
|
||||
@interface RCTShadowViewTests : XCTestCase
|
||||
@property (nonatomic, strong) RCTRootShadowView *parentView;
|
||||
@end
|
||||
|
@ -87,16 +86,23 @@
|
|||
|
||||
[self.parentView layoutWithAffectedShadowViews:[NSHashTable weakObjectsHashTable]];
|
||||
|
||||
XCTAssertTrue(CGRectEqualToRect([self.parentView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(0, 0, 440, 440)));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect([self.parentView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(0, 0, 440, 440)));
|
||||
XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets([self.parentView paddingAsInsets], UIEdgeInsetsMake(10, 10, 10, 10)));
|
||||
|
||||
XCTAssertTrue(CGRectEqualToRect([headerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 10, 420, 100)));
|
||||
XCTAssertTrue(CGRectEqualToRect([mainView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 120, 420, 200)));
|
||||
XCTAssertTrue(CGRectEqualToRect([footerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 330, 420, 100)));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect([headerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 10, 420, 100)));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect([mainView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 120, 420, 200)));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect([footerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 330, 420, 100)));
|
||||
|
||||
XCTAssertTrue(CGRectEqualToRect([leftView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 120, 100, 200)));
|
||||
XCTAssertTrue(CGRectEqualToRect([centerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(120, 120, 200, 200)));
|
||||
XCTAssertTrue(CGRectEqualToRect([rightView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(330, 120, 100, 200)));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect([leftView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 120, 100, 200)));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect([centerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(120, 120, 200, 200)));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect([rightView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(330, 120, 100, 200)));
|
||||
}
|
||||
|
||||
- (void)testAncestorCheck
|
||||
|
@ -124,37 +130,40 @@
|
|||
|
||||
- (void)testAssignsSuggestedWidthDimension
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetHeight(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 3, 10)
|
||||
withIntrinsicContentSize:CGSizeMake(3, UIViewNoIntrinsicMetric)];
|
||||
[self
|
||||
_withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetHeight(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 3, 10)
|
||||
withIntrinsicContentSize:CGSizeMake(3, UIViewNoIntrinsicMetric)];
|
||||
}
|
||||
|
||||
- (void)testAssignsSuggestedHeightDimension
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetWidth(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 10, 4)
|
||||
withIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, 4)];
|
||||
[self
|
||||
_withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetWidth(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 10, 4)
|
||||
withIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, 4)];
|
||||
}
|
||||
|
||||
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetWidth(node, 10);
|
||||
YGNodeStyleSetHeight(node, 10);
|
||||
}
|
||||
[self
|
||||
_withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetWidth(node, 10);
|
||||
YGNodeStyleSetHeight(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 10, 10)
|
||||
withIntrinsicContentSize:CGSizeMake(3, 4)];
|
||||
}
|
||||
|
@ -163,14 +172,15 @@
|
|||
{
|
||||
float parentWidth = YGNodeStyleGetWidth(self.parentView.yogaNode).value;
|
||||
float parentHeight = YGNodeStyleGetHeight(self.parentView.yogaNode).value;
|
||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetFlex(node, 1);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, parentWidth, parentHeight)
|
||||
withIntrinsicContentSize:CGSizeMake(3, 4)];
|
||||
[self
|
||||
_withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetFlex(node, 1);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, parentWidth, parentHeight)
|
||||
withIntrinsicContentSize:CGSizeMake(3, 4)];
|
||||
}
|
||||
|
||||
- (void)_withShadowViewWithStyle:(void(^)(YGNodeRef node))configBlock
|
||||
- (void)_withShadowViewWithStyle:(void (^)(YGNodeRef node))configBlock
|
||||
assertRelativeLayout:(CGRect)expectedRect
|
||||
withIntrinsicContentSize:(CGSize)contentSize
|
||||
{
|
||||
|
@ -179,18 +189,18 @@
|
|||
view.intrinsicContentSize = contentSize;
|
||||
[self.parentView layoutWithAffectedShadowViews:[NSHashTable weakObjectsHashTable]];
|
||||
CGRect actualRect = [view measureLayoutRelativeToAncestor:self.parentView];
|
||||
XCTAssertTrue(CGRectEqualToRect(expectedRect, actualRect),
|
||||
@"Expected layout to be %@, got %@",
|
||||
NSStringFromCGRect(expectedRect),
|
||||
NSStringFromCGRect(actualRect));
|
||||
XCTAssertTrue(
|
||||
CGRectEqualToRect(expectedRect, actualRect),
|
||||
@"Expected layout to be %@, got %@",
|
||||
NSStringFromCGRect(expectedRect),
|
||||
NSStringFromCGRect(actualRect));
|
||||
}
|
||||
|
||||
- (RCTShadowView *)_shadowViewWithConfig:(void(^)(YGNodeRef node))configBlock
|
||||
- (RCTShadowView *)_shadowViewWithConfig:(void (^)(YGNodeRef node))configBlock
|
||||
{
|
||||
RCTShadowView *shadowView = [RCTShadowView new];
|
||||
configBlock(shadowView.yogaNode);
|
||||
return shadowView;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -51,8 +51,8 @@
|
|||
UIView *containerView = _uiManager.viewRegistry[@20];
|
||||
NSMutableArray *addedViews = [NSMutableArray array];
|
||||
|
||||
NSArray *tagsToAdd = @[@1, @2, @3, @4, @5];
|
||||
NSArray *addAtIndices = @[@0, @1, @2, @3, @4];
|
||||
NSArray *tagsToAdd = @[ @1, @2, @3, @4, @5 ];
|
||||
NSArray *addAtIndices = @[ @0, @1, @2, @3, @4 ];
|
||||
for (NSNumber *tag in tagsToAdd) {
|
||||
[addedViews addObject:_uiManager.viewRegistry[tag]];
|
||||
}
|
||||
|
@ -68,12 +68,14 @@
|
|||
|
||||
[containerView didUpdateReactSubviews];
|
||||
|
||||
XCTAssertTrue([[containerView reactSubviews] count] == 5,
|
||||
@"Expect to have 5 react subviews after calling manage children \
|
||||
with 5 tags to add, instead have %lu", (unsigned long)[[containerView reactSubviews] count]);
|
||||
XCTAssertTrue(
|
||||
[[containerView reactSubviews] count] == 5,
|
||||
@"Expect to have 5 react subviews after calling manage children \
|
||||
with 5 tags to add, instead have %lu",
|
||||
(unsigned long)[[containerView reactSubviews] count]);
|
||||
for (UIView *view in addedViews) {
|
||||
XCTAssertTrue([view reactSuperview] == containerView,
|
||||
@"Expected to have manage children successfully add children");
|
||||
XCTAssertTrue(
|
||||
[view reactSuperview] == containerView, @"Expected to have manage children successfully add children");
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +85,7 @@
|
|||
UIView *containerView = _uiManager.viewRegistry[@20];
|
||||
NSMutableArray *removedViews = [NSMutableArray array];
|
||||
|
||||
NSArray *removeAtIndices = @[@0, @4, @8, @12, @16];
|
||||
NSArray *removeAtIndices = @[ @0, @4, @8, @12, @16 ];
|
||||
for (NSNumber *index in removeAtIndices) {
|
||||
NSNumber *reactTag = @(index.integerValue + 2);
|
||||
[removedViews addObject:_uiManager.viewRegistry[reactTag]];
|
||||
|
@ -104,21 +106,24 @@
|
|||
|
||||
[containerView didUpdateReactSubviews];
|
||||
|
||||
XCTAssertEqual(containerView.reactSubviews.count, (NSUInteger)13,
|
||||
@"Expect to have 13 react subviews after calling manage children\
|
||||
XCTAssertEqual(
|
||||
containerView.reactSubviews.count,
|
||||
(NSUInteger)13,
|
||||
@"Expect to have 13 react subviews after calling manage children\
|
||||
with 5 tags to remove and 18 prior children, instead have %zd",
|
||||
containerView.reactSubviews.count);
|
||||
containerView.reactSubviews.count);
|
||||
for (UIView *view in removedViews) {
|
||||
XCTAssertTrue([view reactSuperview] == nil,
|
||||
@"Expected to have manage children successfully remove children");
|
||||
XCTAssertTrue([view reactSuperview] == nil, @"Expected to have manage children successfully remove children");
|
||||
// After removing views are unregistered - we need to reregister
|
||||
_uiManager.viewRegistry[view.reactTag] = view;
|
||||
}
|
||||
for (NSInteger i = 2; i < 20; i++) {
|
||||
UIView *view = _uiManager.viewRegistry[@(i)];
|
||||
if (![removedViews containsObject:view]) {
|
||||
XCTAssertTrue([view superview] == containerView,
|
||||
@"Should not have removed view with react tag %ld during delete but did", (long)i);
|
||||
XCTAssertTrue(
|
||||
[view superview] == containerView,
|
||||
@"Should not have removed view with react tag %ld during delete but did",
|
||||
(long)i);
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
@ -136,11 +141,11 @@
|
|||
{
|
||||
UIView *containerView = _uiManager.viewRegistry[@20];
|
||||
|
||||
NSArray *removeAtIndices = @[@2, @3, @5, @8];
|
||||
NSArray *addAtIndices = @[@0, @6];
|
||||
NSArray *tagsToAdd = @[@11, @12];
|
||||
NSArray *moveFromIndices = @[@4, @9];
|
||||
NSArray *moveToIndices = @[@1, @7];
|
||||
NSArray *removeAtIndices = @[ @2, @3, @5, @8 ];
|
||||
NSArray *addAtIndices = @[ @0, @6 ];
|
||||
NSArray *tagsToAdd = @[ @11, @12 ];
|
||||
NSArray *moveFromIndices = @[ @4, @9 ];
|
||||
NSArray *moveToIndices = @[ @1, @7 ];
|
||||
|
||||
// We need to keep these in array to keep them around
|
||||
NSMutableArray *viewsToRemove = [NSMutableArray array];
|
||||
|
@ -165,15 +170,21 @@
|
|||
|
||||
[containerView didUpdateReactSubviews];
|
||||
|
||||
XCTAssertTrue([[containerView reactSubviews] count] == 8,
|
||||
@"Expect to have 8 react subviews after calling manage children,\
|
||||
instead have the following subviews %@", [containerView reactSubviews]);
|
||||
XCTAssertTrue(
|
||||
[[containerView reactSubviews] count] == 8,
|
||||
@"Expect to have 8 react subviews after calling manage children,\
|
||||
instead have the following subviews %@",
|
||||
[containerView reactSubviews]);
|
||||
|
||||
NSArray *expectedReactTags = @[@11, @5, @1, @2, @7, @8, @12, @10];
|
||||
NSArray *expectedReactTags = @[ @11, @5, @1, @2, @7, @8, @12, @10 ];
|
||||
for (NSUInteger i = 0; i < containerView.subviews.count; i++) {
|
||||
XCTAssertEqualObjects([[containerView reactSubviews][i] reactTag], expectedReactTags[i],
|
||||
@"Expected subview at index %ld to have react tag #%@ but has tag #%@",
|
||||
(long)i, expectedReactTags[i], [[containerView reactSubviews][i] reactTag]);
|
||||
XCTAssertEqualObjects(
|
||||
[[containerView reactSubviews][i] reactTag],
|
||||
expectedReactTags[i],
|
||||
@"Expected subview at index %ld to have react tag #%@ but has tag #%@",
|
||||
(long)i,
|
||||
expectedReactTags[i],
|
||||
[[containerView reactSubviews][i] reactTag]);
|
||||
}
|
||||
|
||||
// Clean up after ourselves
|
||||
|
|
|
@ -9,11 +9,14 @@
|
|||
|
||||
#import <React/RCTNetworking.h>
|
||||
|
||||
static NSString *const niqqudStringB64 = @"15HWsNa816jWtdeQ16nWtNeB15nXqiwg15HWuNa816jWuNeQINeQ1rHXnNa515TWtNeZ150sINeQ1rXXqiDXlNa316nWuNa814HXnta315nWtNedLCDXldaw15DWtdeqINeU1rjXkNa416jWttelLg==";
|
||||
static NSString *const niqqudStringB64 =
|
||||
@"15HWsNa816jWtdeQ16nWtNeB15nXqiwg15HWuNa816jWuNeQINeQ1rHXnNa515TWtNeZ150sINeQ1rXXqiDXlNa316nWuNa814HXnta315nWtNedLCDXldaw15DWtdeqINeU1rjXkNa416jWttelLg==";
|
||||
|
||||
@interface RCTNetworking ()
|
||||
|
||||
+ (NSString *)decodeTextData:(NSData *)data fromResponse:(NSURLResponse *)response withCarryData:(NSMutableData *)inputCarryData;
|
||||
+ (NSString *)decodeTextData:(NSData *)data
|
||||
fromResponse:(NSURLResponse *)response
|
||||
withCarryData:(NSMutableData *)inputCarryData;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -30,10 +33,11 @@ static NSString *const niqqudStringB64 = @"15HWsNa816jWtdeQ16nWtNeB15nXqiwg15HWu
|
|||
|
||||
NSData *unicodeBytes = [unicodeString dataUsingEncoding:encoding];
|
||||
|
||||
NSURLResponse *fakeResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:@"testurl://"]
|
||||
statusCode:200
|
||||
HTTPVersion:@"1.1"
|
||||
headerFields:@{@"content-type": [NSString stringWithFormat:@"text/plain; charset=%@", encodingName]}];
|
||||
NSURLResponse *fakeResponse = [[NSHTTPURLResponse alloc]
|
||||
initWithURL:[NSURL URLWithString:@"testurl://"]
|
||||
statusCode:200
|
||||
HTTPVersion:@"1.1"
|
||||
headerFields:@{@"content-type" : [NSString stringWithFormat:@"text/plain; charset=%@", encodingName]}];
|
||||
XCTAssert([fakeResponse.textEncodingName isEqualToString:encodingName]);
|
||||
|
||||
NSMutableData *carryStorage = [NSMutableData new];
|
||||
|
@ -41,11 +45,16 @@ static NSString *const niqqudStringB64 = @"15HWsNa816jWtdeQ16nWtNeB15nXqiwg15HWu
|
|||
|
||||
[parsedString appendString:[RCTNetworking decodeTextData:[unicodeBytes subdataWithRange:NSMakeRange(0, cutPoint)]
|
||||
fromResponse:fakeResponse
|
||||
withCarryData:carryStorage] ?: @""];
|
||||
withCarryData:carryStorage]
|
||||
?: @""];
|
||||
|
||||
[parsedString appendString:[RCTNetworking decodeTextData:[unicodeBytes subdataWithRange:NSMakeRange(cutPoint, unicodeBytes.length - cutPoint)]
|
||||
fromResponse:fakeResponse
|
||||
withCarryData:carryStorage] ?: @""];
|
||||
[parsedString
|
||||
appendString:[RCTNetworking
|
||||
decodeTextData:[unicodeBytes
|
||||
subdataWithRange:NSMakeRange(cutPoint, unicodeBytes.length - cutPoint)]
|
||||
fromResponse:fakeResponse
|
||||
withCarryData:carryStorage]
|
||||
?: @""];
|
||||
|
||||
XCTAssert(carryStorage.length == 0);
|
||||
XCTAssert([parsedString isEqualToString:unicodeString]);
|
||||
|
@ -53,9 +62,9 @@ static NSString *const niqqudStringB64 = @"15HWsNa816jWtdeQ16nWtNeB15nXqiwg15HWu
|
|||
|
||||
- (void)testNiqqud
|
||||
{
|
||||
NSString *unicodeString = [[NSString alloc] initWithData:[[NSData alloc] initWithBase64EncodedString:niqqudStringB64
|
||||
options:(NSDataBase64DecodingOptions)0]
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSString *unicodeString = [[NSString alloc]
|
||||
initWithData:[[NSData alloc] initWithBase64EncodedString:niqqudStringB64 options:(NSDataBase64DecodingOptions)0]
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
[self runTestForString:unicodeString usingEncoding:@"utf-8" cutAt:25];
|
||||
}
|
||||
|
|
|
@ -10,25 +10,26 @@
|
|||
#import <React/RCTLog.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
static NSString * RCTLogsError(void (^block)(void))
|
||||
static NSString *RCTLogsError(void (^block)(void))
|
||||
{
|
||||
__block NSString* loggedMessage = @"";
|
||||
__block NSString *loggedMessage = @"";
|
||||
__block BOOL loggedError = NO;
|
||||
RCTPerformBlockWithLogFunction(block, ^(RCTLogLevel level,
|
||||
__unused RCTLogSource source,
|
||||
__unused NSString *fileName,
|
||||
__unused NSNumber *lineNumber,
|
||||
NSString *message) {
|
||||
loggedError = (level == RCTLogLevelError);
|
||||
loggedMessage = message;
|
||||
});
|
||||
RCTPerformBlockWithLogFunction(
|
||||
block,
|
||||
^(RCTLogLevel level,
|
||||
__unused RCTLogSource source,
|
||||
__unused NSString *fileName,
|
||||
__unused NSNumber *lineNumber,
|
||||
NSString *message) {
|
||||
loggedError = (level == RCTLogLevelError);
|
||||
loggedMessage = message;
|
||||
});
|
||||
if (loggedError) {
|
||||
return loggedMessage;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@interface RCTUtilsTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
@ -51,13 +52,17 @@ static NSString * RCTLogsError(void (^block)(void))
|
|||
|
||||
- (void)testRCTValidateTypeOfViewCommandArgument
|
||||
{
|
||||
XCTAssertEqualObjects(RCTLogsError(^{
|
||||
RCTValidateTypeOfViewCommandArgument(@"str", [NSNumber class], @"number", @"ScrollView", @"scrollTo", @"2nd");
|
||||
}), @"ScrollView command scrollTo received 2nd argument of type string, expected number.");
|
||||
XCTAssertEqualObjects(
|
||||
RCTLogsError(^{
|
||||
RCTValidateTypeOfViewCommandArgument(@"str", [NSNumber class], @"number", @"ScrollView", @"scrollTo", @"2nd");
|
||||
}),
|
||||
@"ScrollView command scrollTo received 2nd argument of type string, expected number.");
|
||||
|
||||
XCTAssertEqualObjects(RCTLogsError(^{
|
||||
RCTValidateTypeOfViewCommandArgument(@"str", [NSString class], @"string", @"ScrollView", @"scrollTo", @"1st");
|
||||
}), nil);
|
||||
XCTAssertEqualObjects(
|
||||
RCTLogsError(^{
|
||||
RCTValidateTypeOfViewCommandArgument(@"str", [NSString class], @"string", @"ScrollView", @"scrollTo", @"1st");
|
||||
}),
|
||||
nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return facebook::jni::initialize(vm, [] {
|
||||
// TODO: dvacca ramanpreet unify this with the way "ComponentDescriptorFactory" is defined in Fabric
|
||||
// TODO: dvacca ramanpreet unify this with the way
|
||||
// "ComponentDescriptorFactory" is defined in Fabric
|
||||
facebook::react::RNTesterTurboModuleManagerDelegate::registerNatives();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,8 +14,11 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> RNTesterAppModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
auto module = PackagesRnTesterAndroidAppSpec_ModuleProvider(moduleName, params);
|
||||
std::shared_ptr<TurboModule> RNTesterAppModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
auto module =
|
||||
PackagesRnTesterAndroidAppSpec_ModuleProvider(moduleName, params);
|
||||
if (module != nullptr) {
|
||||
return module;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> RNTesterAppModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
std::shared_ptr<TurboModule> RNTesterAppModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
|
|
@ -12,28 +12,38 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
jni::local_ref<RNTesterTurboModuleManagerDelegate::jhybriddata> RNTesterTurboModuleManagerDelegate::initHybrid(jni::alias_ref<jhybridobject>) {
|
||||
jni::local_ref<RNTesterTurboModuleManagerDelegate::jhybriddata>
|
||||
RNTesterTurboModuleManagerDelegate::initHybrid(jni::alias_ref<jhybridobject>) {
|
||||
return makeCxxInstance();
|
||||
}
|
||||
|
||||
void RNTesterTurboModuleManagerDelegate::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod("initHybrid", RNTesterTurboModuleManagerDelegate::initHybrid),
|
||||
makeNativeMethod("canCreateTurboModule", RNTesterTurboModuleManagerDelegate::canCreateTurboModule),
|
||||
makeNativeMethod(
|
||||
"initHybrid", RNTesterTurboModuleManagerDelegate::initHybrid),
|
||||
makeNativeMethod(
|
||||
"canCreateTurboModule",
|
||||
RNTesterTurboModuleManagerDelegate::canCreateTurboModule),
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleManagerDelegate::getTurboModule(const std::string name, const std::shared_ptr<CallInvoker> jsInvoker) {
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) {
|
||||
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleManagerDelegate::getTurboModule(const std::string name, const JavaTurboModule::InitParams ¶ms) {
|
||||
std::shared_ptr<TurboModule> RNTesterTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
return RNTesterAppModuleProvider(name, params);
|
||||
}
|
||||
|
||||
bool RNTesterTurboModuleManagerDelegate::canCreateTurboModule(std::string name) {
|
||||
return getTurboModule(name, nullptr) != nullptr || getTurboModule(name, {.moduleName = name}) != nullptr;
|
||||
bool RNTesterTurboModuleManagerDelegate::canCreateTurboModule(
|
||||
std::string name) {
|
||||
return getTurboModule(name, nullptr) != nullptr ||
|
||||
getTurboModule(name, {.moduleName = name}) != nullptr;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -14,8 +14,11 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class RNTesterTurboModuleManagerDelegate : public jni::HybridClass<RNTesterTurboModuleManagerDelegate, TurboModuleManagerDelegate> {
|
||||
public:
|
||||
class RNTesterTurboModuleManagerDelegate
|
||||
: public jni::HybridClass<
|
||||
RNTesterTurboModuleManagerDelegate,
|
||||
TurboModuleManagerDelegate> {
|
||||
public:
|
||||
static constexpr auto kJavaDescriptor =
|
||||
"Lcom/facebook/react/uiapp/RNTesterTurboModuleManagerDelegate;";
|
||||
|
||||
|
@ -23,19 +26,22 @@ public:
|
|||
|
||||
static void registerNatives();
|
||||
|
||||
std::shared_ptr<TurboModule> getTurboModule(const std::string name, const std::shared_ptr<CallInvoker> jsInvoker) override;
|
||||
std::shared_ptr<TurboModule> getTurboModule(const std::string name, const JavaTurboModule::InitParams ¶ms) override;
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) override;
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) override;
|
||||
|
||||
/**
|
||||
* Test-only method. Allows user to verify whether a TurboModule can be created
|
||||
* by instances of this class.
|
||||
* Test-only method. Allows user to verify whether a TurboModule can be
|
||||
* created by instances of this class.
|
||||
*/
|
||||
bool canCreateTurboModule(std::string name);
|
||||
|
||||
private:
|
||||
private:
|
||||
friend HybridBase;
|
||||
using HybridBase::HybridBase;
|
||||
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
Загрузка…
Ссылка в новой задаче