72 lines
3.4 KiB
TypeScript
72 lines
3.4 KiB
TypeScript
import { expect, it } from "vitest";
|
|
import { chapterIndexAt, chapterWin, PageHeights } from "../src/lib/virt";
|
|
|
|
it("估算高度:offset/total/pageAt/range(带 overscan、夹边)", () => {
|
|
const ph = new PageHeights(10, 100);
|
|
expect(ph.offset(3)).toBe(300);
|
|
expect(ph.total()).toBe(1000);
|
|
expect(ph.pageAt(350)).toBe(3);
|
|
expect(ph.pageAt(-10)).toBe(0);
|
|
expect(ph.pageAt(99_999)).toBe(9);
|
|
expect(ph.range(0, 100, 2)).toEqual([0, 3]);
|
|
expect(ph.range(950, 100, 2)).toEqual([7, 10]);
|
|
});
|
|
|
|
it("set 修正高度并平移后续 offset;返回增量;幂等", () => {
|
|
const ph = new PageHeights(10, 100);
|
|
expect(ph.set(2, 150)).toBe(50);
|
|
expect(ph.offset(2)).toBe(200); // 自身 offset 不受自己影响
|
|
expect(ph.offset(3)).toBe(350); // 后续整体 +50
|
|
expect(ph.total()).toBe(1050);
|
|
expect(ph.pageAt(349)).toBe(2);
|
|
expect(ph.pageAt(351)).toBe(3);
|
|
expect(ph.set(2, 150)).toBe(0);
|
|
});
|
|
|
|
it("setEst:重估默认页高,返回视口上方「未量高」页数,已量高页保留", () => {
|
|
const ph = new PageHeights(5, 100); // cum 顶部: 0,100,200,300,400
|
|
ph.set(0, 160); // 页0 实测 160 → cum 顶部: 0,160,260,360,460
|
|
expect(ph.setEst(140, 260)).toBe(1); // 顶部<260 且未量高:页1(160)。页0 已量高排除,页2(260)不<260
|
|
expect(ph.total()).toBe(160 + 4 * 140); // 页0 实测保留,其余按新估高
|
|
expect(ph.setEst(140, 9999)).toBe(0); // 同值幂等:est 不变直接 0
|
|
});
|
|
|
|
it("n=0 时一切归空", () => {
|
|
const ph = new PageHeights(0, 100);
|
|
expect(ph.total()).toBe(0);
|
|
expect(ph.range(0, 100, 2)).toEqual([0, 0]);
|
|
expect(ph.set(0, 50)).toBe(0);
|
|
});
|
|
|
|
const CH4 = [{ start: 0 }, { start: 10 }, { start: 20 }, { start: 30 }];
|
|
|
|
it("chapterIndexAt:无章/单章恒 0;页号归章;首章 start 之前的散页归 0", () => {
|
|
expect(chapterIndexAt(null, 7)).toBe(0);
|
|
expect(chapterIndexAt([{ start: 0 }], 7)).toBe(0);
|
|
expect(chapterIndexAt(CH4, 0)).toBe(0);
|
|
expect(chapterIndexAt(CH4, 9)).toBe(0);
|
|
expect(chapterIndexAt(CH4, 10)).toBe(1);
|
|
expect(chapterIndexAt(CH4, 999)).toBe(3);
|
|
expect(chapterIndexAt([{ start: 5 }, { start: 10 }], 3)).toBe(0); // 根散页
|
|
});
|
|
|
|
it("chapterWin:扁平/连读 = 全书窗口", () => {
|
|
expect(chapterWin(null, 40, 0, false, 2)).toEqual({ start: 0, end: 40, mountEnd: 40 });
|
|
expect(chapterWin(CH4, 40, 2, true, 2)).toEqual({ start: 0, end: 40, mountEnd: 40 });
|
|
});
|
|
|
|
it("chapterWin:锁章窗口 = 本章;mountEnd 按预读章数延伸、夹到 count", () => {
|
|
expect(chapterWin(CH4, 40, 1, false, 0)).toEqual({ start: 10, end: 20, mountEnd: 20 });
|
|
expect(chapterWin(CH4, 40, 1, false, 1)).toEqual({ start: 10, end: 20, mountEnd: 30 });
|
|
expect(chapterWin(CH4, 40, 1, false, 2)).toEqual({ start: 10, end: 20, mountEnd: 40 });
|
|
expect(chapterWin(CH4, 40, 1, false, 3)).toEqual({ start: 10, end: 20, mountEnd: 40 }); // 越界夹住
|
|
expect(chapterWin(CH4, 40, 3, false, 2)).toEqual({ start: 30, end: 40, mountEnd: 40 }); // 末章
|
|
});
|
|
|
|
it("chapterWin:ci 越界夹边;首章窗口含首章 start 之前的散页;prefetch 负数按 0", () => {
|
|
expect(chapterWin(CH4, 40, 9, false, 1)).toEqual({ start: 30, end: 40, mountEnd: 40 });
|
|
expect(chapterWin(CH4, 40, -2, false, 1)).toEqual({ start: 0, end: 10, mountEnd: 20 });
|
|
expect(chapterWin([{ start: 5 }, { start: 10 }], 20, 0, false, 0)).toEqual({ start: 0, end: 10, mountEnd: 10 });
|
|
expect(chapterWin(CH4, 40, 1, false, -1)).toEqual({ start: 10, end: 20, mountEnd: 20 });
|
|
});
|