Нет описания

reporter.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import React, {Component} from 'react';
  2. import {
  3. AppRegistry,
  4. StyleSheet,
  5. Text,
  6. View,
  7. Platform,
  8. ScrollView,
  9. ListView,
  10. Image,
  11. TouchableOpacity,
  12. Dimensions,
  13. RecyclerViewBackedScrollView,
  14. } from 'react-native';
  15. import Assert from './assert.js'
  16. import RNTEST from '../index.js'
  17. export default class Reporter extends Component {
  18. constructor(props:any) {
  19. super(props)
  20. this.tests = {
  21. common : []
  22. }
  23. this.state = {
  24. listHeight : 0
  25. }
  26. this.testGroups = ['summary','common']
  27. this.ds = null
  28. this.updateDataSource()
  29. }
  30. componentWillUpdate(nextProps, nextState) {
  31. this.updateDataSource()
  32. }
  33. render() {
  34. let tests = RNTEST.TestContext.getTests()
  35. let passed = 0
  36. let executed = 0
  37. let count = 0
  38. for(let i in tests) {
  39. if(tests[i].status !== 'skipped')
  40. count++
  41. if(tests[i].status !== 'waiting' && tests[i].status !== 'skipped')
  42. executed++
  43. passed += tests[i].status === 'pass' ? 1 : 0
  44. }
  45. let percent = passed / count
  46. let color = `rgb(${Math.floor((1-percent) *255)},${Math.floor(percent *255)}, 0)`
  47. return (
  48. <View style={{flex : 1}}>
  49. <View style={{margin : 20}} onLayout={(e) => {
  50. this.setState({
  51. headerHeight : e.nativeEvent.layout.height,
  52. listHeight : Dimensions.get('window').height - e.nativeEvent.layout.height
  53. })
  54. }}>
  55. <Text>{`${executed} tests executed`}</Text>
  56. <Text>{`${passed} test cases passed`}</Text>
  57. <Text>{`${count} test cases`}</Text>
  58. <Text style={{color, fontSize : 120, textAlign : 'center'}} >{`${Math.floor(percent*100)}`}</Text>
  59. <Text style={{color, fontSize : 30, textAlign :'right', marginTop : -54, marginRight : 40, backgroundColor : 'transparent'}} >{`%`}</Text>
  60. </View>
  61. <ListView
  62. style={[styles.container]}
  63. dataSource={this.ds}
  64. renderRow={this.renderTest.bind(this)}
  65. renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
  66. renderSectionHeader={(data, id) => {
  67. return (
  68. <View style={styles.sectionHeader}>
  69. <Text style={styles.sectionText}>{id}</Text>
  70. </View>
  71. )
  72. }}
  73. />
  74. </View>)
  75. }
  76. renderTest(t, group) {
  77. let pass = true
  78. let foundActions = false
  79. let tests = RNTEST.TestContext.getTests()
  80. if(Array.isArray(t.result) && !t.expired) {
  81. t.result = t.result.map((r) => {
  82. if(r.type.name === 'Assert' || r.type.name === 'Info') {
  83. foundActions = true
  84. let comp = r.props.comparer ? r.props.comparer(r.props.expect, r.props.actual) : (r.props.actual === r.props.expect)
  85. pass = pass && comp
  86. }
  87. return React.cloneElement(r, {desc : r.key})
  88. })
  89. }
  90. if(tests[t.sn].running)
  91. t.status = 'running'
  92. else if(tests[t.sn].executed) {
  93. t.status = foundActions ? (pass ? 'pass' : 'fail') : 'skipped'
  94. t.status = t.expired ? 'timeout' : t.status
  95. }
  96. else
  97. t.status = 'waiting'
  98. return (
  99. // <TouchableOpacity onPress={()=>{
  100. // t.start(t.sn)
  101. // }}>
  102. <View key={'rn-test-' + t.desc} style={{
  103. borderBottomWidth : 1.5,
  104. borderColor : '#DDD',
  105. }}>
  106. <View key={t.desc} style={{
  107. alignItems : 'center',
  108. flexDirection : 'row'
  109. }}>
  110. <Text style={[styles.badge, {flex : 1, borderWidth : 0, textAlign : 'left'}]}>{t.desc}</Text>
  111. <Text style={[styles.badge, this.getBadge(t.status)]}>{t.status}</Text>
  112. </View>
  113. <View key={t.desc + '-result'} style={{backgroundColor : '#F4F4F4'}}>
  114. {t.expand ? t.result : (t.status === 'pass' ? null : t.result)}
  115. </View>
  116. </View>)
  117. {/*</TouchableOpacity>)*/}
  118. }
  119. updateDataSource() {
  120. this.tests = {
  121. common : []
  122. }
  123. this.testGroups = ['common']
  124. RNTEST.TestContext.getTests().forEach((t) => {
  125. if(t.group) {
  126. if(!this.tests[t.group]) {
  127. this.testGroups.push(t.group)
  128. this.tests[t.group] = []
  129. }
  130. this.tests[t.group].push(t)
  131. }
  132. else
  133. this.tests.common.push(t)
  134. })
  135. let listDataSource = new ListView.DataSource({
  136. rowHasChanged : (r1, r2) => r1 !== r2,
  137. sectionHeaderHasChanged: (s1, s2) => s1 !== s2
  138. })
  139. this.ds = listDataSource.cloneWithRowsAndSections(this.tests, this.testGroups)
  140. }
  141. getBadge(status: 'waiting' | 'running' | 'pass' | 'fail' | 'timeout') {
  142. return styles[status]
  143. }
  144. }
  145. const styles = StyleSheet.create({
  146. container: {
  147. flex: 1,
  148. },
  149. badge : {
  150. margin : 16,
  151. padding : 4,
  152. borderRadius : 4,
  153. borderWidth : 2,
  154. textAlign : 'center'
  155. },
  156. skipped: {
  157. borderColor : '#AAAAAA',
  158. color : '#AAAAAA'
  159. },
  160. sectionHeader : {
  161. padding : 16,
  162. backgroundColor : '#F4F4F4',
  163. },
  164. waiting: {
  165. borderColor : '#AAAAAA',
  166. color : '#AAAAAA'
  167. },
  168. pass: {
  169. borderColor : '#00a825',
  170. color : '#00a825'
  171. },
  172. running: {
  173. borderColor : '#e3c423',
  174. color : '#e3c423'
  175. },
  176. fail: {
  177. borderColor : '#ff0d0d',
  178. color : '#ff0d0d'
  179. },
  180. timeout: {
  181. borderColor : '#ff0d0d',
  182. color : '#ff0d0d'
  183. }
  184. });