Make Xcode tests run in React environment

The deleteTestFiles() function is now added to the Realm object, so that it's easy for the RPC module to handle this as well. We can only do this in testing environments in the future.
This commit is contained in:
Scott Kyle 2015-10-15 03:12:28 -07:00
parent 18f97b6ec1
commit 7a79ac8803
18 changed files with 69 additions and 66 deletions

View File

@ -20,7 +20,7 @@
@interface RealmReact : NSObject
@property (nonatomic) id executor;
@property (nonatomic, readonly) id executor;
+ (id)executor;

View File

@ -37,7 +37,6 @@ static id s_executor;
@implementation RealmReact
@dynamic executor;
@synthesize bridge = _bridge;
+ (void)load {

View File

@ -83,4 +83,10 @@ class Realm {
Object.defineProperty(Realm, 'Types', {value: types});
Object.defineProperty(Realm, 'deleteTestFiles', {
value: function() {
rpc.deleteTestFiles();
}
});
module.exports = Realm;

View File

@ -37,6 +37,8 @@ exports.beginTransaction = beginTransaction;
exports.cancelTransaction = cancelTransaction;
exports.commitTransaction = commitTransaction;
exports.deleteTestFiles = deleteTestFiles;
function registerTypeConverter(type, handler) {
typeConverters[type] = handler;
}
@ -111,6 +113,10 @@ function commitTransaction(realmId) {
sendRequest('commit_transaction', {realmId});
}
function deleteTestFiles() {
sendRequest('delete_test_files');
}
function serialize(realmId, value) {
if (!value || typeof value != 'object') {
return {value: value};
@ -153,7 +159,7 @@ function deserialize(realmId, info) {
}
function sendRequest(command, data) {
let body = JSON.stringify(data);
let body = JSON.stringify(data || {});
let request = new XMLHttpRequest();
let url = 'http://' + DEVICE_HOST + '/' + command;

View File

@ -20,10 +20,11 @@
using namespace realm;
JSObjectRef RJSRegisterGlobalClass(JSContextRef ctx, JSObjectRef globalObject, JSClassRef classRef, const char * name, JSValueRef *exception) {
JSObjectRef RJSRegisterGlobalClass(JSContextRef ctx, JSObjectRef globalObject, JSClassRef classRef, const char *name, JSValueRef *exception) {
JSObjectRef classObject = JSObjectMake(ctx, classRef, NULL);
JSStringRef nameString = JSStringCreateWithUTF8CString(name);
JSObjectSetProperty(ctx, globalObject, nameString, classObject, kJSPropertyAttributeNone, exception);
JSPropertyAttributes attributes = kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete;
JSObjectSetProperty(ctx, globalObject, nameString, classObject, attributes, exception);
JSStringRelease(nameString);
return classObject;
}

View File

@ -25,6 +25,6 @@
// add realm apis to the given js context
+ (void)initializeContext:(JSContextRef)ctx;
+ (void)cleanupTestRealms;
+ (void)deleteTestFiles;
@end

View File

@ -46,7 +46,6 @@ JSClassRef RJSRealmTypeClass() {
return JSClassCreate(&realmTypesDefinition);
}
NSString *RealmPathForFile(NSString *fileName) {
#if TARGET_OS_IPHONE
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
@ -74,6 +73,11 @@ static void DeleteRealmFilesAtPath(NSString *path) {
DeleteOrThrow([path stringByAppendingString:@".note"]);
}
static JSValueRef DeleteTestFiles(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) {
[RealmJS deleteTestFiles];
return NULL;
}
@implementation RealmJS
+ (void)initializeContext:(JSContextRef)ctx {
@ -83,17 +87,19 @@ static void DeleteRealmFilesAtPath(NSString *path) {
JSObjectRef globalRealmObject = RJSRegisterGlobalClass(ctx, globalObject, RJSRealmConstructorClass(), "Realm", &exception);
JSObjectRef typesObject = JSObjectMake(ctx, RJSRealmTypeClass(), NULL);
JSStringRef typeString = JSStringCreateWithUTF8CString("Types");
JSObjectSetProperty(ctx, globalRealmObject, typeString, typesObject, kJSPropertyAttributeNone, &exception);
JSPropertyAttributes attributes = kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete;
JSObjectSetProperty(ctx, globalRealmObject, typeString, typesObject, attributes, &exception);
JSStringRelease(typeString);
[JSContext contextWithJSGlobalContextRef:JSContextGetGlobalContext(ctx)][@"cleanupTestRealms"] = ^{
[RealmJS cleanupTestRealms];
};
JSStringRef deleteTestFilesString = JSStringCreateWithUTF8CString("deleteTestFiles");
JSObjectRef deleteTestFilesFunction = JSObjectMakeFunctionWithCallback(ctx, deleteTestFilesString, DeleteTestFiles);
JSObjectSetProperty(ctx, globalRealmObject, deleteTestFilesString, deleteTestFilesFunction, attributes, &exception);
JSStringRelease(deleteTestFilesString);
assert(!exception);
}
+ (void)cleanupTestRealms {
+ (void)deleteTestFiles {
realm::Realm::s_global_cache.invalidate_all();
realm::Realm::s_global_cache.clear();

View File

@ -179,6 +179,10 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
args:dict[@"arguments"]
objectId:[dict[@"listId"] unsignedLongValue]];
};
_requests["/delete_test_files"] = [=](NSDictionary *dict) {
[RealmJS deleteTestFiles];
return nil;
};
}
return self;
}

View File

@ -21,10 +21,6 @@ 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) {
@ -32,7 +28,6 @@ function runTests() {
continue;
}
if (testSuite.beforeEach) {
testSuite.beforeEach();
}

View File

@ -448,7 +448,7 @@
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
00E356ED1AD99517003FC87E = {
@ -724,6 +724,7 @@
INFOPLIST_FILE = ReactTestsTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactTests.app/ReactTests";
};
@ -741,6 +742,7 @@
INFOPLIST_FILE = ReactTestsTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactTests.app/ReactTests";
};
@ -750,14 +752,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
);
INFOPLIST_FILE = ReactTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = ReactTests;
};
name = Debug;
@ -766,14 +764,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
);
INFOPLIST_FILE = ReactTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = ReactTests;
};
name = Release;
@ -798,6 +792,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0620"
LastUpgradeVersion = "0700"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@ -22,6 +22,13 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
@ -36,13 +43,5 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSAppTransportSecurity</key>
<dict>
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>

View File

@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>

View File

@ -8,8 +8,8 @@
*/
#import "RealmJSTests.h"
#import "../../node_modules/react-native/React/Base/RCTJavaScriptExecutor.h"
#import "../../node_modules/react-native/React/Base/RCTBridge.h"
#import "Base/RCTJavaScriptExecutor.h"
#import "Base/RCTBridge.h"
@import RealmReact;
@ -26,24 +26,24 @@
- (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) {
[self expectationForNotification:RCTJavaScriptDidLoadNotification object:nil handler:^(NSNotification *notification) {
return YES;
}];
[self waitForExpectationsWithTimeout:10000000 handler:NULL];
});
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
id<RCTJavaScriptExecutor> 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);
NSString *module = [NSString stringWithFormat:@"realm-tests/%@.js", NSStringFromClass(self.class)];
[executor executeJSCall:module method:method arguments:@[] callback:^(id json, NSError *error) {
XCTAssertNil(error, @"%@", [error description]);
dispatch_group_leave(group);
}];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}
@end

View File

@ -19,9 +19,6 @@
#import <XCTest/XCTest.h>
#import <RealmJS/RealmJS.h>
extern NSString *RealmPathForFile(NSString *fileName);
extern NSString *TestRealmPath();
@interface RealmJSTests : XCTestCase
@end

View File

@ -18,7 +18,7 @@
'use strict';
var util = require('./util');
var Realm = require('realm');
var prototype = exports.prototype = {};
@ -28,9 +28,14 @@ exports.extend = function(object) {
};
Object.defineProperties(prototype, {
// TODO: Remove once missing undefined check is fixed inside RCTContextExecutor.
beforeEach: {
value: function() {}
},
afterEach: {
value: function() {
util.cleanupTestRealms();
Realm.deleteTestFiles();
}
}
});

View File

@ -23,7 +23,3 @@ exports.ObjectTests = require('./ObjectTests');
exports.RealmTests = require('./RealmTests');
exports.ResultsTests = require('./ResultsTests');
exports.executeTest = function(suiteName, testName) {
var suite = exports[suiteName];
suite[textName]();
};

View File

@ -20,13 +20,7 @@
var Realm = require('realm');
var global = (typeof global != 'undefined') ? global : this;
exports.realmPathForFile = function(str) {
var path = Realm.defaultPath;
return path.substring(0, path.lastIndexOf("/") + 1) + str;
};
exports.cleanupTestRealms = function() {
global.cleanupTestRealms();
};