mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-12 22:29:41 +08:00
Updates from Wed 24 Jun
This commit is contained in:
@@ -77,12 +77,14 @@ var SearchScreen = React.createClass({
|
||||
var apiKey = API_KEYS[this.state.queryNumber % API_KEYS.length];
|
||||
if (query) {
|
||||
return (
|
||||
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
|
||||
API_URL + 'movies.json?apikey=' + apiKey + '&q=' +
|
||||
encodeURIComponent(query) + '&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
} else {
|
||||
// With no query, load latest movies
|
||||
return (
|
||||
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
|
||||
API_URL + 'lists/movies/in_theaters.json?apikey=' + apiKey +
|
||||
'&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
|
||||
@@ -600,7 +600,7 @@
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist";
|
||||
INFOPLIST_FILE = "iOS/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SampleApp;
|
||||
@@ -616,7 +616,7 @@
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist";
|
||||
INFOPLIST_FILE = "iOS/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SampleApp;
|
||||
|
||||
@@ -125,6 +125,7 @@ var Heading = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = '<DatePickerIOS>';
|
||||
exports.description = 'Select dates and times using the native UIDatePicker.';
|
||||
exports.examples = [
|
||||
|
||||
@@ -25,6 +25,7 @@ var {
|
||||
|
||||
var ImageCapInsetsExample = require('./ImageCapInsetsExample');
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.framework = 'React';
|
||||
exports.title = '<Image>';
|
||||
exports.description = 'Base component for displaying different types of images.';
|
||||
|
||||
@@ -236,6 +236,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = '<MapView>';
|
||||
exports.description = 'Base component to display maps';
|
||||
exports.examples = [
|
||||
|
||||
@@ -92,6 +92,31 @@ function newRandomRoute() {
|
||||
|
||||
var NavigationBarSample = React.createClass({
|
||||
|
||||
componentWillMount: function() {
|
||||
var navigator = this.props.navigator;
|
||||
|
||||
var callback = (event) => {
|
||||
console.log(
|
||||
`NavigationBarSample : event ${event.type}`,
|
||||
{
|
||||
route: JSON.stringify(event.data.route),
|
||||
target: event.target,
|
||||
type: event.type,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Observe focus change events from this component.
|
||||
this._listeners = [
|
||||
navigator.navigationContext.addListener('willfocus', callback),
|
||||
navigator.navigationContext.addListener('didfocus', callback),
|
||||
];
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._listeners && this._listeners.forEach(listener => listener.remove());
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<Navigator
|
||||
|
||||
@@ -132,6 +132,7 @@ var TabBarExample = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<Navigator
|
||||
ref={this._setNavigatorRef}
|
||||
style={styles.container}
|
||||
initialRoute={{ message: "First Scene", }}
|
||||
renderScene={this.renderScene}
|
||||
@@ -145,6 +146,34 @@ var TabBarExample = React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._listeners && this._listeners.forEach(listener => listener.remove());
|
||||
},
|
||||
|
||||
_setNavigatorRef: function(navigator) {
|
||||
if (navigator !== this._navigator) {
|
||||
this._navigator = navigator;
|
||||
|
||||
if (navigator) {
|
||||
var callback = (event) => {
|
||||
console.log(
|
||||
`TabBarExample: event ${event.type}`,
|
||||
{
|
||||
route: JSON.stringify(event.data.route),
|
||||
target: event.target,
|
||||
type: event.type,
|
||||
}
|
||||
);
|
||||
};
|
||||
// Observe focus change events from the owner.
|
||||
this._listeners = [
|
||||
navigator.navigationContext.addListener('willfocus', callback),
|
||||
navigator.navigationContext.addListener('didfocus', callback),
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
|
||||
@@ -112,6 +112,7 @@ var PickerExample = React.createClass({
|
||||
},
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = '<PickerIOS>';
|
||||
exports.description = 'Render lists of selectable options with UIPickerView.';
|
||||
exports.examples = [
|
||||
|
||||
@@ -60,6 +60,7 @@ var ProgressViewExample = React.createClass({
|
||||
},
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.framework = 'React';
|
||||
exports.title = 'ProgressViewIOS';
|
||||
exports.description = 'ProgressViewIOS';
|
||||
|
||||
@@ -23,6 +23,7 @@ var {
|
||||
Image
|
||||
} = React;
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = '<ScrollView>';
|
||||
exports.description = 'Component that enables scrolling through child components';
|
||||
exports.examples = [
|
||||
|
||||
@@ -25,7 +25,7 @@ var {
|
||||
var Entity = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<Text style={styles.entity}>
|
||||
<Text style={{fontWeight: '500', color: '#527fe4'}}>
|
||||
{this.props.children}
|
||||
</Text>
|
||||
);
|
||||
@@ -34,7 +34,12 @@ var Entity = React.createClass({
|
||||
|
||||
var AttributeToggler = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {fontWeight: '500', fontSize: 15};
|
||||
return {fontWeight: 'bold', fontSize: 15};
|
||||
},
|
||||
toggleWeight: function() {
|
||||
this.setState({
|
||||
fontWeight: this.state.fontWeight === 'bold' ? 'normal' : 'bold'
|
||||
});
|
||||
},
|
||||
increaseSize: function() {
|
||||
this.setState({
|
||||
@@ -42,22 +47,26 @@ var AttributeToggler = React.createClass({
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
var curStyle = {fontSize: this.state.fontSize};
|
||||
var curStyle = {fontWeight: this.state.fontWeight, fontSize: this.state.fontSize};
|
||||
return (
|
||||
<Text>
|
||||
<View>
|
||||
<Text style={curStyle}>
|
||||
Tap the controls below to change attributes.
|
||||
</Text>
|
||||
<Text>
|
||||
See how it will even work on{' '}
|
||||
<Text style={curStyle}>
|
||||
this nested text
|
||||
</Text>
|
||||
<Text onPress={this.increaseSize}>
|
||||
{'>> Increase Size <<'}
|
||||
</Text>
|
||||
<Text>See how it will even work on <Text style={curStyle}>this nested text</Text></Text>
|
||||
</Text>
|
||||
</Text>
|
||||
<Text
|
||||
style={{backgroundColor: '#ffaaaa', marginTop: 5}}
|
||||
onPress={this.toggleWeight}>
|
||||
Toggle Weight
|
||||
</Text>
|
||||
<Text
|
||||
style={{backgroundColor: '#aaaaff', marginTop: 5}}
|
||||
onPress={this.increaseSize}>
|
||||
Increase Size
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -206,6 +215,12 @@ exports.examples = [
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<Text>
|
||||
auto (default) - english LTR
|
||||
</Text>
|
||||
<Text>
|
||||
أحب اللغة العربية auto (default) - arabic RTL
|
||||
</Text>
|
||||
<Text style={{textAlign: 'left'}}>
|
||||
left left left left left left left left left left left left left left left
|
||||
</Text>
|
||||
@@ -282,43 +297,21 @@ exports.examples = [
|
||||
description: 'backgroundColor is inherited from all types of views.',
|
||||
render: function() {
|
||||
return (
|
||||
<View style={{backgroundColor: 'yellow'}}>
|
||||
<Text>
|
||||
Yellow background inherited from View parent,
|
||||
<Text style={{backgroundColor: '#ffaaaa'}}>
|
||||
{' '}red background,
|
||||
<Text style={{backgroundColor: '#aaaaff'}}>
|
||||
{' '}blue background,
|
||||
<Text>
|
||||
{' '}inherited blue background,
|
||||
<Text style={{backgroundColor: '#aaffaa'}}>
|
||||
{' '}nested green background.
|
||||
</Text>
|
||||
<Text style={{backgroundColor: 'yellow'}}>
|
||||
Yellow container background,
|
||||
<Text style={{backgroundColor: '#ffaaaa'}}>
|
||||
{' '}red background,
|
||||
<Text style={{backgroundColor: '#aaaaff'}}>
|
||||
{' '}blue background,
|
||||
<Text>
|
||||
{' '}inherited blue background,
|
||||
<Text style={{backgroundColor: '#aaffaa'}}>
|
||||
{' '}nested green background.
|
||||
</Text>
|
||||
</Text>
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'containerBackgroundColor attribute',
|
||||
render: function() {
|
||||
return (
|
||||
<View style={{backgroundColor: 'yellow'}}>
|
||||
<View style={{flexDirection: 'row', position: 'absolute', height: 80}}>
|
||||
<View style={{backgroundColor: '#ffaaaa', width: 140}} />
|
||||
<View style={{backgroundColor: '#aaaaff', width: 140}} />
|
||||
</View>
|
||||
<Text style={styles.backgroundColorText}>
|
||||
Default containerBackgroundColor (inherited) + backgroundColor wash
|
||||
</Text>
|
||||
<Text style={[
|
||||
styles.backgroundColorText,
|
||||
{marginBottom: 5, containerBackgroundColor: 'transparent'}]}>
|
||||
{"containerBackgroundColor: 'transparent' + backgroundColor wash"}
|
||||
</Text>
|
||||
</View>
|
||||
</Text>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
@@ -346,8 +339,4 @@ var styles = StyleSheet.create({
|
||||
marginBottom: 0,
|
||||
backgroundColor: 'rgba(100, 100, 100, 0.3)'
|
||||
},
|
||||
entity: {
|
||||
fontWeight: '500',
|
||||
color: '#527fe4',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -133,6 +133,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = '<TextInput>';
|
||||
exports.description = 'Single and multi-line text inputs.';
|
||||
exports.examples = [
|
||||
|
||||
@@ -26,6 +26,7 @@ var {
|
||||
View,
|
||||
} = React;
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = '<Touchable*> and onPress';
|
||||
exports.examples = [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
version = "1.8">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
@@ -22,10 +22,10 @@
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForRunning = "NO"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
buildForAnalyzing = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "004D289D1AAF61C70097A701"
|
||||
@@ -36,10 +36,10 @@
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForRunning = "NO"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
buildForAnalyzing = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "143BC5941B21E3E100462512"
|
||||
|
||||
@@ -26,16 +26,12 @@
|
||||
- (void)setUp
|
||||
{
|
||||
#if __LP64__
|
||||
#error Tests should be run on 32-bit device simulators (e.g. iPhone 5)
|
||||
RCTAssert(false, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
|
||||
#endif
|
||||
|
||||
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
|
||||
RCTAssert(version.majorVersion == 8 || version.minorVersion == 3, @"Tests should be run on iOS 8.3, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
|
||||
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp");
|
||||
|
||||
// If tests have changes, set recordMode = YES below and run the affected
|
||||
// tests on an iPhone5, iOS 8.3 simulator.
|
||||
_runner.recordMode = NO;
|
||||
}
|
||||
|
||||
#pragma mark Logic Tests
|
||||
@@ -53,8 +49,7 @@
|
||||
expectErrorBlock:nil];
|
||||
}
|
||||
|
||||
// TODO: this seems to stall forever - figure out why
|
||||
- (void)DISABLED_testTheTester_ExpectError
|
||||
- (void)testTheTester_ExpectError
|
||||
{
|
||||
[_runner runTest:_cmd
|
||||
module:@"IntegrationTestHarnessTest"
|
||||
@@ -91,12 +86,9 @@
|
||||
|
||||
- (void)testSimpleSnapshot
|
||||
{
|
||||
// If tests have changes, set recordMode = YES below and re-run
|
||||
_runner.recordMode = NO;
|
||||
[_runner runTest:_cmd module:@"SimpleSnapshotTest"];
|
||||
}
|
||||
|
||||
- (void)testZZZ_NotInRecordMode
|
||||
{
|
||||
RCTAssert(_runner.recordMode == NO, @"Don't forget to turn record mode back to NO before commit.");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 264 KiB |
@@ -21,8 +21,6 @@
|
||||
#import "RCTRedBox.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
#define TIMEOUT_SECONDS 240
|
||||
|
||||
@interface UIExplorerTests : XCTestCase
|
||||
{
|
||||
RCTTestRunner *_runner;
|
||||
@@ -40,52 +38,6 @@
|
||||
NSString *version = [[UIDevice currentDevice] systemVersion];
|
||||
RCTAssert([version isEqualToString:@"8.3"], @"Snapshot tests should be run on iOS 8.3, found %@", version);
|
||||
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerApp.ios");
|
||||
|
||||
// If tests have changes, set recordMode = YES below and run the affected
|
||||
// tests on an iPhone5, iOS 8.3 simulator.
|
||||
_runner.recordMode = NO;
|
||||
}
|
||||
|
||||
- (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;
|
||||
}
|
||||
|
||||
// Make sure this test runs first because the other tests will tear out the rootView
|
||||
- (void)testAAA_RootViewLoadsAndRenders
|
||||
{
|
||||
// TODO (t7296305) Fix and Re-Enable this UIExplorer Test
|
||||
return;
|
||||
|
||||
UIViewController *vc = [UIApplication sharedApplication].delegate.window.rootViewController;
|
||||
RCTAssert([vc.view isKindOfClass:[RCTRootView class]], @"This test must run first.");
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
||||
BOOL foundElement = NO;
|
||||
NSString *redboxError = nil;
|
||||
|
||||
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
|
||||
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
|
||||
redboxError = [[RCTRedBox sharedInstance] currentErrorMessage];
|
||||
foundElement = [self findSubviewInView:vc.view matching:^(UIView *view) {
|
||||
if ([view.accessibilityLabel isEqualToString:@"<View>"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}];
|
||||
}
|
||||
|
||||
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
|
||||
XCTAssertTrue(foundElement, @"Couldn't find element with '<View>' text in %d seconds", TIMEOUT_SECONDS);
|
||||
}
|
||||
|
||||
#define RCT_SNAPSHOT_TEST(name, reRecord) \
|
||||
@@ -102,10 +54,4 @@ RCT_SNAPSHOT_TEST(SwitchExample, NO)
|
||||
RCT_SNAPSHOT_TEST(SliderExample, NO)
|
||||
RCT_SNAPSHOT_TEST(TabBarExample, NO)
|
||||
|
||||
// Make sure this test runs last
|
||||
- (void)testZZZ_NotInRecordMode
|
||||
{
|
||||
RCTAssert(_runner.recordMode == NO, @"Don't forget to turn record mode back to NO before commit.");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -53,6 +53,8 @@ var AppEventsTest = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
AppEventsTest.displayName = 'AppEventsTest';
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
margin: 40,
|
||||
|
||||
@@ -53,15 +53,18 @@ function expectEqual(lhs, rhs, testname) {
|
||||
);
|
||||
}
|
||||
|
||||
function expectAsyncNoError(err) {
|
||||
expectTrue(err === null, 'Unexpected Async error: ' + JSON.stringify(err));
|
||||
function expectAsyncNoError(place, err) {
|
||||
if (err instanceof Error) {
|
||||
err = err.message;
|
||||
}
|
||||
expectTrue(err === null, 'Unexpected error in ' + place + ': ' + JSON.stringify(err));
|
||||
}
|
||||
|
||||
function testSetAndGet() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, (err1) => {
|
||||
expectAsyncNoError(err1);
|
||||
expectAsyncNoError('testSetAndGet/setItem', err1);
|
||||
AsyncStorage.getItem(KEY_1, (err2, result) => {
|
||||
expectAsyncNoError(err2);
|
||||
expectAsyncNoError('testSetAndGet/getItem', err2);
|
||||
expectEqual(result, VAL_1, 'testSetAndGet setItem');
|
||||
updateMessage('get(key_1) correctly returned ' + result);
|
||||
runTestCase('should get null for missing key', testMissingGet);
|
||||
@@ -71,7 +74,7 @@ function testSetAndGet() {
|
||||
|
||||
function testMissingGet() {
|
||||
AsyncStorage.getItem(KEY_2, (err, result) => {
|
||||
expectAsyncNoError(err);
|
||||
expectAsyncNoError('testMissingGet/setItem', err);
|
||||
expectEqual(result, null, 'testMissingGet');
|
||||
updateMessage('missing get(key_2) correctly returned ' + result);
|
||||
runTestCase('check set twice results in a single key', testSetTwice);
|
||||
@@ -82,7 +85,7 @@ function testSetTwice() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, ()=>{
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, ()=>{
|
||||
AsyncStorage.getItem(KEY_1, (err, result) => {
|
||||
expectAsyncNoError(err);
|
||||
expectAsyncNoError('testSetTwice/setItem', err);
|
||||
expectEqual(result, VAL_1, 'testSetTwice');
|
||||
updateMessage('setTwice worked as expected');
|
||||
runTestCase('test removeItem', testRemoveItem);
|
||||
@@ -95,17 +98,17 @@ function testRemoveItem() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, ()=>{
|
||||
AsyncStorage.setItem(KEY_2, VAL_2, ()=>{
|
||||
AsyncStorage.getAllKeys((err, result) => {
|
||||
expectAsyncNoError(err);
|
||||
expectAsyncNoError('testRemoveItem/getAllKeys', err);
|
||||
expectTrue(
|
||||
result.indexOf(KEY_1) >= 0 && result.indexOf(KEY_2) >= 0,
|
||||
'Missing KEY_1 or KEY_2 in ' + '(' + result + ')'
|
||||
);
|
||||
updateMessage('testRemoveItem - add two items');
|
||||
AsyncStorage.removeItem(KEY_1, (err2) => {
|
||||
expectAsyncNoError(err2);
|
||||
expectAsyncNoError('testRemoveItem/removeItem', err2);
|
||||
updateMessage('delete successful ');
|
||||
AsyncStorage.getItem(KEY_1, (err3, result2) => {
|
||||
expectAsyncNoError(err3);
|
||||
expectAsyncNoError('testRemoveItem/getItem', err3);
|
||||
expectEqual(
|
||||
result2,
|
||||
null,
|
||||
@@ -113,7 +116,7 @@ function testRemoveItem() {
|
||||
);
|
||||
updateMessage('key properly removed ');
|
||||
AsyncStorage.getAllKeys((err4, result3) => {
|
||||
expectAsyncNoError(err4);
|
||||
expectAsyncNoError('testRemoveItem/getAllKeys', err4);
|
||||
expectTrue(
|
||||
result3.indexOf(KEY_1) === -1,
|
||||
'Unexpected: KEY_1 present in ' + result3
|
||||
@@ -130,11 +133,11 @@ function testRemoveItem() {
|
||||
|
||||
function testMerge() {
|
||||
AsyncStorage.setItem(KEY_MERGE, JSON.stringify(VAL_MERGE_1), (err1) => {
|
||||
expectAsyncNoError(err1);
|
||||
expectAsyncNoError('testMerge/setItem', err1);
|
||||
AsyncStorage.mergeItem(KEY_MERGE, JSON.stringify(VAL_MERGE_2), (err2) => {
|
||||
expectAsyncNoError(err2);
|
||||
expectAsyncNoError('testMerge/mergeItem', err2);
|
||||
AsyncStorage.getItem(KEY_MERGE, (err3, result) => {
|
||||
expectAsyncNoError(err3);
|
||||
expectAsyncNoError('testMerge/setItem', err3);
|
||||
expectEqual(JSON.parse(result), VAL_MERGE_EXPECT, 'testMerge');
|
||||
updateMessage('objects deeply merged\nDone!');
|
||||
done();
|
||||
@@ -173,4 +176,6 @@ var AsyncStorageTest = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
AsyncStorageTest.displayName = 'AsyncStorageTest';
|
||||
|
||||
module.exports = AsyncStorageTest;
|
||||
|
||||
@@ -59,4 +59,6 @@ var IntegrationTestHarnessTest = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
IntegrationTestHarnessTest.displayName = 'IntegrationTestHarnessTest';
|
||||
|
||||
module.exports = IntegrationTestHarnessTest;
|
||||
|
||||
@@ -164,4 +164,6 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
LayoutEventsTest.displayName = 'LayoutEventsTest';
|
||||
|
||||
module.exports = LayoutEventsTest;
|
||||
|
||||
@@ -22,7 +22,7 @@ var PromiseTest = React.createClass({
|
||||
Promise.all([
|
||||
this.testShouldResolve(),
|
||||
this.testShouldReject(),
|
||||
]).then(() => RCTTestModule.finish(
|
||||
]).then(() => RCTTestModule.markTestPassed(
|
||||
this.shouldResolve && this.shouldReject
|
||||
));
|
||||
},
|
||||
@@ -42,9 +42,11 @@ var PromiseTest = React.createClass({
|
||||
},
|
||||
|
||||
render() {
|
||||
return <React.View />;
|
||||
return <React.View />;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
PromiseTest.displayName = 'PromiseTest';
|
||||
|
||||
module.exports = PromiseTest;
|
||||
|
||||
@@ -24,8 +24,8 @@ var SimpleSnapshotTest = React.createClass({
|
||||
requestAnimationFrame(() => TestModule.verifySnapshot(this.done));
|
||||
},
|
||||
|
||||
done() {
|
||||
TestModule.markTestCompleted();
|
||||
done(success) {
|
||||
TestModule.markTestPassed(success);
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -53,4 +53,6 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
SimpleSnapshotTest.displayName = 'SimpleSnapshotTest';
|
||||
|
||||
module.exports = SimpleSnapshotTest;
|
||||
|
||||
@@ -152,4 +152,6 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
TimersTest.displayName = 'TimersTest';
|
||||
|
||||
module.exports = TimersTest;
|
||||
|
||||
@@ -115,7 +115,7 @@ COMPONENTS.concat(APIS).forEach((Example) => {
|
||||
// View is still blank after first RAF :\
|
||||
global.requestAnimationFrame(() =>
|
||||
global.requestAnimationFrame(() => TestModule.verifySnapshot(
|
||||
TestModule.markTestCompleted
|
||||
TestModule.markTestPassed
|
||||
)
|
||||
));
|
||||
},
|
||||
|
||||
@@ -79,25 +79,19 @@ RCT_EXPORT_MODULE()
|
||||
{
|
||||
RCTBridge *_bridge;
|
||||
BOOL _testMethodCalled;
|
||||
dispatch_queue_t _queue;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation RCTBridgeTests
|
||||
|
||||
RCT_EXPORT_MODULE(TestModule)
|
||||
@synthesize methodQueue = _methodQueue;
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
return _queue;
|
||||
}
|
||||
RCT_EXPORT_MODULE(TestModule)
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
_queue = dispatch_queue_create("com.facebook.React.TestQueue", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
_bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
moduleProvider:^{ return @[self]; }
|
||||
launchOptions:nil];
|
||||
@@ -151,7 +145,7 @@ RCT_EXPORT_MODULE(TestModule)
|
||||
|
||||
[_bridge.batchedBridge _handleBuffer:buffer context:RCTGetExecutorID(executor)];
|
||||
|
||||
dispatch_sync(_queue, ^{
|
||||
dispatch_sync(_methodQueue, ^{
|
||||
// clear the queue
|
||||
XCTAssertTrue(_testMethodCalled);
|
||||
});
|
||||
|
||||
99
Examples/UIExplorer/UIExplorerUnitTests/RCTShadowViewTests.m
Normal file
99
Examples/UIExplorer/UIExplorerUnitTests/RCTShadowViewTests.m
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "RCTShadowView.h"
|
||||
|
||||
@interface RCTShadowViewTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTShadowViewTests
|
||||
|
||||
// Just a basic sanity test to ensure css-layout is applied correctly in the context of our shadow view hierarchy.
|
||||
//
|
||||
// ====================================
|
||||
// || header ||
|
||||
// ====================================
|
||||
// || || || ||
|
||||
// || left || center || right ||
|
||||
// || || || ||
|
||||
// ====================================
|
||||
// || footer ||
|
||||
// ====================================
|
||||
//
|
||||
- (void)testApplyingLayoutRecursivelyToShadowView
|
||||
{
|
||||
RCTShadowView *leftView = [self _shadowViewWithStyle:^(css_style_t *style) {
|
||||
style->flex = 1;
|
||||
}];
|
||||
|
||||
RCTShadowView *centerView = [self _shadowViewWithStyle:^(css_style_t *style) {
|
||||
style->flex = 2;
|
||||
style->margin[0] = 10;
|
||||
style->margin[2] = 10;
|
||||
}];
|
||||
|
||||
RCTShadowView *rightView = [self _shadowViewWithStyle:^(css_style_t *style) {
|
||||
style->flex = 1;
|
||||
}];
|
||||
|
||||
RCTShadowView *mainView = [self _shadowViewWithStyle:^(css_style_t *style) {
|
||||
style->flex_direction = CSS_FLEX_DIRECTION_ROW;
|
||||
style->flex = 2;
|
||||
style->margin[1] = 10;
|
||||
style->margin[3] = 10;
|
||||
}];
|
||||
|
||||
[mainView insertReactSubview:leftView atIndex:0];
|
||||
[mainView insertReactSubview:centerView atIndex:1];
|
||||
[mainView insertReactSubview:rightView atIndex:2];
|
||||
|
||||
RCTShadowView *headerView = [self _shadowViewWithStyle:^(css_style_t *style) {
|
||||
style->flex = 1;
|
||||
}];
|
||||
|
||||
RCTShadowView *footerView = [self _shadowViewWithStyle:^(css_style_t *style) {
|
||||
style->flex = 1;
|
||||
}];
|
||||
|
||||
RCTShadowView *parentView = [self _shadowViewWithStyle:^(css_style_t *style) {
|
||||
style->flex_direction = CSS_FLEX_DIRECTION_COLUMN;
|
||||
style->padding[0] = 10;
|
||||
style->padding[1] = 10;
|
||||
style->padding[2] = 10;
|
||||
style->padding[3] = 10;
|
||||
style->dimensions[0] = 440;
|
||||
style->dimensions[1] = 440;
|
||||
}];
|
||||
|
||||
[parentView insertReactSubview:headerView atIndex:0];
|
||||
[parentView insertReactSubview:mainView atIndex:1];
|
||||
[parentView insertReactSubview:footerView atIndex:2];
|
||||
|
||||
[parentView collectRootUpdatedFrames:nil parentConstraint:CGSizeZero];
|
||||
|
||||
XCTAssertTrue(CGRectEqualToRect([parentView measureLayoutRelativeToAncestor:parentView], CGRectMake(0, 0, 440, 440)));
|
||||
XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets([parentView paddingAsInsets], UIEdgeInsetsMake(10, 10, 10, 10)));
|
||||
|
||||
XCTAssertTrue(CGRectEqualToRect([headerView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 10, 420, 100)));
|
||||
XCTAssertTrue(CGRectEqualToRect([mainView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 120, 420, 200)));
|
||||
XCTAssertTrue(CGRectEqualToRect([footerView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 330, 420, 100)));
|
||||
|
||||
XCTAssertTrue(CGRectEqualToRect([leftView measureLayoutRelativeToAncestor:parentView], CGRectMake(10, 120, 100, 200)));
|
||||
XCTAssertTrue(CGRectEqualToRect([centerView measureLayoutRelativeToAncestor:parentView], CGRectMake(120, 120, 200, 200)));
|
||||
XCTAssertTrue(CGRectEqualToRect([rightView measureLayoutRelativeToAncestor:parentView], CGRectMake(330, 120, 100, 200)));
|
||||
}
|
||||
|
||||
- (RCTShadowView *)_shadowViewWithStyle:(void(^)(css_style_t *style))styleBlock
|
||||
{
|
||||
RCTShadowView *shadowView = [[RCTShadowView alloc] init];
|
||||
|
||||
css_style_t style = shadowView.cssNode->style;
|
||||
styleBlock(&style);
|
||||
shadowView.cssNode->style = style;
|
||||
|
||||
return shadowView;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -43,6 +43,7 @@ var WebViewExample = React.createClass({
|
||||
backButtonEnabled: false,
|
||||
forwardButtonEnabled: false,
|
||||
loading: true,
|
||||
scalesPageToFit: true,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -97,6 +98,7 @@ var WebViewExample = React.createClass({
|
||||
javaScriptEnabledAndroid={true}
|
||||
onNavigationStateChange={this.onNavigationStateChange}
|
||||
startInLoadingState={true}
|
||||
scalesPageToFit={this.state.scalesPageToFit}
|
||||
/>
|
||||
<View style={styles.statusBar}>
|
||||
<Text style={styles.statusBarText}>{this.state.status}</Text>
|
||||
@@ -124,6 +126,7 @@ var WebViewExample = React.createClass({
|
||||
url: navState.url,
|
||||
status: navState.title,
|
||||
loading: navState.loading,
|
||||
scalesPageToFit: true
|
||||
});
|
||||
},
|
||||
|
||||
@@ -217,6 +220,7 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = '<WebView>';
|
||||
exports.description = 'Base component to display web content';
|
||||
exports.examples = [
|
||||
|
||||
Reference in New Issue
Block a user