Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit cfbcdfb

Browse files
committed
Add test cases for #45
1 parent f307c69 commit cfbcdfb

File tree

7 files changed

+263
-35
lines changed

7 files changed

+263
-35
lines changed
+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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+
}

test/react-native-testkit/components/reporter.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
RecyclerViewBackedScrollView,
1414
} from 'react-native';
1515

16+
import AnimateNumber from '../animate-text.js'
1617
import Assert from './assert.js'
1718
import RNTEST from '../index.js'
1819

@@ -51,7 +52,7 @@ export default class Reporter extends Component {
5152
passed += tests[i].status === 'pass' ? 1 : 0
5253
}
5354
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)`
5556

5657
return (
5758
<View style={{flex : 1}}>
@@ -64,8 +65,16 @@ export default class Reporter extends Component {
6465
<Text>{`${executed} tests executed`}</Text>
6566
<Text>{`${passed} test cases passed`}</Text>
6667
<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>
6978
</View>
7079
<ListView
7180
style={[styles.container]}
@@ -109,9 +118,6 @@ export default class Reporter extends Component {
109118
t.status = 'waiting'
110119

111120
return (
112-
// <TouchableOpacity onPress={()=>{
113-
// t.start(t.sn)
114-
// }}>
115121
<View key={'rn-test-' + t.desc} style={{
116122
borderBottomWidth : 1.5,
117123
borderColor : '#DDD',
@@ -127,7 +133,6 @@ export default class Reporter extends Component {
127133
{t.expand ? t.result : (t.status === 'pass' ? null : t.result)}
128134
</View>
129135
</View>)
130-
{/*</TouchableOpacity>)*/}
131136
}
132137

133138
updateDataSource() {

test/react-native-testkit/lib/test-context.js

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ export default class TestContext {
128128
})
129129
resolve(...res)
130130
}
131+
RCTContext.forceUpdate()
131132
}).catch((err) => {
132133
updateInternal({
133134
executed : true,

test/test-0.5.1.js

+28-20
Original file line numberDiff line numberDiff line change
@@ -194,36 +194,44 @@ RNTest.config({
194194
let filename = '22mb-dummy-' + Date.now()
195195
let begin = -1
196196
let begin2 = -1
197+
let deb = Date.now()
197198
RNFetchBlob.config({
198199
fileCache : true
199200
})
200201
.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+
})
210214
.then((res) => {
215+
deb = Date.now()
211216
return RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
212217
Authorization : `Bearer ${DROPBOX_TOKEN}`,
213218
'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+filename+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
214219
'Content-Type' : 'application/octet-stream',
215220
}, 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+
})
227235
})
228236
.then((res) => {
229237
report(<Assert

test/test-0.6.2.js

+40-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const describe = RNTest.config({
1919
group : '0.6.2',
2020
run : true,
2121
expand : false,
22-
timeout : 12000,
22+
timeout : 30000,
2323
})
2424
const { TEST_SERVER_URL, TEST_SERVER_URL_SSL, DROPBOX_TOKEN, styles } = prop()
2525
const dirs = RNFetchBlob.fs.dirs
@@ -29,6 +29,7 @@ let photo = null
2929

3030
describe('upload asset from camera roll', (report, done) => {
3131
let imgName = `image-from-camera-roll-${Platform.OS}.jpg`
32+
let tick = Date.now()
3233
CameraRoll.getPhotos({first : 10})
3334
.then((resp) => {
3435
let url = resp.edges[0].node.image.uri
@@ -38,6 +39,13 @@ describe('upload asset from camera roll', (report, done) => {
3839
'Dropbox-API-Arg': `{\"path\": \"/rn-upload/${imgName}\",\"mode\": \"add\",\"autorename\": false,\"mute\": false}`,
3940
'Content-Type' : 'application/octet-stream',
4041
}, 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+
})
4149
})
4250
.then((resp) => {
4351
resp = resp.json()
@@ -147,3 +155,34 @@ describe('copy asset', (report, done) => {
147155
done()
148156
})
149157
})
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+
})

test/test-android.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const { Assert, Comparer, Info, prop } = RNTest
1717
const describe = RNTest.config({
1818
group : 'Android only functions',
1919
run : Platform.OS === 'android',
20-
expand : true,
20+
expand : false,
2121
})
2222
const { TEST_SERVER_URL, FILENAME, DROPBOX_TOKEN, styles } = prop()
2323

test/test-init.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ describe('GET image from server', (report, done) => {
5151
})
5252
})
5353

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')
5859
require('./test-0.6.2')
59-
require('./test-fs')
60-
require('./test-android')
60+
// require('./test-fs')
61+
// require('./test-android')

0 commit comments

Comments
 (0)