misc.spec.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import { vi } from 'vitest'
  2. import Vue from '@vue/compat'
  3. import { nextTick } from '../../runtime-core/src/scheduler'
  4. import {
  5. DeprecationTypes,
  6. deprecationData,
  7. toggleDeprecationWarning
  8. } from '../../runtime-core/src/compat/compatConfig'
  9. import { triggerEvent } from './utils'
  10. import { h } from '@vue/runtime-core'
  11. beforeEach(() => {
  12. toggleDeprecationWarning(true)
  13. Vue.configureCompat({
  14. MODE: 2,
  15. GLOBAL_MOUNT: 'suppress-warning'
  16. })
  17. })
  18. afterEach(() => {
  19. toggleDeprecationWarning(false)
  20. Vue.configureCompat({ MODE: 3 })
  21. })
  22. test('mode as function', () => {
  23. const Foo = {
  24. name: 'Foo',
  25. render: (h: any) => h('div', 'foo')
  26. }
  27. const Bar = {
  28. name: 'Bar',
  29. data: () => ({ msg: 'bar' }),
  30. render: (ctx: any) => h('div', ctx.msg)
  31. }
  32. toggleDeprecationWarning(false)
  33. Vue.configureCompat({
  34. MODE: comp => (comp && comp.name === 'Bar' ? 3 : 2)
  35. })
  36. const vm = new Vue({
  37. components: { Foo, Bar },
  38. template: `<div><foo/><bar/></div>`
  39. }).$mount()
  40. expect(vm.$el.innerHTML).toBe(`<div>foo</div><div>bar</div>`)
  41. })
  42. test('WATCH_ARRAY', async () => {
  43. const spy = vi.fn()
  44. const vm = new Vue({
  45. data() {
  46. return {
  47. foo: []
  48. }
  49. },
  50. watch: {
  51. foo: spy
  52. }
  53. }) as any
  54. expect(
  55. deprecationData[DeprecationTypes.WATCH_ARRAY].message
  56. ).toHaveBeenWarned()
  57. expect(spy).not.toHaveBeenCalled()
  58. vm.foo.push(1)
  59. await nextTick()
  60. expect(spy).toHaveBeenCalledTimes(1)
  61. })
  62. test('PROPS_DEFAULT_THIS', () => {
  63. let thisCtx: any
  64. const Child = {
  65. customOption: 1,
  66. inject: ['provided'],
  67. props: {
  68. foo: null,
  69. bar: {
  70. default(this: any) {
  71. // copy values since injection must be sync
  72. thisCtx = {
  73. foo: this.foo,
  74. $options: this.$options,
  75. provided: this.provided
  76. }
  77. return this.foo + 1
  78. }
  79. }
  80. },
  81. template: `{{ bar }}`
  82. }
  83. const vm = new Vue({
  84. components: { Child },
  85. provide: {
  86. provided: 2
  87. },
  88. template: `<child :foo="0" />`
  89. }).$mount()
  90. expect(vm.$el.textContent).toBe('1')
  91. // other props
  92. expect(thisCtx.foo).toBe(0)
  93. // $options
  94. expect(thisCtx.$options.customOption).toBe(1)
  95. // injections
  96. expect(thisCtx.provided).toBe(2)
  97. expect(
  98. (deprecationData[DeprecationTypes.PROPS_DEFAULT_THIS].message as Function)(
  99. 'bar'
  100. )
  101. ).toHaveBeenWarned()
  102. })
  103. test('V_ON_KEYCODE_MODIFIER', () => {
  104. const spy = vi.fn()
  105. const vm = new Vue({
  106. template: `<input @keyup.1="spy">`,
  107. methods: { spy }
  108. }).$mount()
  109. triggerEvent(vm.$el, 'keyup', e => {
  110. e.key = '_'
  111. e.keyCode = 1
  112. })
  113. expect(spy).toHaveBeenCalled()
  114. expect(
  115. deprecationData[DeprecationTypes.V_ON_KEYCODE_MODIFIER].message
  116. ).toHaveBeenWarned()
  117. })
  118. test('CUSTOM_DIR', async () => {
  119. const myDir = {
  120. bind: vi.fn(),
  121. inserted: vi.fn(),
  122. update: vi.fn(),
  123. componentUpdated: vi.fn(),
  124. unbind: vi.fn()
  125. } as any
  126. const getCalls = () =>
  127. Object.keys(myDir).map(key => myDir[key].mock.calls.length)
  128. const vm = new Vue({
  129. data() {
  130. return {
  131. ok: true,
  132. foo: 1
  133. }
  134. },
  135. template: `<div v-if="ok" v-my-dir="foo"/>`,
  136. directives: {
  137. myDir
  138. }
  139. }).$mount() as any
  140. expect(getCalls()).toMatchObject([1, 1, 0, 0, 0])
  141. expect(
  142. (deprecationData[DeprecationTypes.CUSTOM_DIR].message as Function)(
  143. 'bind',
  144. 'beforeMount'
  145. )
  146. ).toHaveBeenWarned()
  147. expect(
  148. (deprecationData[DeprecationTypes.CUSTOM_DIR].message as Function)(
  149. 'inserted',
  150. 'mounted'
  151. )
  152. ).toHaveBeenWarned()
  153. vm.foo++
  154. await nextTick()
  155. expect(getCalls()).toMatchObject([1, 1, 1, 1, 0])
  156. expect(
  157. (deprecationData[DeprecationTypes.CUSTOM_DIR].message as Function)(
  158. 'update',
  159. 'updated'
  160. )
  161. ).toHaveBeenWarned()
  162. expect(
  163. (deprecationData[DeprecationTypes.CUSTOM_DIR].message as Function)(
  164. 'componentUpdated',
  165. 'updated'
  166. )
  167. ).toHaveBeenWarned()
  168. })
  169. test('ATTR_FALSE_VALUE', () => {
  170. const vm = new Vue({
  171. template: `<div :id="false" :foo="false"/>`
  172. }).$mount()
  173. expect(vm.$el.hasAttribute('id')).toBe(false)
  174. expect(vm.$el.hasAttribute('foo')).toBe(false)
  175. expect(
  176. (deprecationData[DeprecationTypes.ATTR_FALSE_VALUE].message as Function)(
  177. 'id'
  178. )
  179. ).toHaveBeenWarned()
  180. expect(
  181. (deprecationData[DeprecationTypes.ATTR_FALSE_VALUE].message as Function)(
  182. 'foo'
  183. )
  184. ).toHaveBeenWarned()
  185. })
  186. test('ATTR_ENUMERATED_COERCION', () => {
  187. const vm = new Vue({
  188. template: `<div :draggable="null" :spellcheck="0" contenteditable="foo" />`
  189. }).$mount()
  190. expect(vm.$el.getAttribute('draggable')).toBe('false')
  191. expect(vm.$el.getAttribute('spellcheck')).toBe('true')
  192. expect(vm.$el.getAttribute('contenteditable')).toBe('true')
  193. expect(
  194. (
  195. deprecationData[DeprecationTypes.ATTR_ENUMERATED_COERCION]
  196. .message as Function
  197. )('draggable', null, 'false')
  198. ).toHaveBeenWarned()
  199. expect(
  200. (
  201. deprecationData[DeprecationTypes.ATTR_ENUMERATED_COERCION]
  202. .message as Function
  203. )('spellcheck', 0, 'true')
  204. ).toHaveBeenWarned()
  205. expect(
  206. (
  207. deprecationData[DeprecationTypes.ATTR_ENUMERATED_COERCION]
  208. .message as Function
  209. )('contenteditable', 'foo', 'true')
  210. ).toHaveBeenWarned()
  211. })