scheduler.spec.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import Vue from 'vue'
  2. import config from 'core/config'
  3. import { queueWatcher } from 'core/observer/scheduler'
  4. describe('Scheduler', () => {
  5. let spy
  6. beforeEach(() => {
  7. spy = jasmine.createSpy('scheduler')
  8. })
  9. it('queueWatcher', done => {
  10. queueWatcher({
  11. run: spy
  12. })
  13. waitForUpdate(() => {
  14. expect(spy.calls.count()).toBe(1)
  15. }).then(done)
  16. })
  17. it('dedup', done => {
  18. queueWatcher({
  19. id: 1,
  20. run: spy
  21. })
  22. queueWatcher({
  23. id: 1,
  24. run: spy
  25. })
  26. waitForUpdate(() => {
  27. expect(spy.calls.count()).toBe(1)
  28. }).then(done)
  29. })
  30. it('allow duplicate when flushing', done => {
  31. const job = {
  32. id: 1,
  33. run: spy
  34. }
  35. queueWatcher(job)
  36. queueWatcher({
  37. id: 2,
  38. run () { queueWatcher(job) }
  39. })
  40. waitForUpdate(() => {
  41. expect(spy.calls.count()).toBe(2)
  42. }).then(done)
  43. })
  44. it('call user watchers before component re-render', done => {
  45. const calls = []
  46. const vm = new Vue({
  47. data: {
  48. a: 1
  49. },
  50. template: '<div>{{ a }}</div>',
  51. watch: {
  52. a () { calls.push(1) }
  53. },
  54. beforeUpdate () {
  55. calls.push(2)
  56. }
  57. }).$mount()
  58. vm.a = 2
  59. waitForUpdate(() => {
  60. expect(calls).toEqual([1, 2])
  61. }).then(done)
  62. })
  63. it('call user watcher triggered by component re-render immediately', done => {
  64. // this happens when a component re-render updates the props of a child
  65. const calls = []
  66. const vm = new Vue({
  67. data: {
  68. a: 1
  69. },
  70. watch: {
  71. a () {
  72. calls.push(1)
  73. }
  74. },
  75. beforeUpdate () {
  76. calls.push(2)
  77. },
  78. template: '<div><test :a="a"></test></div>',
  79. components: {
  80. test: {
  81. props: ['a'],
  82. template: '<div>{{ a }}</div>',
  83. watch: {
  84. a () {
  85. calls.push(3)
  86. }
  87. },
  88. beforeUpdate () {
  89. calls.push(4)
  90. }
  91. }
  92. }
  93. }).$mount()
  94. vm.a = 2
  95. waitForUpdate(() => {
  96. expect(calls).toEqual([1, 2, 3, 4])
  97. }).then(done)
  98. })
  99. it('warn against infinite update loops', function (done) {
  100. let count = 0
  101. const job = {
  102. id: 1,
  103. run () {
  104. count++
  105. queueWatcher(job)
  106. }
  107. }
  108. queueWatcher(job)
  109. waitForUpdate(() => {
  110. expect(count).toBe(config._maxUpdateCount + 1)
  111. expect('infinite update loop').toHaveBeenWarned()
  112. }).then(done)
  113. })
  114. it('should call newly pushed watcher after current watcher is done', done => {
  115. const callOrder = []
  116. queueWatcher({
  117. id: 1,
  118. user: true,
  119. run () {
  120. callOrder.push(1)
  121. queueWatcher({
  122. id: 2,
  123. run () {
  124. callOrder.push(3)
  125. }
  126. })
  127. callOrder.push(2)
  128. }
  129. })
  130. waitForUpdate(() => {
  131. expect(callOrder).toEqual([1, 2, 3])
  132. }).then(done)
  133. })
  134. })