import { nextTick, unref } from 'vue' import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' import makeMount from '@element-plus/test-utils/make-mount' import makeScroll from '@element-plus/test-utils/make-scroll' import setupMock from '../setup-mock' import { CENTERED_ALIGNMENT, END_ALIGNMENT, SMART_ALIGNMENT, START_ALIGNMENT, } from '../src/defaults' import { FixedSizeGrid } from '..' import type { GridExposes } from '../src/types' type GridRef = GridExposes const onItemRendered = vi.fn() const WINDOW_KLS = 'window' const ITEM_KLS = 'item' const ITEM_SELECTOR = `.${ITEM_KLS}` const mount = makeMount( { template: ` item {{ rowIndex }} {{ columnIndex }} `, components: { FixedSizeGrid, }, }, { props: { className: WINDOW_KLS, columnWidth: 50, height: 100, rowHeight: 25, totalColumn: 100, totalRow: 100, width: 100, onItemRendered, }, } ) let cleanup: () => void describe('', () => { beforeAll(() => { cleanup = setupMock() }) afterAll(() => { cleanup() }) describe('render testing', () => { it('should render correctly', async () => { const wrapper = mount() await nextTick() // 8 visible grid. 2 x 4 // total rows total columns // | | // 16 cached grid (2 + 2) x (4 + 2) - (2 x 4) expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) const gridRef = wrapper.vm.$refs.gridRef as GridRef expect(unref(gridRef.innerRef).style.height).toBe('2500px') expect(unref(gridRef.innerRef).style.width).toBe('5000px') }) it('should render zero row zero column', async () => { const wrapper = mount({ props: { totalColumn: 0, totalRow: 0, }, }) await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(0) }) }) describe('scroll testing', () => { it('should scroll correctly', async () => { const wrapper = mount() await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) const gridRef = wrapper.vm.$refs.gridRef as GridRef makeScroll(unref(gridRef.windowRef), 'scrollTop', 100) await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(21) makeScroll(unref(gridRef.windowRef), 'scrollLeft', 100) await nextTick() // 5 (backward cache 1 + visible 2 + forward cache 2) // * 7 (backward cache 1 + visible 4 + forward cache 2) // 35 expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(35) }) it('should not scroll at all', async () => { const wrapper = mount() await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) const gridRef = wrapper.vm.$refs.gridRef as GridRef makeScroll(unref(gridRef.windowRef), 'scrollTop', 0) await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) makeScroll(unref(gridRef.windowRef), 'scrollLeft', 0) await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) }) it('should run scrollTo correctly', async () => { const wrapper = mount() await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) const gridRef = wrapper.vm.$refs.gridRef as GridRef gridRef.scrollTo({ scrollLeft: 100, scrollTop: 0, }) await nextTick() // 4 (0 + 2 + 2) * 8 (2 + 4 + 2) grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(36) gridRef.scrollTo({ scrollLeft: 100, scrollTop: 100, }) await nextTick() // 6 (2 + 2 + 2) * 8 (2 + 4 + 2) grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(48) const prevFirstItem = wrapper.find(ITEM_SELECTOR) // should do nothing gridRef.scrollTo({ scrollLeft: 100, scrollTop: 100, }) await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(48) expect(wrapper.find(ITEM_SELECTOR).element).toEqual(prevFirstItem.element) }) it('should scrollToItem with correct alignment', async () => { const wrapper = mount() await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) const gridRef = wrapper.vm.$refs.gridRef as GridRef // do nothing scroll gridRef.scrollToItem() await nextTick() expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(24) // auto alignment gridRef.scrollToItem(10) await nextTick() // 8 x 4 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(32) gridRef.scrollToItem(10, 10) await nextTick() // 8 x 6 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(48) gridRef.scrollToItem(5, 5, SMART_ALIGNMENT) await nextTick() // 8 x 7 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(56) gridRef.scrollToItem(6, 6, SMART_ALIGNMENT) await nextTick() // 8 x 6 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(48) gridRef.scrollToItem(6, 6, START_ALIGNMENT) await nextTick() // 8 x 6 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(48) gridRef.scrollToItem(5, 5, CENTERED_ALIGNMENT) await nextTick() // 9 x 7 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(63) gridRef.scrollToItem(6, 6, CENTERED_ALIGNMENT) await nextTick() // 9 x 7 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(63) gridRef.scrollToItem(4, 4, END_ALIGNMENT) await nextTick() // 7 x 6 grid expect(wrapper.findAll(ITEM_SELECTOR)).toHaveLength(42) }) }) describe('error handling', () => { it('should throw when column-width is not number', () => { const errorHandler = vi.fn() mount({ props: { columnWidth: '1', }, global: { config: { errorHandler, warnHandler() { // suppress warning }, }, }, }) expect(errorHandler).toHaveBeenCalled() }) it('should throw when row-height is not number', () => { const errorHandler = vi.fn() mount({ props: { rowHeight: '1', }, global: { config: { errorHandler, warnHandler() { // suppress warning }, }, }, }) expect(errorHandler).toHaveBeenCalled() }) }) })