Files
radicle-desktop/tests/unit/commentNavigation.test.ts
Rūdolfs Ošiņš f267d3d16f Move comment and commit stepping into lib
The order the stepper walks comments in and its wraparound index math
were untested, and ReviewPage ordered its file groups with its own copy.
2026-10-01 18:20:24 +02:00

122 lines
3.0 KiB
TypeScript

import { describe, expect, test } from "vitest";
import {
orderComments,
orderFileGroups,
stepCommitIndex,
stepIndex,
} from "@app/lib/commentNavigation";
import { comment, location, thread } from "./support/cobs";
function at(
id: string,
path: string,
side: "old" | "new",
line: number,
timestamp = 0,
) {
return thread(
comment({ id, location: location(path, side, line), timestamp }),
);
}
describe("orderComments", () => {
test("orders by file order, line, side, then age", () => {
const ordered = orderComments(
[
at("b-5", "b.ts", "new", 5),
at("a-9", "a.ts", "new", 9),
at("a-2-new", "a.ts", "new", 2),
at("a-2-old", "a.ts", "old", 2),
at("a-2-new-older", "a.ts", "new", 2, -1),
],
["a.ts", "b.ts"],
() => "modified",
);
expect(ordered.map(c => c.id)).toEqual([
"a-2-old",
"a-2-new-older",
"a-2-new",
"a-9",
"b-5",
]);
expect(ordered[0].anchor).toEqual({
path: "a.ts",
side: "deletions",
line: 2,
});
});
test("leaves out comments the diff can't show", () => {
const ordered = orderComments(
[
at("elsewhere", "gone.ts", "new", 1),
at("moved", "moved.ts", "new", 1),
thread(comment({ id: "plain", location: null })),
at("shown", "a.ts", "new", 1),
],
["a.ts", "moved.ts"],
path => (path === "moved.ts" ? "moved" : "modified"),
);
expect(ordered.map(c => c.id)).toEqual(["shown"]);
});
});
describe("stepIndex", () => {
test.each([
[-1, 1, 0],
[-1, -1, 2],
[0, 1, 1],
[2, 1, 0],
[0, -1, 2],
])("from %j by %j lands on %j of three", (current, delta, expected) => {
expect(stepIndex(current, 3, delta)).toBe(expected);
});
test("has nowhere to go in an empty list", () => {
expect(stepIndex(-1, 0, 1)).toBeUndefined();
});
});
describe("stepCommitIndex", () => {
test.each([
[-1, -1, 2],
[-1, 1, 0],
[1, 1, 2],
[1, -1, 0],
[2, 1, 2],
[0, -1, 0],
])("from %j by %j selects %j of three", (current, delta, expected) => {
expect(stepCommitIndex(current, 3, delta)).toBe(expected);
});
});
test("orderFileGroups follows the diff's file order and line order", () => {
const groups = orderFileGroups(
[
{
path: "b.ts",
threads: [at("b-9", "b.ts", "new", 9), at("b-1", "b.ts", "new", 1)],
},
{ path: "gone.ts", threads: [at("g", "gone.ts", "new", 1)] },
{ path: "a.ts", threads: [at("a-3", "a.ts", "old", 3)] },
],
["a.ts", "b.ts"],
);
expect(groups.map(g => [g.path, ...g.threads.map(t => t.root.id)])).toEqual([
["a.ts", "a-3"],
["b.ts", "b-1", "b-9"],
]);
});
test("orderFileGroups leaves the caller's groups as they were", () => {
const threads = [at("b-9", "b.ts", "new", 9), at("b-1", "b.ts", "new", 1)];
orderFileGroups([{ path: "b.ts", threads }], ["b.ts"]);
expect(threads.map(t => t.root.id)).toEqual(["b-9", "b-1"]);
});