Нет описания

test-context.js 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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. new Promise((done) => {
  59. this.fn.bind(this)(update, done)
  60. })
  61. .then((...res) => {
  62. if(!expired) {
  63. clearTimeout(tm)
  64. updateInternal({
  65. executed : true,
  66. running : false
  67. })
  68. resolve(...res)
  69. }
  70. }).catch((err) => {
  71. updateInternal({
  72. executed : true,
  73. running : false
  74. })
  75. })
  76. })
  77. }
  78. .bind(
  79. this.tests[i],
  80. this.update.bind(this, i),
  81. this.updateInternal.bind(this, i)
  82. ))
  83. }
  84. return promise
  85. }
  86. /**
  87. * Update test task result of given index.
  88. * @param {number} i Index of test case to be updated.
  89. * @param {ReactElement<Info | Assert>} ...data Assertion or Info of test.
  90. * @return {void}
  91. */
  92. update(i, ...data) {
  93. let test = this.tests[i]
  94. let result = test.result || []
  95. Object.assign(test, {result : [...result, ...data]})
  96. this.context.forceUpdate()
  97. }
  98. /**
  99. * Update test result for testkit internal use
  100. * @param {[type]} i Index of test case to be updated.
  101. * @param {TestCaseContext} result Test case object
  102. * @return {void}
  103. */
  104. updateInternal(i, result) {
  105. Object.assign(this.tests[i], result)
  106. this.context.forceUpdate()
  107. }
  108. }