test: App 与 main 函数覆盖提升至 90%+(右键操作/右侧面板/解码回退/入口)
This commit is contained in:
@@ -18,10 +18,18 @@ function mockApi(overrides?: Partial<typeof window.api>): typeof window.api {
|
||||
return { ...base, ...overrides } as typeof window.api
|
||||
}
|
||||
|
||||
let clipboardSpy: ReturnType<typeof vi.fn>
|
||||
|
||||
beforeEach(() => {
|
||||
window.api = mockApi()
|
||||
// jsdom 未实现 scrollIntoView,导航定位需要打桩
|
||||
Element.prototype.scrollIntoView = vi.fn()
|
||||
// jsdom 未实现 navigator.clipboard,右键复制需要打桩
|
||||
clipboardSpy = vi.fn()
|
||||
Object.defineProperty(navigator, 'clipboard', {
|
||||
value: { writeText: clipboardSpy },
|
||||
configurable: true
|
||||
})
|
||||
})
|
||||
|
||||
describe('App - 初始空态', () => {
|
||||
@@ -105,6 +113,19 @@ describe('App - 拖拽导入', () => {
|
||||
fireEvent.dragLeave(pane)
|
||||
expect(pane.className).not.toContain('dragging')
|
||||
})
|
||||
|
||||
it('解码失败时回退 file.text(覆盖 dropPane catch 分支)', async () => {
|
||||
window.api = mockApi({
|
||||
decodeBuffer: async () => {
|
||||
throw new Error('boom')
|
||||
}
|
||||
})
|
||||
render(<App />)
|
||||
const file = new File(['fallback1'], 'd.txt', { type: 'text/plain' })
|
||||
const pane = screen.getByText(/选择左侧文件/).closest('.pane-empty') as Element
|
||||
fireEvent.drop(pane, { dataTransfer: { files: [file] } })
|
||||
expect(await screen.findByText('导出报告')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('App - 差异导航与清空', () => {
|
||||
@@ -124,4 +145,69 @@ describe('App - 差异导航与清空', () => {
|
||||
fireEvent.click(screen.getByText('清空'))
|
||||
expect(await screen.findByText(/选择左侧文件/)).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('App - 空态打开按钮', () => {
|
||||
it('点击空面板的打开文件按钮加载左侧文件', async () => {
|
||||
render(<App />)
|
||||
fireEvent.click(screen.getAllByText('打开文件')[0])
|
||||
expect(await screen.findByText('导出报告')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('App - 右键菜单操作', () => {
|
||||
it('执行复制本行内容并关闭菜单', async () => {
|
||||
render(<App />)
|
||||
fireEvent.click(screen.getByText('打开左侧'))
|
||||
await screen.findByText('导出报告')
|
||||
fireEvent.contextMenu((await screen.findAllByText(/line1/))[0])
|
||||
fireEvent.click(await screen.findByText('复制左侧此行内容'))
|
||||
expect(clipboardSpy).toHaveBeenCalled()
|
||||
expect(screen.queryByText('复制左侧此行内容')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('执行复制文件名', async () => {
|
||||
render(<App />)
|
||||
fireEvent.click(screen.getByText('打开左侧'))
|
||||
await screen.findByText('导出报告')
|
||||
fireEvent.contextMenu((await screen.findAllByText(/line1/))[0])
|
||||
fireEvent.click(await screen.findByText('复制文件名'))
|
||||
expect(clipboardSpy).toHaveBeenCalledWith('a.txt')
|
||||
})
|
||||
|
||||
it('执行在文件夹中显示(覆盖 showInFolder)', async () => {
|
||||
const showInFolder = vi.fn(async () => true)
|
||||
window.api = mockApi({ showInFolder })
|
||||
render(<App />)
|
||||
fireEvent.click(screen.getByText('打开左侧'))
|
||||
await screen.findByText('导出报告')
|
||||
fireEvent.contextMenu((await screen.findAllByText(/line1/))[0])
|
||||
fireEvent.click(await screen.findByText('在文件夹中显示'))
|
||||
expect(showInFolder).toHaveBeenCalledWith('/tmp/a.txt')
|
||||
})
|
||||
})
|
||||
|
||||
describe('App - 右侧面板交互', () => {
|
||||
it('点击右侧打开文件按钮加载', async () => {
|
||||
render(<App />)
|
||||
fireEvent.click(screen.getAllByText('打开文件')[1])
|
||||
expect(await screen.findByText('导出报告')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('右侧拖拽悬停/离开高亮切换', () => {
|
||||
render(<App />)
|
||||
const pane = screen.getByText(/选择右侧文件/).closest('.pane-empty') as Element
|
||||
fireEvent.dragOver(pane)
|
||||
expect(pane.className).toContain('dragging')
|
||||
fireEvent.dragLeave(pane)
|
||||
expect(pane.className).not.toContain('dragging')
|
||||
})
|
||||
|
||||
it('右侧拖放加载(覆盖右侧 onDrop 与 dropPane 右分支)', async () => {
|
||||
render(<App />)
|
||||
const file = new File(['r1\nr2'], 'e.txt', { type: 'text/plain' })
|
||||
const pane = screen.getByText(/选择右侧文件/).closest('.pane-empty') as Element
|
||||
fireEvent.drop(pane, { dataTransfer: { files: [file] } })
|
||||
expect(await screen.findByText('导出报告')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,20 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { screen, act } from '@testing-library/react'
|
||||
|
||||
// main.tsx 引入全局样式,测试中替换为空模块避免 CSS 处理
|
||||
vi.mock('../styles/global.css', () => ({}))
|
||||
|
||||
describe('main 入口', () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = '<div id="root"></div>'
|
||||
vi.resetModules()
|
||||
})
|
||||
|
||||
it('挂载 DiffLens 应用(覆盖 main.tsx 入口)', async () => {
|
||||
await act(async () => {
|
||||
await import('../main')
|
||||
})
|
||||
expect(document.getElementById('root')).toBeTruthy()
|
||||
expect(await screen.findByText('DiffLens')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user