import { describe, it, expect } from 'vitest' import { mount } from '@vue/test-utils' import { nextTick } from 'vue' import Select from '@/components/ui/select/select.vue' /** 下拉浮层 Teleport 到 body,需从 body 查 */ function popoverContent() { return document.body.querySelector('.popover-content') } describe('Select 下拉浮层宽度上限', () => { it('浮层内容盒带 select-popover-content 锚点类(:has() 定位浮层加 max-width 用)', async () => { // 浮层由 Popover 渲染、Teleport 到 body,不在 Select 的 scoped 作用域内, // 只能靠 content-class 传递锚点类,再由全局样式 .popover:has(> .select-popover-content) // 把 max-width 上限压到浮层上;锚点类丢失等于宽度上限静默失效 const wrapper = mount(Select, { props: { options: [{ value: 'a', label: '选项' }] }, }) await wrapper.find('.select-trigger').trigger('click') await nextTick() const content = popoverContent() expect(content).not.toBeNull() expect(content.classList.contains('select-popover-content')).toBe(true) wrapper.unmount() }) }) describe('Select 远程分页增强(visible-change / load-more)', () => { it('展开时 emit visible-change(true),供远程选择在打开时加载首页', async () => { const wrapper = mount(Select, { props: { options: [{ value: 'a', label: '甲' }] } }) await wrapper.find('.select-trigger').trigger('click') await nextTick() expect(wrapper.emitted('visible-change')?.at(-1)).toEqual([true]) wrapper.unmount() }) it('选项列表滚动触底 emit load-more', async () => { const options = Array.from({ length: 30 }, (_, i) => ({ value: String(i), label: `项${i}` })) const wrapper = mount(Select, { props: { options }, attachTo: document.body }) await wrapper.find('.select-trigger').trigger('click') await nextTick() const list = document.body.querySelector('.select-list') expect(list).not.toBeNull() // jsdom 不做布局,手动造出"已滚到触底"的度量:scrollTop + clientHeight >= scrollHeight - 24 Object.defineProperty(list, 'scrollHeight', { value: 300, configurable: true }) Object.defineProperty(list, 'clientHeight', { value: 200, configurable: true }) Object.defineProperty(list, 'scrollTop', { value: 100, configurable: true }) list.dispatchEvent(new Event('scroll')) await nextTick() expect(wrapper.emitted('load-more')).toBeTruthy() wrapper.unmount() }) it('loading 中滚动触底不重复 emit load-more', async () => { const options = Array.from({ length: 30 }, (_, i) => ({ value: String(i), label: `项${i}` })) const wrapper = mount(Select, { props: { options, loading: true }, attachTo: document.body }) await wrapper.find('.select-trigger').trigger('click') await nextTick() const list = document.body.querySelector('.select-list') Object.defineProperty(list, 'scrollHeight', { value: 300, configurable: true }) Object.defineProperty(list, 'clientHeight', { value: 200, configurable: true }) Object.defineProperty(list, 'scrollTop', { value: 100, configurable: true }) list.dispatchEvent(new Event('scroll')) await nextTick() expect(wrapper.emitted('load-more')).toBeFalsy() wrapper.unmount() }) })