69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
assertParent,
|
|
collectSubtree,
|
|
validateSiblingOrder,
|
|
} from "./hierarchy";
|
|
|
|
const pages = [
|
|
{ id: 1, parentId: -1, orderNum: 0 },
|
|
{ id: 2, parentId: 1, orderNum: 1 },
|
|
{ id: 3, parentId: 1, orderNum: 2 },
|
|
{ id: 4, parentId: 2, orderNum: 1 },
|
|
];
|
|
describe("catalog hierarchy commands", () => {
|
|
it("rejects self, descendant, missing and malformed destinations", () => {
|
|
for (const parent of [1, 2, 4, 999, 1.5, -2])
|
|
expect(() => assertParent(pages, 1, parent)).toThrow();
|
|
});
|
|
it("allows detaching a page from an inherited cycle", () =>
|
|
expect(() =>
|
|
assertParent(
|
|
[
|
|
{ id: 1, parentId: 2 },
|
|
{ id: 2, parentId: 1 },
|
|
],
|
|
1,
|
|
-1,
|
|
),
|
|
).not.toThrow());
|
|
it("rejects a destination with an inherited parent cycle", () =>
|
|
expect(() =>
|
|
assertParent(
|
|
[
|
|
{ id: 1, parentId: -1 },
|
|
{ id: 2, parentId: 3 },
|
|
{ id: 3, parentId: 2 },
|
|
],
|
|
1,
|
|
2,
|
|
),
|
|
).toThrow());
|
|
it("collects cyclic subtrees once without recursion", () =>
|
|
expect(
|
|
collectSubtree(
|
|
[
|
|
{ id: 1, parentId: 2 },
|
|
{ id: 2, parentId: 1 },
|
|
],
|
|
1,
|
|
),
|
|
).toEqual([1, 2]));
|
|
it("rejects stale or partial sibling lists before reordering", () => {
|
|
expect(() => validateSiblingOrder(pages, 1, [2], [2, 3])).toThrow();
|
|
expect(() => validateSiblingOrder(pages, 1, [3, 2], [3, 2])).toThrow();
|
|
expect(() => validateSiblingOrder(pages, 1, [2, 2], [2, 3])).toThrow();
|
|
});
|
|
it("accepts a complete reorder matching the previous sibling order", () =>
|
|
expect(() => validateSiblingOrder(pages, 1, [3, 2], [2, 3])).not.toThrow());
|
|
});
|
|
|
|
it("orders mixed root conventions with a stable ID tie breaker", () => {
|
|
const roots = [
|
|
{ id: 3, parentId: 0, orderNum: 1 },
|
|
{ id: 2, parentId: -1, orderNum: 1 },
|
|
];
|
|
expect(() => validateSiblingOrder(roots, -1, [3, 2], [2, 3])).not.toThrow();
|
|
expect(() => validateSiblingOrder(roots, -1, [2, 3], [3, 2])).toThrow();
|
|
});
|