macos-web/tests/cases/26-preview.test.ts

104 lines
4.0 KiB
TypeScript

/**
* 26-preview: 深层测试——画廊/图片/PDF/文本模式、缩放、旋转、边界
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { h, render, nextTick } from 'vue'
import PreviewComponent from '../../src/apps/preview/Preview.vue'
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 { id: 'pv', appId: 'preview', el, body, timers: [] as any[], data: {} }
}
function click(win: any, selector: string) {
(win.body.querySelector(selector) as HTMLElement)?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
}
describe('26-preview — 深层测试', () => {
let win: any
beforeEach(() => { setupDOM(); win = makeMockWin() })
afterEach(() => { render(null, win.body); win.el.remove() })
function mount() { const v = h(PreviewComponent, { win }); render(v, win.body) }
describe('画廊模式(无文件)', () => {
it('默认显示画廊', () => { mount(); expect(win.body.querySelector('.preview-gallery')).toBeTruthy() })
it('画廊中有 WALLPAPERS 图片', () => { mount(); expect(win.body.querySelectorAll('.preview-cell').length).toBeGreaterThanOrEqual(4) })
it('工具栏有缩放/旋转按钮', () => {
mount()
expect(win.body.querySelector('.fb-btn[title="放大"]')).toBeTruthy()
expect(win.body.querySelector('.fb-btn[title="缩小"]')).toBeTruthy()
})
it('默认缩放 100%', () => {
mount()
expect(win.body.querySelector('.preview-info')?.textContent).toContain('100%')
})
})
describe('缩放', () => {
it('zoom(0.2) → 120%', async () => {
mount()
win.appState.zoom(0.2); await nextTick()
expect(win.body.querySelector('.preview-info')?.textContent).toContain('120%')
})
it('zoom(-0.2) → 80%', async () => {
mount()
win.appState.zoom(0.4); win.appState.zoom(-0.2); await nextTick()
expect(win.body.querySelector('.preview-info')?.textContent).toContain('120%')
})
it('zoomReset() 重置为 100%', async () => {
mount()
win.appState.zoom(1); win.appState.zoomReset(); await nextTick()
expect(win.body.querySelector('.preview-info')?.textContent).toContain('100%')
})
it('zoom 不超过上限 4', () => {
mount()
for (let i = 0; i < 20; i++) win.appState.zoom(0.2)
const info = win.body.querySelector('.preview-info')?.textContent || ''
// clamp(scale + 0.2, 0.2, 4) — 20次后应稳定在4
expect(info).toMatch(/400|缩放/)
})
it('zoom 不低于下限 0.2', () => {
mount()
for (let i = 0; i < 20; i++) win.appState.zoom(-0.2)
const info = win.body.querySelector('.preview-info')?.textContent || ''
expect(info).toMatch(/20|缩放/)
})
})
describe('图片模式', () => {
it('传入 asset 显示图片', async () => {
win.data = { asset: '/assets/wallpapers/monterey.jpg', name: 'Monterey' }
mount(); await nextTick()
expect(win.body.querySelector('.preview-img')).toBeTruthy()
})
})
describe('文本模式', () => {
it('传入 txt 文件显示文本内容', async () => {
win.data = { path: '/Users/guest/Desktop/welcome.txt' }
mount(); await nextTick()
expect(win.body.querySelector('.preview-text')).toBeTruthy()
})
it('info 显示缩放百分比', async () => {
win.data = { path: '/Users/guest/Desktop/welcome.txt' }
mount(); await nextTick()
expect(win.body.querySelector('.preview-info')?.textContent).toContain('%')
})
})
describe('appState', () => {
it('暴露 zoom/zoomReset', () => {
mount()
expect(typeof win.appState.zoom).toBe('function')
expect(typeof win.appState.zoomReset).toBe('function')
})
})
describe('卸载', () => {
it('卸载后 DOM 为空', () => { mount(); render(null, win.body); expect(win.body.children.length).toBe(0) })
})
})