82 lines
3.3 KiB
TypeScript
82 lines
3.3 KiB
TypeScript
// @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() ?? "<null>";
|
||
}
|
||
|
||
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");
|
||
});
|
||
});
|