model-dynamic.spec.ts 5.5 KB

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