import { defineComponent, nextTick, reactive, ref } from 'vue'
import { mount } from '@vue/test-utils'
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { useLocale } from '@element-plus/hooks'
import Chinese from '@element-plus/locale/lang/zh-cn'
import English from '@element-plus/locale/lang/en'
import { ElButton, ElMessage } from '@element-plus/components'
import { rAF } from '@element-plus/test-utils/tick'
import {
useGlobalComponentSettings,
useGlobalConfig,
} from '../src/hooks/use-global-config'
import ConfigProvider from '../src/config-provider'
import type { PropType } from 'vue'
import type { VueWrapper } from '@vue/test-utils'
import type { Language } from '@element-plus/locale'
import type { ComponentSize } from '@element-plus/constants'
import type { ConfigProviderProps } from '../src/config-provider-props'
const TestComp = defineComponent({
setup() {
const { t } = useLocale()
return () =>
{t('el.popconfirm.confirmButtonText')}
},
})
describe('config-provider', () => {
describe('locale-provider', () => {
let wrapper: VueWrapper
beforeEach(() => {
const currentLocale = ref(English)
const oppositeLocale = ref(Chinese)
const toEn = () => {
currentLocale.value = English
oppositeLocale.value = Chinese
}
const toZh = () => {
currentLocale.value = Chinese
oppositeLocale.value = English
}
wrapper = mount(() => (
<>
toEn
toZh
>
))
})
afterEach(() => {
wrapper.unmount()
})
it('should provide locale properly', async () => {
expect(wrapper.find('.current-locale').text()).toBe(
English.el.popconfirm.confirmButtonText
)
expect(wrapper.find('.opposite-locale').text()).toBe(
Chinese.el.popconfirm.confirmButtonText
)
})
it('should reactively update the text on page', async () => {
expect(wrapper.find('.current-locale').text()).toBe(
English.el.popconfirm.confirmButtonText
)
expect(wrapper.find('.opposite-locale').text()).toBe(
Chinese.el.popconfirm.confirmButtonText
)
await wrapper.find('.to-zh').trigger('click')
expect(wrapper.find('.current-locale').text()).toBe(
Chinese.el.popconfirm.confirmButtonText
)
expect(wrapper.find('.opposite-locale').text()).toBe(
English.el.popconfirm.confirmButtonText
)
})
})
describe('button-config', () => {
it('autoInsertSpace', async () => {
const config = reactive({
autoInsertSpace: true,
})
const wrapper = mount(() => (
<>
中文
(config.autoInsertSpace = !config.autoInsertSpace)}
>
toggle
>
))
await nextTick()
expect(
wrapper.find('.el-button .el-button__text--expand').exists()
).toBeTruthy()
await wrapper.find('.toggle').trigger('click')
expect(
wrapper.find('.el-button .el-button__text--expand').exists()
).toBeFalsy()
})
})
describe('namespace-config', () => {
it('reactive namespace', async () => {
const namespace = ref()
const wrapper = mount(() => (
test str
))
await nextTick()
expect(wrapper.find('button').classes().join('')).toBe('el-button')
namespace.value = 'ep'
await nextTick()
expect(wrapper.find('button').classes().join('')).toBe('ep-button')
})
})
describe('message-config', () => {
afterEach(() => {
ElMessage.closeAll()
})
it('limit the number of messages displayed at the same time', async () => {
const config = reactive({
max: 3,
})
const open = () => {
ElMessage('this is a message.')
}
const wrapper = mount(() => (
open
))
await nextTick()
wrapper.find('.el-button').trigger('click')
wrapper.find('.el-button').trigger('click')
wrapper.find('.el-button').trigger('click')
wrapper.find('.el-button').trigger('click')
await nextTick()
expect(document.querySelectorAll('.el-message').length).toBe(3)
config.max = 10
await nextTick()
wrapper.find('.el-button').trigger('click')
wrapper.find('.el-button').trigger('click')
wrapper.find('.el-button').trigger('click')
wrapper.find('.el-button').trigger('click')
await nextTick()
expect(document.querySelectorAll('.el-message').length).toBe(7)
})
it('multiple config-provider config override', async () => {
const config = reactive({
max: 3,
})
const overrideConfig = reactive({
max: 1,
})
const open = () => {
ElMessage('this is a message.')
}
const wrapper = mount(() => (
open
))
await rAF()
await wrapper.find('.el-button').trigger('click')
await wrapper.find('.el-button').trigger('click')
await wrapper.find('.el-button').trigger('click')
await nextTick()
expect(document.querySelectorAll('.el-message').length).toBe(1)
})
})
describe('feature checking', () => {
const TestComponent = defineComponent({
props: {
configKey: {
type: String as PropType,
required: true,
},
},
setup(props) {
const features = useGlobalConfig(props.configKey)
return {
[props.configKey]: features,
}
},
render: () =>
,
})
it.each([
{ feature: 'a11y', config: false },
{ feature: 'keyboardNavigation', config: false },
{ feature: 'experimentalFeatures', config: { someFeature: true } },
])(
'should inject config $feature to $config correctly',
({ feature, config }: { feature: string; config: any }) => {
const props: Record = {}
props[feature] = config
const wrapper = mount(() => (
))
expect(wrapper.findComponent(TestComponent).vm[feature]).toEqual(config)
}
)
})
describe('global component configs', () => {
it('should use global configured settings', async () => {
const namespace = 'test'
const locale = Chinese
const zIndex = 1000
const block = 'button'
const size = 'large'
const receiverRef = ref()
const fallback = ref('' as ComponentSize)
const ReceiverComponent = defineComponent({
setup() {
receiverRef.value = useGlobalComponentSettings(block, fallback)
},
template: '
',
})
mount(() => (
))
const vm = receiverRef.value
expect(vm.ns.namespace).toBe(namespace)
expect(vm.locale.locale).toBe(locale)
expect(vm.zIndex.currentZIndex).toBeGreaterThanOrEqual(zIndex)
expect(vm.size).toBe(size)
fallback.value = 'small'
await nextTick()
expect(vm.size).toBe('small')
})
})
})