set-delete.spec.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import Vue from 'vue'
  2. describe('Global API: set/delete', () => {
  3. describe('Vue.set', () => {
  4. it('should update a vue object', done => {
  5. const vm = new Vue({
  6. template: '<div>{{x}}</div>',
  7. data: { x: 1 }
  8. }).$mount()
  9. expect(vm.$el.innerHTML).toBe('1')
  10. Vue.set(vm, 'x', 2)
  11. waitForUpdate(() => {
  12. expect(vm.$el.innerHTML).toBe('2')
  13. }).then(done)
  14. })
  15. it('should update an observing object', done => {
  16. const vm = new Vue({
  17. template: '<div>{{foo.x}}</div>',
  18. data: { foo: { x: 1 }}
  19. }).$mount()
  20. expect(vm.$el.innerHTML).toBe('1')
  21. Vue.set(vm.foo, 'x', 2)
  22. waitForUpdate(() => {
  23. expect(vm.$el.innerHTML).toBe('2')
  24. }).then(done)
  25. })
  26. it('should update an observing array', done => {
  27. const vm = new Vue({
  28. template: '<div><div v-for="v,k in list">{{k}}-{{v}}</div></div>',
  29. data: { list: ['a', 'b', 'c'] }
  30. }).$mount()
  31. expect(vm.$el.innerHTML).toBe('<div>0-a</div><div>1-b</div><div>2-c</div>')
  32. Vue.set(vm.list, 1, 'd')
  33. waitForUpdate(() => {
  34. expect(vm.$el.innerHTML).toBe('<div>0-a</div><div>1-d</div><div>2-c</div>')
  35. Vue.set(vm.list, '2', 'e')
  36. }).then(() => {
  37. expect(vm.$el.innerHTML).toBe('<div>0-a</div><div>1-d</div><div>2-e</div>')
  38. /* eslint-disable no-new-wrappers */
  39. Vue.set(vm.list, new Number(1), 'f')
  40. }).then(() => {
  41. expect(vm.$el.innerHTML).toBe('<div>0-a</div><div>1-f</div><div>2-e</div>')
  42. Vue.set(vm.list, '3g', 'g')
  43. }).then(() => {
  44. expect(vm.$el.innerHTML).toBe('<div>0-a</div><div>1-f</div><div>2-e</div>')
  45. }).then(done)
  46. })
  47. it('should update a vue object with nothing', done => {
  48. const vm = new Vue({
  49. template: '<div>{{x}}</div>',
  50. data: { x: 1 }
  51. }).$mount()
  52. expect(vm.$el.innerHTML).toBe('1')
  53. Vue.set(vm, 'x', null)
  54. waitForUpdate(() => {
  55. expect(vm.$el.innerHTML).toBe('')
  56. Vue.set(vm, 'x')
  57. }).then(() => {
  58. expect(vm.$el.innerHTML).toBe('')
  59. }).then(done)
  60. })
  61. it('be able to use string type index in array', done => {
  62. const vm = new Vue({
  63. template: '<div><p v-for="obj in lists">{{obj.name}}</p></div>',
  64. data: {
  65. lists: [
  66. { name: 'A' },
  67. { name: 'B' },
  68. { name: 'C' }
  69. ]
  70. }
  71. }).$mount()
  72. expect(vm.$el.innerHTML).toBe('<p>A</p><p>B</p><p>C</p>')
  73. Vue.set(vm.lists, '0', { name: 'D' })
  74. waitForUpdate(() => {
  75. expect(vm.$el.innerHTML).toBe('<p>D</p><p>B</p><p>C</p>')
  76. }).then(done)
  77. })
  78. // #6845
  79. it('should not overwrite properties on prototype chain', () => {
  80. class Model {
  81. _bar?: string
  82. constructor () {
  83. this._bar = null
  84. }
  85. get bar () {
  86. return this._bar
  87. }
  88. set bar (newvalue) {
  89. this._bar = newvalue
  90. }
  91. }
  92. const vm = new Vue({
  93. data: {
  94. data: new Model()
  95. }
  96. })
  97. Vue.set(vm.data, 'bar', 123)
  98. expect(vm.data.bar).toBe(123)
  99. expect(vm.data.hasOwnProperty('bar')).toBe(false)
  100. expect(vm.data._bar).toBe(123)
  101. })
  102. })
  103. describe('Vue.delete', () => {
  104. it('should delete a key', done => {
  105. const vm = new Vue({
  106. template: '<div>{{obj.x}}</div>',
  107. data: { obj: { x: 1 }}
  108. }).$mount()
  109. expect(vm.$el.innerHTML).toBe('1')
  110. vm.obj.x = 2
  111. waitForUpdate(() => {
  112. expect(vm.$el.innerHTML).toBe('2')
  113. Vue.delete(vm.obj, 'x')
  114. }).then(() => {
  115. expect(vm.$el.innerHTML).toBe('')
  116. vm.obj.x = 3
  117. }).then(() => {
  118. expect(vm.$el.innerHTML).toBe('')
  119. }).then(done)
  120. })
  121. it('be able to delete an item in array', done => {
  122. const vm = new Vue({
  123. template: '<div><p v-for="obj in lists">{{obj.name}}</p></div>',
  124. data: {
  125. lists: [
  126. { name: 'A' },
  127. { name: 'B' },
  128. { name: 'C' }
  129. ]
  130. }
  131. }).$mount()
  132. expect(vm.$el.innerHTML).toBe('<p>A</p><p>B</p><p>C</p>')
  133. Vue.delete(vm.lists, 1)
  134. waitForUpdate(() => {
  135. expect(vm.$el.innerHTML).toBe('<p>A</p><p>C</p>')
  136. Vue.delete(vm.lists, NaN)
  137. }).then(() => {
  138. expect(vm.$el.innerHTML).toBe('<p>A</p><p>C</p>')
  139. Vue.delete(vm.lists, -1)
  140. }).then(() => {
  141. expect(vm.$el.innerHTML).toBe('<p>A</p><p>C</p>')
  142. Vue.delete(vm.lists, '1.3')
  143. }).then(() => {
  144. expect(vm.$el.innerHTML).toBe('<p>A</p><p>C</p>')
  145. Vue.delete(vm.lists, true)
  146. }).then(() => {
  147. expect(vm.$el.innerHTML).toBe('<p>A</p><p>C</p>')
  148. Vue.delete(vm.lists, {})
  149. }).then(() => {
  150. expect(vm.$el.innerHTML).toBe('<p>A</p><p>C</p>')
  151. Vue.delete(vm.lists, '1')
  152. }).then(() => {
  153. expect(vm.$el.innerHTML).toBe('<p>A</p>')
  154. /* eslint-disable no-new-wrappers */
  155. Vue.delete(vm.lists, new Number(0) as number)
  156. }).then(() => {
  157. expect(vm.$el.innerHTML).toBe('')
  158. }).then(done)
  159. })
  160. })
  161. })