123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- import { h, nextTick } from 'vue'
- import { describe, expect, test, vi } from 'vitest'
- import makeMount from '@element-plus/test-utils/make-mount'
- import { rAF } from '@element-plus/test-utils/tick'
- import { TypeComponentsMap } from '@element-plus/utils'
- import { EVENT_CODE } from '@element-plus/constants'
- import Message from '../src/message.vue'
- import type { CSSProperties, Component, ComponentPublicInstance } from 'vue'
- const AXIOM = 'Rem is the best girl'
- type MessageInstance = ComponentPublicInstance<{
- visible: boolean
- iconComponent: string | Component
- customStyle: CSSProperties
- }>
- const onClose = vi.fn()
- const _mount = makeMount(Message, {
- props: {
- onClose,
- },
- })
- describe('Message.vue', () => {
- describe('render', () => {
- test('basic render test', () => {
- const wrapper = _mount({
- slots: {
- default: AXIOM,
- },
- })
- const vm = wrapper.vm as MessageInstance
- expect(wrapper.text()).toEqual(AXIOM)
- expect(vm.visible).toBe(true)
- expect(vm.iconComponent).toBe(TypeComponentsMap['info'])
- expect(vm.customStyle).toEqual({ top: '16px', zIndex: 2001 })
- })
- test('should be able to render VNode', () => {
- const wrapper = _mount({
- slots: {
- default: h('span', { class: 'text-node' }, AXIOM),
- },
- })
- expect(wrapper.find('.text-node').exists()).toBe(true)
- })
- test('should be able to render raw HTML with dangerouslyUseHTMLString prop', () => {
- const tagClass = 'test-class'
- const wrapper = _mount({
- props: {
- dangerouslyUseHTMLString: true,
- message: `<string class="${tagClass}"'>${AXIOM}</strong>`,
- },
- })
- expect(wrapper.find(`.${tagClass}`).exists()).toBe(true)
- })
- test('should not be able to render raw HTML without dangerouslyUseHTMLString prop', () => {
- const tagClass = 'test-class'
- const wrapper = _mount({
- props: {
- dangerouslyUseHTMLString: false,
- message: `<string class="${tagClass}"'>${AXIOM}</strong>`,
- },
- })
- expect(wrapper.find(`.${tagClass}`).exists()).toBe(false)
- })
- })
- describe('Message.type', () => {
- test('should be able to render typed messages', () => {
- for (const type of ['success', 'warning', 'info', 'error'] as const) {
- const wrapper = _mount({ props: { type } })
- expect(wrapper.findComponent(TypeComponentsMap[type]).exists()).toBe(
- true
- )
- }
- })
- test('should not be able to render invalid type icon', () => {
- const consoleWarn = console.warn
- console.warn = vi.fn()
- const type = 'some-type'
- const wrapper = _mount({ props: { type } })
- for (const component of Object.values(TypeComponentsMap)) {
- expect(wrapper.findComponent(component).exists()).toBe(false)
- }
- console.warn = consoleWarn
- })
- })
- describe('event handlers', () => {
- test('it should be able to close the message by clicking close button', async () => {
- const onClose = vi.fn()
- const wrapper = _mount({
- slots: { default: AXIOM },
- props: {
- onClose,
- showClose: true,
- },
- })
- const closeBtn = wrapper.find('.el-message__closeBtn')
- expect(closeBtn.exists()).toBe(true)
- await closeBtn.trigger('click')
- expect((wrapper.vm as MessageInstance).visible).toBe(false)
- })
- test('it should close after duration', async () => {
- vi.useFakeTimers()
- const duration = 1000
- const wrapper = _mount({ props: { duration } })
- const vm = wrapper.vm as MessageInstance
- await nextTick()
- expect(vm.visible).toBe(true)
- vi.runAllTimers()
- await nextTick()
- expect(vm.visible).toBe(false)
- vi.useRealTimers()
- })
- test('it should prevent close when hovered', async () => {
- vi.useFakeTimers()
- const duration = 1000
- const wrapper = _mount({ props: { duration } })
- const vm = wrapper.vm as MessageInstance
- vi.advanceTimersByTime(50)
- expect(vm.visible).toBe(true)
- await wrapper.find('[role="alert"]').trigger('mouseenter')
- vi.runAllTimers()
- expect(vm.visible).toBe(true)
- await wrapper.find('[role="alert"]').trigger('mouseleave')
- expect(vm.visible).toBe(true)
- vi.runAllTimers()
- expect(vm.visible).toBe(false)
- vi.useRealTimers()
- })
- test('it should not close when duration is set to 0', () => {
- vi.useFakeTimers()
- const duration = 0
- const wrapper = _mount({ props: { duration } })
- const vm = wrapper.vm as MessageInstance
- expect(vm.visible).toBe(true)
- vi.runAllTimers()
- expect(vm.visible).toBe(true)
- vi.useRealTimers()
- })
- test('it should close when esc is pressed', async () => {
- const wrapper = _mount({ slots: { default: AXIOM } })
- const event = new KeyboardEvent('keydown', {
- code: EVENT_CODE.esc,
- })
- document.dispatchEvent(event)
- expect((wrapper.vm as MessageInstance).visible).toBe(false)
- })
- test('it should call close after transition ends', async () => {
- const onClose = vi.fn()
- const wrapper = _mount({
- slots: { default: AXIOM },
- props: { onClose },
- })
- await rAF()
- const vm = wrapper.vm as MessageInstance
- vm.visible = false
- await rAF()
- expect(onClose).toHaveBeenCalledTimes(1)
- })
- })
- })
|