Remove dependency on JavaScriptCore for RealmReactTests
The test structure is now provided by a JS API, that is used by all things that run tests. Also, the tests can be run manually by tapping a button in the ReactTests app.
This commit is contained in:
parent
7a79ac8803
commit
7f5902b021
|
@ -144,7 +144,6 @@
|
|||
/* Begin PBXFileReference section */
|
||||
02258FB11BC6E2D00075F13A /* RealmRPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmRPC.h; path = src/RealmRPC.h; sourceTree = "<group>"; };
|
||||
02258FB21BC6E2D00075F13A /* RealmRPC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmRPC.mm; path = src/RealmRPC.mm; sourceTree = "<group>"; };
|
||||
02409DC01BCF11D6005F3B3E /* RealmJSCoreTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmJSCoreTests.h; path = src/RealmJSCoreTests.h; sourceTree = SOURCE_ROOT; };
|
||||
02409DC11BCF11D6005F3B3E /* RealmJSCoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RealmJSCoreTests.m; path = src/RealmJSCoreTests.m; sourceTree = SOURCE_ROOT; };
|
||||
02601F011BA0F0C4007C91FF /* external_commit_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = external_commit_helper.cpp; path = "src/object-store/apple/external_commit_helper.cpp"; sourceTree = "<group>"; };
|
||||
02601F021BA0F0C4007C91FF /* external_commit_helper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = external_commit_helper.hpp; path = "src/object-store/apple/external_commit_helper.hpp"; sourceTree = "<group>"; };
|
||||
|
@ -339,7 +338,6 @@
|
|||
0270BC7D1B7D020100010E03 /* ResultsTests.js */,
|
||||
0270BC7A1B7D020100010E03 /* RealmJSTests.h */,
|
||||
0270BC7B1B7D020100010E03 /* RealmJSTests.mm */,
|
||||
02409DC01BCF11D6005F3B3E /* RealmJSCoreTests.h */,
|
||||
02409DC11BCF11D6005F3B3E /* RealmJSCoreTests.m */,
|
||||
F68A278A1BC2722A0063D40A /* RJSModuleLoader.h */,
|
||||
F68A278B1BC2722A0063D40A /* RJSModuleLoader.m */,
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "RealmJSTests.h"
|
||||
|
||||
@interface RealmJSCoreTests : RealmJSTests
|
||||
|
||||
@end
|
|
@ -17,12 +17,82 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#import "RealmJSCoreTests.h"
|
||||
#import "RealmJSTests.h"
|
||||
#import "RJSModuleLoader.h"
|
||||
|
||||
@interface RealmJSCoreTests : RealmJSTests
|
||||
|
||||
@property (nonatomic, strong) JSValue *testObject;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RealmJSCoreTests
|
||||
|
||||
+ (NSURL *)scriptURL {
|
||||
return [[NSBundle bundleForClass:self] URLForResource:@"index" withExtension:@"js"];
|
||||
+ (XCTestSuite *)defaultTestSuite {
|
||||
XCTestSuite *suite = [super defaultTestSuite];
|
||||
JSContext *context = [[JSContext alloc] init];
|
||||
RJSModuleLoader *moduleLoader = [[RJSModuleLoader alloc] initWithContext:context];
|
||||
NSURL *scriptURL = [[NSBundle bundleForClass:self] URLForResource:@"index" withExtension:@"js"];
|
||||
|
||||
[RealmJS initializeContext:context.JSGlobalContextRef];
|
||||
|
||||
// Expose the global Realm object as a global 'realm' CommonJS module.
|
||||
[moduleLoader addGlobalModuleObject:context[@"Realm"] forName:@"realm"];
|
||||
|
||||
NSError *error;
|
||||
JSValue *testObjects = [moduleLoader loadModuleFromURL:scriptURL error:&error];
|
||||
|
||||
if (!testObjects) {
|
||||
NSLog(@"%@", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
NSDictionary *testCaseNames = [[testObjects invokeMethod:@"getTestNames" withArguments:nil] toDictionary];
|
||||
|
||||
if (!testCaseNames.count) {
|
||||
NSLog(@"No test case names from getTestNames() JS method!");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (XCTestSuite *testSuite in [self testSuitesFromDictionary:testCaseNames]) {
|
||||
for (RealmJSCoreTests *test in testSuite.tests) {
|
||||
test.testObject = testObjects[testSuite.name];
|
||||
}
|
||||
|
||||
[suite addTest:testSuite];
|
||||
}
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
- (JSContext *)context {
|
||||
return self.testObject.context;
|
||||
}
|
||||
|
||||
- (void)invokeMethod:(NSString *)method {
|
||||
JSValue *testObject = self.testObject;
|
||||
|
||||
if (![testObject hasProperty:method]) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSContext *context = testObject.context;
|
||||
context.exception = nil;
|
||||
|
||||
[testObject invokeMethod:method withArguments:nil];
|
||||
|
||||
JSValue *exception = context.exception;
|
||||
if (exception) {
|
||||
JSValue *message = [exception hasProperty:@"message"] ? exception[@"message"] : exception;
|
||||
NSString *source = [exception hasProperty:@"sourceURL"] ? [exception[@"sourceURL"] toString] : nil;
|
||||
NSUInteger line = [exception hasProperty:@"line"] ? [exception[@"line"] toUInt32] - 1 : 0;
|
||||
NSURL *sourceURL = source ? [NSURL URLWithString:source.lastPathComponent relativeToURL:[NSURL URLWithString:@(__FILE__)]] : nil;
|
||||
|
||||
[self recordFailureWithDescription:message.description
|
||||
inFile:sourceURL ? sourceURL.absoluteString : @(__FILE__)
|
||||
atLine:sourceURL ? line : __LINE__
|
||||
expected:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -9,25 +9,22 @@ var Realm = require('realm');
|
|||
var RealmTests = require('realm-tests');
|
||||
|
||||
var {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
function runTests() {
|
||||
let specialMethodNames = {'beforeEach': true, 'afterEach': true};
|
||||
let testNames = RealmTests.getTestNames();
|
||||
|
||||
for (let suiteName in RealmTests) {
|
||||
for (let suiteName in testNames) {
|
||||
let testSuite = RealmTests[suiteName];
|
||||
|
||||
console.log('Starting suite:', suiteName);
|
||||
|
||||
for (let testName in testSuite) {
|
||||
if (testName in specialMethodNames || typeof testSuite[testName] != 'function') {
|
||||
continue;
|
||||
}
|
||||
console.log('Starting ' + suiteName);
|
||||
|
||||
for (let testName of testNames[suiteName]) {
|
||||
if (testSuite.beforeEach) {
|
||||
testSuite.beforeEach();
|
||||
}
|
||||
|
@ -50,18 +47,11 @@ function runTests() {
|
|||
}
|
||||
|
||||
var ReactTests = React.createClass({
|
||||
componentDidMount() {
|
||||
runTests();
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.welcome}>
|
||||
Welcome to React Native!
|
||||
</Text>
|
||||
<Text style={styles.instructions}>
|
||||
To get started, edit index.ios.js
|
||||
<Text style={styles.button} onPress={runTests}>
|
||||
Tap to Run Tests
|
||||
</Text>
|
||||
<Text style={styles.instructions}>
|
||||
Press Cmd+R to reload,{'\n'}
|
||||
|
@ -73,22 +63,26 @@ var ReactTests = React.createClass({
|
|||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
welcome: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
},
|
||||
instructions: {
|
||||
textAlign: 'center',
|
||||
color: '#333333',
|
||||
marginBottom: 5,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
button: {
|
||||
borderColor: '#cccccc',
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 20,
|
||||
padding: 10,
|
||||
},
|
||||
instructions: {
|
||||
textAlign: 'center',
|
||||
color: '#333333',
|
||||
marginBottom: 5,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('ReactTests', () => ReactTests);
|
||||
|
|
|
@ -15,16 +15,6 @@
|
|||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
|
||||
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 */; };
|
||||
|
@ -169,20 +159,9 @@
|
|||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* RealmReactTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RealmReactTests.m; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* RealmReactTests.m */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = RealmReactTests.m; sourceTree = "<group>"; tabWidth = 4; };
|
||||
02409E1A1BCF1F2E005F3B3E /* RealmJSTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmJSTests.h; path = ../../../RealmJSTests.h; sourceTree = "<group>"; };
|
||||
02409E1B1BCF1F2E005F3B3E /* RealmJSTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmJSTests.mm; path = ../../../RealmJSTests.mm; sourceTree = "<group>"; };
|
||||
02409E1C1BCF1F2E005F3B3E /* RJSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RJSModuleLoader.h; path = ../../../RJSModuleLoader.h; sourceTree = "<group>"; };
|
||||
02409E1D1BCF1F2E005F3B3E /* RJSModuleLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RJSModuleLoader.m; path = ../../../RJSModuleLoader.m; sourceTree = "<group>"; };
|
||||
02409E201BCF1F45005F3B3E /* ArrayTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ArrayTests.js; path = ../../ArrayTests.js; sourceTree = "<group>"; };
|
||||
02409E211BCF1F45005F3B3E /* asserts.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = asserts.js; path = ../../asserts.js; sourceTree = "<group>"; };
|
||||
02409E221BCF1F45005F3B3E /* base-test.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = "base-test.js"; path = "../../base-test.js"; sourceTree = "<group>"; };
|
||||
02409E231BCF1F45005F3B3E /* index.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = index.js; path = ../../index.js; sourceTree = "<group>"; };
|
||||
02409E241BCF1F45005F3B3E /* ObjectTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ObjectTests.js; path = ../../ObjectTests.js; sourceTree = "<group>"; };
|
||||
02409E251BCF1F45005F3B3E /* RealmTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = RealmTests.js; path = ../../RealmTests.js; sourceTree = "<group>"; };
|
||||
02409E261BCF1F45005F3B3E /* ResultsTests.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ResultsTests.js; path = ../../ResultsTests.js; sourceTree = "<group>"; };
|
||||
02409E271BCF1F45005F3B3E /* schemas.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = schemas.js; path = ../../schemas.js; sourceTree = "<group>"; };
|
||||
02409E281BCF1F45005F3B3E /* util.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = util.js; path = ../../util.js; sourceTree = "<group>"; };
|
||||
027799061BBF3BB700C96559 /* RealmJS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RealmJS.xcodeproj; path = ../../../RealmJS.xcodeproj; sourceTree = "<group>"; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
|
||||
|
@ -273,8 +252,6 @@
|
|||
00E356F21AD99517003FC87E /* RealmReactTests.m */,
|
||||
02409E1A1BCF1F2E005F3B3E /* RealmJSTests.h */,
|
||||
02409E1B1BCF1F2E005F3B3E /* RealmJSTests.mm */,
|
||||
02409E1C1BCF1F2E005F3B3E /* RJSModuleLoader.h */,
|
||||
02409E1D1BCF1F2E005F3B3E /* RJSModuleLoader.m */,
|
||||
00E356F01AD99517003FC87E /* Supporting Files */,
|
||||
);
|
||||
name = RealmReactTests;
|
||||
|
@ -374,15 +351,6 @@
|
|||
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 /* RealmReactTests */,
|
||||
|
@ -621,15 +589,6 @@
|
|||
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;
|
||||
};
|
||||
|
@ -666,7 +625,6 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
02409E1F1BCF1F2E005F3B3E /* RJSModuleLoader.m in Sources */,
|
||||
02409E1E1BCF1F2E005F3B3E /* RealmJSTests.mm in Sources */,
|
||||
00E356F31AD99517003FC87E /* RealmReactTests.m in Sources */,
|
||||
);
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "RealmJSTests.h"
|
||||
#import "Base/RCTJavaScriptExecutor.h"
|
||||
|
@ -16,34 +25,78 @@
|
|||
@interface RealmReactTests : RealmJSTests
|
||||
@end
|
||||
|
||||
|
||||
@implementation RealmReactTests
|
||||
|
||||
+ (NSURL *)scriptURL {
|
||||
return [[NSBundle bundleForClass:self] URLForResource:@"index" withExtension:@"js"];
|
||||
+ (XCTestSuite *)defaultTestSuite {
|
||||
[self waitForNotification:RCTJavaScriptDidLoadNotification];
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *testCaseNames = [self invokeMethod:@"getTestNames" inModule:@"index" error:&error];
|
||||
|
||||
if (error || !testCaseNames.count) {
|
||||
NSLog(@"Error from calling getTestNames() - %@", error ?: @"None returned");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
XCTestSuite *suite = [super defaultTestSuite];
|
||||
|
||||
for (XCTestSuite *testSuite in [self testSuitesFromDictionary:testCaseNames]) {
|
||||
[suite addTest:testSuite];
|
||||
}
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
- (void)invokeMethod:(NSString *)method {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self expectationForNotification:RCTJavaScriptDidLoadNotification object:nil handler:^(NSNotification *notification) {
|
||||
return YES;
|
||||
}];
|
||||
[self waitForExpectationsWithTimeout:10000000 handler:NULL];
|
||||
});
|
||||
+ (void)waitForNotification:(NSString *)notificationName {
|
||||
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
__block BOOL received = NO;
|
||||
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
dispatch_group_enter(group);
|
||||
id token = [nc addObserverForName:notificationName object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
received = YES;
|
||||
}];
|
||||
|
||||
while (!received) {
|
||||
@autoreleasepool {
|
||||
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||
}
|
||||
}
|
||||
|
||||
[nc removeObserver:token];
|
||||
}
|
||||
|
||||
+ (id)invokeMethod:(NSString *)method inModule:(NSString *)module error:(NSError * __strong *)outError {
|
||||
module = [NSString stringWithFormat:@"realm-tests/%@.js", module];
|
||||
|
||||
id<RCTJavaScriptExecutor> executor = [RealmReact executor];
|
||||
NSString *module = [NSString stringWithFormat:@"realm-tests/%@.js", NSStringFromClass(self.class)];
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
__block id result;
|
||||
|
||||
dispatch_group_enter(group);
|
||||
|
||||
[executor executeJSCall:module method:method arguments:@[] callback:^(id json, NSError *error) {
|
||||
XCTAssertNil(error, @"%@", [error description]);
|
||||
result = json;
|
||||
|
||||
if (error && outError) {
|
||||
*outError = error;
|
||||
}
|
||||
|
||||
dispatch_group_leave(group);
|
||||
}];
|
||||
|
||||
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)invokeMethod:(NSString *)method {
|
||||
NSError *error;
|
||||
[self.class invokeMethod:method inModule:NSStringFromClass(self.class) error:&error];
|
||||
|
||||
if (error) {
|
||||
// TODO: Parse and use localizedFailureReason info once we can source map the failure location in JS.
|
||||
[self recordFailureWithDescription:error.localizedDescription inFile:@(__FILE__) atLine:__LINE__ expected:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -21,4 +21,8 @@
|
|||
|
||||
@interface RealmJSTests : XCTestCase
|
||||
|
||||
+ (NSArray *)testSuitesFromDictionary:(NSDictionary *)testCaseNames;
|
||||
|
||||
- (instancetype)initWithTestName:(NSString *)name;
|
||||
|
||||
@end
|
||||
|
|
|
@ -19,29 +19,29 @@
|
|||
#import <objc/runtime.h>
|
||||
|
||||
#import "RealmJSTests.h"
|
||||
#import "RJSModuleLoader.h"
|
||||
|
||||
@interface RealmJSTests ()
|
||||
|
||||
@property (nonatomic, strong) JSValue *testObject;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RealmJSTests
|
||||
|
||||
- (instancetype)initWithJSTestObject:(JSValue *)testObject methodName:(NSString *)methodName {
|
||||
self = [super initWithSelector:NSSelectorFromString(methodName)];
|
||||
if (!self) {
|
||||
return nil;
|
||||
+ (NSArray *)testSuitesFromDictionary:(NSDictionary *)testCaseNames {
|
||||
NSMutableArray *testSuites = [[NSMutableArray alloc] init];
|
||||
|
||||
for (NSString *suiteName in testCaseNames) {
|
||||
XCTestSuite *testSuite = [[XCTestSuite alloc] initWithName:suiteName];
|
||||
Class testClass = objc_allocateClassPair(self, suiteName.UTF8String, 0);
|
||||
|
||||
for (NSString *testName in testCaseNames[suiteName]) {
|
||||
XCTestCase *testCase = [[testClass alloc] initWithTestName:testName];
|
||||
[testSuite addTest:testCase];
|
||||
}
|
||||
|
||||
[testSuites addObject:testSuite];
|
||||
}
|
||||
|
||||
_testObject = testObject;
|
||||
|
||||
return self;
|
||||
return [testSuites copy];
|
||||
}
|
||||
|
||||
- (JSContext *)context {
|
||||
return self.testObject.context;
|
||||
- (instancetype)initWithTestName:(NSString *)name {
|
||||
return [super initWithSelector:NSSelectorFromString(name)];
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
|
@ -62,59 +62,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
+ (NSURL *)scriptURL {
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (XCTestSuite *)defaultTestSuite {
|
||||
XCTestSuite *suite = [super defaultTestSuite];
|
||||
JSContext *context = [[JSContext alloc] init];
|
||||
RJSModuleLoader *moduleLoader = [[RJSModuleLoader alloc] initWithContext:context];
|
||||
|
||||
[RealmJS initializeContext:context.JSGlobalContextRef];
|
||||
|
||||
// Expose the global Realm object as a global 'realm' CommonJS module.
|
||||
[moduleLoader addGlobalModuleObject:context[@"Realm"] forName:@"realm"];
|
||||
|
||||
NSError *error;
|
||||
|
||||
NSURL *scriptURL = [self scriptURL];
|
||||
if (!scriptURL) {
|
||||
return suite;
|
||||
}
|
||||
|
||||
JSValue *testObjects = [moduleLoader loadModuleFromURL:scriptURL error:&error];
|
||||
if (!testObjects) {
|
||||
NSLog(@"index.js - %@", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
NSSet *specialMethodNames = [NSSet setWithObjects:@"beforeEach", @"afterEach", nil];
|
||||
|
||||
for (NSString *testName in [testObjects toDictionary]) {
|
||||
JSValue *testObject = testObjects[testName];
|
||||
XCTestSuite *testSuite = [[XCTestSuite alloc] initWithName:testName];
|
||||
Class testClass = objc_allocateClassPair(self, testName.UTF8String, 0);
|
||||
|
||||
for (NSString *methodName in [testObject toDictionary]) {
|
||||
if ([specialMethodNames containsObject:methodName]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JSObjectRef jsMethod = JSValueToObject(context.JSGlobalContextRef, [testObject[methodName] JSValueRef], NULL);
|
||||
|
||||
if (jsMethod && JSObjectIsFunction(context.JSGlobalContextRef, jsMethod)) {
|
||||
XCTestCase *testCase = [[testClass alloc] initWithJSTestObject:testObject methodName:methodName];
|
||||
[testSuite addTest:testCase];
|
||||
}
|
||||
}
|
||||
|
||||
[suite addTest:testSuite];
|
||||
}
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
|
||||
NSMethodSignature *sig = [super methodSignatureForSelector:aSelector];
|
||||
return sig ?: [NSMethodSignature signatureWithObjCTypes:"v@:"];
|
||||
|
@ -125,29 +72,7 @@
|
|||
}
|
||||
|
||||
- (void)invokeMethod:(NSString *)method {
|
||||
JSValue *testObject = self.testObject;
|
||||
|
||||
if (![testObject hasProperty:method]) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSContext *context = testObject.context;
|
||||
context.exception = nil;
|
||||
|
||||
[testObject invokeMethod:method withArguments:nil];
|
||||
|
||||
JSValue *exception = context.exception;
|
||||
if (exception) {
|
||||
JSValue *message = [exception hasProperty:@"message"] ? exception[@"message"] : exception;
|
||||
NSString *source = [exception hasProperty:@"sourceURL"] ? [exception[@"sourceURL"] toString] : nil;
|
||||
NSUInteger line = [exception hasProperty:@"line"] ? [exception[@"line"] toUInt32] - 1 : 0;
|
||||
NSURL *sourceURL = source ? [NSURL URLWithString:source.lastPathComponent relativeToURL:[NSURL URLWithString:@(__FILE__)]] : nil;
|
||||
|
||||
[self recordFailureWithDescription:message.description
|
||||
inFile:sourceURL ? sourceURL.absoluteString : @(__FILE__)
|
||||
atLine:sourceURL ? line : __LINE__
|
||||
expected:YES];
|
||||
}
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -80,7 +80,7 @@ function TestFailureError(message) {
|
|||
|
||||
// This regular expression will match stack trace lines provided by JavaScriptCore.
|
||||
// Example: someMethod@file:///path/to/file.js:10:24
|
||||
var regex = /^(?:.*?@)?([^\[\(].+?):(\d+)(?::(\d+))?/;
|
||||
var regex = /^(?:.*?@)?([^\[\(].+?):(\d+)(?::(\d+))?\s*$/;
|
||||
|
||||
// Remove the top two stack frames and use information from the third, if possible.
|
||||
var stack = error.stack && error.stack.split('\n');
|
||||
|
|
|
@ -23,3 +23,23 @@ exports.ObjectTests = require('./ObjectTests');
|
|||
exports.RealmTests = require('./RealmTests');
|
||||
exports.ResultsTests = require('./ResultsTests');
|
||||
|
||||
var SPECIAL_METHODS = {
|
||||
beforeEach: true,
|
||||
afterEach: true,
|
||||
};
|
||||
|
||||
Object.defineProperty(exports, 'getTestNames', {
|
||||
value: function() {
|
||||
var testNames = {};
|
||||
|
||||
for (var suiteName in exports) {
|
||||
var testSuite = exports[suiteName];
|
||||
|
||||
testNames[suiteName] = Object.keys(testSuite).filter(function(testName) {
|
||||
return !(testName in SPECIAL_METHODS) && typeof testSuite[testName] == 'function';
|
||||
});
|
||||
}
|
||||
|
||||
return testNames;
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue