mirror of
https://github.com/status-im/realm-js.git
synced 2025-03-01 14:40:37 +00:00
Fix crash when a test fails inside RealmReactTests
This also appears to fix crashes when running ReactTests with Chrome debugging enabled! The crash when tests failed was due to JavaScriptCore trying to create a backtrace with the native call stack.
This commit is contained in:
parent
7f5902b021
commit
5d59431860
@ -17,11 +17,10 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@import Foundation;
|
@import Foundation;
|
||||||
|
@import JavaScriptCore;
|
||||||
|
|
||||||
|
extern JSGlobalContextRef RealmReactGetJSGlobalContextForExecutor(id executor);
|
||||||
|
|
||||||
@interface RealmReact : NSObject
|
@interface RealmReact : NSObject
|
||||||
|
|
||||||
@property (nonatomic, readonly) id executor;
|
|
||||||
|
|
||||||
+ (id)executor;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
@import GCDWebServers;
|
@import GCDWebServers;
|
||||||
@import RealmJS;
|
@import RealmJS;
|
||||||
@import JavaScriptCore;
|
|
||||||
@import ObjectiveC;
|
@import ObjectiveC;
|
||||||
@import Darwin;
|
@import Darwin;
|
||||||
|
|
||||||
@ -30,11 +29,16 @@
|
|||||||
- (JSGlobalContextRef)ctx;
|
- (JSGlobalContextRef)ctx;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
JSGlobalContextRef RealmReactGetJSGlobalContextForExecutor(id executor) {
|
||||||
|
Ivar contextIvar = class_getInstanceVariable([executor class], "_context");
|
||||||
|
id rctJSContext = contextIvar ? object_getIvar(executor, contextIvar) : nil;
|
||||||
|
|
||||||
|
return [rctJSContext ctx];
|
||||||
|
}
|
||||||
|
|
||||||
@interface RealmReact () <RCTBridgeModule>
|
@interface RealmReact () <RCTBridgeModule>
|
||||||
@end
|
@end
|
||||||
|
|
||||||
static id s_executor;
|
|
||||||
|
|
||||||
@implementation RealmReact
|
@implementation RealmReact
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
@ -54,16 +58,12 @@ static id s_executor;
|
|||||||
return @"Realm";
|
return @"Realm";
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)executor {
|
|
||||||
return s_executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setBridge:(RCTBridge *)bridge {
|
- (void)setBridge:(RCTBridge *)bridge {
|
||||||
_bridge = bridge;
|
_bridge = bridge;
|
||||||
|
|
||||||
Ivar executorIvar = class_getInstanceVariable([bridge class], "_javaScriptExecutor");
|
Ivar executorIvar = class_getInstanceVariable([bridge class], "_javaScriptExecutor");
|
||||||
s_executor = object_getIvar(bridge, executorIvar);
|
id executor = object_getIvar(bridge, executorIvar);
|
||||||
Ivar contextIvar = class_getInstanceVariable([s_executor class], "_context");
|
Ivar contextIvar = class_getInstanceVariable([executor class], "_context");
|
||||||
|
|
||||||
// The executor could be a RCTWebSocketExecutor, in which case it won't have a JS context.
|
// The executor could be a RCTWebSocketExecutor, in which case it won't have a JS context.
|
||||||
if (!contextIvar) {
|
if (!contextIvar) {
|
||||||
@ -96,8 +96,8 @@ static id s_executor;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[s_executor executeBlockOnJavaScriptQueue:^{
|
[executor executeBlockOnJavaScriptQueue:^{
|
||||||
id rctJSContext = object_getIvar(s_executor, contextIvar);
|
id rctJSContext = object_getIvar(executor, contextIvar);
|
||||||
JSGlobalContextRef ctx;
|
JSGlobalContextRef ctx;
|
||||||
|
|
||||||
if (rctJSContext) {
|
if (rctJSContext) {
|
||||||
@ -108,7 +108,7 @@ static id s_executor;
|
|||||||
|
|
||||||
if (RCTJavaScriptContext) {
|
if (RCTJavaScriptContext) {
|
||||||
ctx = JSGlobalContextCreate(NULL);
|
ctx = JSGlobalContextCreate(NULL);
|
||||||
object_setIvar(s_executor, contextIvar, [[RCTJavaScriptContext alloc] initWithJSContext:ctx]);
|
object_setIvar(executor, contextIvar, [[RCTJavaScriptContext alloc] initWithJSContext:ctx]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NSLog(@"Failed to load RCTJavaScriptContext class");
|
NSLog(@"Failed to load RCTJavaScriptContext class");
|
||||||
|
@ -22,13 +22,31 @@
|
|||||||
|
|
||||||
@import RealmReact;
|
@import RealmReact;
|
||||||
|
|
||||||
|
extern void JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx, bool includesNativeCallStack);
|
||||||
|
|
||||||
|
static id<RCTJavaScriptExecutor> s_currentJavaScriptExecutor;
|
||||||
|
|
||||||
@interface RealmReactTests : RealmJSTests
|
@interface RealmReactTests : RealmJSTests
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RealmReactTests
|
@implementation RealmReactTests
|
||||||
|
|
||||||
+ (XCTestSuite *)defaultTestSuite {
|
+ (XCTestSuite *)defaultTestSuite {
|
||||||
[self waitForNotification:RCTJavaScriptDidLoadNotification];
|
NSNotification *notification = [self waitForNotification:RCTJavaScriptDidLoadNotification];
|
||||||
|
RCTBridge *bridge = notification.userInfo[@"bridge"];
|
||||||
|
|
||||||
|
if (!bridge) {
|
||||||
|
NSLog(@"No RCTBridge provided by RCTJavaScriptDidLoadNotification");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_currentJavaScriptExecutor = [bridge valueForKey:@"javaScriptExecutor"];
|
||||||
|
|
||||||
|
// FIXME: Remove this nonsense once the crashes go away when a test fails!
|
||||||
|
JSGlobalContextRef ctx = RealmReactGetJSGlobalContextForExecutor(s_currentJavaScriptExecutor);
|
||||||
|
if (ctx) {
|
||||||
|
JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(ctx, false);
|
||||||
|
}
|
||||||
|
|
||||||
NSError *error;
|
NSError *error;
|
||||||
NSDictionary *testCaseNames = [self invokeMethod:@"getTestNames" inModule:@"index" error:&error];
|
NSDictionary *testCaseNames = [self invokeMethod:@"getTestNames" inModule:@"index" error:&error];
|
||||||
@ -47,34 +65,34 @@
|
|||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)waitForNotification:(NSString *)notificationName {
|
+ (NSNotification *)waitForNotification:(NSString *)notificationName {
|
||||||
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
||||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||||
__block BOOL received = NO;
|
__block NSNotification *notification;
|
||||||
|
|
||||||
id token = [nc addObserverForName:notificationName object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
id token = [nc addObserverForName:notificationName object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||||
received = YES;
|
notification = note;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
while (!received) {
|
while (!notification) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[nc removeObserver:token];
|
[nc removeObserver:token];
|
||||||
|
return notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)invokeMethod:(NSString *)method inModule:(NSString *)module error:(NSError * __strong *)outError {
|
+ (id)invokeMethod:(NSString *)method inModule:(NSString *)module error:(NSError * __strong *)outError {
|
||||||
module = [NSString stringWithFormat:@"realm-tests/%@.js", module];
|
module = [NSString stringWithFormat:@"realm-tests/%@.js", module];
|
||||||
|
|
||||||
id<RCTJavaScriptExecutor> executor = [RealmReact executor];
|
|
||||||
dispatch_group_t group = dispatch_group_create();
|
dispatch_group_t group = dispatch_group_create();
|
||||||
__block id result;
|
__block id result;
|
||||||
|
|
||||||
dispatch_group_enter(group);
|
dispatch_group_enter(group);
|
||||||
|
|
||||||
[executor executeJSCall:module method:method arguments:@[] callback:^(id json, NSError *error) {
|
[s_currentJavaScriptExecutor executeJSCall:module method:method arguments:@[] callback:^(id json, NSError *error) {
|
||||||
result = json;
|
result = json;
|
||||||
|
|
||||||
if (error && outError) {
|
if (error && outError) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user