component.spec.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import {
  2. type ComponentInternalInstance,
  3. getCurrentInstance,
  4. h,
  5. nodeOps,
  6. render,
  7. } from '@vue/runtime-test'
  8. import { type GenericComponent, formatComponentName } from '../src/component'
  9. describe('formatComponentName', () => {
  10. test('default name', () => {
  11. let instance: ComponentInternalInstance | null = null
  12. const Comp = {
  13. setup() {
  14. instance = getCurrentInstance()
  15. return () => null
  16. },
  17. } as GenericComponent
  18. render(h(Comp), nodeOps.createElement('div'))
  19. expect(formatComponentName(null, Comp)).toBe('Anonymous')
  20. expect(formatComponentName(null, Comp, true)).toBe('App')
  21. expect(formatComponentName(instance, Comp)).toBe('Anonymous')
  22. expect(formatComponentName(instance, Comp, true)).toBe('App')
  23. })
  24. test('name option', () => {
  25. let instance: ComponentInternalInstance | null = null
  26. const Comp = {
  27. name: 'number-input',
  28. setup() {
  29. instance = getCurrentInstance()
  30. return () => null
  31. },
  32. }
  33. render(h(Comp), nodeOps.createElement('div'))
  34. expect(formatComponentName(null, Comp)).toBe('NumberInput')
  35. expect(formatComponentName(instance, Comp, true)).toBe('NumberInput')
  36. })
  37. test('self recursive name', () => {
  38. let instance: ComponentInternalInstance | null = null
  39. const Comp = {
  40. components: {} as any,
  41. setup() {
  42. instance = getCurrentInstance()
  43. return () => null
  44. },
  45. }
  46. Comp.components.ToggleButton = Comp
  47. render(h(Comp), nodeOps.createElement('div'))
  48. expect(formatComponentName(instance, Comp as GenericComponent)).toBe(
  49. 'ToggleButton',
  50. )
  51. })
  52. test('name from parent', () => {
  53. let instance: ComponentInternalInstance | null = null
  54. const Comp = {
  55. setup() {
  56. instance = getCurrentInstance()
  57. return () => null
  58. },
  59. }
  60. const Parent = {
  61. components: {
  62. list_item: Comp,
  63. },
  64. render() {
  65. return h(Comp)
  66. },
  67. }
  68. render(h(Parent), nodeOps.createElement('div'))
  69. expect(formatComponentName(instance, Comp as GenericComponent)).toBe(
  70. 'ListItem',
  71. )
  72. })
  73. test('functional components', () => {
  74. const UserAvatar = () => null
  75. expect(formatComponentName(null, UserAvatar)).toBe('UserAvatar')
  76. UserAvatar.displayName = 'UserPicture'
  77. expect(formatComponentName(null, UserAvatar)).toBe('UserPicture')
  78. expect(formatComponentName(null, () => null)).toBe('Anonymous')
  79. })
  80. test('Name from file', () => {
  81. const Comp = {
  82. __file: './src/locale-dropdown.vue',
  83. }
  84. expect(formatComponentName(null, Comp)).toBe('LocaleDropdown')
  85. })
  86. test('inferred name', () => {
  87. const Comp = {
  88. __name: 'MainSidebar',
  89. }
  90. expect(formatComponentName(null, Comp)).toBe('MainSidebar')
  91. })
  92. test('global component', () => {
  93. let instance: ComponentInternalInstance | null = null
  94. const Comp = {
  95. setup() {
  96. instance = getCurrentInstance()
  97. return () => null
  98. },
  99. }
  100. render(h(Comp), nodeOps.createElement('div'))
  101. instance!.appContext.components.FieldLabel = Comp
  102. expect(formatComponentName(instance, Comp as GenericComponent)).toBe(
  103. 'FieldLabel',
  104. )
  105. })
  106. test('name precedence', () => {
  107. let instance: ComponentInternalInstance | null = null
  108. const Dummy = () => null
  109. const Comp: Record<string, any> = {
  110. components: { Dummy },
  111. setup() {
  112. instance = getCurrentInstance()
  113. return () => null
  114. },
  115. }
  116. const Parent = {
  117. components: { Dummy } as any,
  118. render() {
  119. return h(Comp)
  120. },
  121. }
  122. render(h(Parent), nodeOps.createElement('div'))
  123. expect(formatComponentName(instance, Comp)).toBe('Anonymous')
  124. expect(formatComponentName(instance, Comp, true)).toBe('App')
  125. instance!.appContext.components.CompA = Comp
  126. expect(formatComponentName(instance, Comp)).toBe('CompA')
  127. expect(formatComponentName(instance, Comp, true)).toBe('CompA')
  128. Parent.components.CompB = Comp
  129. expect(formatComponentName(instance, Comp)).toBe('CompB')
  130. Comp.components.CompC = Comp
  131. expect(formatComponentName(instance, Comp)).toBe('CompC')
  132. Comp.__file = './CompD.js'
  133. expect(formatComponentName(instance, Comp)).toBe('CompD')
  134. Comp.__name = 'CompE'
  135. expect(formatComponentName(instance, Comp)).toBe('CompE')
  136. Comp.name = 'CompF'
  137. expect(formatComponentName(instance, Comp)).toBe('CompF')
  138. })
  139. })