model-dynamic.spec.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import Vue from 'vue'
  2. describe('Directive v-model dynamic input type', () => {
  3. it('should work', done => {
  4. const vm = new Vue({
  5. data: {
  6. inputType: null,
  7. test: 'b'
  8. },
  9. template: `<input :type="inputType" v-model="test">`
  10. }).$mount()
  11. document.body.appendChild(vm.$el)
  12. // test text
  13. assertInputWorks(vm, 'inputType').then(done)
  14. })
  15. it('with v-if', done => {
  16. const vm = new Vue({
  17. data: {
  18. ok: true,
  19. type: null,
  20. test: 'b'
  21. },
  22. template: `<input v-if="ok" :type="type" v-model="test"><div v-else>haha</div>`
  23. }).$mount()
  24. document.body.appendChild(vm.$el)
  25. const chain = assertInputWorks(vm).then(() => {
  26. vm.ok = false
  27. }).then(() => {
  28. expect(vm.$el.textContent).toBe('haha')
  29. }).then(() => {
  30. // reset
  31. vm.ok = true
  32. vm.type = null
  33. vm.test = 'b'
  34. })
  35. assertInputWorks(vm, chain).then(done)
  36. })
  37. it('with v-else', done => {
  38. const data = {
  39. ok: true,
  40. type: null,
  41. test: 'b'
  42. }
  43. const vm = new Vue({
  44. data,
  45. template: `<div v-if="ok">haha</div><input v-else :type="type" v-model="test">`
  46. }).$mount()
  47. document.body.appendChild(vm.$el)
  48. expect(vm.$el.textContent).toBe('haha')
  49. vm.ok = false
  50. assertInputWorks(vm).then(done)
  51. })
  52. it('with v-else-if', done => {
  53. const vm = new Vue({
  54. data: {
  55. foo: true,
  56. bar: false,
  57. type: null,
  58. test: 'b'
  59. },
  60. template: `<div v-if="foo">text</div><input v-else-if="bar" :type="type" v-model="test">`
  61. }).$mount()
  62. document.body.appendChild(vm.$el)
  63. const chain = waitForUpdate(() => {
  64. expect(vm.$el.textContent).toBe('text')
  65. }).then(() => {
  66. vm.foo = false
  67. }).then(() => {
  68. expect(vm._vnode.isComment).toBe(true)
  69. }).then(() => {
  70. vm.bar = true
  71. })
  72. assertInputWorks(vm, chain).then(done)
  73. })
  74. it('with v-for', done => {
  75. const vm = new Vue({
  76. data: {
  77. data: {
  78. text: 'foo',
  79. checkbox: true
  80. },
  81. types: ['text', 'checkbox']
  82. },
  83. template: `<div>
  84. <input v-for="type in types" :type="type" v-model="data[type]">
  85. </div>`
  86. }).$mount()
  87. document.body.appendChild(vm.$el)
  88. let el1 = vm.$el.children[0]
  89. expect(el1.type).toBe('text')
  90. expect(el1.value).toBe('foo')
  91. el1.value = 'bar'
  92. triggerEvent(el1, 'input')
  93. expect(vm.data.text).toBe('bar')
  94. let el2 = vm.$el.children[1]
  95. expect(el2.type).toBe('checkbox')
  96. expect(el2.checked).toBe(true)
  97. el2.click()
  98. expect(vm.data.checkbox).toBe(false)
  99. // now in reverse!
  100. vm.types.reverse()
  101. waitForUpdate(() => {
  102. el1 = vm.$el.children[0]
  103. expect(el1.type).toBe('checkbox')
  104. expect(el1.checked).toBe(false)
  105. el1.click()
  106. expect(vm.data.checkbox).toBe(true)
  107. el2 = vm.$el.children[1]
  108. expect(el2.type).toBe('text')
  109. expect(el2.value).toBe('bar')
  110. el2.value = 'foo'
  111. triggerEvent(el2, 'input')
  112. expect(vm.data.text).toBe('foo')
  113. }).then(done)
  114. })
  115. it('with v-bind', done => {
  116. const vm = new Vue({
  117. data: {
  118. data: {
  119. text: 'foo',
  120. checkbox: true
  121. },
  122. inputs: [{ id: 'one', type: 'text' }, { id: 'two', type: 'checkbox' }]
  123. },
  124. template: `<div>
  125. <input v-for="i in inputs" v-bind="i" v-model="data[i.type]">
  126. </div>`
  127. }).$mount()
  128. document.body.appendChild(vm.$el)
  129. let el1 = vm.$el.children[0]
  130. expect(el1.id).toBe('one')
  131. expect(el1.type).toBe('text')
  132. expect(el1.value).toBe('foo')
  133. el1.value = 'bar'
  134. triggerEvent(el1, 'input')
  135. expect(vm.data.text).toBe('bar')
  136. let el2 = vm.$el.children[1]
  137. expect(el2.id).toBe('two')
  138. expect(el2.type).toBe('checkbox')
  139. expect(el2.checked).toBe(true)
  140. el2.click()
  141. expect(vm.data.checkbox).toBe(false)
  142. // now in reverse!
  143. vm.inputs.reverse()
  144. waitForUpdate(() => {
  145. el1 = vm.$el.children[0]
  146. expect(el1.id).toBe('two')
  147. expect(el1.type).toBe('checkbox')
  148. expect(el1.checked).toBe(false)
  149. el1.click()
  150. expect(vm.data.checkbox).toBe(true)
  151. el2 = vm.$el.children[1]
  152. expect(el2.id).toBe('one')
  153. expect(el2.type).toBe('text')
  154. expect(el2.value).toBe('bar')
  155. el2.value = 'foo'
  156. triggerEvent(el2, 'input')
  157. expect(vm.data.text).toBe('foo')
  158. }).then(done)
  159. })
  160. })
  161. function assertInputWorks (vm, type, chain) {
  162. if (typeof type !== 'string') {
  163. if (!chain) chain = type
  164. type = 'type'
  165. }
  166. if (!chain) chain = waitForUpdate()
  167. chain.then(() => {
  168. expect(vm.$el.value).toBe('b')
  169. vm.test = 'a'
  170. }).then(() => {
  171. expect(vm.$el.value).toBe('a')
  172. vm.$el.value = 'c'
  173. triggerEvent(vm.$el, 'input')
  174. expect(vm.test).toBe('c')
  175. }).then(() => {
  176. // change it to password
  177. vm[type] = 'password'
  178. vm.test = 'b'
  179. }).then(() => {
  180. expect(vm.$el.type).toBe('password')
  181. expect(vm.$el.value).toBe('b')
  182. vm.$el.value = 'c'
  183. triggerEvent(vm.$el, 'input')
  184. expect(vm.test).toBe('c')
  185. }).then(() => {
  186. // change it to checkbox...
  187. vm[type] = 'checkbox'
  188. }).then(() => {
  189. expect(vm.$el.type).toBe('checkbox')
  190. expect(vm.$el.checked).toBe(true)
  191. }).then(() => {
  192. vm.$el.click()
  193. expect(vm.$el.checked).toBe(false)
  194. expect(vm.test).toBe(false)
  195. })
  196. return chain
  197. }