90 lines
4.0 KiB
TypeScript
90 lines
4.0 KiB
TypeScript
// tests/unit/renderer/components/import-no-auto-open.test.ts
|
|
//
|
|
// 守卫(r177):「导入文件后不应该马上自动打开」。
|
|
//
|
|
// 旧行为(notes 侧 audit-r22 引入的 macOS Finder 风格、literature 侧同款):
|
|
// 导入成功 → select(最后一条导入的资源) + setActive('notes'/'library')
|
|
// + requestFocusNote(光标丢进 body)
|
|
// → 右侧面板被强制切到刚导入的文件,用户正在读的笔记/PDF 被顶掉,读一半
|
|
// 的内容被切走,还得再点回去。
|
|
//
|
|
// 期望契约:导入只做「落盘(必要时搬进当前文件夹)+ toast(+ 列表滚到新行)」,
|
|
// **不改变选中态、不切面板、不抢焦点**。要打开,用户自己点那一行。
|
|
//
|
|
// 本测是**源码契约 guard**:两个列表组件的 importFiles 回调体里不允许出现
|
|
// select( / setActive( / requestFocusNote(
|
|
// 为什么用源码扫描而不是渲染组件测:
|
|
// NotesList / LiteratureList 都依赖 react-virtuoso,jsdom 下容器高度为 0,
|
|
// 行根本不渲染 —— 渲染测测不到「点了导入之后有没有自动打开」这个行为,
|
|
// 只能退到源码契约。仓库里 layering / i18n-parity 同款做法。
|
|
import { describe, expect, it } from 'vitest';
|
|
import { readFileSync } from 'fs';
|
|
import { join } from 'path';
|
|
|
|
const ROOT = process.cwd();
|
|
|
|
/**
|
|
* 从 `const importFiles = useCallback(` 起,做花括号配平,截出回调体文本。
|
|
* 先剥掉注释(注释里可能有花括号),字符串字面量里的花括号在本仓库这两个
|
|
* 回调里不存在(importFiles 的文案 key 都不带 '{}')。
|
|
*/
|
|
function extractCallbackBody(fileRel: string, marker: string): string {
|
|
const src = readFileSync(join(ROOT, fileRel), 'utf8');
|
|
const start = src.indexOf(marker);
|
|
expect(start, `${fileRel} 里找不到 ${marker}`).toBeGreaterThan(-1);
|
|
const open = src.indexOf('{', start);
|
|
expect(open, `${fileRel} 里 ${marker} 之后没有 '{'`).toBeGreaterThan(-1);
|
|
const stripped = src
|
|
.slice(open)
|
|
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
.replace(/^[ \t]*\/\/.*$/gm, '');
|
|
let depth = 0;
|
|
for (let i = 0; i < stripped.length; i++) {
|
|
const ch = stripped[i];
|
|
if (ch === '{') depth++;
|
|
else if (ch === '}') {
|
|
depth--;
|
|
if (depth === 0) return stripped.slice(0, i);
|
|
}
|
|
}
|
|
throw new Error(`${fileRel}: ${marker} 的回调体花括号没配平,提取失败`);
|
|
}
|
|
|
|
const NOTES = 'src/renderer/src/components/notes/NotesList.tsx';
|
|
const LIT = 'src/renderer/src/components/literature/LiteratureList.tsx';
|
|
|
|
describe('导入后不自动打开(r177)', () => {
|
|
it('notes 侧 importFiles 不 select / 不切面板 / 不抢焦点', () => {
|
|
const body = extractCallbackBody(NOTES, 'const importFiles = useCallback(');
|
|
expect(body).not.toMatch(/\bselect\(/);
|
|
expect(body).not.toMatch(/\bsetActive\(/);
|
|
expect(body).not.toMatch(/\brequestFocusNote\(/);
|
|
});
|
|
|
|
it('literature 侧 importFiles 不 select / 不切面板', () => {
|
|
const body = extractCallbackBody(LIT, 'const importFiles = useCallback(');
|
|
expect(body).not.toMatch(/\bselect\(/);
|
|
expect(body).not.toMatch(/\bsetActive\(/);
|
|
expect(body).not.toMatch(/\brequestFocusNote\(/);
|
|
});
|
|
|
|
it('notes 侧导入仍然落盘 + 仍搬进当前文件夹 + 仍出成功 toast', () => {
|
|
const body = extractCallbackBody(NOTES, 'const importFiles = useCallback(');
|
|
expect(body).toMatch(/\bimportFromFile\(/);
|
|
expect(body).toMatch(/\bmoveToFolder\(/);
|
|
expect(body).toMatch(/toast\.importSuccess/);
|
|
});
|
|
|
|
it('literature 侧导入仍然落盘 + 仍搬进当前文件夹 + 仍出成功 toast', () => {
|
|
const body = extractCallbackBody(LIT, 'const importFiles = useCallback(');
|
|
expect(body).toMatch(/\bimportFromFile\(/);
|
|
expect(body).toMatch(/\bapi\.litMove\(/);
|
|
expect(body).toMatch(/literature\.importSuccess/);
|
|
});
|
|
|
|
it('notes 侧仍把新行滚进视野(落点可见),但只是滚动不是选中', () => {
|
|
const body = extractCallbackBody(NOTES, 'const importFiles = useCallback(');
|
|
expect(body).toMatch(/scrollToIndex/);
|
|
});
|
|
});
|