Skip to content
98 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { buildTree, canDo, citationHref, coverStyle, cursorColour, dayGroups, dayKey, flatten, linkedArtifacts, pathTo, readingTime, repoFilePath, repoFolders, snippetParts, spacePath } from "./folios.ts";
5
6const node = (id: string, parent_id: string | null, position: number) => ({ id, kind: "doc" as const, parent_id, position, title: id.toUpperCase(), icon: null, slug: id, restricted: false });
7
8const nodes = [node("b", null, 2), node("a", null, 1), node("c", "a", 1), node("orphan", "gone", 3)];
9
10test("the tree orders each level and lifts folios whose parent isn't there", () => {
11 const tree = buildTree(nodes);
12 assert.deepEqual(
13 tree.map((n) => n.id),
14 ["a", "b", "orphan"],
15 );
16 assert.equal(tree[0]!.children[0]!.id, "c");
17 assert.equal(tree[0]!.children[0]!.depth, 1);
18 assert.deepEqual(
19 flatten(tree).map((n) => n.id),
20 ["a", "c", "b", "orphan"],
21 );
22 assert.deepEqual(pathTo(nodes, "c"), ["a"]);
23});
24
25test("the home list groups by the viewer's day: Today, Yesterday, then dates", () => {
26 const now = new Date("2026-10-09T15:00:00Z");
27 const items = ["2026-10-09T14:00:00Z", "2026-10-09T01:00:00Z", "2026-10-08T20:00:00Z", "2026-10-07T12:00:00Z", "2025-12-31T12:00:00Z"];
28 const utc = dayGroups(items, (i) => i, "UTC", now);
29 assert.deepEqual(
30 utc.map((g) => [g.label, g.items.length]),
31 [
32 ["Today", 2],
33 ["Yesterday", 1],
34 ["Oct 7", 1],
35 ["Dec 31, 2025", 1],
36 ],
37 );
38 // At 01:00 UTC it is still the 8th in Chicago: that one is yesterday's there.
39 const chicago = dayGroups(items, (i) => i, "America/Chicago", now);
40 assert.deepEqual(
41 chicago.map((g) => [g.label, g.items.length]),
42 [
43 ["Today", 1],
44 ["Yesterday", 2],
45 ["Oct 7", 1],
46 ["Dec 31, 2025", 1],
47 ],
48 );
49 assert.equal(dayKey("2026-10-09T01:00:00Z", "America/Chicago"), "2026-10-08");
50});
51
52test("chat messages name the artifacts they link to, in this workspace only", () => {
53 const id = "fol_01jb2k7x9hfq0b3zj0f5s2m8ra";
54 const other = "fol_01jb2k7x9hfq0b3zj0f5s2m8rb";
55 assert.deepEqual(linkedArtifacts(`See https://g1t.sh/acme/-/artifacts/q4-plan-${id} and /acme/-/artifacts/${other}, and again /Acme/-/artifacts/${id}`, "acme"), [id, other]);
56 assert.deepEqual(linkedArtifacts(`/other/-/artifacts/x-${id}`, "acme"), []);
57 assert.deepEqual(linkedArtifacts(`/acme/-/artifacts/spaces/general`, "acme"), []);
58});
59
60test("snippets mark their matches", () => {
61 assert.deepEqual(snippetParts("a [[b]] c"), [
62 { text: "a ", match: false },
63 { text: "b", match: true },
64 { text: " c", match: false },
65 ]);
66});
67
68test("covers, colours, roles, reading time", () => {
69 assert.match(coverStyle("gradient:1")!, /^linear-gradient/);
70 assert.match(coverStyle("https://g1tusercontent.com/docs-files/x")!, /url\("https:/);
71 assert.equal(coverStyle("javascript:alert(1)"), null);
72 assert.equal(cursorColour("ana"), cursorColour("ana"));
73 assert.equal(canDo("edit", "comment"), true);
74 assert.equal(canDo("comment", "edit"), false);
75 assert.deepEqual(readingTime("one two three"), { words: 3, minutes: 1 });
76});
77
78test("a citation links to its code, a glob to the folder it starts from", () => {
79 assert.equal(citationHref({ repo: "acme/web", path: "src/export.ts", ref: "abc1234" }), "/acme/web/blob/abc1234/src/export.ts");
80 assert.equal(citationHref({ repo: "acme/web", path: "src/jobs", ref: null }), "/acme/web/tree/HEAD/src/jobs");
81 assert.equal(citationHref({ repo: "acme/web", path: "src/**/*.sql", ref: "abc" }), "/acme/web/tree/abc/src");
82});
83
84test("a project's docs become folders, and spaces and files have addresses under Artifacts", () => {
85 const root = repoFolders([
86 { path: "README.md", title: "Acme" },
87 { path: "docs/setup.md", title: "Setup" },
88 { path: "docs/guides/deploy.md", title: "Deploy" },
89 ]);
90 assert.deepEqual(
91 root.files.map((f) => f.path),
92 ["README.md", "docs/setup.md"],
93 );
94 assert.equal(root.folders[0]!.name, "guides");
95 assert.deepEqual(root.folders[0]!.files.map((f) => f.title), ["Deploy"]);
96 assert.equal(repoFilePath("acme", "acme/web", "docs/a b.md"), "/acme/-/artifacts/repo/acme/web/docs/a%20b.md");
97 assert.equal(spacePath("acme", "general"), "/acme/-/artifacts/spaces/general");
98});