model-checkbox.spec.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. import Vue from 'vue'
  2. describe('Directive v-model checkbox', () => {
  3. it('should work', done => {
  4. const vm = new Vue({
  5. data: {
  6. test: true
  7. },
  8. template: '<input type="checkbox" v-model="test">'
  9. }).$mount()
  10. document.body.appendChild(vm.$el)
  11. expect(vm.$el.checked).toBe(true)
  12. vm.test = false
  13. waitForUpdate(function () {
  14. expect(vm.$el.checked).toBe(false)
  15. expect(vm.test).toBe(false)
  16. vm.$el.click()
  17. expect(vm.$el.checked).toBe(true)
  18. expect(vm.test).toBe(true)
  19. }).then(() => {
  20. document.body.removeChild(vm.$el)
  21. }).then(done)
  22. })
  23. it('should respect value bindings', done => {
  24. const vm = new Vue({
  25. data: {
  26. test: 1,
  27. a: 1,
  28. b: 2
  29. },
  30. template: '<input type="checkbox" v-model="test" :true-value="a" :false-value="b">'
  31. }).$mount()
  32. document.body.appendChild(vm.$el)
  33. expect(vm.$el.checked).toBe(true)
  34. vm.$el.click()
  35. expect(vm.$el.checked).toBe(false)
  36. expect(vm.test).toBe(2)
  37. vm.$el.click()
  38. expect(vm.$el.checked).toBe(true)
  39. expect(vm.test).toBe(1)
  40. vm.test = 2
  41. waitForUpdate(() => {
  42. expect(vm.$el.checked).toBe(false)
  43. vm.test = 1
  44. }).then(() => {
  45. expect(vm.$el.checked).toBe(true)
  46. document.body.removeChild(vm.$el)
  47. }).then(done)
  48. })
  49. it('bind to Array value', done => {
  50. const vm = new Vue({
  51. data: {
  52. test: ['1']
  53. },
  54. template: `
  55. <div>
  56. <input type="checkbox" v-model="test" value="1">
  57. <input type="checkbox" v-model="test" value="2">
  58. </div>
  59. `
  60. }).$mount()
  61. document.body.appendChild(vm.$el)
  62. expect(vm.$el.children[0].checked).toBe(true)
  63. expect(vm.$el.children[1].checked).toBe(false)
  64. vm.$el.children[0].click()
  65. expect(vm.test.length).toBe(0)
  66. vm.$el.children[1].click()
  67. expect(vm.test).toEqual(['2'])
  68. vm.$el.children[0].click()
  69. expect(vm.test).toEqual(['2', '1'])
  70. vm.test = ['1']
  71. waitForUpdate(() => {
  72. expect(vm.$el.children[0].checked).toBe(true)
  73. expect(vm.$el.children[1].checked).toBe(false)
  74. }).then(done)
  75. })
  76. it('bind to Array value ignores false-value', done => {
  77. const vm = new Vue({
  78. data: {
  79. test: ['1']
  80. },
  81. template: `
  82. <div>
  83. <input type="checkbox" v-model="test" value="1" :false-value="true">
  84. <input type="checkbox" v-model="test" value="2" :false-value="true">
  85. </div>
  86. `
  87. }).$mount()
  88. document.body.appendChild(vm.$el)
  89. expect(vm.$el.children[0].checked).toBe(true)
  90. expect(vm.$el.children[1].checked).toBe(false)
  91. vm.$el.children[0].click()
  92. expect(vm.test.length).toBe(0)
  93. vm.$el.children[1].click()
  94. expect(vm.test).toEqual(['2'])
  95. vm.$el.children[0].click()
  96. expect(vm.test).toEqual(['2', '1'])
  97. vm.test = ['1']
  98. waitForUpdate(() => {
  99. expect(vm.$el.children[0].checked).toBe(true)
  100. expect(vm.$el.children[1].checked).toBe(false)
  101. }).then(done)
  102. })
  103. it('bind to Array value with value bindings', done => {
  104. const vm = new Vue({
  105. data: {
  106. test: [1]
  107. },
  108. template: `
  109. <div>
  110. <input type="checkbox" v-model="test" :value="1">
  111. <input type="checkbox" v-model="test" :value="2">
  112. </div>
  113. `
  114. }).$mount()
  115. document.body.appendChild(vm.$el)
  116. expect(vm.$el.children[0].checked).toBe(true)
  117. expect(vm.$el.children[1].checked).toBe(false)
  118. vm.$el.children[0].click()
  119. expect(vm.test.length).toBe(0)
  120. vm.$el.children[1].click()
  121. expect(vm.test).toEqual([2])
  122. vm.$el.children[0].click()
  123. expect(vm.test).toEqual([2, 1])
  124. vm.test = [1]
  125. waitForUpdate(() => {
  126. expect(vm.$el.children[0].checked).toBe(true)
  127. expect(vm.$el.children[1].checked).toBe(false)
  128. }).then(done)
  129. })
  130. it('bind to Array value with value bindings (object loose equal)', done => {
  131. const vm = new Vue({
  132. data: {
  133. test: [{ a: 1 }]
  134. },
  135. template: `
  136. <div>
  137. <input type="checkbox" v-model="test" :value="{ a: 1 }">
  138. <input type="checkbox" v-model="test" :value="{ a: 2 }">
  139. </div>
  140. `
  141. }).$mount()
  142. document.body.appendChild(vm.$el)
  143. expect(vm.$el.children[0].checked).toBe(true)
  144. expect(vm.$el.children[1].checked).toBe(false)
  145. vm.$el.children[0].click()
  146. expect(vm.test.length).toBe(0)
  147. vm.$el.children[1].click()
  148. expect(vm.test).toEqual([{ a: 2 }])
  149. vm.$el.children[0].click()
  150. expect(vm.test).toEqual([{ a: 2 }, { a: 1 }])
  151. vm.test = [{ a: 1 }]
  152. waitForUpdate(() => {
  153. expect(vm.$el.children[0].checked).toBe(true)
  154. expect(vm.$el.children[1].checked).toBe(false)
  155. }).then(done)
  156. })
  157. it('bind to Array value with array value bindings (object loose equal)', done => {
  158. const vm = new Vue({
  159. data: {
  160. test: [{ a: 1 }]
  161. },
  162. template: `
  163. <div>
  164. <input type="checkbox" v-model="test" :value="{ a: 1 }">
  165. <input type="checkbox" v-model="test" :value="[2]">
  166. </div>
  167. `
  168. }).$mount()
  169. document.body.appendChild(vm.$el)
  170. expect(vm.$el.children[0].checked).toBe(true)
  171. expect(vm.$el.children[1].checked).toBe(false)
  172. vm.$el.children[0].click()
  173. expect(vm.test.length).toBe(0)
  174. vm.$el.children[1].click()
  175. expect(vm.test).toEqual([[2]])
  176. vm.$el.children[0].click()
  177. expect(vm.test).toEqual([[2], { a: 1 }])
  178. vm.test = [{ a: 1 }]
  179. waitForUpdate(() => {
  180. expect(vm.$el.children[0].checked).toBe(true)
  181. expect(vm.$el.children[1].checked).toBe(false)
  182. }).then(done)
  183. })
  184. it('.number modifier', () => {
  185. const vm = new Vue({
  186. data: {
  187. test: [],
  188. check: true
  189. },
  190. template: `
  191. <div>
  192. <input type="checkbox" v-model.number="test" value="1">
  193. <input type="checkbox" v-model="test" value="2">
  194. <input type="checkbox" v-model.number="check">
  195. </div>
  196. `
  197. }).$mount()
  198. document.body.appendChild(vm.$el)
  199. const checkboxInputs = vm.$el.getElementsByTagName('input')
  200. expect(checkboxInputs[0].checked).toBe(false)
  201. expect(checkboxInputs[1].checked).toBe(false)
  202. expect(checkboxInputs[2].checked).toBe(true)
  203. checkboxInputs[0].click()
  204. checkboxInputs[1].click()
  205. checkboxInputs[2].click()
  206. expect(vm.test).toEqual([1, '2'])
  207. expect(vm.check).toEqual(false)
  208. })
  209. it('should respect different primitive type value', (done) => {
  210. const vm = new Vue({
  211. data: {
  212. test: [0]
  213. },
  214. template:
  215. '<div>' +
  216. '<input type="checkbox" value="" v-model="test">' +
  217. '<input type="checkbox" value="0" v-model="test">' +
  218. '<input type="checkbox" value="1" v-model="test">' +
  219. '<input type="checkbox" value="false" v-model="test">' +
  220. '<input type="checkbox" value="true" v-model="test">' +
  221. '</div>'
  222. }).$mount()
  223. const checkboxInput = vm.$el.children
  224. expect(checkboxInput[0].checked).toBe(false)
  225. expect(checkboxInput[1].checked).toBe(true)
  226. expect(checkboxInput[2].checked).toBe(false)
  227. expect(checkboxInput[3].checked).toBe(false)
  228. expect(checkboxInput[4].checked).toBe(false)
  229. vm.test = [1]
  230. waitForUpdate(() => {
  231. expect(checkboxInput[0].checked).toBe(false)
  232. expect(checkboxInput[1].checked).toBe(false)
  233. expect(checkboxInput[2].checked).toBe(true)
  234. expect(checkboxInput[3].checked).toBe(false)
  235. expect(checkboxInput[4].checked).toBe(false)
  236. vm.test = ['']
  237. }).then(() => {
  238. expect(checkboxInput[0].checked).toBe(true)
  239. expect(checkboxInput[1].checked).toBe(false)
  240. expect(checkboxInput[2].checked).toBe(false)
  241. expect(checkboxInput[3].checked).toBe(false)
  242. expect(checkboxInput[4].checked).toBe(false)
  243. vm.test = [false]
  244. }).then(() => {
  245. expect(checkboxInput[0].checked).toBe(false)
  246. expect(checkboxInput[1].checked).toBe(false)
  247. expect(checkboxInput[2].checked).toBe(false)
  248. expect(checkboxInput[3].checked).toBe(true)
  249. expect(checkboxInput[4].checked).toBe(false)
  250. vm.test = [true]
  251. }).then(() => {
  252. expect(checkboxInput[0].checked).toBe(false)
  253. expect(checkboxInput[1].checked).toBe(false)
  254. expect(checkboxInput[2].checked).toBe(false)
  255. expect(checkboxInput[3].checked).toBe(false)
  256. expect(checkboxInput[4].checked).toBe(true)
  257. vm.test = ['', 0, 1, false, true]
  258. }).then(() => {
  259. expect(checkboxInput[0].checked).toBe(true)
  260. expect(checkboxInput[1].checked).toBe(true)
  261. expect(checkboxInput[2].checked).toBe(true)
  262. expect(checkboxInput[3].checked).toBe(true)
  263. expect(checkboxInput[4].checked).toBe(true)
  264. }).then(done)
  265. })
  266. // #4521
  267. it('should work with click event', (done) => {
  268. const vm = new Vue({
  269. data: {
  270. num: 1,
  271. checked: false
  272. },
  273. template: '<div @click="add">click {{ num }}<input ref="checkbox" type="checkbox" v-model="checked"/></div>',
  274. methods: {
  275. add: function () {
  276. this.num++
  277. }
  278. }
  279. }).$mount()
  280. document.body.appendChild(vm.$el)
  281. const checkbox = vm.$refs.checkbox
  282. checkbox.click()
  283. waitForUpdate(() => {
  284. expect(checkbox.checked).toBe(true)
  285. expect(vm.num).toBe(2)
  286. }).then(done)
  287. })
  288. it('should get updated with model when in focus', (done) => {
  289. const vm = new Vue({
  290. data: {
  291. a: 2
  292. },
  293. template: '<input type="checkbox" v-model="a"/>'
  294. }).$mount()
  295. document.body.appendChild(vm.$el)
  296. vm.$el.click()
  297. waitForUpdate(() => {
  298. expect(vm.$el.checked).toBe(false)
  299. vm.a = 2
  300. }).then(() => {
  301. expect(vm.$el.checked).toBe(true)
  302. }).then(done)
  303. })
  304. it('triggers a watcher when binding to an array value in a checkbox', done => {
  305. const vm = new Vue({
  306. data: {
  307. test: {
  308. thing: false,
  309. arr: [true]
  310. }
  311. },
  312. template: `
  313. <div>
  314. <input type="checkbox" v-model="test.arr[0]">
  315. <span>{{ test.arr[0] }}</span>
  316. </div>
  317. `
  318. }).$mount()
  319. document.body.appendChild(vm.$el)
  320. expect(vm.$el.children[0].checked).toBe(true)
  321. expect(vm.$el.children[1].textContent).toBe('true')
  322. vm.$el.children[0].click()
  323. expect(vm.$el.children[0].checked).toBe(false)
  324. waitForUpdate(() => {
  325. expect(vm.$el.children[1].textContent).toBe('false')
  326. }).then(done)
  327. })
  328. // #7811
  329. it('type should not be overwritten by v-bind', () => {
  330. const vm = new Vue({
  331. data: {
  332. test: true
  333. },
  334. template: '<input type="checkbox" v-model="test" v-bind="$attrs">'
  335. }).$mount()
  336. expect(vm.$el.type).toBe('checkbox')
  337. })
  338. })