Open sourced SwipeRefreshLayoutRecordingModule

Reviewed By: dmmiller

Differential Revision: D3264212

fb-gh-sync-id: 8790200a0d3c47050d6a91c906854b3a55640829
fbshipit-source-id: 8790200a0d3c47050d6a91c906854b3a55640829
This commit is contained in:
Konstantin Raev 2016-05-05 08:17:02 -07:00 committed by Facebook Github Bot 7
parent a1ba0918ab
commit 457e348081
10 changed files with 832 additions and 17 deletions

View File

@ -5,31 +5,41 @@ include_defs('//ReactAndroid/DEFS')
SANDCASTLE_FLAKY = [ SANDCASTLE_FLAKY = [
'ReactHorizontalScrollViewTestCase.java', 'ReactHorizontalScrollViewTestCase.java',
'ReactScrollViewTestCase.java', 'ReactScrollViewTestCase.java',
'ReactSwipeRefreshLayoutTestCase.java',
'TestIdTestCase.java',
]
deps = [
react_native_integration_tests_target('java/com/facebook/react/testing:testing'),
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/views/picker:picker'),
react_native_target('java/com/facebook/react/views/swiperefresh:swiperefresh'),
react_native_target('java/com/facebook/react:react'),
react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/views/progressbar:progressbar'),
react_native_target('java/com/facebook/react/views/recyclerview:recyclerview'),
react_native_target('java/com/facebook/react/views/scroll:scroll'),
react_native_target('java/com/facebook/react/views/slider:slider'),
react_native_target('java/com/facebook/react/views/text:text'),
react_native_target('java/com/facebook/react/views/textinput:textinput'),
react_native_target('java/com/facebook/react/views/view:view'),
react_native_dep('third-party/android/support/v4:lib-support-v4'),
] ]
android_library( android_library(
name = 'tests', name = 'tests',
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [
react_native_integration_tests_target('java/com/facebook/react/testing:testing'),
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/views/picker:picker'),
],
visibility = [ visibility = [
'PUBLIC', 'PUBLIC',
], ],
deps = deps,
) )
android_library( android_library(
name = 'stable-tests', name = 'stable-tests',
srcs = glob(['**/*.java'], excludes=SANDCASTLE_FLAKY), srcs = glob(['**/*.java'], excludes=SANDCASTLE_FLAKY),
deps = [ deps = deps,
react_native_integration_tests_target('java/com/facebook/react/testing:testing'),
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/views/picker:picker'),
],
visibility = [ visibility = [
'PUBLIC', 'PUBLIC',
], ],

View File

@ -0,0 +1,104 @@
/**
* Copyright (c) 2014-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.
*/
package com.facebook.react.tests;
import android.view.View;
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
import com.facebook.react.testing.ReactInstanceSpecForTest;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.views.swiperefresh.ReactSwipeRefreshLayout;
/**
* Test case for {@link ReactSwipeRefreshLayout}.
*/
public class ReactSwipeRefreshLayoutTestCase extends ReactAppInstrumentationTestCase {
private class SwipeRefreshLayoutRecordingModule extends BaseJavaModule {
private int mCount = 0;
@Override
public String getName() {
return "SwipeRefreshLayoutRecordingModule";
}
@ReactMethod
public void onRefresh() {
mCount++;
}
public int getCount() {
return mCount;
}
}
private interface SwipeRefreshLayoutTestModule extends JavaScriptModule {
void setRows(int rows);
}
private final SwipeRefreshLayoutRecordingModule mRecordingModule =
new SwipeRefreshLayoutRecordingModule();
@Override
protected String getReactApplicationKeyUnderTest() {
return "SwipeRefreshLayoutTestApp";
}
@Override
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
return super.createReactInstanceSpecForTest()
.addNativeModule(mRecordingModule)
.addJSModule(SwipeRefreshLayoutTestModule.class);
}
public void testRefreshNoScroll() {
View refreshLayout = getViewAtPath(0);
createGestureGenerator()
.startGesture(refreshLayout.getWidth() / 2, 10)
.dragTo(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2, 100, 1000)
.endGesture();
waitForBridgeAndUIIdle();
assertEquals(1, mRecordingModule.getCount());
}
public void testRefreshScroll() {
View refreshLayout = getViewAtPath(0);
getReactContext().getJSModule(SwipeRefreshLayoutTestModule.class).setRows(100);
createGestureGenerator()
.startGesture(refreshLayout.getWidth() / 2, 10)
.dragTo(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2, 100, 1000)
.endGesture();
waitForBridgeAndUIIdle();
assertEquals(1, mRecordingModule.getCount());
}
public void testNoRefreshAfterScroll() {
View refreshLayout = getViewAtPath(0);
getReactContext().getJSModule(SwipeRefreshLayoutTestModule.class).setRows(100);
createGestureGenerator()
.startGesture(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2)
.dragTo(refreshLayout.getWidth() / 2, 10, 100, 1000)
.endGesture();
waitForBridgeAndUIIdle();
createGestureGenerator()
.startGesture(refreshLayout.getWidth() / 2, 10)
.dragTo(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2, 100, 1000)
.endGesture();
waitForBridgeAndUIIdle();
assertEquals(0, mRecordingModule.getCount());
}
}

View File

@ -0,0 +1,62 @@
/**
* Copyright (c) 2014-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.
*/
package com.facebook.react.tests;
import java.util.Arrays;
import java.util.List;
import android.view.View;
import com.facebook.react.views.picker.ReactDropdownPickerManager;
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
import com.facebook.react.testing.ReactInstanceSpecForTest;
import com.facebook.react.testing.ReactTestHelper;
/**
* Tests that the 'testID' property can be set on various views.
* The 'testID' property is used to locate views in UI tests.
*/
public class TestIdTestCase extends ReactAppInstrumentationTestCase {
@Override
protected String getReactApplicationKeyUnderTest() {
return "TestIdTestApp";
}
private final List<String> viewTags = Arrays.asList(
"Image",
"ProgressBar",
"ScrollView",
"Horizontal ScrollView",
"Dropdown Picker",
"Dialog Picker",
"Switch",
"Text",
"TouchableBounce",
"TouchableHighlight",
"TouchableOpacity",
"TouchableWithoutFeedback",
"Toolbar",
"TextInput",
"View",
"WebView",
"ScrollView Item (same id used for all items)");
public void testPropertyIsSetForViews() {
for (String tag : viewTags) {
View viewWithTag = ReactTestHelper.getViewWithReactTestId(
getActivity().getRootView(),
tag);
assertNotNull(
"View with testID tag " + tag + " was not found. Check TestIdTestModule.js.",
viewWithTag);
}
}
}

View File

@ -0,0 +1,223 @@
/**
* Copyright (c) 2014-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.
*/
package com.facebook.react.tests;
import android.graphics.Color;
import android.text.style.ForegroundColorSpan;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.common.SystemClock;
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
import com.facebook.react.testing.ReactInstanceSpecForTest;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.textinput.ReactEditText;
import com.facebook.react.views.textinput.ReactTextChangedEvent;
import com.facebook.react.views.textinput.ReactTextInputEvent;
/**
* Test to verify that TextInput renders correctly
*/
public class TextInputTestCase extends ReactAppInstrumentationTestCase {
private interface TextInputTestModule extends JavaScriptModule {
void setValueRef(String ref, String value);
}
/**
* Test that the actual height of the text input is not dependant on the font size of the text
* within.
*/
public void testTextInputMeasurements() {
View textInputViewHeightSet = getViewByTestId("textInput1");
EditText textInputViewNoHeight = getViewByTestId("textInput2");
int expectedHeight = Math.round(PixelUtil.toPixelFromDIP(30));
assertEquals(expectedHeight, textInputViewHeightSet.getHeight());
EditText editText = new EditText(textInputViewNoHeight.getContext());
editText.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
(float) Math.ceil(PixelUtil.toPixelFromSP(21.f)));
editText.setPadding(0, 0, 0, 0);
int measureSpec = View.MeasureSpec.makeMeasureSpec(
ViewGroup.LayoutParams.WRAP_CONTENT,
View.MeasureSpec.UNSPECIFIED);
editText.measure(measureSpec, measureSpec);
assertEquals(editText.getMeasuredHeight(), textInputViewNoHeight.getHeight());
}
/**
* Test that the cursor moves to the end of the word.
*/
public void testTextInputCursorPosition() throws Throwable {
final EditText textInputWithText = getViewByTestId("textInput3");
runTestOnUiThread(
new Runnable() {
@Override
public void run() {
textInputWithText.setSelection(3);
}
});
getReactContext().getJSModule(TextInputTestModule.class)
.setValueRef("textInput3", "Some other value");
waitForBridgeAndUIIdle();
assertEquals(4, textInputWithText.getSelectionStart());
assertEquals(4, textInputWithText.getSelectionEnd());
}
/**
* Test that the colors are applied to new text
*/
public void testTextInputColors() throws Throwable {
String testIDs[] = new String[] {"textInput4", "textInput5", "textInput6"};
for (String testID : testIDs) {
getReactContext().getJSModule(TextInputTestModule.class).setValueRef(testID, "NewText");
}
waitForBridgeAndUIIdle();
for (String testID : testIDs) {
ReactEditText reactEditText = getViewByTestId(testID);
assertEquals(
Color.GREEN,
reactEditText.getText().getSpans(0, 1, ForegroundColorSpan.class)[0]
.getForegroundColor());
}
}
/**
* Test that the mentions input has colors displayed correctly.
*/
public void testMetionsInputColors() throws Throwable {
EventDispatcher eventDispatcher =
getReactContext().getNativeModule(UIManagerModule.class).getEventDispatcher();
ReactEditText reactEditText = getViewByTestId("tokenizedInput");
String newText = "#Things and more #things";
int contentWidth = reactEditText.getWidth();
int contentHeight = reactEditText.getHeight();
int start = 0;
int count = newText.length();
eventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
reactEditText.getId(),
SystemClock.nanoTime(),
newText.toString(),
(int) PixelUtil.toDIPFromPixel(contentWidth),
(int) PixelUtil.toDIPFromPixel(contentHeight),
reactEditText.incrementAndGetEventCounter()));
eventDispatcher.dispatchEvent(
new ReactTextInputEvent(
reactEditText.getId(),
SystemClock.nanoTime(),
newText.toString(),
"",
start,
start + count - 1));
waitForBridgeAndUIIdle();
ForegroundColorSpan[] spans = reactEditText
.getText().getSpans(0, reactEditText.getText().length(), ForegroundColorSpan.class);
assertEquals(2, spans.length);
assertEquals(spans[0].getForegroundColor(), spans[1].getForegroundColor());
assertEquals(0, reactEditText.getText().getSpanStart(spans[1]));
assertEquals(7, reactEditText.getText().getSpanEnd(spans[1]));
assertEquals(newText.length() - 7, reactEditText.getText().getSpanStart(spans[0]));
assertEquals(newText.length(), reactEditText.getText().getSpanEnd(spans[0]));
String moreText = "andsuch ";
String previousText = newText;
newText += moreText;
count = moreText.length();
start = previousText.length();
eventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
reactEditText.getId(),
SystemClock.nanoTime(),
newText.toString(),
(int) PixelUtil.toDIPFromPixel(contentWidth),
(int) PixelUtil.toDIPFromPixel(contentHeight),
reactEditText.incrementAndGetEventCounter()));
eventDispatcher.dispatchEvent(
new ReactTextInputEvent(
reactEditText.getId(),
SystemClock.nanoTime(),
moreText,
"",
start,
start + count - 1));
waitForBridgeAndUIIdle();
spans = reactEditText.getText()
.getSpans(0, reactEditText.getText().length(), ForegroundColorSpan.class);
assertEquals(2, spans.length);
assertEquals(spans[0].getForegroundColor(), spans[1].getForegroundColor());
assertEquals(0, reactEditText.getText().getSpanStart(spans[1]));
assertEquals(7, reactEditText.getText().getSpanEnd(spans[1]));
assertEquals(newText.length() - 15, reactEditText.getText().getSpanStart(spans[0]));
assertEquals(newText.length() - 1, reactEditText.getText().getSpanEnd(spans[0]));
moreText = "morethings";
previousText = newText;
newText += moreText;
count = moreText.length();
start = previousText.length();
eventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
reactEditText.getId(),
SystemClock.nanoTime(),
newText.toString(),
(int) PixelUtil.toDIPFromPixel(contentWidth),
(int) PixelUtil.toDIPFromPixel(contentHeight),
reactEditText.incrementAndGetEventCounter()));
eventDispatcher.dispatchEvent(
new ReactTextInputEvent(
reactEditText.getId(),
SystemClock.nanoTime(),
moreText,
"",
start,
start + count - 1));
waitForBridgeAndUIIdle();
spans = reactEditText.getText()
.getSpans(0, reactEditText.getText().length(), ForegroundColorSpan.class);
assertEquals(spans[0].getForegroundColor(), spans[1].getForegroundColor());
assertEquals(2, spans.length);
assertEquals(0, reactEditText.getText().getSpanStart(spans[1]));
assertEquals(7, reactEditText.getText().getSpanEnd(spans[1]));
assertEquals(newText.length() - 25, reactEditText.getText().getSpanStart(spans[0]));
assertEquals(newText.length() - 11, reactEditText.getText().getSpanEnd(spans[0]));
}
@Override
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
return super.createReactInstanceSpecForTest()
.addJSModule(TextInputTestModule.class);
}
@Override
protected String getReactApplicationKeyUnderTest() {
return "TextInputTestApp";
}
}

View File

@ -0,0 +1,90 @@
/**
* Copyright (c) 2013-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.
*
* @providesModule SwipeRefreshLayoutTestModule
*/
'use strict';
var BatchedBridge = require('BatchedBridge');
var React = require('React');
var RecordingModule = require('NativeModules').SwipeRefreshLayoutRecordingModule;
var ScrollView = require('ScrollView');
var PullToRefreshViewAndroid = require('PullToRefreshViewAndroid');
var Text = require('Text');
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
var View = require('View');
var Row = React.createClass({
getInitialState: function() {
return {
clicks: 0,
};
},
render: function() {
return (
<TouchableWithoutFeedback onPress={this._onPress}>
<View>
<Text>
{this.state.clicks + ' clicks'}
</Text>
</View>
</TouchableWithoutFeedback>
);
},
_onPress: function() {
this.setState({clicks: this.state.clicks + 1});
},
});
var app = null;
var SwipeRefreshLayoutTestApp = React.createClass({
getInitialState: function() {
return {
rows: 2,
};
},
componentDidMount: function() {
app = this;
},
render: function() {
var rows = [];
for (var i = 0; i < this.state.rows; i++) {
rows.push(<Row key={i} />);
}
return (
<PullToRefreshViewAndroid
style={{flex: 1}}
onRefresh={() => RecordingModule.onRefresh()}>
<ScrollView style={{flex: 1}}>
{rows}
</ScrollView>
</PullToRefreshViewAndroid>
);
},
});
var SwipeRefreshLayoutTestModule = {
SwipeRefreshLayoutTestApp,
setRows: function(rows) {
if (app != null) {
app.setState({rows});
}
}
};
BatchedBridge.registerCallableModule(
'SwipeRefreshLayoutTestModule',
SwipeRefreshLayoutTestModule
);
module.exports = SwipeRefreshLayoutTestModule;

View File

@ -15,15 +15,13 @@ console.disableYellowBox = true;
// Include modules used by integration tests // Include modules used by integration tests
require('ScrollViewTestModule'); require('ScrollViewTestModule');
require('PickerAndroidTestModule'); require('PickerAndroidTestModule');
require('SwipeRefreshLayoutTestModule');
require('TextInputTestModule');
// Define catalyst test apps used in integration tests // Define catalyst test apps used in integration tests
var AppRegistry = require('AppRegistry'); var AppRegistry = require('AppRegistry');
var apps = [ var apps = [
{
appKey: 'ScrollViewTestApp',
component: () => require('ScrollViewTestModule').ScrollViewTestApp,
},
{ {
appKey: 'HorizontalScrollViewTestApp', appKey: 'HorizontalScrollViewTestApp',
component: () => require('ScrollViewTestModule').HorizontalScrollViewTestApp, component: () => require('ScrollViewTestModule').HorizontalScrollViewTestApp,
@ -32,7 +30,25 @@ var apps = [
appKey: 'PickerAndroidTestApp', appKey: 'PickerAndroidTestApp',
component: () => require('PickerAndroidTestModule').PickerAndroidTestApp, component: () => require('PickerAndroidTestModule').PickerAndroidTestApp,
}, },
{
appKey: 'ScrollViewTestApp',
component: () => require('ScrollViewTestModule').ScrollViewTestApp,
},
{
appKey: 'SwipeRefreshLayoutTestApp',
component: () => require('SwipeRefreshLayoutTestModule').SwipeRefreshLayoutTestApp
},
{
appKey: 'TextInputTestApp',
component: () => require('TextInputTestModule').TextInputTestApp
},
{
appKey: 'TestIdTestApp',
component: () => require('TestIdTestModule').TestIdTestApp
},
]; ];
module.exports = apps; module.exports = apps;
AppRegistry.registerConfig(apps); AppRegistry.registerConfig(apps);

View File

@ -0,0 +1,135 @@
/**
* Copyright (c) 2013-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.
*
* @providesModule TestIdTestModule
*/
'use strict';
var Image = require('Image');
var ProgressBarAndroid = require('ProgressBarAndroid');
var React = require('React');
var ScrollView = require('ScrollView');
var Picker = require('Picker');
var StyleSheet = require('StyleSheet');
var SwitchAndroid = require('SwitchAndroid');
var Text = require('Text');
var TextInput = require('TextInput');
var ToolbarAndroid = require('ToolbarAndroid');
var TouchableBounce = require('TouchableBounce');
var TouchableHighlight = require('TouchableHighlight');
var TouchableOpacity = require('TouchableOpacity');
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
var View = require('View');
var WebView = require('WebView');
/**
* All the views implemented on Android, each with the testID property set.
* We test that:
* - The app renders fine
* - The testID property is passed to the native views
*/
var TestIdTestApp = React.createClass({
render: function() {
return (
<View>
<Image
testID="Image"
source={{uri: 'data:image/gif;base64,' +
'R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapy' +
'uvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/' +
'TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5' +
'iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97V' +
'riy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7'}}
style={styles.base} />
<ProgressBarAndroid
testID="ProgressBar"
styleAttr="Horizontal"
style={styles.base} />
<ScrollView
testID="ScrollView"
style={styles.base}>
<Text testID="ScrollView Item (same id used for all items)">Item 1</Text>
<Text testID="ScrollView Item (same id used for all items)">Item 2</Text>
</ScrollView>
<ScrollView
testID="Horizontal ScrollView"
horizontal={true}
style={styles.base}>
<Text testID="ScrollView Item (same id used for all items)">Item 1</Text>
<Text testID="ScrollView Item (same id used for all items)">Item 2</Text>
</ScrollView>
<Picker
testID="Dropdown Picker"
mode={Picker.MODE_DROPDOWN}
style={styles.base}>
<Picker.Item label="Dropdown picker" value="key0" />
</Picker>
<Picker
testID="Dialog Picker"
mode={Picker.MODE_DIALOG}
style={styles.base}>
<Picker.Item label="Dialog picker" value="key0" />
</Picker>
<SwitchAndroid testID="Switch" value={true} />
<Text testID="Text">text</Text>
<ToolbarAndroid testID="Toolbar" style={styles.base} subtitle="toolbar" />
<TextInput testID="TextInput" value="Text input" />
<TouchableBounce testID="TouchableBounce">
<Text>TouchableBounce</Text>
</TouchableBounce>
<TouchableHighlight testID="TouchableHighlight">
<Text>TouchableHighlight</Text>
</TouchableHighlight>
<TouchableOpacity testID="TouchableOpacity">
<Text>TouchableOpacity</Text>
</TouchableOpacity>
<TouchableWithoutFeedback testID="TouchableWithoutFeedback">
<View>
<Text>TouchableWithoutFeedback</Text>
</View>
</TouchableWithoutFeedback>
<View testID="View" />
<WebView
testID="WebView"
url={'http://newsroom.fb.com'}
renderError={() => <View /> }
style={styles.base}
/>
</View>
);
},
});
var styles = StyleSheet.create({
base: {
width: 150,
height: 50,
},
});
module.exports = {
TestIdTestApp: TestIdTestApp,
};

View File

@ -0,0 +1,170 @@
/**
* Copyright (c) 2013-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.
*
* @providesModule TextInputTestModule
*/
"use strict";
var BatchedBridge = require('BatchedBridge');
var React = require('React');
var StyleSheet = require('StyleSheet');
var Text = require('Text');
var TextInput = require('TextInput');
var View = require('View');
var app;
class TokenizedTextExample extends React.Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
//define delimiter
let delimiter = /\s+/;
//split string
let _text = this.state.text;
let token, index, parts = [];
while (_text) {
delimiter.lastIndex = 0;
token = delimiter.exec(_text);
if (token === null) {
break;
}
index = token.index;
if (token[0].length === 0) {
index = 1;
}
parts.push(_text.substr(0, index));
parts.push(token[0]);
index = index + token[0].length;
_text = _text.slice(index);
}
parts.push(_text);
//highlight hashtags
parts = parts.map((text) => {
if (/^#/.test(text)) {
return <Text key={text} style={styles.hashtag}>{text}</Text>;
} else {
return text;
}
});
return (
<View>
<TextInput
ref="tokenizedInput"
testID="tokenizedInput"
multiline={true}
style={styles.multiline}
onChangeText={(text) => {
this.setState({text});
}}>
<Text>{parts}</Text>
</TextInput>
</View>
);
}
}
var TextInputTestApp = React.createClass({
componentDidMount: function() {
app = this;
},
render: function() {
return (
<View style={styles.container}>
<TextInput
style={styles.textInputHeight}
autoCorrect={true}
autoFocus={true}
keyboardType='numeric'
multiline={true}
password={true}
defaultValue="This is text"
testID="textInput1"
/>
<TextInput
style={styles.textInput}
autoCapitalize='sentences'
autoCorrect={false}
autoFocus={false}
keyboardType='default'
multiline={false}
password={false}
placeholder='1234'
testID="textInput2"
/>
<TextInput
ref="textInput3"
style={styles.textInput}
defaultValue="Hello, World"
testID="textInput3"
/>
<TextInput
ref="textInput4"
style={[styles.textInput, {color: '#00ff00'}]}
testID="textInput4"
/>
<TextInput
ref="textInput5"
style={[styles.textInput, {color: '#00ff00'}]}
defaultValue=""
testID="textInput5"
/>
<TextInput
ref="textInput6"
style={[styles.textInput, {color: '#00ff00'}]}
defaultValue="Text"
testID="textInput6"
/>
<TokenizedTextExample />
</View>
);
},
});
var styles = StyleSheet.create({
container: {
padding: 5,
margin: 10,
},
textInputHeight: {
fontSize: 21,
height: 30,
},
textInput: {
fontSize: 21,
padding: 0,
},
hashtag: {
color: 'blue',
fontWeight: 'bold',
},
});
var TextInputTestModule = {
TextInputTestApp,
setValueRef: function(ref, value) {
app.refs[ref].setNativeProps({
text: value,
});
},
};
BatchedBridge.registerCallableModule(
'TextInputTestModule',
TextInputTestModule
);
module.exports = TextInputTestModule;

View File

@ -3,6 +3,8 @@
# Runs all Android integration tests locally. # Runs all Android integration tests locally.
# See http://facebook.github.io/react-native/docs/testing.html # See http://facebook.github.io/react-native/docs/testing.html
set -e
which buck > /dev/null || { which buck > /dev/null || {
echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html"; echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html";
exit 1; exit 1;
@ -13,6 +15,7 @@ echo "Compiling native code..."
echo "Building JS bundle..." echo "Building JS bundle..."
node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
echo "Installing test app on the device..." echo "Installing test app on the device..."
buck fetch ReactAndroid/src/androidTest/buck-runner:instrumentation-tests
buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests
echo "Running integration tests..." echo "Running integration tests..."
./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests adb shell am instrument -w com.facebook.react.tests/android.support.test.runner.AndroidJUnitRunner

View File

@ -3,6 +3,8 @@
# Runs all Android unit tests locally. # Runs all Android unit tests locally.
# See http://facebook.github.io/react-native/docs/testing.html # See http://facebook.github.io/react-native/docs/testing.html
set -e
which buck > /dev/null || { which buck > /dev/null || {
echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html"; echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html";
exit 1; exit 1;