/** * 36-reminders: Reminders Vue 组件化测试 */ import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { h, render, nextTick } from 'vue' import RemindersComponent from '../../src/apps/reminders/Reminders.vue' import { store } from '../../src/composables/useStore' import { setupDOM } from '../helpers' function makeMockWin() { const el = document.createElement('div'); el.className = 'window'; document.getElementById('window-layer')?.appendChild(el); const body = document.createElement('div'); body.className = 'win-body'; el.appendChild(body); return { el, body, timers: [] as any[], data: {} } } describe('36-reminders — Reminders Vue 组件化', () => { let win: any beforeEach(() => { localStorage.clear(); store.set('reminders', null); setupDOM(); win = makeMockWin() }) afterEach(() => { render(null, win.body); win.el.remove() }) function mount() { const v = h(RemindersComponent, { win }); render(v, win.body) } it('显示 3 个列表', () => { mount(); expect(win.body.querySelectorAll('.fb-side-item').length).toBe(3) }) it('列表有颜色标识', () => { mount(); expect(win.body.querySelector('.rem-color')).toBeTruthy() }) it('显示未完成计数', () => { mount(); expect(win.body.querySelector('.rem-count')?.textContent).toBeTruthy() }) it('切换列表', async () => { mount(); const items = win.body.querySelectorAll('.fb-side-item'); (items[1] as HTMLElement).dispatchEvent(new MouseEvent('click', { bubbles: true })); await nextTick(); expect(items[1].classList.contains('sel')).toBe(true) }) it('显示提醒事项', () => { mount(); expect(win.body.querySelector('.rem-title')).toBeTruthy() }) // ⚠️ jsdom 中 toggleItem 触发后 class 更新可能需额外 nextTick it('勾选标记完成', async () => { mount(); const cb = win.body.querySelector('.rem-check') as HTMLElement; expect(cb).toBeTruthy(); const wasDone = cb.classList.contains('done'); cb.dispatchEvent(new MouseEvent('click', { bubbles: true })); await nextTick(); await nextTick(); const cb2 = win.body.querySelector('.rem-check') as HTMLElement; expect(cb2.classList.contains('done')).toBe(!wasDone) }) it('Enter 添加新事项', async () => { mount(); const input = win.body.querySelector('.rem-new') as HTMLInputElement; input.value = '新提醒'; input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })); await nextTick(); expect(input.value).toBe('') }) it('空列表显示提示', () => { store.set('reminders', { lists: [{ id: 'e1', name: '空', color: '#ff9f0a' }], items: [] }); mount(); expect(win.body.querySelector('.empty-state')?.textContent).toContain('此列表为空') }) it('卸载', () => { mount(); render(null, win.body); expect(win.body.children.length).toBe(0) }) })