diff --git a/ReactNative/RealmReact.h b/ReactNative/RealmReact.h index fa334b79..91874a16 100644 --- a/ReactNative/RealmReact.h +++ b/ReactNative/RealmReact.h @@ -19,4 +19,9 @@ @import Foundation; @interface RealmReact : NSObject + +@property (nonatomic) id executor; + ++ (id)executor; + @end diff --git a/ReactNative/RealmReact.m b/ReactNative/RealmReact.m index 57992ea8..3a9a2b01 100644 --- a/ReactNative/RealmReact.m +++ b/ReactNative/RealmReact.m @@ -33,8 +33,11 @@ @interface RealmReact () @end +static id s_executor; + @implementation RealmReact +@dynamic executor; @synthesize bridge = _bridge; + (void)load { @@ -52,12 +55,16 @@ return @"Realm"; } ++ (id)executor { + return s_executor; +} + - (void)setBridge:(RCTBridge *)bridge { _bridge = bridge; Ivar executorIvar = class_getInstanceVariable([bridge class], "_javaScriptExecutor"); - id contextExecutor = object_getIvar(bridge, executorIvar); - Ivar contextIvar = class_getInstanceVariable([contextExecutor class], "_context"); + s_executor = object_getIvar(bridge, executorIvar); + Ivar contextIvar = class_getInstanceVariable([s_executor class], "_context"); // The executor could be a RCTWebSocketExecutor, in which case it won't have a JS context. if (!contextIvar) { @@ -86,8 +93,8 @@ return; } - [contextExecutor executeBlockOnJavaScriptQueue:^{ - id rctJSContext = object_getIvar(contextExecutor, contextIvar); + [s_executor executeBlockOnJavaScriptQueue:^{ + id rctJSContext = object_getIvar(s_executor, contextIvar); JSGlobalContextRef ctx; if (rctJSContext) { @@ -98,7 +105,7 @@ if (RCTJavaScriptContext) { ctx = JSGlobalContextCreate(NULL); - object_setIvar(contextExecutor, contextIvar, [[RCTJavaScriptContext alloc] initWithJSContext:ctx]); + object_setIvar(s_executor, contextIvar, [[RCTJavaScriptContext alloc] initWithJSContext:ctx]); } else { NSLog(@"Failed to load RCTJavaScriptContext class"); diff --git a/RealmJS.xcodeproj/xcshareddata/xcschemes/RealmReact.xcscheme b/RealmJS.xcodeproj/xcshareddata/xcschemes/RealmReact.xcscheme index 2699e2b9..0ba909fd 100644 --- a/RealmJS.xcodeproj/xcshareddata/xcschemes/RealmReact.xcscheme +++ b/RealmJS.xcodeproj/xcshareddata/xcschemes/RealmReact.xcscheme @@ -28,7 +28,31 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + + + + + diff --git a/src/RealmJS.h b/src/RealmJS.h index ecee3d7d..54e1476e 100644 --- a/src/RealmJS.h +++ b/src/RealmJS.h @@ -25,4 +25,6 @@ // add realm apis to the given js context + (void)initializeContext:(JSContextRef)ctx; ++ (void)cleanupTestRealms; + @end diff --git a/src/RealmJS.mm b/src/RealmJS.mm index fe89b02a..6bbf9366 100644 --- a/src/RealmJS.mm +++ b/src/RealmJS.mm @@ -21,6 +21,8 @@ #import "RJSObject.hpp" #import "RJSUtil.hpp" +#include "shared_realm.hpp" + JSValueRef RJSTypeGet(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) { return RJSValueForString(ctx, RJSTypeGet(RJSStringForJSString(propertyName))); } @@ -44,6 +46,34 @@ JSClassRef RJSRealmTypeClass() { return JSClassCreate(&realmTypesDefinition); } + +NSString *RealmPathForFile(NSString *fileName) { +#if TARGET_OS_IPHONE + NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; +#else + NSString *path = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0]; + path = [path stringByAppendingPathComponent:[[[NSBundle mainBundle] executablePath] lastPathComponent]]; +#endif + return [path stringByAppendingPathComponent:fileName]; +} + +static void DeleteOrThrow(NSString *path) { + NSError *error; + if (![[NSFileManager defaultManager] removeItemAtPath:path error:&error]) { + if (error.code != NSFileNoSuchFileError) { + @throw [NSException exceptionWithName:@"RLMTestException" + reason:[@"Unable to delete realm: " stringByAppendingString:error.description] + userInfo:nil]; + } + } +} + +static void DeleteRealmFilesAtPath(NSString *path) { + DeleteOrThrow(path); + DeleteOrThrow([path stringByAppendingString:@".lock"]); + DeleteOrThrow([path stringByAppendingString:@".note"]); +} + @implementation RealmJS + (void)initializeContext:(JSContextRef)ctx { @@ -56,7 +86,23 @@ JSClassRef RJSRealmTypeClass() { JSObjectSetProperty(ctx, globalRealmObject, typeString, typesObject, kJSPropertyAttributeNone, &exception); JSStringRelease(typeString); + [JSContext contextWithJSGlobalContextRef:JSContextGetGlobalContext(ctx)][@"cleanupTestRealms"] = ^{ + [RealmJS cleanupTestRealms]; + }; + assert(!exception); } ++ (void)cleanupTestRealms { + realm::Realm::s_global_cache.invalidate_all(); + realm::Realm::s_global_cache.clear(); + + // FIXME - find all realm files in the docs dir and delete them rather than hardcoding these + + DeleteRealmFilesAtPath(RealmPathForFile(@"test.realm")); + DeleteRealmFilesAtPath(RealmPathForFile(@"test1.realm")); + DeleteRealmFilesAtPath(RealmPathForFile(@"test2.realm")); + DeleteRealmFilesAtPath(@(RJSDefaultPath().c_str())); +} + @end diff --git a/tests/ReactTests/index.ios.js b/tests/ReactTests/index.ios.js index f24797f5..1396ab32 100644 --- a/tests/ReactTests/index.ios.js +++ b/tests/ReactTests/index.ios.js @@ -21,6 +21,10 @@ function runTests() { for (let suiteName in RealmTests) { let testSuite = RealmTests[suiteName]; + if (typeof testSuite != 'object') { + continue; + } + console.log('Starting suite:', suiteName); for (let testName in testSuite) { diff --git a/tests/ReactTests/ios/ReactTests.xcodeproj/project.pbxproj b/tests/ReactTests/ios/ReactTests.xcodeproj/project.pbxproj index 4df22ab0..7cb351fc 100644 --- a/tests/ReactTests/ios/ReactTests.xcodeproj/project.pbxproj +++ b/tests/ReactTests/ios/ReactTests.xcodeproj/project.pbxproj @@ -13,7 +13,18 @@ 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; - 00E356F31AD99517003FC87E /* ReactTestsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ReactTestsTests.m */; }; + 00E356F31AD99517003FC87E /* RealmReactTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RealmReactTests.m */; }; + 02409E1E1BCF1F2E005F3B3E /* RealmJSTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 02409E1B1BCF1F2E005F3B3E /* RealmJSTests.mm */; settings = {ASSET_TAGS = (); }; }; + 02409E1F1BCF1F2E005F3B3E /* RJSModuleLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 02409E1D1BCF1F2E005F3B3E /* RJSModuleLoader.m */; settings = {ASSET_TAGS = (); }; }; + 02409E291BCF1F45005F3B3E /* ArrayTests.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E201BCF1F45005F3B3E /* ArrayTests.js */; }; + 02409E2A1BCF1F45005F3B3E /* asserts.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E211BCF1F45005F3B3E /* asserts.js */; }; + 02409E2B1BCF1F45005F3B3E /* base-test.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E221BCF1F45005F3B3E /* base-test.js */; }; + 02409E2C1BCF1F45005F3B3E /* index.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E231BCF1F45005F3B3E /* index.js */; }; + 02409E2D1BCF1F45005F3B3E /* ObjectTests.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E241BCF1F45005F3B3E /* ObjectTests.js */; }; + 02409E2E1BCF1F45005F3B3E /* RealmTests.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E251BCF1F45005F3B3E /* RealmTests.js */; }; + 02409E2F1BCF1F45005F3B3E /* ResultsTests.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E261BCF1F45005F3B3E /* ResultsTests.js */; }; + 02409E301BCF1F45005F3B3E /* schemas.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E271BCF1F45005F3B3E /* schemas.js */; }; + 02409E311BCF1F45005F3B3E /* util.js in Resources */ = {isa = PBXBuildFile; fileRef = 02409E281BCF1F45005F3B3E /* util.js */; }; 0277991C1BBF3BC600C96559 /* RealmReact.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0277991B1BBF3BB700C96559 /* RealmReact.framework */; }; 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; @@ -156,9 +167,22 @@ 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; - 00E356EE1AD99517003FC87E /* ReactTestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactTestsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 00E356EE1AD99517003FC87E /* RealmReactTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RealmReactTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 00E356F21AD99517003FC87E /* ReactTestsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactTestsTests.m; sourceTree = ""; }; + 00E356F21AD99517003FC87E /* RealmReactTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RealmReactTests.m; sourceTree = ""; }; + 02409E1A1BCF1F2E005F3B3E /* RealmJSTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmJSTests.h; path = ../../../RealmJSTests.h; sourceTree = ""; }; + 02409E1B1BCF1F2E005F3B3E /* RealmJSTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmJSTests.mm; path = ../../../RealmJSTests.mm; sourceTree = ""; }; + 02409E1C1BCF1F2E005F3B3E /* RJSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RJSModuleLoader.h; path = ../../../RJSModuleLoader.h; sourceTree = ""; }; + 02409E1D1BCF1F2E005F3B3E /* RJSModuleLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RJSModuleLoader.m; path = ../../../RJSModuleLoader.m; sourceTree = ""; }; + 02409E201BCF1F45005F3B3E /* ArrayTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ArrayTests.js; path = ../../ArrayTests.js; sourceTree = ""; }; + 02409E211BCF1F45005F3B3E /* asserts.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = asserts.js; path = ../../asserts.js; sourceTree = ""; }; + 02409E221BCF1F45005F3B3E /* base-test.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = "base-test.js"; path = "../../base-test.js"; sourceTree = ""; }; + 02409E231BCF1F45005F3B3E /* index.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = index.js; path = ../../index.js; sourceTree = ""; }; + 02409E241BCF1F45005F3B3E /* ObjectTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ObjectTests.js; path = ../../ObjectTests.js; sourceTree = ""; }; + 02409E251BCF1F45005F3B3E /* RealmTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = RealmTests.js; path = ../../RealmTests.js; sourceTree = ""; }; + 02409E261BCF1F45005F3B3E /* ResultsTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ResultsTests.js; path = ../../ResultsTests.js; sourceTree = ""; }; + 02409E271BCF1F45005F3B3E /* schemas.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = schemas.js; path = ../../schemas.js; sourceTree = ""; }; + 02409E281BCF1F45005F3B3E /* util.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = util.js; path = ../../util.js; sourceTree = ""; }; 027799061BBF3BB700C96559 /* RealmJS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RealmJS.xcodeproj; path = ../../../RealmJS.xcodeproj; sourceTree = ""; }; 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; @@ -243,12 +267,17 @@ name = Products; sourceTree = ""; }; - 00E356EF1AD99517003FC87E /* ReactTestsTests */ = { + 00E356EF1AD99517003FC87E /* RealmReactTests */ = { isa = PBXGroup; children = ( - 00E356F21AD99517003FC87E /* ReactTestsTests.m */, + 00E356F21AD99517003FC87E /* RealmReactTests.m */, + 02409E1A1BCF1F2E005F3B3E /* RealmJSTests.h */, + 02409E1B1BCF1F2E005F3B3E /* RealmJSTests.mm */, + 02409E1C1BCF1F2E005F3B3E /* RJSModuleLoader.h */, + 02409E1D1BCF1F2E005F3B3E /* RJSModuleLoader.m */, 00E356F01AD99517003FC87E /* Supporting Files */, ); + name = RealmReactTests; path = ReactTestsTests; sourceTree = ""; }; @@ -345,9 +374,18 @@ 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( + 02409E201BCF1F45005F3B3E /* ArrayTests.js */, + 02409E211BCF1F45005F3B3E /* asserts.js */, + 02409E221BCF1F45005F3B3E /* base-test.js */, + 02409E231BCF1F45005F3B3E /* index.js */, + 02409E241BCF1F45005F3B3E /* ObjectTests.js */, + 02409E251BCF1F45005F3B3E /* RealmTests.js */, + 02409E261BCF1F45005F3B3E /* ResultsTests.js */, + 02409E271BCF1F45005F3B3E /* schemas.js */, + 02409E281BCF1F45005F3B3E /* util.js */, 13B07FAE1A68108700A75B9A /* ReactTests */, 832341AE1AAA6A7D00B99B32 /* Libraries */, - 00E356EF1AD99517003FC87E /* ReactTestsTests */, + 00E356EF1AD99517003FC87E /* RealmReactTests */, 83CBBA001A601CBA00E9B192 /* Products */, ); indentWidth = 2; @@ -358,7 +396,7 @@ isa = PBXGroup; children = ( 13B07F961A680F5B00A75B9A /* ReactTests.app */, - 00E356EE1AD99517003FC87E /* ReactTestsTests.xctest */, + 00E356EE1AD99517003FC87E /* RealmReactTests.xctest */, ); name = Products; sourceTree = ""; @@ -366,9 +404,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 00E356ED1AD99517003FC87E /* ReactTestsTests */ = { + 00E356ED1AD99517003FC87E /* RealmReactTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactTestsTests" */; + buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RealmReactTests" */; buildPhases = ( 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, @@ -379,9 +417,9 @@ dependencies = ( 00E356F51AD99517003FC87E /* PBXTargetDependency */, ); - name = ReactTestsTests; + name = RealmReactTests; productName = ReactTestsTests; - productReference = 00E356EE1AD99517003FC87E /* ReactTestsTests.xctest */; + productReference = 00E356EE1AD99517003FC87E /* RealmReactTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 13B07F861A680F5B00A75B9A /* ReactTests */ = { @@ -479,7 +517,7 @@ projectRoot = ""; targets = ( 13B07F861A680F5B00A75B9A /* ReactTests */, - 00E356ED1AD99517003FC87E /* ReactTestsTests */, + 00E356ED1AD99517003FC87E /* RealmReactTests */, ); }; /* End PBXProject section */ @@ -583,6 +621,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 02409E291BCF1F45005F3B3E /* ArrayTests.js in Resources */, + 02409E2A1BCF1F45005F3B3E /* asserts.js in Resources */, + 02409E2B1BCF1F45005F3B3E /* base-test.js in Resources */, + 02409E2C1BCF1F45005F3B3E /* index.js in Resources */, + 02409E2D1BCF1F45005F3B3E /* ObjectTests.js in Resources */, + 02409E2E1BCF1F45005F3B3E /* RealmTests.js in Resources */, + 02409E2F1BCF1F45005F3B3E /* ResultsTests.js in Resources */, + 02409E301BCF1F45005F3B3E /* schemas.js in Resources */, + 02409E311BCF1F45005F3B3E /* util.js in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -619,7 +666,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 00E356F31AD99517003FC87E /* ReactTestsTests.m in Sources */, + 02409E1F1BCF1F2E005F3B3E /* RJSModuleLoader.m in Sources */, + 02409E1E1BCF1F2E005F3B3E /* RealmJSTests.mm in Sources */, + 00E356F31AD99517003FC87E /* RealmReactTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -818,7 +867,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactTestsTests" */ = { + 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RealmReactTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 00E356F61AD99517003FC87E /* Debug */, diff --git a/tests/ReactTests/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTests.xcscheme b/tests/ReactTests/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTests.xcscheme index a0d2883b..74ba8c85 100644 --- a/tests/ReactTests/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTests.xcscheme +++ b/tests/ReactTests/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTests.xcscheme @@ -29,26 +29,26 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -62,15 +62,18 @@ ReferencedContainer = "container:ReactTests.xcodeproj"> + + @@ -86,10 +89,10 @@ diff --git a/tests/ReactTests/ios/ReactTestsTests/ReactTestsTests.m b/tests/ReactTests/ios/ReactTestsTests/ReactTestsTests.m deleted file mode 100644 index c9770887..00000000 --- a/tests/ReactTests/ios/ReactTestsTests/ReactTestsTests.m +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import -#import - -#import "RCTLog.h" -#import "RCTRootView.h" - -#define TIMEOUT_SECONDS 240 -#define TEXT_TO_LOOK_FOR @"Welcome to React Native!" - -@interface ReactTestsTests : XCTestCase - -@end - -@implementation ReactTestsTests - -- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test -{ - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; - } - } - return NO; -} - -- (void)testRendersWelcomeScreen -{ - UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; - - __block NSString *redboxError = nil; - RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) { - if (level >= RCTLogLevelError) { - redboxError = message; - } - }); - - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - - foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } - - RCTSetLogFunction(RCTDefaultLogFunction); - - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); -} - - -@end diff --git a/tests/ReactTests/ios/ReactTestsTests/RealmReactTests.m b/tests/ReactTests/ios/ReactTestsTests/RealmReactTests.m new file mode 100644 index 00000000..01899f69 --- /dev/null +++ b/tests/ReactTests/ios/ReactTestsTests/RealmReactTests.m @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "RealmJSTests.h" +#import "../../node_modules/react-native/React/Base/RCTJavaScriptExecutor.h" +#import "../../node_modules/react-native/React/Base/RCTBridge.h" + +@import RealmReact; + +@interface RealmReactTests : RealmJSTests +@end + + +@implementation RealmReactTests + ++ (NSURL *)scriptURL { + return [[NSBundle bundleForClass:self] URLForResource:@"index" withExtension:@"js"]; +} + +- (void)invokeMethod:(NSString *)method { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [self expectationForNotification:RCTJavaScriptDidLoadNotification object:nil handler:^BOOL(NSNotification * _Nonnull notification) { + return YES; + }]; + [self waitForExpectationsWithTimeout:10000000 handler:^(NSError * _Nullable error) { + }]; + }); + + dispatch_group_t group = dispatch_group_create(); + dispatch_group_enter(group); + + id executor = [RealmReact executor]; + [executor executeBlockOnJavaScriptQueue:^{ + [executor executeJSCall:@"realm-tests" method:@"executeTest" arguments:@[NSStringFromClass(self.class), method] callback:^(id json, NSError *error) { + XCTAssertNil(error, @"%@", [error description]); + dispatch_group_leave(group); + }]; + dispatch_group_wait(group, DISPATCH_TIME_FOREVER); + }]; +} + +@end diff --git a/tests/RealmJSTests.mm b/tests/RealmJSTests.mm index f075bdd3..dfaeec09 100644 --- a/tests/RealmJSTests.mm +++ b/tests/RealmJSTests.mm @@ -19,44 +19,8 @@ #import #import "RealmJSTests.h" -#import "RJSUtil.hpp" -#import "RJSRealm.hpp" #import "RJSModuleLoader.h" -#import "shared_realm.hpp" - -NSString *RealmPathForFile(NSString *fileName) { -#if TARGET_OS_IPHONE - NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; -#else - NSString *path = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0]; - path = [path stringByAppendingPathComponent:[[[NSBundle mainBundle] executablePath] lastPathComponent]]; -#endif - return [path stringByAppendingPathComponent:fileName]; -} - - -NSString *TestRealmPath() { - return RealmPathForFile(@"test.realm"); -} - -static void DeleteOrThrow(NSString *path) { - NSError *error; - if (![[NSFileManager defaultManager] removeItemAtPath:path error:&error]) { - if (error.code != NSFileNoSuchFileError) { - @throw [NSException exceptionWithName:@"RLMTestException" - reason:[@"Unable to delete realm: " stringByAppendingString:error.description] - userInfo:nil]; - } - } -} - -static void DeleteRealmFilesAtPath(NSString *path) { - DeleteOrThrow(path); - DeleteOrThrow([path stringByAppendingString:@".lock"]); - DeleteOrThrow([path stringByAppendingString:@".note"]); -} - @interface RealmJSTests () @property (nonatomic, strong) JSValue *testObject; @@ -83,9 +47,6 @@ static void DeleteRealmFilesAtPath(NSString *path) { - (void)setUp { [super setUp]; - NSString *defaultDir = [[NSString stringWithUTF8String:RJSDefaultPath().c_str()] stringByDeletingLastPathComponent]; - [[NSFileManager defaultManager] createDirectoryAtPath:defaultDir withIntermediateDirectories:YES attributes:nil error:nil]; - [self invokeMethod:@"beforeEach"]; } @@ -110,10 +71,6 @@ static void DeleteRealmFilesAtPath(NSString *path) { JSContext *context = [[JSContext alloc] init]; RJSModuleLoader *moduleLoader = [[RJSModuleLoader alloc] initWithContext:context]; - context[@"cleanupTestRealms"] = ^{ - [self cleanupTestRealms]; - }; - [RealmJS initializeContext:context.JSGlobalContextRef]; // Expose the global Realm object as a global 'realm' CommonJS module. @@ -158,17 +115,6 @@ static void DeleteRealmFilesAtPath(NSString *path) { return suite; } -+ (void)cleanupTestRealms { - realm::Realm::s_global_cache.invalidate_all(); - realm::Realm::s_global_cache.clear(); - - // FIXME - find all realm files in the docs dir and delete them rather than hardcoding these - DeleteRealmFilesAtPath(RealmPathForFile(@"test.realm")); - DeleteRealmFilesAtPath(RealmPathForFile(@"test1.realm")); - DeleteRealmFilesAtPath(RealmPathForFile(@"test2.realm")); - DeleteRealmFilesAtPath(@(RJSDefaultPath().c_str())); -} - - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { NSMethodSignature *sig = [super methodSignatureForSelector:aSelector]; return sig ?: [NSMethodSignature signatureWithObjCTypes:"v@:"]; diff --git a/tests/index.js b/tests/index.js index 0888ad6b..9ea35ae3 100644 --- a/tests/index.js +++ b/tests/index.js @@ -22,3 +22,8 @@ exports.ArrayTests = require('./ArrayTests'); exports.ObjectTests = require('./ObjectTests'); exports.RealmTests = require('./RealmTests'); exports.ResultsTests = require('./ResultsTests'); + +exports.executeTest = function(suiteName, testName) { + var suite = exports[suiteName]; + suite[textName](); +};