model-checkbox.spec.ts 11 KB

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