暫無描述

test-context.js 2.8KB

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