110 lines
6.3 KiB
TypeScript
Vendored
110 lines
6.3 KiB
TypeScript
Vendored
import { describe, expect, it } from "vitest";
|
|
import { alignedCommentLeadingWidth, alignedSidebarCommentLabelWidths, canTreeNodeShowExpander, sidebarTreeNaturalContentWidth, sidebarTreeNodeComment, trailingCommentAvailableWidth, treeItemPaddingLeft, treeLabelWidthClass, usesFullWidthTreeLabel } from "@/lib/sidebar/sidebarTreeItemLayout";
|
|
import type { TreeNode } from "@/types/database";
|
|
|
|
describe("sidebar tree item layout", () => {
|
|
it("keeps a table row constrained when it displays a comment", () => {
|
|
expect(usesFullWidthTreeLabel("table", true)).toBe(true);
|
|
expect(usesFullWidthTreeLabel("table", true, true)).toBe(false);
|
|
});
|
|
|
|
it("shows connection notes only after the user opts in", () => {
|
|
const connection: TreeNode = { id: "connection-1", label: "MySQL", type: "connection", comment: "Production" };
|
|
expect(sidebarTreeNodeComment(connection, false)).toBeNull();
|
|
expect(sidebarTreeNodeComment(connection, true)).toBe("Production");
|
|
});
|
|
|
|
it("lets a table name consume the available row width before truncating when aligned", () => {
|
|
expect(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true, alignLeading: true })).toBe("min-w-0 flex-1 truncate");
|
|
// inline/right 模式 label 不撑满,让 comment 紧跟
|
|
expect(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true, alignLeading: false })).toBe("min-w-0 shrink truncate");
|
|
});
|
|
|
|
it("keeps a pinned action next to the name while preserving the aligned comment column", () => {
|
|
expect(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true, hasInlineAction: true })).toBe("min-w-0 shrink truncate");
|
|
expect(alignedCommentLeadingWidth(100, true)).toBe(124);
|
|
expect(alignedCommentLeadingWidth(100, false)).toBe(100);
|
|
expect(alignedCommentLeadingWidth(undefined, true)).toBeUndefined();
|
|
});
|
|
|
|
it("renders navigation leaf actions without expanders", () => {
|
|
expect(canTreeNodeShowExpander({ type: "dynamodb-table", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "nacos-namespace", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "nacos-access-control", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "etcd-root", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "etcd-dashboard", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "etcd-access-control", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "consul-overview", childCount: 0 })).toBe(false);
|
|
});
|
|
|
|
it("shows an expander only for package nodes explicitly marked as containers", () => {
|
|
expect(canTreeNodeShowExpander({ type: "package", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "package", childCount: 0, explicitContainer: true })).toBe(true);
|
|
expect(canTreeNodeShowExpander({ type: "package-body", childCount: 0, explicitContainer: true })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "procedure", childCount: 0, explicitContainer: true })).toBe(false);
|
|
});
|
|
|
|
it("allows only an explicitly marked Xugu type specification to expand", () => {
|
|
expect(canTreeNodeShowExpander({ type: "type", childCount: 0, explicitContainer: true })).toBe(true);
|
|
expect(canTreeNodeShowExpander({ type: "type", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "type-body", childCount: 0, explicitContainer: true })).toBe(false);
|
|
});
|
|
|
|
it("shows an expander only while a custom type may still load children", () => {
|
|
expect(canTreeNodeShowExpander({ type: "type", childCount: undefined })).toBe(true);
|
|
expect(canTreeNodeShowExpander({ type: "type", childCount: 2 })).toBe(true);
|
|
expect(canTreeNodeShowExpander({ type: "type", childCount: 0 })).toBe(false);
|
|
expect(canTreeNodeShowExpander({ type: "type-member", childCount: undefined })).toBe(false);
|
|
});
|
|
|
|
it("aligns comments to the longest sibling name without crossing parent groups", () => {
|
|
const widths = alignedSidebarCommentLabelWidths([
|
|
{ id: "tables", depth: 1, alignable: false, hasComment: false, labelWidth: 0 },
|
|
{ id: "short", depth: 2, alignable: true, hasComment: true, labelWidth: 48 },
|
|
{ id: "long", depth: 2, alignable: true, hasComment: false, labelWidth: 136 },
|
|
{ id: "views", depth: 1, alignable: false, hasComment: false, labelWidth: 0 },
|
|
{ id: "view", depth: 2, alignable: true, hasComment: true, labelWidth: 72 },
|
|
]);
|
|
|
|
expect(widths.get("short")).toBe(136);
|
|
expect(widths.has("long")).toBe(false);
|
|
expect(widths.get("view")).toBe(72);
|
|
});
|
|
|
|
it("limits right-aligned comments to the space after the complete name and gap", () => {
|
|
expect(trailingCommentAvailableWidth(260, 100)).toBe(152);
|
|
expect(trailingCommentAvailableWidth(108, 100)).toBe(0);
|
|
expect(trailingCommentAvailableWidth(100, 100)).toBe(0);
|
|
expect(trailingCommentAvailableWidth(99, 100)).toBe(0);
|
|
});
|
|
|
|
it("keeps the natural width of the widest node in the complete virtual tree", () => {
|
|
const width = sidebarTreeNaturalContentWidth(
|
|
[
|
|
{ depth: 1, label: "visible", usesNaturalWidth: true },
|
|
{ depth: 4, label: "widest-node-outside-the-mounted-window", usesNaturalWidth: true, trailingWidth: 20 },
|
|
{ depth: 8, label: "constrained metadata row", usesNaturalWidth: false },
|
|
],
|
|
(text) => text.length * 7,
|
|
);
|
|
|
|
expect(width).toBe(4 * 16 + 8 + 54 + "widest-node-outside-the-mounted-window".length * 7 + 20);
|
|
});
|
|
|
|
it("returns zero when no tree row uses natural width", () => {
|
|
expect(sidebarTreeNaturalContentWidth([{ depth: 2, label: "commented", usesNaturalWidth: false }], (text) => text.length * 7)).toBe(0);
|
|
});
|
|
|
|
it("applies a configurable per-depth indent to rows and natural-width measurement", () => {
|
|
// Default keeps the historical 16px per level.
|
|
expect(treeItemPaddingLeft(2)).toBe("40px");
|
|
expect(treeItemPaddingLeft(2, 24)).toBe("56px");
|
|
expect(treeItemPaddingLeft(0, 24)).toBe("8px");
|
|
|
|
const items = [{ depth: 4, label: "nested", usesNaturalWidth: true, trailingWidth: 20 }];
|
|
const measure = (text: string) => text.length * 7;
|
|
expect(sidebarTreeNaturalContentWidth(items, measure, 16)).toBe(4 * 16 + 8 + 54 + "nested".length * 7 + 20);
|
|
expect(sidebarTreeNaturalContentWidth(items, measure, 32)).toBe(4 * 32 + 8 + 54 + "nested".length * 7 + 20);
|
|
});
|
|
});
|