~james/core

core/web/src/lib/components/profile/pagination.test.ts -rw-r--r-- 2.2 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { describe, expect, it } from "vitest";
import {
	createOffsetPager,
	discoveredPageCount,
	pageCount,
	pageRows
} from "#lib/components/profile/pagination.svelte.ts";

describe("profile pagination counts", () => {
	it("uses the known total for profile lists", () => {
		expect(pageCount(4, 30)).toBe(1);
		expect(pageCount(30, 30)).toBe(1);
		expect(pageCount(31, 30)).toBe(2);
	});

	it("only discovers an extra page when totals are unavailable", () => {
		expect(discoveredPageCount(1, false)).toBe(1);
		expect(discoveredPageCount(1, true)).toBe(2);
		expect(discoveredPageCount(2, true)).toBe(3);
	});

	it("sizes a page's skeleton to the items it will hold", () => {
		expect(pageRows(1, 30, 100)).toBe(30);
		expect(pageRows(4, 30, 100)).toBe(10);
		expect(pageRows(4, 30, 90)).toBe(1);
		expect(pageRows(4, 30)).toBe(30);
	});

	it("jumps to a page in one fetch", async () => {
		const requested: number[] = [];
		const pager = createOffsetPager({ page: 1, items: ["first"] }, 30, async (offset) => {
			requested.push(offset);
			return [`page at ${offset}`];
		});

		await pager.select(40);
		expect(requested).toEqual([1170]);
		expect(pager.items).toEqual(["page at 1170"]);
		expect(pager.state).toEqual({ kind: "at-page", page: 40 });

		await pager.select(40);
		await pager.select(1);
		expect(requested).toEqual([1170]);
		expect(pager.items).toEqual(["first"]);
	});

	it("keeps pager lifecycle in one state", async () => {
		let release!: (items: string[]) => void;
		const pager = createOffsetPager(
			{ page: 1, items: ["first"] },
			30,
			() => new Promise<string[]>((resolve) => (release = resolve))
		);

		const loading = pager.select(2);
		// while loading, state points to the incoming page, not the page left behind
		expect(pager.state).toEqual({ kind: "loading", page: 2 });
		expect(pager.items).toEqual([]);
		expect(pager.hasNext).toBe(true);
		release(["second"]);
		await loading;
		expect(pager.state).toEqual({ kind: "at-page", page: 2 });

		const failing = createOffsetPager({ page: 1, items: ["first"] }, 30, async () => {
			throw new Error("nope");
		});
		await failing.select(2);
		expect(failing.state).toEqual({ kind: "failed", page: 1 });
	});
});