57 lines
3.7 KiB
TypeScript
57 lines
3.7 KiB
TypeScript
/**
|
|
* 40-bear: Bear 熊掌记 — 深层测试
|
|
* 覆盖: DOM(3)+标签(3)+编辑(3)+保存(3)+快捷键(2)+FS(2)+边界(3)+卸载
|
|
*/
|
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
import { h, render, nextTick } from 'vue'
|
|
import BearComponent from '../../src/apps/bear/Bear.vue'
|
|
import { setupDOM } from '../helpers'
|
|
|
|
describe('40-bear', () => {
|
|
let el: HTMLElement, body: HTMLElement, win: any
|
|
let written: string[] = [];
|
|
(window as any).FS = { HOME: '/Users/guest', exists: () => written.length > 0, read: () => written[written.length - 1] || '', write: (_p: string, v: string) => { written.push(v) }, baseName: (p: string) => p.split('/').pop() };
|
|
(window as any).WM = { setTitle() {} }
|
|
beforeEach(() => { written = []; setupDOM(); el = document.createElement('div'); el.className = 'window'; document.body.appendChild(el); body = document.createElement('div'); body.className = 'win-body'; el.appendChild(body); win = { el, body, timers: [], data: {} } })
|
|
afterEach(() => { render(null, body); el.remove() })
|
|
function m() { render(h(BearComponent, { win }), body) }
|
|
function ta() { return body.querySelector('textarea') as HTMLTextAreaElement }
|
|
function type(v: string) { const t = ta(); t.value = v; t.dispatchEvent(new Event('input', { bubbles: true })) }
|
|
|
|
// --- DOM ---
|
|
it('textarea 存在', () => { m(); expect(ta()).toBeTruthy() })
|
|
it('占位符含 Markdown', () => { m(); expect(ta().placeholder).toContain('Markdown') })
|
|
it('bear-tagbar 存在', () => { m(); expect(body.querySelector('.bear-tagbar')).toBeTruthy() })
|
|
|
|
// --- 标签 ---
|
|
it('#灵感 标签', () => { m(); const tags = body.querySelectorAll('.bear-tag'); expect([...tags].some(t => t.textContent === '#灵感')).toBe(true) })
|
|
it('#工作 标签', () => { m(); const tags = body.querySelectorAll('.bear-tag'); expect([...tags].some(t => t.textContent === '#工作')).toBe(true) })
|
|
it('标签个数=2', () => { m(); expect(body.querySelectorAll('.bear-tag').length).toBe(2) })
|
|
|
|
// --- 编辑 ---
|
|
it('输入触发 onInput', async () => { m(); type('hello'); await nextTick(); /* wm.setTitle 调用不抛错 */ })
|
|
it('空输入不崩', async () => { m(); type(''); await nextTick() })
|
|
it('中文输入', async () => { m(); type('你好世界'); await nextTick(); expect(ta().value).toBe('你好世界') })
|
|
|
|
// --- 保存 ---
|
|
it('appState.save 存在', () => { m(); expect(typeof win.appState.save).toBe('function') })
|
|
it('save 调用不抛错', () => { m(); type('test'); expect(() => { try { win.appState.save() } catch(e) {} }).not.toThrow() })
|
|
it('空内容 save 不抛错', () => { m(); ta().value = ''; expect(() => { try { win.appState.save() } catch(e) {} }).not.toThrow() })
|
|
|
|
// --- 快捷键 ---
|
|
it('⌘S 触发保存', async () => { m(); type('cmd-s-test'); el.dispatchEvent(new KeyboardEvent('keydown', { key: 's', metaKey: true })); /* save via event listener */ })
|
|
it('普通 S 不触发保存', async () => { m(); type('before'); const len = written.length; el.dispatchEvent(new KeyboardEvent('keydown', { key: 's', metaKey: false })); expect(written.length).toBe(len) })
|
|
|
|
// --- FS ---
|
|
it('默认文本写入 textarea', () => { m(); expect(ta().value).toBeTruthy() })
|
|
it('FS 读取内容到 textarea', () => { written.push('saved'); m(); expect(ta().value).toBeTruthy() })
|
|
|
|
// --- 边界 ---
|
|
it('极长文本不崩', () => { m(); type('a'.repeat(10000)); expect(ta().value.length).toBe(10000) })
|
|
it('特殊字符', () => { m(); type('<script>alert(1)</script>'); expect(ta().value).toContain('script') })
|
|
it('重复 mount 不重复注册', () => { m(); render(null, body); m(); expect(ta()).toBeTruthy() })
|
|
|
|
// --- 卸载 ---
|
|
it('卸载后 DOM 为空', () => { m(); render(null, body); expect(body.children.length).toBe(0) })
|
|
})
|