// @vitest-environment jsdom // เทสต์ pure helpers ของ useCustomSelection ที่ต้องมี DOM Range จริง — แยกจาก // ชุด pure utils (environment node ตาม vitest.config.ts) ด้วย pragma ต่อไฟล์ // ตัว hook เอง (Pointer Events + rAF + gesture จริง) ยืนยันด้วย Playwright แทน import { describe, expect, it } from "vitest"; import { rangeBetween, snapCaretToWord } from "@/hooks/useCustomSelection"; /** text node เดียวใน body + collapsed caret ที่ offset (เลียน anchor/focus ของ * useCustomSelection ก่อนผ่าน word snap) */ function setup(text: string, offset: number): { caret: () => Range } { const node = document.createTextNode(text); document.body.replaceChildren(node); return { caret: () => { const r = document.createRange(); r.setStart(node, offset); r.collapse(true); return r; }, }; } describe("snapCaretToWord", () => { it("จิ้มกลางคำ → ขยายครอบทั้งคำ (อังกฤษ)", () => { const { caret } = setup("alpha beta gamma", 2); const c = caret(); snapCaretToWord(c); expect(c.toString()).toBe("alpha"); }); it("จิ้มกลางคำไทย (ไม่มีช่องว่าง) → Intl.Segmenter แยกคำให้ (node ≥16 มี full-icu)", () => { const { caret } = setup("แมวกินปลา", 1); const c = caret(); snapCaretToWord(c); expect(c.toString()).toBe("แมว"); }); it("จิ้มกลางช่องว่างล้วน → ไม่ขยาย (ยัง collapsed)", () => { const { caret } = setup("alpha beta", 6); const c = caret(); snapCaretToWord(c); expect(c.collapsed).toBe(true); }); }); describe("rangeBetween — ฝั่งหลังต้องใช้ end boundary (A1: อย่าทิ้งคำท้าย)", () => { const TEXT = "alpha beta gamma delta"; // offset: alpha 0–5, beta 6–10, gamma 11–16, delta 17–22 /** เลียน flow จริง: สร้าง caret สองจุด → word snap ทั้งคู่ → rangeBetween */ function between(offA: number, offB: number): string { const node = document.createTextNode(TEXT); document.body.replaceChildren(node); const mk = (off: number) => { const r = document.createRange(); r.setStart(node, off); r.collapse(true); return r; }; const a = mk(offA); const b = mk(offB); snapCaretToWord(a); snapCaretToWord(b); return rangeBetween(a, b)?.toString() ?? ""; } it("ลาก alpha→gamma ได้ครบถึงคำท้าย (เดิมหาย gamma)", () => { expect(between(2, 13)).toBe("alpha beta gamma"); }); it("ลากย้อน gamma→alpha ได้ผลเดียวกัน", () => { expect(between(13, 2)).toBe("alpha beta gamma"); }); it("ลากในคำเดียว (beta→beta) ได้ทั้งคำ (เดิม selection ว่าง)", () => { expect(between(7, 9)).toBe("beta"); }); it("ลาก alpha→beta ได้สองคำ", () => { expect(between(2, 8)).toBe("alpha beta"); }); });