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:
Nicola Corti 2021-11-18 04:42:46 -08:00 коммит произвёл Facebook GitHub Bot
Родитель 8ace78c082
Коммит aa4da248c1
62 изменённых файлов: 1459 добавлений и 1298 удалений

Просмотреть файл

@ -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 &params);
};
} // namespace react
class JSI_EXPORT NativeTestModuleSpecJSI : public ObjCTurboModule {
public:
NativeTestModuleSpecJSI(const ObjCTurboModule::InitParams &params);
};
} // 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 &params) : ObjCTurboModule(params)
{
methodMap_["markTestCompleted"] = MethodMetadata{0, __hostFunction_NativeTestModuleSpecJSI_markTestCompleted};
methodMap_["markTestPassed"] = MethodMetadata{1, __hostFunction_NativeTestModuleSpecJSI_markTestPassed};
NativeTestModuleSpecJSI::NativeTestModuleSpecJSI(const ObjCTurboModule::InitParams &params)
: 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 &params) {
auto module = PackagesRnTesterAndroidAppSpec_ModuleProvider(moduleName, params);
std::shared_ptr<TurboModule> RNTesterAppModuleProvider(
const std::string moduleName,
const JavaTurboModule::InitParams &params) {
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 &params);
std::shared_ptr<TurboModule> RNTesterAppModuleProvider(
const std::string moduleName,
const JavaTurboModule::InitParams &params);
} // 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 &params) {
std::shared_ptr<TurboModule> RNTesterTurboModuleManagerDelegate::getTurboModule(
const std::string name,
const JavaTurboModule::InitParams &params) {
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 &params) 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 &params) 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