Files
writer-work-flow/apps/web/lib/review/snippet.test.ts
Yaojia Wang d81583d5d1 feat(ux): R1+R2 审稿裁决人体学 — 冲突卡内联片段 + 分组/排序/跳下一条/主次按钮
R1: 新 lib/review/snippet.ts 从 where 解析段号取终稿命中段预览,ConflictCard 渲染引用块。
R2: 新 lib/review/grouping.ts 按 type 分组+严重度排序(仅改显示顺序,保留原始 index 守 conflict_index 不变量),组计数徽标、跳到下一条未裁决(环回)、采纳改法主按钮/忽略手改次级。
TDD: snippet 8 测 + grouping 10 测。前端门禁绿: lint/tsc/vitest 201/build。
2026-06-20 15:53:45 +02:00

51 lines
1.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, it } from "vitest";
import { conflictSnippet, parseParagraphNo } from "./snippet";
describe("parseParagraphNo", () => {
it("extracts 1-based paragraph number from 第 N 段 wording", () => {
expect(parseParagraphNo("第 3 段,主角忽然示弱")).toBe(3);
expect(parseParagraphNo("第9段老者道破来历")).toBe(9);
});
it("returns null when no paragraph number present", () => {
expect(parseParagraphNo("战斗场景")).toBeNull();
expect(parseParagraphNo("开篇提到三日后")).toBeNull();
expect(parseParagraphNo("")).toBeNull();
});
it("takes the first number for a range like 第 46 段", () => {
expect(parseParagraphNo("第 46 段反复描写天气")).toBe(4);
});
});
describe("conflictSnippet", () => {
const text = "第一段正文。\n\n第二段正文。\n\n第三段正文命中冲突的句子。";
it("returns the trimmed paragraph for a parseable where", () => {
expect(conflictSnippet(text, "第 3 段,主角忽然示弱")).toBe(
"第三段正文,命中冲突的句子。",
);
});
it("returns null when paragraph number is unparseable", () => {
expect(conflictSnippet(text, "战斗场景")).toBeNull();
});
it("returns null when paragraph index is out of range", () => {
expect(conflictSnippet(text, "第 9 段")).toBeNull();
});
it("returns null when the located paragraph is empty", () => {
expect(conflictSnippet("\n\n\n\n正文", "第 1 段")).toBeNull();
});
it("truncates long paragraphs with an ellipsis", () => {
const long = "甲".repeat(200);
const snippet = conflictSnippet(long, "第 1 段");
expect(snippet).not.toBeNull();
expect(snippet!.length).toBeLessThanOrEqual(81);
expect(snippet!.endsWith("…")).toBe(true);
});
});