Browse Source

Add test cases for #45

Ben Hsieh 8 years ago
parent
commit
cfbcdfbf05

+ 174
- 0
test/react-native-testkit/animate-text.js View File

1
+/**
2
+ * @author wkh237
3
+ * @version 0.1.1
4
+ */
5
+
6
+// @flow
7
+
8
+import React, { Component } from 'react';
9
+import {
10
+  Text,
11
+  View
12
+} from 'react-native';
13
+import Timer from 'react-timer-mixin';
14
+
15
+const HALF_RAD = Math.PI/2
16
+
17
+export default class AnimateNumber extends Component {
18
+
19
+  props : {
20
+    countBy? : ?number,
21
+    interval? : ?number,
22
+    steps? : ?number,
23
+    value : number,
24
+    timing : 'linear' | 'easeOut' | 'easeIn' | () => number,
25
+    formatter : () => {},
26
+    onProgress : () => {},
27
+    onFinish : () => {}
28
+  };
29
+
30
+  static defaultProps = {
31
+    interval : 14,
32
+    timing : 'linear',
33
+    steps : 45,
34
+    value : 0,
35
+    formatter : (val) => val,
36
+    onFinish : () => {}
37
+  };
38
+
39
+  static TimingFunctions = {
40
+
41
+    linear : (interval:number, progress:number):number => {
42
+      return interval
43
+    },
44
+
45
+    easeOut : (interval:number, progress:number):number => {
46
+      return interval * Math.sin(HALF_RAD*progress) * 5
47
+    },
48
+
49
+    easeIn : (interval:number, progress:number):number => {
50
+      return interval * Math.sin((HALF_RAD - HALF_RAD*progress)) * 5
51
+    },
52
+
53
+  };
54
+
55
+  state : {
56
+    value? : ?number,
57
+    displayValue? : ?number
58
+  };
59
+
60
+  /**
61
+   * Animation direction, true means positive, false means negative.
62
+   * @type {bool}
63
+   */
64
+  direction : bool;
65
+  /**
66
+   * Start value of last animation.
67
+   * @type {number}
68
+   */
69
+  startFrom : number;
70
+  /**
71
+  * End value of last animation.
72
+  * @type {number}
73
+   */
74
+  endWith : number;
75
+
76
+  constructor(props:any) {
77
+    super(props);
78
+    // default values of state and non-state variables
79
+    this.state = {
80
+      value : 0,
81
+      displayValue : 0
82
+    }
83
+    this.dirty = false;
84
+    this.startFrom = 0;
85
+    this.endWith = 0;
86
+  }
87
+
88
+  componentDidMount() {
89
+    this.startFrom = this.state.value
90
+    this.endWith = this.props.value
91
+    this.dirty = true
92
+    this.startAnimate()
93
+  }
94
+
95
+  componentWillUpdate(nextProps, nextState) {
96
+
97
+    // check if start an animation
98
+    if(this.props.value !== nextProps.value) {
99
+      this.startFrom = this.props.value
100
+      this.endWith = nextProps.value
101
+      this.dirty = true
102
+      this.startAnimate()
103
+      return
104
+    }
105
+    // Check if iterate animation frame
106
+    if(!this.dirty) {
107
+      return
108
+    }
109
+    if (this.direction === true) {
110
+      if(parseFloat(this.state.value) <= parseFloat(this.props.value)) {
111
+        this.startAnimate();
112
+      }
113
+    }
114
+    else if(this.direction === false){
115
+      if (parseFloat(this.state.value) >= parseFloat(this.props.value)) {
116
+        this.startAnimate();
117
+      }
118
+    }
119
+
120
+  }
121
+
122
+  render() {
123
+    return (
124
+      <Text {...this.props}>
125
+        {this.state.displayValue}
126
+      </Text>)
127
+  }
128
+
129
+  startAnimate() {
130
+
131
+    let progress = this.getAnimationProgress()
132
+
133
+    Timer.setTimeout(() => {
134
+
135
+      let value = (this.endWith - this.startFrom)/this.props.steps
136
+      if(this.props.countBy)
137
+        value = Math.sign(value)*Math.abs(this.props.countBy)
138
+      let total = parseFloat(this.state.value) + parseFloat(value)
139
+
140
+      this.direction = (value > 0)
141
+      // animation terminate conditions
142
+      if (((this.direction) ^ (total <= this.endWith)) === 1) {
143
+        this.dirty = false
144
+        total = this.endWith
145
+        this.props.onFinish(total, this.props.formatter(total))
146
+      }
147
+
148
+      if(this.props.onProgress)
149
+        this.props.onProgress(this.state.value, total)
150
+
151
+      this.setState({
152
+        value : total,
153
+        displayValue : this.props.formatter(total)
154
+      })
155
+
156
+    }, this.getTimingFunction(this.props.interval, progress))
157
+
158
+  }
159
+
160
+  getAnimationProgress():number {
161
+    return (this.state.value - this.startFrom) / (this.endWith - this.startFrom)
162
+  }
163
+
164
+  getTimingFunction(interval:number, progress:number) {
165
+    if(typeof this.props.timing === 'string') {
166
+      let fn = AnimateNumber.TimingFunctions[this.props.timing]
167
+      return fn(interval, progress)
168
+    } else if(typeof this.props.timing === 'function')
169
+      return this.props.timing(interval, progress)
170
+    else
171
+      return AnimateNumber.TimingFunctions['linear'](interval, progress)
172
+  }
173
+
174
+}

+ 12
- 7
test/react-native-testkit/components/reporter.js View File

13
   RecyclerViewBackedScrollView,
13
   RecyclerViewBackedScrollView,
14
 } from 'react-native';
14
 } from 'react-native';
15
 
15
 
16
+import AnimateNumber from '../animate-text.js'
16
 import Assert from './assert.js'
17
 import Assert from './assert.js'
17
 import RNTEST from '../index.js'
18
 import RNTEST from '../index.js'
18
 
19
 
51
         passed += tests[i].status === 'pass' ? 1 : 0
52
         passed += tests[i].status === 'pass' ? 1 : 0
52
     }
53
     }
53
     let percent = passed / count
54
     let percent = passed / count
54
-    let color = `rgb(${Math.floor((1-percent) *255)},${Math.floor(percent *255)}, 0)`
55
+    let color = `rgb(${Math.floor((1-percent) *255)},${Math.floor(percent *192)}, 0)`
55
 
56
 
56
     return (
57
     return (
57
       <View style={{flex : 1}}>
58
       <View style={{flex : 1}}>
64
           <Text>{`${executed} tests executed`}</Text>
65
           <Text>{`${executed} tests executed`}</Text>
65
           <Text>{`${passed} test cases passed`}</Text>
66
           <Text>{`${passed} test cases passed`}</Text>
66
           <Text>{`${count} test cases`}</Text>
67
           <Text>{`${count} test cases`}</Text>
67
-          <Text style={{color, fontSize : 120, textAlign : 'center'}} >{`${Math.floor(percent*100)}`}</Text>
68
-          <Text style={{color, fontSize : 30, textAlign :'right', marginTop : -54, marginRight : 40, backgroundColor : 'transparent'}} >{`%`}</Text>
68
+          <View style={{flexDirection : 'row', alignSelf : 'center', alignItems : 'flex-end'}}>
69
+            <AnimateNumber style={{
70
+              color,
71
+              fontSize : 100,
72
+              textAlign : 'right'
73
+            }}
74
+              value={Math.floor(passed / count*100)}
75
+              countBy={1}/>
76
+            <Text style={{color, fontSize : 30, textAlign : 'left'}} >{`%`}</Text>
77
+          </View>
69
         </View>
78
         </View>
70
         <ListView
79
         <ListView
71
           style={[styles.container]}
80
           style={[styles.container]}
109
       t.status = 'waiting'
118
       t.status = 'waiting'
110
 
119
 
111
     return (
120
     return (
112
-      // <TouchableOpacity onPress={()=>{
113
-      //   t.start(t.sn)
114
-      // }}>
115
         <View key={'rn-test-' + t.desc} style={{
121
         <View key={'rn-test-' + t.desc} style={{
116
           borderBottomWidth : 1.5,
122
           borderBottomWidth : 1.5,
117
           borderColor : '#DDD',
123
           borderColor : '#DDD',
127
             {t.expand ? t.result : (t.status === 'pass' ? null : t.result)}
133
             {t.expand ? t.result : (t.status === 'pass' ? null : t.result)}
128
           </View>
134
           </View>
129
         </View>)
135
         </View>)
130
-        {/*</TouchableOpacity>)*/}
131
   }
136
   }
132
 
137
 
133
   updateDataSource() {
138
   updateDataSource() {

+ 1
- 0
test/react-native-testkit/lib/test-context.js View File

128
           })
128
           })
129
           resolve(...res)
129
           resolve(...res)
130
         }
130
         }
131
+        RCTContext.forceUpdate()
131
       }).catch((err) => {
132
       }).catch((err) => {
132
         updateInternal({
133
         updateInternal({
133
           executed : true,
134
           executed : true,

+ 28
- 20
test/test-0.5.1.js View File

194
   let filename = '22mb-dummy-' + Date.now()
194
   let filename = '22mb-dummy-' + Date.now()
195
   let begin = -1
195
   let begin = -1
196
   let begin2 = -1
196
   let begin2 = -1
197
+  let deb = Date.now()
197
   RNFetchBlob.config({
198
   RNFetchBlob.config({
198
     fileCache : true
199
     fileCache : true
199
   })
200
   })
200
   .fetch('GET', `${TEST_SERVER_URL}/public/22mb-dummy`)
201
   .fetch('GET', `${TEST_SERVER_URL}/public/22mb-dummy`)
201
-  // .progress((now, total) => {
202
-  //   if(begin === -1)
203
-  //     begin = Date.now()
204
-  //   report(<Info uid="200" key="progress">
205
-  //     <Text>
206
-  //       {`download ${now} / ${total} bytes (${Math.floor(now / (Date.now() - begin))} kb/s)`}
207
-  //     </Text>
208
-  //   </Info>)
209
-  // })
202
+  .progress((now, total) => {
203
+    if(begin === -1)
204
+      begin = Date.now()
205
+    if(Date.now() - deb < 1000)
206
+      return
207
+    deb = Date.now()
208
+    report(<Info uid="200" key="progress">
209
+      <Text>
210
+        {`download ${now} / ${total} bytes (${Math.floor(now / (Date.now() - begin))} kb/s)`}
211
+      </Text>
212
+    </Info>)
213
+  })
210
   .then((res) => {
214
   .then((res) => {
215
+    deb = Date.now()
211
     return RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
216
     return RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
212
       Authorization : `Bearer ${DROPBOX_TOKEN}`,
217
       Authorization : `Bearer ${DROPBOX_TOKEN}`,
213
       'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+filename+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
218
       'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+filename+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
214
       'Content-Type' : 'application/octet-stream',
219
       'Content-Type' : 'application/octet-stream',
215
     }, RNFetchBlob.wrap(res.path()))
220
     }, RNFetchBlob.wrap(res.path()))
216
-    // .progress((now, total) => {
217
-    //   if(begin2 === -1)
218
-    //     begin2 = Date.now()
219
-    //   let speed = Math.floor(now / (Date.now() - begin2))
220
-    //   report(<Info uid="100"  key="progress">
221
-    //     <Text>
222
-    //       {`upload ${now} / ${total} bytes (${speed} kb/s)`}
223
-    //       {` ${Math.floor((total-now)/speed/1000)} seconds left`}
224
-    //     </Text>
225
-    //   </Info>)
226
-    // })
221
+    .progress((now, total) => {
222
+      if(Date.now() - deb < 1000)
223
+        return
224
+      deb = Date.now()
225
+      if(begin2 === -1)
226
+        begin2 = Date.now()
227
+      let speed = Math.floor(now / (Date.now() - begin2))
228
+      report(<Info uid="100"  key="progress">
229
+        <Text>
230
+          {`upload ${now} / ${total} bytes (${speed} kb/s)`}
231
+          {` ${Math.floor((total-now)/speed/1000)} seconds left`}
232
+        </Text>
233
+      </Info>)
234
+    })
227
   })
235
   })
228
   .then((res) => {
236
   .then((res) => {
229
     report(<Assert
237
     report(<Assert

+ 40
- 1
test/test-0.6.2.js View File

19
   group : '0.6.2',
19
   group : '0.6.2',
20
   run : true,
20
   run : true,
21
   expand : false,
21
   expand : false,
22
-  timeout : 12000,
22
+  timeout : 30000,
23
 })
23
 })
24
 const { TEST_SERVER_URL, TEST_SERVER_URL_SSL, DROPBOX_TOKEN, styles } = prop()
24
 const { TEST_SERVER_URL, TEST_SERVER_URL_SSL, DROPBOX_TOKEN, styles } = prop()
25
 const  dirs = RNFetchBlob.fs.dirs
25
 const  dirs = RNFetchBlob.fs.dirs
29
 
29
 
30
 describe('upload asset from camera roll', (report, done) => {
30
 describe('upload asset from camera roll', (report, done) => {
31
   let imgName = `image-from-camera-roll-${Platform.OS}.jpg`
31
   let imgName = `image-from-camera-roll-${Platform.OS}.jpg`
32
+  let tick = Date.now()
32
   CameraRoll.getPhotos({first : 10})
33
   CameraRoll.getPhotos({first : 10})
33
     .then((resp) => {
34
     .then((resp) => {
34
       let url = resp.edges[0].node.image.uri
35
       let url = resp.edges[0].node.image.uri
38
         'Dropbox-API-Arg': `{\"path\": \"/rn-upload/${imgName}\",\"mode\": \"add\",\"autorename\": false,\"mute\": false}`,
39
         'Dropbox-API-Arg': `{\"path\": \"/rn-upload/${imgName}\",\"mode\": \"add\",\"autorename\": false,\"mute\": false}`,
39
         'Content-Type' : 'application/octet-stream',
40
         'Content-Type' : 'application/octet-stream',
40
       }, RNFetchBlob.wrap(url))
41
       }, RNFetchBlob.wrap(url))
42
+      .progress((now, total) => {
43
+        if(Date.now() - tick < 1000)
44
+        return
45
+        report(<Info key="progress" uid="pg1">
46
+          <Text>{`upload ${now} / ${total} ${Math.floor(now/total*100)}% `}</Text>
47
+        </Info>)
48
+      })
41
     })
49
     })
42
     .then((resp) => {
50
     .then((resp) => {
43
       resp = resp.json()
51
       resp = resp.json()
147
       done()
155
       done()
148
     })
156
     })
149
 })
157
 })
158
+
159
+
160
+describe('upload file from assets',(report, done) => {
161
+  let assetName = fs.asset('test-asset1.json')
162
+  RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
163
+    Authorization : `Bearer ${DROPBOX_TOKEN}`,
164
+    'Dropbox-API-Arg': `{\"path\": \"/rn-upload/file-from-asset-${Platform.OS}.json\",\"mode\": \"add\",\"autorename\": false,\"mute\": false}`,
165
+    'Content-Type' : 'application/octet-stream',
166
+  }, RNFetchBlob.wrap(assetName))
167
+  .then((resp) => {
168
+    resp = resp.json()
169
+    report(
170
+      <Assert key="file name check"
171
+        expect={`file-from-asset-${Platform.OS}.json`}
172
+        actual={resp.name}/>)
173
+    done()
174
+  })
175
+})
176
+
177
+describe('Check custom MIME type correctness',(report, done) => {
178
+  RNFetchBlob.fetch('POST', `${TEST_SERVER_URL}/mime`, null, [
179
+    { name : 'image', filename : 'image', type : 'image/jpeg', data : RNFetchBlob.base64.encode('123456') },
180
+    { name : 'mp3', filename : 'mp3', type : 'application/mp3', data : RNFetchBlob.base64.encode('123456') },
181
+    { name : 'mp3', filename : 'mp3', data : RNFetchBlob.base64.encode('123456') }
182
+  ])
183
+  .then((resp) => {
184
+    resp = resp.json()
185
+    report(<Assert key="check first mime" expect={'image/jpeg'} actual={resp[0]} />)
186
+    done()
187
+  })
188
+})

+ 1
- 1
test/test-android.js View File

17
 const describe = RNTest.config({
17
 const describe = RNTest.config({
18
   group : 'Android only functions',
18
   group : 'Android only functions',
19
   run : Platform.OS === 'android',
19
   run : Platform.OS === 'android',
20
-  expand : true,
20
+  expand : false,
21
 })
21
 })
22
 const { TEST_SERVER_URL, FILENAME, DROPBOX_TOKEN, styles } = prop()
22
 const { TEST_SERVER_URL, FILENAME, DROPBOX_TOKEN, styles } = prop()
23
 
23
 

+ 7
- 6
test/test-init.js View File

51
     })
51
     })
52
 })
52
 })
53
 
53
 
54
-require('./test-0.1.x-0.4.x')
55
-require('./test-0.5.1')
56
-require('./test-0.5.2')
57
-require('./test-0.6.0')
54
+
55
+// require('./test-0.1.x-0.4.x')
56
+// require('./test-0.5.1')
57
+// require('./test-0.5.2')
58
+// require('./test-0.6.0')
58
 require('./test-0.6.2')
59
 require('./test-0.6.2')
59
-require('./test-fs')
60
-require('./test-android')
60
+// require('./test-fs')
61
+// require('./test-android')