only-child.test.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { Comment, Fragment, h, nextTick, ref } from 'vue'
  2. import { shallowMount } from '@vue/test-utils'
  3. import { afterEach, describe, expect, it, vi } from 'vitest'
  4. import { debugWarn } from '@element-plus/utils'
  5. import { FORWARD_REF_INJECTION_KEY } from '@element-plus/hooks'
  6. import { OnlyChild } from '../src/only-child'
  7. import type { MountingOptions } from '@vue/test-utils'
  8. type Slot = NonNullable<NonNullable<MountingOptions<any>['slots']>['default']>
  9. vi.mock('@element-plus/utils/error', () => ({
  10. debugWarn: vi.fn(),
  11. }))
  12. const AXIOM = 'rem is the best girl'
  13. const defaultProvide = {
  14. [FORWARD_REF_INJECTION_KEY as any]: {
  15. forwardRef: ref(null),
  16. },
  17. }
  18. const createComponent = (slot: Slot) => {
  19. return shallowMount(OnlyChild, {
  20. global: {
  21. provide: defaultProvide,
  22. },
  23. // vue test utils adds the entry for us even though default's value is null
  24. slots: slot ? { default: slot } : undefined,
  25. })
  26. }
  27. describe('ElOnlyChild', () => {
  28. let wrapper: ReturnType<typeof createComponent>
  29. afterEach(() => {
  30. wrapper?.unmount()
  31. })
  32. it('should be able to render only one child', async () => {
  33. const kls = 'test_kls'
  34. wrapper = createComponent(() => [<div class={kls}>{AXIOM}</div>])
  35. await nextTick()
  36. expect(debugWarn).not.toHaveBeenCalled()
  37. const renderedChild = wrapper.find(`.${kls}`)
  38. expect(renderedChild.exists()).toBe(true)
  39. expect(renderedChild.text()).toBe(AXIOM)
  40. })
  41. it('should be able to render string type and wrap it into span', async () => {
  42. wrapper = createComponent(() => [AXIOM])
  43. await nextTick()
  44. expect(debugWarn).not.toHaveBeenCalled()
  45. expect(wrapper.find('span').exists()).toBe(true)
  46. })
  47. it('should be able to unwrap fragmented children', async () => {
  48. wrapper = createComponent(() => [<>{AXIOM}</>])
  49. await nextTick()
  50. expect(debugWarn).not.toHaveBeenCalled()
  51. expect(wrapper.find('span').exists()).toBe(true)
  52. })
  53. it('should skip svg and child type is svg', async () => {
  54. const wrapper = createComponent(() => [
  55. <svg
  56. xmlns="http://www.w3.org/2000/svg"
  57. viewBox="0 0 32 32"
  58. width="20"
  59. height="20"
  60. >
  61. <path d="M14.667 14.667v-8h2.667v8h8v2.667h-8v8h-2.667v-8h-8v-2.667z" />
  62. </svg>,
  63. ])
  64. await nextTick()
  65. expect(debugWarn).not.toHaveBeenCalled()
  66. expect(wrapper.find('svg').attributes('viewBox')).toEqual('0 0 32 32')
  67. expect(wrapper.find('svg').attributes('width')).toEqual('20')
  68. expect(wrapper.find('svg').attributes('height')).toEqual('20')
  69. await wrapper.trigger('hover')
  70. await expect(wrapper.find('svg').exists()).toBe(true)
  71. })
  72. it('should skip comment', async () => {
  73. wrapper = createComponent(() => [
  74. <>
  75. {h(Comment, 'some comment')}
  76. {AXIOM}
  77. </>,
  78. ])
  79. await nextTick()
  80. expect(debugWarn).not.toHaveBeenCalled()
  81. expect(wrapper.find('span').exists()).toBe(true)
  82. })
  83. it('should return nothing and warn when no valid children found', async () => {
  84. wrapper = createComponent(() => [<></>])
  85. await nextTick()
  86. expect(debugWarn).toHaveBeenCalled()
  87. })
  88. it('should render nothing when invalid node were found', async () => {
  89. wrapper = createComponent(() => [h(Fragment, null)])
  90. await nextTick()
  91. expect(debugWarn).toHaveBeenCalled()
  92. })
  93. it('should warns about having multiple children', async () => {
  94. wrapper = createComponent(() => [AXIOM, AXIOM])
  95. await nextTick()
  96. expect(debugWarn).toHaveBeenCalledTimes(1)
  97. expect(wrapper.text()).toBe('')
  98. })
  99. it('should render nothing when no children provided', async () => {
  100. wrapper = createComponent(null as any)
  101. await nextTick()
  102. expect(debugWarn).not.toHaveBeenCalled()
  103. expect(wrapper.text()).toBe('')
  104. })
  105. })