wait-for-update.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import Vue from 'vue'
  2. // helper for async assertions.
  3. // Use like this:
  4. //
  5. // vm.a = 123
  6. // waitForUpdate(() => {
  7. // expect(vm.$el.textContent).toBe('123')
  8. // vm.a = 234
  9. // })
  10. // .then(() => {
  11. // // more assertions...
  12. // })
  13. // .then(done)
  14. window.waitForUpdate = initialCb => {
  15. let end
  16. const queue = initialCb ? [initialCb] : []
  17. function shift () {
  18. const job = queue.shift()
  19. if (queue.length) {
  20. let hasError = false
  21. try {
  22. job.wait ? job(shift) : job()
  23. } catch (e) {
  24. hasError = true
  25. const done = queue[queue.length - 1]
  26. if (done && done.fail) {
  27. done.fail(e)
  28. }
  29. }
  30. if (!hasError && !job.wait) {
  31. if (queue.length) {
  32. Vue.nextTick(shift)
  33. }
  34. }
  35. } else if (job && (job.fail || job === end)) {
  36. job() // done
  37. }
  38. }
  39. Vue.nextTick(() => {
  40. if (!queue.length || (!end && !queue[queue.length - 1].fail)) {
  41. throw new Error('waitForUpdate chain is missing .then(done)')
  42. }
  43. shift()
  44. })
  45. const chainer = {
  46. then: nextCb => {
  47. queue.push(nextCb)
  48. return chainer
  49. },
  50. thenWaitFor: (wait) => {
  51. if (typeof wait === 'number') {
  52. wait = timeout(wait)
  53. }
  54. wait.wait = true
  55. queue.push(wait)
  56. return chainer
  57. },
  58. end: endFn => {
  59. queue.push(endFn)
  60. end = endFn
  61. }
  62. }
  63. return chainer
  64. }
  65. function timeout (n) {
  66. return next => setTimeout(next, n)
  67. }