watch.spec.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import Vue from 'vue'
  2. import testObjectOption from '../../../helpers/test-object-option'
  3. describe('Options watch', () => {
  4. let spy
  5. beforeEach(() => {
  6. spy = vi.fn()
  7. })
  8. testObjectOption('watch')
  9. it('basic usage', done => {
  10. const vm = new Vue({
  11. data: {
  12. a: 1
  13. },
  14. watch: {
  15. a: spy
  16. }
  17. })
  18. expect(spy).not.toHaveBeenCalled()
  19. vm.a = 2
  20. expect(spy).not.toHaveBeenCalled()
  21. waitForUpdate(() => {
  22. expect(spy).toHaveBeenCalledWith(2, 1)
  23. }).then(done)
  24. })
  25. it('string method name', done => {
  26. const vm = new Vue({
  27. data: {
  28. a: 1
  29. },
  30. watch: {
  31. a: 'onChange'
  32. },
  33. methods: {
  34. onChange: spy
  35. }
  36. })
  37. expect(spy).not.toHaveBeenCalled()
  38. vm.a = 2
  39. expect(spy).not.toHaveBeenCalled()
  40. waitForUpdate(() => {
  41. expect(spy).toHaveBeenCalledWith(2, 1)
  42. }).then(done)
  43. })
  44. it('multiple cbs (after option merge)', done => {
  45. const spy1 = vi.fn()
  46. const Test = Vue.extend({
  47. watch: {
  48. a: spy1
  49. }
  50. })
  51. const vm = new Test({
  52. data: { a: 1 },
  53. watch: {
  54. a: spy
  55. }
  56. })
  57. vm.a = 2
  58. waitForUpdate(() => {
  59. expect(spy1).toHaveBeenCalledWith(2, 1)
  60. expect(spy).toHaveBeenCalledWith(2, 1)
  61. }).then(done)
  62. })
  63. it('with option: immediate', done => {
  64. const vm = new Vue({
  65. data: { a: 1 },
  66. watch: {
  67. a: {
  68. handler: spy,
  69. immediate: true
  70. }
  71. }
  72. })
  73. expect(spy).toHaveBeenCalledWith(1)
  74. vm.a = 2
  75. waitForUpdate(() => {
  76. expect(spy).toHaveBeenCalledWith(2, 1)
  77. }).then(done)
  78. })
  79. it('with option: deep', done => {
  80. const vm = new Vue({
  81. data: { a: { b: 1 } },
  82. watch: {
  83. a: {
  84. handler: spy,
  85. deep: true
  86. }
  87. }
  88. })
  89. const oldA = vm.a
  90. expect(spy).not.toHaveBeenCalled()
  91. vm.a.b = 2
  92. expect(spy).not.toHaveBeenCalled()
  93. waitForUpdate(() => {
  94. expect(spy).toHaveBeenCalledWith(vm.a, vm.a)
  95. vm.a = { b: 3 }
  96. })
  97. .then(() => {
  98. expect(spy).toHaveBeenCalledWith(vm.a, oldA)
  99. })
  100. .then(done)
  101. })
  102. it('correctly merges multiple extends', done => {
  103. const spy2 = vi.fn()
  104. const spy3 = vi.fn()
  105. const A = Vue.extend({
  106. data: function () {
  107. return {
  108. a: 0,
  109. b: 0
  110. }
  111. },
  112. watch: {
  113. b: spy
  114. }
  115. })
  116. const B = Vue.extend({
  117. extends: A,
  118. watch: {
  119. a: spy2
  120. }
  121. })
  122. const C = Vue.extend({
  123. extends: B,
  124. watch: {
  125. a: spy3
  126. }
  127. })
  128. const vm = new C()
  129. vm.a = 1
  130. waitForUpdate(() => {
  131. expect(spy).not.toHaveBeenCalled()
  132. expect(spy2).toHaveBeenCalledWith(1, 0)
  133. expect(spy3).toHaveBeenCalledWith(1, 0)
  134. }).then(done)
  135. })
  136. it('should support watching unicode paths', done => {
  137. const vm = new Vue({
  138. data: {
  139. 数据: 1
  140. },
  141. watch: {
  142. 数据: spy
  143. }
  144. })
  145. expect(spy).not.toHaveBeenCalled()
  146. vm['数据'] = 2
  147. expect(spy).not.toHaveBeenCalled()
  148. waitForUpdate(() => {
  149. expect(spy).toHaveBeenCalledWith(2, 1)
  150. }).then(done)
  151. })
  152. it('should not warn proper usage', () => {
  153. new Vue({
  154. data: {
  155. foo: { _bar: 1 }, // element has such watchers...
  156. prop1: 123
  157. },
  158. watch: {
  159. 'foo._bar': () => {},
  160. prop1() {}
  161. }
  162. })
  163. expect(`Failed watching path`).not.toHaveBeenWarned()
  164. })
  165. })