content.test.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import { computed, defineComponent, nextTick, ref } from 'vue'
  2. import { mount } from '@vue/test-utils'
  3. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
  4. import { POPPER_INJECTION_KEY } from '@element-plus/components/popper'
  5. import ElContent from '../src/content.vue'
  6. import type { VueWrapper } from '@vue/test-utils'
  7. import type { PopperContentInstance } from '../src/content'
  8. const AXIOM = 'rem is the best girl'
  9. const popperInjection = {
  10. triggerRef: ref(),
  11. popperInstanceRef: ref(),
  12. contentRef: ref(),
  13. role: computed(() => 'test-role'),
  14. }
  15. const TestComponent = defineComponent({
  16. setup() {
  17. return {
  18. contentRef: ref(),
  19. }
  20. },
  21. render() {
  22. return (
  23. <ElContent ref="contentRef" {...this.$attrs}>
  24. {AXIOM}
  25. </ElContent>
  26. )
  27. },
  28. })
  29. const mountContent = (props = {}) =>
  30. mount(<ElContent {...props}>{AXIOM}</ElContent>, {
  31. global: {
  32. provide: {
  33. [POPPER_INJECTION_KEY as symbol]: popperInjection,
  34. },
  35. },
  36. })
  37. const mountWrappedContent = (props = {}) =>
  38. mount(<TestComponent {...props} />, {
  39. global: {
  40. provide: {
  41. [POPPER_INJECTION_KEY as symbol]: popperInjection,
  42. },
  43. },
  44. })
  45. describe('<ElPopperContent />', () => {
  46. describe('with triggerRef provided', () => {
  47. const triggerKls = 'el-popper__trigger'
  48. let wrapper: VueWrapper<PopperContentInstance>
  49. beforeEach(() => {
  50. const trigger = document.createElement('div')
  51. trigger.className = triggerKls
  52. popperInjection.triggerRef.value = trigger
  53. })
  54. afterEach(() => {
  55. popperInjection.triggerRef.value = null
  56. wrapper?.unmount()
  57. })
  58. it('should mount the component correctly and set popperInstance correctly', async () => {
  59. wrapper = mountContent()
  60. await nextTick()
  61. expect(popperInjection.triggerRef).toBeDefined()
  62. expect(wrapper.html()).toContain(AXIOM)
  63. expect(popperInjection.popperInstanceRef.value).toBeDefined()
  64. expect(wrapper.classes()).toEqual(['el-popper', 'is-dark'])
  65. expect(wrapper.vm.contentStyle).toHaveLength(3)
  66. expect(wrapper.vm.contentStyle[0]).toHaveProperty('zIndex')
  67. expect(wrapper.vm.contentStyle[1]).toEqual({})
  68. expect(wrapper.vm.contentStyle[2]).toEqual(
  69. expect.objectContaining({
  70. position: 'absolute',
  71. top: '0',
  72. left: '0',
  73. })
  74. )
  75. })
  76. it('should be able to be pure and themed', async () => {
  77. wrapper = mountContent()
  78. await nextTick()
  79. await wrapper.setProps({
  80. pure: true,
  81. effect: 'custom',
  82. })
  83. expect(wrapper.classes()).toEqual(['el-popper', 'is-pure', 'is-custom'])
  84. })
  85. it('should be able to set customized styles', async () => {
  86. wrapper = mountContent()
  87. await nextTick()
  88. const style = {
  89. position: 'absolute',
  90. }
  91. await wrapper.setProps({
  92. popperStyle: style,
  93. })
  94. expect(wrapper.vm.contentStyle[1]).toEqual(style)
  95. })
  96. it('should be able to emit events', async () => {
  97. wrapper = mountContent()
  98. await nextTick()
  99. expect(wrapper.emitted()).not.toHaveProperty('mouseenter')
  100. expect(wrapper.emitted()).not.toHaveProperty('mouseleave')
  101. await wrapper.trigger('mouseenter')
  102. expect(wrapper.emitted()).toHaveProperty('mouseenter')
  103. await wrapper.trigger('mouseleave')
  104. expect(wrapper.emitted()).toHaveProperty('mouseleave')
  105. })
  106. describe('instantiate popper instance', () => {
  107. it('should be able to update the current instance', async () => {
  108. await nextTick()
  109. vi.spyOn(
  110. popperInjection.triggerRef.value,
  111. 'getBoundingClientRect'
  112. ).mockImplementation(() => ({
  113. bottom: 1,
  114. height: 0,
  115. left: 0,
  116. right: 0,
  117. top: 0,
  118. width: 0,
  119. }))
  120. wrapper.vm.$forceUpdate()
  121. })
  122. it('should be able to update the reference node', async () => {
  123. const w = mountWrappedContent()
  124. await nextTick()
  125. const { contentRef } = w.vm
  126. const oldInstance = contentRef.popperInstanceRef
  127. const newRef = document.createElement('div')
  128. newRef.classList.add('new-ref')
  129. popperInjection.triggerRef.value = newRef
  130. await nextTick()
  131. expect(contentRef.popperInstanceRef).not.toStrictEqual(oldInstance)
  132. popperInjection.triggerRef.value = undefined
  133. await nextTick()
  134. expect(contentRef.popperInstanceRef).toBeUndefined()
  135. })
  136. })
  137. })
  138. })