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 第 4–6 段", () => { expect(parseParagraphNo("第 4–6 段反复描写天气")).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); }); });