componentProxy.spec.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { h, render, getCurrentInstance, nodeOps } from '@vue/runtime-test'
  2. import { mockWarn } from '@vue/shared'
  3. import { ComponentInternalInstance } from '../src/component'
  4. describe('component: proxy', () => {
  5. mockWarn()
  6. test('data', () => {
  7. let instance: ComponentInternalInstance
  8. let instanceProxy: any
  9. const Comp = {
  10. data() {
  11. return {
  12. foo: 1
  13. }
  14. },
  15. mounted() {
  16. instance = getCurrentInstance()!
  17. instanceProxy = this
  18. },
  19. render() {
  20. return null
  21. }
  22. }
  23. render(h(Comp), nodeOps.createElement('div'))
  24. expect(instanceProxy.foo).toBe(1)
  25. instanceProxy.foo = 2
  26. expect(instance!.data.foo).toBe(2)
  27. })
  28. test('renderContext', () => {
  29. let instance: ComponentInternalInstance
  30. let instanceProxy: any
  31. const Comp = {
  32. setup() {
  33. return {
  34. foo: 1
  35. }
  36. },
  37. mounted() {
  38. instance = getCurrentInstance()!
  39. instanceProxy = this
  40. },
  41. render() {
  42. return null
  43. }
  44. }
  45. render(h(Comp), nodeOps.createElement('div'))
  46. expect(instanceProxy.foo).toBe(1)
  47. instanceProxy.foo = 2
  48. expect(instance!.renderContext.foo).toBe(2)
  49. })
  50. test('propsProxy', () => {
  51. let instance: ComponentInternalInstance
  52. let instanceProxy: any
  53. const Comp = {
  54. props: {
  55. foo: {
  56. type: Number,
  57. default: 1
  58. }
  59. },
  60. setup() {
  61. return () => null
  62. },
  63. mounted() {
  64. instance = getCurrentInstance()!
  65. instanceProxy = this
  66. }
  67. }
  68. render(h(Comp), nodeOps.createElement('div'))
  69. expect(instanceProxy.foo).toBe(1)
  70. expect(instance!.propsProxy!.foo).toBe(1)
  71. expect(() => (instanceProxy.foo = 2)).toThrow(TypeError)
  72. expect(`Attempting to mutate prop "foo"`).toHaveBeenWarned()
  73. })
  74. test('public properties', () => {
  75. let instance: ComponentInternalInstance
  76. let instanceProxy: any
  77. const Comp = {
  78. setup() {
  79. return () => null
  80. },
  81. mounted() {
  82. instance = getCurrentInstance()!
  83. instanceProxy = this
  84. }
  85. }
  86. render(h(Comp), nodeOps.createElement('div'))
  87. expect(instanceProxy.$data).toBe(instance!.data)
  88. expect(instanceProxy.$props).toBe(instance!.propsProxy)
  89. expect(instanceProxy.$attrs).toBe(instance!.attrs)
  90. expect(instanceProxy.$slots).toBe(instance!.slots)
  91. expect(instanceProxy.$refs).toBe(instance!.refs)
  92. expect(instanceProxy.$parent).toBe(instance!.parent)
  93. expect(instanceProxy.$root).toBe(instance!.root)
  94. expect(instanceProxy.$emit).toBe(instance!.emit)
  95. expect(instanceProxy.$el).toBe(instance!.vnode.el)
  96. expect(instanceProxy.$options).toBe(instance!.type)
  97. expect(() => (instanceProxy.$data = {})).toThrow(TypeError)
  98. expect(`Attempting to mutate public property "$data"`).toHaveBeenWarned()
  99. })
  100. test('sink', async () => {
  101. let instance: ComponentInternalInstance
  102. let instanceProxy: any
  103. const Comp = {
  104. setup() {
  105. return () => null
  106. },
  107. mounted() {
  108. instance = getCurrentInstance()!
  109. instanceProxy = this
  110. }
  111. }
  112. render(h(Comp), nodeOps.createElement('div'))
  113. instanceProxy.foo = 1
  114. expect(instanceProxy.foo).toBe(1)
  115. expect(instance!.sink.foo).toBe(1)
  116. })
  117. test('has check', () => {
  118. let instanceProxy: any
  119. const Comp = {
  120. render() {},
  121. props: {
  122. msg: String
  123. },
  124. data() {
  125. return {
  126. foo: 0
  127. }
  128. },
  129. setup() {
  130. return {
  131. bar: 1
  132. }
  133. },
  134. mounted() {
  135. instanceProxy = this
  136. }
  137. }
  138. render(h(Comp, { msg: 'hello' }), nodeOps.createElement('div'))
  139. // props
  140. expect('msg' in instanceProxy).toBe(true)
  141. // data
  142. expect('foo' in instanceProxy).toBe(true)
  143. // renderContext
  144. expect('bar' in instanceProxy).toBe(true)
  145. // public properties
  146. expect('$el' in instanceProxy).toBe(true)
  147. // non-existent
  148. expect('$foobar' in instanceProxy).toBe(false)
  149. expect('baz' in instanceProxy).toBe(false)
  150. // set non-existent (goes into sink)
  151. instanceProxy.baz = 1
  152. expect('baz' in instanceProxy).toBe(true)
  153. })
  154. })