[tests] Move test suite into same repo

This commit is contained in:
Aleck Greenham
2017-04-23 20:22:19 +01:00
parent fac0efa9d0
commit 9308994db2
148 changed files with 11251 additions and 1 deletions

View File

@@ -0,0 +1,51 @@
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
function Banner({ type, children, style, textStyle }) {
return (
<View style={[styles.banner, styles[type || 'default'], style]}>
<Text
numberOfLines={1}
style={[styles.bannerText, textStyle]}
>
{children}
</Text>
</View>
);
}
Banner.propTypes = {
type: React.PropTypes.oneOf([
'success',
'warning',
'error',
'info',
]),
children: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.array,
]).isRequired,
style: View.propTypes.style,
textStyle: Text.propTypes.style,
};
const styles = StyleSheet.create({
banner: {
alignItems: 'center',
elevation: 3,
},
bannerText: {
color: '#ffffff',
},
warning: {
backgroundColor: '#FFC107',
},
error: {
backgroundColor: '#f44336',
},
success: {
backgroundColor: '#4CAF50',
},
});
export default Banner;

View File

@@ -0,0 +1,75 @@
import React from 'react';
import { View, TouchableHighlight } from 'react-native';
import VectorIcon from 'react-native-vector-icons/MaterialIcons';
type Props = {
name: string,
size?: number,
color?: string,
allowFontScaling?: boolean,
style?: Object,
rotate?: number,
onPress?: () => void,
underlayColor?: string,
};
// TODO Spin?
class Icon extends React.Component {
constructor() {
super();
this.measured = false;
this.state = {
width: 0,
};
}
setDimensions(e) {
if (!this.measured) {
this.measured = true;
this.setState({
width: e.nativeEvent.layout.width,
});
}
}
props: Props;
render() {
const { name, size = 24, color = '#757575', allowFontScaling = true, style, rotate, onPress, underlayColor } = this.props;
const icon = (
<View
onLayout={(e) => this.setDimensions(e)}
style={[
style,
rotate ? { transform: [{ rotate: `${rotate}deg` }] } : null,
]}
>
<VectorIcon
name={name.toLowerCase().replace(/\s+/g, '-')}
size={size}
color={color}
allowFontScaling={allowFontScaling}
/>
</View>
);
if (!onPress) {
return icon;
}
return (
<TouchableHighlight
underlayColor={underlayColor || 'rgba(0, 0, 0, 0.054)'}
onPress={onPress}
style={{ padding: 8, borderRadius: (this.state.width + 8) / 2 }}
>
{icon}
</TouchableHighlight>
);
}
}
export default Icon;

View File

@@ -0,0 +1,70 @@
import React, { PropTypes, Component } from 'react';
import some from 'lodash.some';
import { connect } from 'react-redux';
import Toast from 'react-native-simple-toast';
import { runTests } from '../tests/index';
import RunStatus from '../../lib/RunStatus';
import Icon from '../components/Icon';
class OverviewControlButton extends Component {
constructor(props, context) {
super(props, context);
this.handleOnPress = this.handleOnPress.bind(this);
}
testSuitesAreRunning() {
const { testSuites } = this.props;
return some(Object.values(testSuites), ({ status }) => status === RunStatus.RUNNING);
}
handleOnPress() {
const { focusedTestIds, pendingTestIds, tests } = this.props;
runTests(tests, { focusedTestIds, pendingTestIds });
Toast.show('Running all suite tests.');
}
render() {
if (this.testSuitesAreRunning()) {
return (
<Icon
color={'#ffffff'}
size={28}
name="autorenew"
/>
);
}
return (
<Icon
color={'#ffffff'}
size={28}
name="play circle filled"
onPress={this.handleOnPress}
/>
);
}
}
OverviewControlButton.propTypes = {
tests: PropTypes.objectOf(PropTypes.object).isRequired,
testSuites: PropTypes.objectOf(PropTypes.object).isRequired,
focusedTestIds: PropTypes.objectOf(PropTypes.bool).isRequired,
pendingTestIds: PropTypes.objectOf(PropTypes.bool).isRequired,
};
function mapStateToProps({ tests, testSuites, focusedTestIds, pendingTestIds }) {
return {
tests,
testSuites,
focusedTestIds,
pendingTestIds,
};
}
export default connect(mapStateToProps)(OverviewControlButton);

View File

@@ -0,0 +1,52 @@
import { View, Text } from 'react-native';
import React, { PropTypes, Component } from 'react';
import RunStatus from '../../lib/RunStatus';
import Icon from './Icon';
class StatusIndicator extends Component {
render() {
const { status, progress } = this.props;
switch (status) {
case RunStatus.RUNNING:
if (progress > 0) {
return (
<View style={{ width: 30, flex: 1, justifyContent: 'flex-end' }}>
<Text style={{ fontSize: 11, marginBottom: 20 }}>
{progress.toFixed(0)}%
</Text>
</View>
);
}
return (
<Icon color={'rgba(0, 0, 0, 0.2)'} name="autorenew" />
);
case RunStatus.OK:
return (
<Icon name={'done'} />
);
case RunStatus.ERR:
return (
<Icon color={'#f44336'} name="clear" />
);
default:
return null;
}
}
}
StatusIndicator.propTypes = {
status: PropTypes.oneOf(Object.values(RunStatus)),
progress: PropTypes.number,
};
StatusIndicator.defaultProps = {
status: null,
progress: 0
};
module.exports = StatusIndicator;

View File

@@ -0,0 +1,71 @@
import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import Toast from 'react-native-simple-toast';
import RunStatus from '../../lib/RunStatus';
import { runTest } from '../tests/index';
import Icon from './Icon';
class TestControlButton extends Component {
constructor(props, context) {
super(props, context);
this.handleOnPress = this.handleOnPress.bind(this);
}
testIsPending() {
const { test: { id }, pendingTestIds } = this.props;
return !!pendingTestIds[id];
}
handleOnPress() {
const { test: { id, description } } = this.props;
runTest(id);
Toast.show(`Running ${description}.`);
}
render() {
const { test: { status } } = this.props;
if (status !== RunStatus.STARTED && !this.testIsPending()) {
return (
<Icon
color={'#ffffff'}
size={28}
name="play circle filled"
onPress={this.handleOnPress}
/>
);
}
return null;
}
}
TestControlButton.propTypes = {
test: PropTypes.shape({
id: PropTypes.number.isRequired,
status: PropTypes.string,
description: PropTypes.string.isRequired,
}).isRequired,
pendingTestIds: PropTypes.objectOf(PropTypes.bool).isRequired,
};
TestControlButton.defaultProps = {
};
function mapStateToProps({ tests, pendingTestIds }, { testId }) {
const test = tests[testId];
return {
test,
pendingTestIds,
};
}
module.exports = connect(mapStateToProps)(TestControlButton);

View File

@@ -0,0 +1,96 @@
import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import Toast from 'react-native-simple-toast';
import RunStatus from '../../lib/RunStatus';
import { runTests } from '../tests/index';
import Icon from './Icon';
class TestSuiteControlButton extends Component {
constructor(props, context) {
super(props, context);
this.toggleOnlyShowFailingTests = this.toggleOnlyShowFailingTests.bind(this);
this.startTestSuite = this.startTestSuite.bind(this);
}
startTestSuite() {
const { testSuite: { name, testIds }, tests, focusedTestIds, pendingTestIds } = this.props;
const testSuiteTests = testIds.reduce((memo, testId) => {
// eslint-disable-next-line no-param-reassign
memo[testId] = tests[testId];
return memo;
}, {});
runTests(testSuiteTests, { focusedTestIds, pendingTestIds });
Toast.show(`Running ${name} tests.`);
}
toggleOnlyShowFailingTests() {
const { onlyShowFailingTests, onFilterChange } = this.props;
onFilterChange({ onlyShowFailingTests: !onlyShowFailingTests });
}
render() {
const { testSuite: { status }, onlyShowFailingTests } = this.props;
if (status === RunStatus.ERR) {
return (
<Icon
color={onlyShowFailingTests ? '#ffffff' : 'rgba(255, 255, 255, 0.54)'}
size={28}
name="error outline"
onPress={this.toggleOnlyShowFailingTests}
/>
);
} else if (status !== RunStatus.RUNNING) {
return (
<Icon
color={'#ffffff'}
size={28}
name="play circle filled"
onPress={this.startTestSuite}
/>
);
}
return null;
}
}
TestSuiteControlButton.propTypes = {
testSuite: PropTypes.shape({
status: PropTypes.oneOf(Object.values(RunStatus)),
}).isRequired,
tests: PropTypes.objectOf(PropTypes.object).isRequired,
focusedTestIds: PropTypes.objectOf(PropTypes.bool).isRequired,
pendingTestIds: PropTypes.objectOf(PropTypes.bool).isRequired,
onlyShowFailingTests: PropTypes.bool,
onFilterChange: PropTypes.func.isRequired,
};
TestSuiteControlButton.defaultProps = {
onlyShowFailingTests: false,
};
function mapStateToProps({ tests, testSuites, focusedTestIds, pendingTestIds }, { testSuiteId }) {
const testSuite = testSuites[testSuiteId];
return {
tests,
testSuite,
focusedTestIds,
pendingTestIds,
};
}
module.exports = connect(mapStateToProps)(TestSuiteControlButton);