componentProxy.spec.ts 4.3 KB

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