computed.spec.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import Vue from 'vue'
  2. describe('Options computed', () => {
  3. it('basic usage', done => {
  4. const vm = new Vue({
  5. template: '<div>{{ b }}</div>',
  6. data: {
  7. a: 1
  8. },
  9. computed: {
  10. b () {
  11. return this.a + 1
  12. }
  13. }
  14. }).$mount()
  15. expect(vm.b).toBe(2)
  16. expect(vm.$el.textContent).toBe('2')
  17. vm.a = 2
  18. expect(vm.b).toBe(3)
  19. waitForUpdate(() => {
  20. expect(vm.$el.textContent).toBe('3')
  21. }).then(done)
  22. })
  23. it('with setter', done => {
  24. const vm = new Vue({
  25. template: '<div>{{ b }}</div>',
  26. data: {
  27. a: 1
  28. },
  29. computed: {
  30. b: {
  31. get () { return this.a + 1 },
  32. set (v) { this.a = v - 1 }
  33. }
  34. }
  35. }).$mount()
  36. expect(vm.b).toBe(2)
  37. expect(vm.$el.textContent).toBe('2')
  38. vm.a = 2
  39. expect(vm.b).toBe(3)
  40. waitForUpdate(() => {
  41. expect(vm.$el.textContent).toBe('3')
  42. vm.b = 1
  43. expect(vm.a).toBe(0)
  44. }).then(() => {
  45. expect(vm.$el.textContent).toBe('1')
  46. }).then(done)
  47. })
  48. it('warn with setter and no getter', () => {
  49. const vm = new Vue({
  50. template: `
  51. <div>
  52. <test></test>
  53. </div>
  54. `,
  55. components: {
  56. test: {
  57. data () {
  58. return {
  59. a: 1
  60. }
  61. },
  62. computed: {
  63. b: {
  64. set (v) { this.a = v }
  65. }
  66. },
  67. template: `<div>{{a}}</div>`
  68. }
  69. }
  70. }).$mount()
  71. expect(vm.$el.innerHTML).toBe('<div>1</div>')
  72. expect('No getter function has been defined for computed property "b".').toHaveBeenWarned()
  73. })
  74. it('watching computed', done => {
  75. const spy = jasmine.createSpy('watch computed')
  76. const vm = new Vue({
  77. data: {
  78. a: 1
  79. },
  80. computed: {
  81. b () { return this.a + 1 }
  82. }
  83. })
  84. vm.$watch('b', spy)
  85. vm.a = 2
  86. waitForUpdate(() => {
  87. expect(spy).toHaveBeenCalledWith(3, 2)
  88. }).then(done)
  89. })
  90. it('caching', () => {
  91. const spy = jasmine.createSpy('cached computed')
  92. const vm = new Vue({
  93. data: {
  94. a: 1
  95. },
  96. computed: {
  97. b () {
  98. spy()
  99. return this.a + 1
  100. }
  101. }
  102. })
  103. expect(spy.calls.count()).toBe(0)
  104. vm.b
  105. expect(spy.calls.count()).toBe(1)
  106. vm.b
  107. expect(spy.calls.count()).toBe(1)
  108. })
  109. it('cache: false', () => {
  110. const spy = jasmine.createSpy('cached computed')
  111. const vm = new Vue({
  112. data: {
  113. a: 1
  114. },
  115. computed: {
  116. b: {
  117. cache: false,
  118. get () {
  119. spy()
  120. return this.a + 1
  121. }
  122. }
  123. }
  124. })
  125. expect(spy.calls.count()).toBe(0)
  126. vm.b
  127. expect(spy.calls.count()).toBe(1)
  128. vm.b
  129. expect(spy.calls.count()).toBe(2)
  130. })
  131. it('as component', done => {
  132. const Comp = Vue.extend({
  133. template: `<div>{{ b }} {{ c }}</div>`,
  134. data () {
  135. return { a: 1 }
  136. },
  137. computed: {
  138. // defined on prototype
  139. b () {
  140. return this.a + 1
  141. }
  142. }
  143. })
  144. const vm = new Comp({
  145. computed: {
  146. // defined at instantiation
  147. c () {
  148. return this.b + 1
  149. }
  150. }
  151. }).$mount()
  152. expect(vm.b).toBe(2)
  153. expect(vm.c).toBe(3)
  154. expect(vm.$el.textContent).toBe('2 3')
  155. vm.a = 2
  156. expect(vm.b).toBe(3)
  157. expect(vm.c).toBe(4)
  158. waitForUpdate(() => {
  159. expect(vm.$el.textContent).toBe('3 4')
  160. }).then(done)
  161. })
  162. it('warn conflict with data', () => {
  163. new Vue({
  164. data: {
  165. a: 1
  166. },
  167. computed: {
  168. a: () => 2
  169. }
  170. })
  171. expect(`computed property "a" is already defined in data`).toHaveBeenWarned()
  172. })
  173. it('warn conflict with props', () => {
  174. new Vue({
  175. props: ['a'],
  176. propsData: { a: 1 },
  177. computed: {
  178. a: () => 2
  179. }
  180. })
  181. expect(`computed property "a" is already defined as a prop`).toHaveBeenWarned()
  182. })
  183. })