on_spec.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. var _ = require('src/util')
  2. var Vue = require('src')
  3. function trigger (target, event, process) {
  4. var e = document.createEvent('HTMLEvents')
  5. e.initEvent(event, true, true)
  6. if (process) process(e)
  7. target.dispatchEvent(e)
  8. return e
  9. }
  10. describe('v-on', function () {
  11. var el
  12. beforeEach(function () {
  13. el = document.createElement('div')
  14. })
  15. it('methods', function () {
  16. var spy = jasmine.createSpy()
  17. var vm = new Vue({
  18. el: el,
  19. template: '<a v-on:click="test"></a>',
  20. data: {a: 1},
  21. methods: {
  22. test: spy
  23. }
  24. })
  25. var a = el.firstChild
  26. trigger(a, 'click')
  27. expect(spy.calls.count()).toBe(1)
  28. vm.$destroy()
  29. trigger(a, 'click')
  30. expect(spy.calls.count()).toBe(1)
  31. })
  32. it('shorthand', function () {
  33. var spy = jasmine.createSpy()
  34. var vm = new Vue({
  35. el: el,
  36. template: '<a @click="test"></a>',
  37. data: {a: 1},
  38. methods: {
  39. test: spy
  40. }
  41. })
  42. var a = el.firstChild
  43. trigger(a, 'click')
  44. expect(spy.calls.count()).toBe(1)
  45. vm.$destroy()
  46. trigger(a, 'click')
  47. expect(spy.calls.count()).toBe(1)
  48. })
  49. it('inline expression', function (done) {
  50. new Vue({
  51. el: el,
  52. template: '<a v-on:click="a++">{{a}}</a>',
  53. data: {a: 1}
  54. })
  55. var a = el.firstChild
  56. trigger(a, 'click')
  57. _.nextTick(function () {
  58. expect(a.textContent).toBe('2')
  59. done()
  60. })
  61. })
  62. it('with key modifier', function (done) {
  63. new Vue({
  64. el: el,
  65. template: '<a v-on:keyup.enter="test">{{a}}</a>',
  66. data: {a: 1},
  67. methods: {
  68. test: function () {
  69. this.a++
  70. }
  71. }
  72. })
  73. var a = el.firstChild
  74. trigger(a, 'keyup', function (e) {
  75. e.keyCode = 13
  76. })
  77. _.nextTick(function () {
  78. expect(a.textContent).toBe('2')
  79. done()
  80. })
  81. })
  82. it('with delete modifier capturing DEL', function (done) {
  83. new Vue({
  84. el: el,
  85. template: '<a v-on:keyup.delete="test">{{a}}</a>',
  86. data: {a: 1},
  87. methods: {
  88. test: function () {
  89. this.a++
  90. }
  91. }
  92. })
  93. var a = el.firstChild
  94. trigger(a, 'keyup', function (e) {
  95. e.keyCode = 46
  96. })
  97. _.nextTick(function () {
  98. expect(a.textContent).toBe('2')
  99. done()
  100. })
  101. })
  102. it('with delete modifier capturing backspace', function (done) {
  103. new Vue({
  104. el: el,
  105. template: '<a v-on:keyup.delete="test">{{a}}</a>',
  106. data: {a: 1},
  107. methods: {
  108. test: function () {
  109. this.a++
  110. }
  111. }
  112. })
  113. var a = el.firstChild
  114. trigger(a, 'keyup', function (e) {
  115. e.keyCode = 8
  116. })
  117. _.nextTick(function () {
  118. expect(a.textContent).toBe('2')
  119. done()
  120. })
  121. })
  122. it('with key modifier (keycode)', function (done) {
  123. new Vue({
  124. el: el,
  125. template: '<a v-on:keyup.13="test">{{a}}</a>',
  126. data: {a: 1},
  127. methods: {
  128. test: function () {
  129. this.a++
  130. }
  131. }
  132. })
  133. var a = el.firstChild
  134. trigger(a, 'keyup', function (e) {
  135. e.keyCode = 13
  136. })
  137. _.nextTick(function () {
  138. expect(a.textContent).toBe('2')
  139. done()
  140. })
  141. })
  142. it('with key modifier (letter)', function (done) {
  143. new Vue({
  144. el: el,
  145. template: '<a v-on:keyup.a="test">{{a}}</a>',
  146. data: {a: 1},
  147. methods: {
  148. test: function () {
  149. this.a++
  150. }
  151. }
  152. })
  153. var a = el.firstChild
  154. trigger(a, 'keyup', function (e) {
  155. e.keyCode = 65
  156. })
  157. _.nextTick(function () {
  158. expect(a.textContent).toBe('2')
  159. done()
  160. })
  161. })
  162. it('stop modifier', function () {
  163. var outer = jasmine.createSpy('outer')
  164. var inner = jasmine.createSpy('inner')
  165. new Vue({
  166. el: el,
  167. template: '<div @click="outer"><div class="inner" @click.stop="inner"></div></div>',
  168. methods: {
  169. outer: outer,
  170. inner: inner
  171. }
  172. })
  173. trigger(el.querySelector('.inner'), 'click')
  174. expect(inner).toHaveBeenCalled()
  175. expect(outer).not.toHaveBeenCalled()
  176. })
  177. it('prevent modifier', function () {
  178. var prevented
  179. new Vue({
  180. el: el,
  181. template: '<a href="#" @click.prevent="onClick">',
  182. methods: {
  183. onClick: function (e) {
  184. // store the prevented state now:
  185. // IE will reset the `defaultPrevented` flag
  186. // once the event handler call stack is done!
  187. prevented = e.defaultPrevented
  188. }
  189. }
  190. })
  191. trigger(el.firstChild, 'click')
  192. expect(prevented).toBe(true)
  193. })
  194. it('prevent modifier with no value', function () {
  195. new Vue({
  196. el: el,
  197. template: '<a href="#123" @click.prevent>'
  198. })
  199. var hash = window.location.hash
  200. trigger(el.firstChild, 'click')
  201. expect(window.location.hash).toBe(hash)
  202. })
  203. it('capture modifier', function () {
  204. document.body.appendChild(el)
  205. var outer = jasmine.createSpy('outer')
  206. var inner = jasmine.createSpy('inner')
  207. new Vue({
  208. el: el,
  209. template: '<div @click.capture.stop="outer"><div class="inner" @click="inner"></div></div>',
  210. methods: {
  211. outer: outer,
  212. inner: inner
  213. }
  214. })
  215. trigger(el.querySelector('.inner'), 'click')
  216. expect(outer).toHaveBeenCalled()
  217. expect(inner).not.toHaveBeenCalled()
  218. document.body.removeChild(el)
  219. })
  220. it('self modifier', function () {
  221. var outer = jasmine.createSpy('outer')
  222. new Vue({
  223. el: el,
  224. template: '<div class="outer" @click.self="outer"><div class="inner"></div></div>',
  225. methods: {
  226. outer: outer
  227. }
  228. })
  229. trigger(el.querySelector('.inner'), 'click')
  230. expect(outer).not.toHaveBeenCalled()
  231. trigger(el.querySelector('.outer'), 'click')
  232. expect(outer).toHaveBeenCalled()
  233. })
  234. it('multiple modifiers working together', function () {
  235. var outer = jasmine.createSpy('outer')
  236. var prevented
  237. new Vue({
  238. el: el,
  239. template: '<div @keyup="outer"><input class="inner" @keyup.enter.stop.prevent="inner"></div></div>',
  240. methods: {
  241. outer: outer,
  242. inner: function (e) {
  243. prevented = e.defaultPrevented
  244. }
  245. }
  246. })
  247. trigger(el.querySelector('.inner'), 'keyup', function (e) {
  248. e.keyCode = 13
  249. })
  250. expect(outer).not.toHaveBeenCalled()
  251. expect(prevented).toBe(true)
  252. })
  253. it('warn non-function values', function () {
  254. new Vue({
  255. el: el,
  256. data: { test: 123 },
  257. template: '<a v-on:keyup="test"></a>'
  258. })
  259. expect('expects a function value').toHaveBeenWarned()
  260. })
  261. it('iframe', function () {
  262. // iframes only gets contentWindow when inserted
  263. // into the document
  264. document.body.appendChild(el)
  265. var spy = jasmine.createSpy()
  266. var vm = new Vue({
  267. el: el,
  268. template: '<iframe v-on:click="test"></iframe>',
  269. methods: {
  270. test: spy
  271. }
  272. })
  273. var iframeDoc = el.firstChild.contentDocument
  274. trigger(iframeDoc, 'click')
  275. expect(spy.calls.count()).toBe(1)
  276. vm.$destroy()
  277. trigger(iframeDoc, 'click')
  278. expect(spy.calls.count()).toBe(1)
  279. document.body.removeChild(el)
  280. })
  281. it('passing $event', function () {
  282. var test = jasmine.createSpy()
  283. new Vue({
  284. el: el,
  285. template: '<a v-on:click="test($event)"></a>',
  286. methods: {
  287. test: test
  288. }
  289. })
  290. var e = trigger(el.firstChild, 'click')
  291. expect(test).toHaveBeenCalledWith(e)
  292. })
  293. it('passing $event on a nested instance', function () {
  294. var test = jasmine.createSpy()
  295. var parent = new Vue({
  296. methods: {
  297. test: test
  298. }
  299. })
  300. var child = new Vue({
  301. el: el,
  302. template: '<a v-on:click="$parent.test($event)"></a>',
  303. parent: parent
  304. })
  305. var e = trigger(child.$el.firstChild, 'click')
  306. expect(test).toHaveBeenCalledWith(e)
  307. })
  308. })