Browse Source

Change testkit API and function

Ben Hsieh 8 years ago
parent
commit
dad766f308

+ 32
- 18
test/react-native-testkit/components/reporter.js View File

25
   }
25
   }
26
 
26
 
27
   renderTests() {
27
   renderTests() {
28
-    return this.props.context.tests.map((t, i) => {
28
+    let tests = this.props.context.tests
29
+    return tests.map((t, i) => {
29
 
30
 
30
       let pass = true
31
       let pass = true
31
-      let foundAssertions = false
32
+      let foundActions = false
32
 
33
 
33
-      if(Array.isArray(t.result)) {
34
+      if(Array.isArray(t.result) && !t.expired) {
34
         t.result = t.result.map((r) => {
35
         t.result = t.result.map((r) => {
35
-          if(r.type.name === 'Assert') {
36
-            foundAssertions = true
36
+          if(r.type.name === 'Assert' || r.type.name === 'Info') {
37
+            foundActions = true
37
             let comp = r.props.comparer ? r.props.comparer(r.props.expect, r.props.actual) : (r.props.actual === r.props.expect)
38
             let comp = r.props.comparer ? r.props.comparer(r.props.expect, r.props.actual) : (r.props.actual === r.props.expect)
38
             pass = pass && comp
39
             pass = pass && comp
39
           }
40
           }
40
           return React.cloneElement(r, {desc : r.key})
41
           return React.cloneElement(r, {desc : r.key})
41
         })
42
         })
42
       }
43
       }
43
-
44
-      t.status = foundAssertions ? (pass ? 'pass' : 'fail') : 'pass'
44
+      if(tests[i].running)
45
+        t.status = 'running'
46
+      else if(this.props.context.tests[i].executed) {
47
+        t.status = foundActions ? (pass ? 'pass' : 'fail') : 'skipped'
48
+        t.status = t.expired ? 'timeout' : t.status
49
+      }
50
+      else
51
+        t.status = 'waiting'
45
 
52
 
46
       return (<View key={'rn-test-' + t.desc} style={{
53
       return (<View key={'rn-test-' + t.desc} style={{
47
         borderBottomWidth : 1.5,
54
         borderBottomWidth : 1.5,
52
           flexDirection : 'row'
59
           flexDirection : 'row'
53
         }}>
60
         }}>
54
           <Text style={[styles.badge, {flex : 1, borderWidth : 0, textAlign : 'left'}]}>{t.desc}</Text>
61
           <Text style={[styles.badge, {flex : 1, borderWidth : 0, textAlign : 'left'}]}>{t.desc}</Text>
55
-          <Text style={[styles.badge, this.getBadge(t.status)]}>{t.status ? 'pass' : 'fail'}</Text>
62
+          <Text style={[styles.badge, this.getBadge(t.status)]}>{t.status}</Text>
56
         </View>
63
         </View>
57
         <View key={t.desc + '-result'} style={{backgroundColor : '#F4F4F4'}}>
64
         <View key={t.desc + '-result'} style={{backgroundColor : '#F4F4F4'}}>
58
           {t.result}
65
           {t.result}
61
     })
68
     })
62
   }
69
   }
63
 
70
 
64
-  getBadge(status: 'running' | 'pass' | 'fail') {
65
-    if(status === 'running')
66
-      return styles.badgeWaiting
67
-    else if(status === 'pass')
68
-      return styles.badgePass
69
-    else
70
-      return styles.badgeFail
71
+  getBadge(status: 'waiting' | 'running' | 'pass' | 'fail' | 'timeout') {
72
+    return styles[status]
71
   }
73
   }
72
 
74
 
73
 }
75
 }
84
     borderWidth : 2,
86
     borderWidth : 2,
85
     textAlign : 'center'
87
     textAlign : 'center'
86
   },
88
   },
87
-  badgePass: {
89
+  skipped: {
90
+    borderColor : '#AAAAAA',
91
+    color : '#AAAAAA'
92
+  },
93
+  waiting: {
94
+    borderColor : '#AAAAAA',
95
+    color : '#AAAAAA'
96
+  },
97
+  pass: {
88
     borderColor : '#00a825',
98
     borderColor : '#00a825',
89
     color : '#00a825'
99
     color : '#00a825'
90
   },
100
   },
91
-  badgeWaiting: {
101
+  running: {
92
     borderColor : '#e3c423',
102
     borderColor : '#e3c423',
93
     color : '#e3c423'
103
     color : '#e3c423'
94
   },
104
   },
95
-  badgeFail: {
105
+  fail: {
106
+    borderColor : '#ff0d0d',
107
+    color : '#ff0d0d'
108
+  },
109
+  timeout: {
96
     borderColor : '#ff0d0d',
110
     borderColor : '#ff0d0d',
97
     color : '#ff0d0d'
111
     color : '#ff0d0d'
98
   }
112
   }

+ 90
- 8
test/react-native-testkit/lib/test-context.js View File

1
+//@flow
1
 export default class TestContext {
2
 export default class TestContext {
2
 
3
 
4
+  test: Array<TestCase>;
5
+  context: ReactElement;
6
+
7
+  static timeout = 3000;
8
+
9
+  static setTimeout (val) {
10
+    this.timeout  = val
11
+  }
12
+
3
   constructor() {
13
   constructor() {
4
     this.tests = []
14
     this.tests = []
5
     this.context = null
15
     this.context = null
6
   }
16
   }
7
 
17
 
8
-  describe (desc, fn) {
18
+  /**
19
+   * Calling this method will push a test case into task queue.
20
+   * @param  {String}   desc Description of test case.
21
+   * @param  {Function:Promise<any>} fn   Body of test case, this function
22
+   *         should return a promise.
23
+   * @return {void}
24
+   */
25
+  describe (desc:string, fn:() => Promise<any>) {
9
 
26
 
10
     this.tests.push({
27
     this.tests.push({
11
-      status : 'running',
28
+      status : 'waiting',
12
       result : null,
29
       result : null,
13
       asserts : [],
30
       asserts : [],
31
+      timeout : 3000,
32
+      expired : false,
33
+      running : false,
34
+      executed : false,
14
       desc, fn,
35
       desc, fn,
15
     })
36
     })
16
 
37
 
17
   }
38
   }
18
 
39
 
19
-  run (context) {
40
+  /**
41
+   * Run test cases in sequence.
42
+   * @param  {ReactElement} context ReactElement instance context.
43
+   * @return {void}
44
+   */
45
+  run (context:ReactElement) {
20
     this.context = context
46
     this.context = context
21
     let promise = Promise.resolve()
47
     let promise = Promise.resolve()
48
+    // run test case sequently
22
     for(let i in this.tests) {
49
     for(let i in this.tests) {
23
-      promise = promise.then(function(update, data) {
24
-        return this.fn(update, data)
25
-      }.bind(
50
+      promise = promise.then(function(update, updateInternal, data) {
51
+        return new Promise((resolve, reject) => {
52
+
53
+          let expired = false
54
+          updateInternal({
55
+            running : true,
56
+          })
57
+
58
+          // set timeout timer
59
+          let tm = setTimeout(() => {
60
+            updateInternal({
61
+              expired : true,
62
+              executed : true,
63
+              running : false
64
+            })
65
+            resolve('ETIMEOUT')
66
+          }, this.timeout)
67
+
68
+          // run test body
69
+          this.fn.bind(this)(update, data).then((...res) => {
70
+            if(!expired) {
71
+              clearTimeout(tm)
72
+              updateInternal({
73
+                executed : true,
74
+                running : false
75
+              })
76
+              resolve(...res)
77
+            }
78
+          }).catch((err) => {
79
+            updateInternal({
80
+              executed : true,
81
+              running : false
82
+            })
83
+          })
84
+
85
+        })
86
+      }
87
+      .bind(
26
         this.tests[i],
88
         this.tests[i],
27
-        this.update.bind(this, i)
89
+        this.update.bind(this, i),
90
+        this.updateInternal.bind(this, i)
28
       ))
91
       ))
29
     }
92
     }
30
     return promise
93
     return promise
31
   }
94
   }
32
 
95
 
96
+  /**
97
+   * Update test task result of given index.
98
+   * @param  {number} i       Index of test case to be updated.
99
+   * @param  {ReactElement<Info | Assert>} ...data Assertion or Info of test.
100
+   * @return {void}
101
+   */
33
   update(i, ...data) {
102
   update(i, ...data) {
34
-    Object.assign(this.tests[i], {result : [...data]})
103
+    let test = this.tests[i]
104
+    let result = test.result || []
105
+    Object.assign(test, {result : [...result, ...data]})
106
+    this.context.forceUpdate()
107
+  }
108
+
109
+  /**
110
+   * Update test result for testkit internal use
111
+   * @param  {[type]} i      Index of test case to be updated.
112
+   * @param  {TestCaseContext} result Test case object
113
+   * @return {void}
114
+   */
115
+  updateInternal(i, result) {
116
+    Object.assign(this.tests[i], result)
35
     this.context.forceUpdate()
117
     this.context.forceUpdate()
36
   }
118
   }
37
 
119