wait-for-update.js 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. const queue = initialCb ? [initialCb] : []
  16. function shift () {
  17. const job = queue.shift()
  18. if (queue.length) {
  19. let hasError = false
  20. try {
  21. job.wait ? job(shift) : job()
  22. } catch (e) {
  23. hasError = true
  24. const done = queue[queue.length - 1]
  25. if (done && done.fail) {
  26. done.fail(e)
  27. }
  28. }
  29. if (!hasError && !job.wait) {
  30. if (queue.length) {
  31. Vue.nextTick(shift)
  32. }
  33. }
  34. } else if (job && job.fail) {
  35. job() // done
  36. }
  37. }
  38. Vue.nextTick(() => {
  39. if (!queue.length || !queue[queue.length - 1].fail) {
  40. throw new Error('waitForUpdate chain is missing .then(done)')
  41. }
  42. shift()
  43. })
  44. const chainer = {
  45. then: nextCb => {
  46. queue.push(nextCb)
  47. return chainer
  48. },
  49. thenWaitFor: (wait) => {
  50. if (typeof wait === 'number') {
  51. wait = timeout(wait)
  52. }
  53. wait.wait = true
  54. queue.push(wait)
  55. return chainer
  56. }
  57. }
  58. return chainer
  59. }
  60. function timeout (n) {
  61. return next => setTimeout(next, n)
  62. }