componentProxy.spec.ts 4.3 KB

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