Test that example app loads properly

Re-using the existing React testing class to hook into the example app. Right now, the test is extremely basic but is able to be expanded later.

Resolves #36
This commit is contained in:
Scott Kyle 2016-02-15 15:47:07 -08:00
parent 2bdb6bfa28
commit c64524f985
7 changed files with 155 additions and 69 deletions

View File

@ -6,6 +6,18 @@
"ecmaFeatures": {
"jsx": true
},
"globals": {
"cancelAnimationFrame": false,
"clearImmediate": false,
"clearInterval": false,
"clearTimeout": false,
"console": false,
"global": false,
"requestAnimationFrame": false,
"setImmediate": false,
"setInterval": false,
"setTimeout": false
},
"parser": "babel-eslint",
"plugins": [
"react"

View File

@ -4,4 +4,6 @@
'use strict';
// Allow our test harness to test this app.
import './tests';
import './main';

View File

@ -12,7 +12,6 @@
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 */; };
027798491BBB2F1000C96559 /* ReactExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 027798481BBB2F1000C96559 /* ReactExampleTests.m */; };
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
@ -24,6 +23,8 @@
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
F6C4656F1C48DBE900E79896 /* RealmReact.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C465551C48D4C300E79896 /* RealmReact.framework */; };
F6C465701C48DBF700E79896 /* RealmReact.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F6C465551C48D4C300E79896 /* RealmReact.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F6DC9DE51C519CFF00ED587E /* RealmJSTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6DC9DE41C519CFF00ED587E /* RealmJSTests.mm */; };
F6DC9DE71C519D2300ED587E /* RealmReactTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F6DC9DE61C519D2300ED587E /* RealmReactTests.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -170,7 +171,6 @@
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
0270BC9E1B7D04D700010E03 /* RealmJS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RealmJS.xcodeproj; path = ../../../RealmJS.xcodeproj; sourceTree = "<group>"; };
027798461BBB2F1000C96559 /* ReactExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
027798481BBB2F1000C96559 /* ReactExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactExampleTests.m; sourceTree = "<group>"; };
0277984A1BBB2F1000C96559 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 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>"; };
@ -184,6 +184,9 @@
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
F6DC9DE31C519CFF00ED587E /* RealmJSTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmJSTests.h; path = ../../../../tests/ios/RealmJSTests.h; sourceTree = "<group>"; };
F6DC9DE41C519CFF00ED587E /* RealmJSTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmJSTests.mm; path = ../../../../tests/ios/RealmJSTests.mm; sourceTree = "<group>"; };
F6DC9DE61C519D2300ED587E /* RealmReactTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RealmReactTests.m; path = "../../../../tests/react-test-app/ios/ReactTests/RealmReactTests.m"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -258,7 +261,9 @@
027798471BBB2F1000C96559 /* ReactExampleTests */ = {
isa = PBXGroup;
children = (
027798481BBB2F1000C96559 /* ReactExampleTests.m */,
F6DC9DE31C519CFF00ED587E /* RealmJSTests.h */,
F6DC9DE41C519CFF00ED587E /* RealmJSTests.mm */,
F6DC9DE61C519D2300ED587E /* RealmReactTests.m */,
0277984A1BBB2F1000C96559 /* Info.plist */,
);
path = ReactExampleTests;
@ -653,7 +658,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
027798491BBB2F1000C96559 /* ReactExampleTests.m in Sources */,
F6DC9DE71C519D2300ED587E /* RealmReactTests.m in Sources */,
F6DC9DE51C519CFF00ED587E /* RealmJSTests.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -698,7 +704,6 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = ReactExampleTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";

View File

@ -1,64 +0,0 @@
/* Copyright 2015 Realm Inc - All Rights Reserved
* Proprietary and Confidential
*/
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "RCTLog.h"
#import "RCTRootView.h"
#define TIMEOUT_SECONDS 10
#define TEXT_TO_LOOK_FOR @"Todo Items"
@interface ReactExampleTests : XCTestCase
@end
@implementation ReactExampleTests
- (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)testLaunched
{
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
__block NSString *redboxError = nil;
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, 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

View File

@ -0,0 +1,16 @@
/* Copyright 2016 Realm Inc - All Rights Reserved
* Proprietary and Confidential
*/
'use strict';
import {
getRootComponent,
assertChildExists,
} from './util';
export default {
async testTodoAppRendered() {
assertChildExists(await getRootComponent(), 'TodoApp');
},
}

View File

@ -0,0 +1,56 @@
/* Copyright 2016 Realm Inc - All Rights Reserved
* Proprietary and Confidential
*/
'use strict';
import {
NativeAppEventEmitter,
NativeModules,
} from 'react-native';
import ExampleTest from './example-test';
const TESTS = {
ExampleTest,
};
const SPECIAL_METHODS = {
beforeEach: true,
afterEach: true,
};
// Listen for event to run a particular test.
NativeAppEventEmitter.addListener('realm-run-test', async ({suite, name}) => {
let testSuite = TESTS[suite];
let testMethod = testSuite && testSuite[name];
let error;
try {
if (testMethod) {
await testMethod.call(testSuite);
} else if (!testSuite || !(name in SPECIAL_METHODS)) {
throw new Error('Missing test: ' + suite + '.' + name);
}
} catch (e) {
error = '' + e;
}
NativeModules.Realm.emit('realm-test-finished', error);
});
// Inform the native test harness about the test suite once it's ready.
setTimeout(() => {
NativeModules.Realm.emit('realm-test-names', getTestNames());
}, 0);
function getTestNames() {
let testNames = {};
for (let suiteName in TESTS) {
let testSuite = TESTS[suiteName];
testNames[suiteName] = Object.keys(testSuite);
}
return testNames;
}

View File

@ -0,0 +1,59 @@
/* Copyright 2016 Realm Inc - All Rights Reserved
* Proprietary and Confidential
*/
'use strict';
import React from 'react-native';
const rootComponentPromise = new Promise((resolve) => {
// Require internal module here so the promise is rejected if there is an error.
let Mount = require('react-native/Libraries/ReactNative/ReactNativeMount');
let renderComponent = Mount.renderComponent;
Mount.renderComponent = function() {
let component = renderComponent.apply(this, arguments);
resolve(component);
return component;
};
});
export function getRootComponent() {
return rootComponentPromise;
}
export function assertChildExists(component, name) {
if (!findChildComponent(component, name)) {
throw new Error(name + ' not rendered');
}
}
export function findChildComponent(component, name) {
for (let child of traverseChildren(component)) {
if (child.type.name == name) {
return child;
}
}
return null;
}
export function* traverseChildren(component) {
let props = component.props;
// The hacky TopLevelWrapper has its props set to the root element.
if (props.props) {
props = props.props;
}
let children = props.children;
if (!children) {
return;
}
// ReactNative is missing React.Children.toArray()
for (let child of React.Children.map(children, (x) => x)) {
yield child;
yield* traverseChildren(child);
}
}