87 lines
4.0 KiB
TypeScript
Vendored
87 lines
4.0 KiB
TypeScript
Vendored
import { describe, expect, it } from "vitest";
|
|
import type { CompletionAssistantCandidate, TreeNode } from "@/types/database";
|
|
import { buildPackageMemberNodes, markPackageNodesExpandable, packageMemberGroupOwnerId } from "@/lib/sidebar/packageMembers";
|
|
|
|
function packageNode(): TreeNode {
|
|
return {
|
|
id: "conn:db:schema:package:business_api",
|
|
label: "business_api",
|
|
type: "package",
|
|
objectName: "business_api",
|
|
connectionId: "conn",
|
|
database: "db",
|
|
schema: "app_schema",
|
|
valid: false,
|
|
};
|
|
}
|
|
|
|
describe("package member tree", () => {
|
|
it("marks package specifications as expandable without changing other objects", () => {
|
|
const nodes: TreeNode[] = [packageNode(), { id: "body", label: "business_api", type: "package-body" }, { id: "proc", label: "standalone", type: "procedure" }];
|
|
const result = markPackageNodesExpandable(nodes);
|
|
|
|
expect(result[0]?.children).toEqual([]);
|
|
expect(result[1]?.children).toBeUndefined();
|
|
expect(result[2]?.children).toBeUndefined();
|
|
});
|
|
|
|
it("builds public procedure and function children with overload identities", () => {
|
|
const candidates: CompletionAssistantCandidate[] = [
|
|
{ name: "calculate", kind: "procedure", signature: "p_value IN INT" },
|
|
{ name: "calculate", kind: "procedure", signature: "p_value IN VARCHAR" },
|
|
{ name: "lookup", kind: "function", signature: null, data_type: "VARCHAR" },
|
|
{ name: "ignored_table", kind: "table" },
|
|
];
|
|
const result = buildPackageMemberNodes(packageNode(), candidates, "xugu");
|
|
|
|
expect(result.map((node) => [node.type, node.label, node.objectCount])).toEqual([
|
|
["group-procedures", "tree.procedures", 2],
|
|
["group-functions", "tree.functions", 1],
|
|
]);
|
|
expect(result[0]?.children?.map((node) => node.label)).toEqual(["calculate(p_value IN INT)", "calculate(p_value IN VARCHAR)"]);
|
|
expect(result[1]?.children?.map((node) => node.label)).toEqual(["lookup"]);
|
|
expect(result.flatMap((node) => node.children ?? []).every((node) => node.parentName === "business_api" && node.parentSchema === "app_schema" && node.parentType === "package" && node.valid === false)).toBe(true);
|
|
expect(new Set(result.flatMap((node) => node.children ?? []).map((node) => node.id)).size).toBe(3);
|
|
expect(packageMemberGroupOwnerId(result[0]!)).toBe(packageNode().id);
|
|
expect(packageMemberGroupOwnerId({ ...result[0]!, parentType: undefined })).toBeNull();
|
|
expect(packageMemberGroupOwnerId({ ...result[0]!, id: "invalid" })).toBeNull();
|
|
});
|
|
|
|
it("keeps package body source metadata on the package without adding a duplicate body node", () => {
|
|
const node = { ...packageNode(), xuguPackageBodyAvailable: true, xuguPackageBodyValid: false };
|
|
const result = buildPackageMemberNodes(node, [{ name: "calculate", kind: "procedure", signature: null }], "xugu");
|
|
|
|
expect(result.map((child) => [child.type, child.label])).toEqual([["group-procedures", "tree.procedures"]]);
|
|
expect(result[0]?.children).toHaveLength(1);
|
|
expect(result.some((child) => child.type === "package-body")).toBe(false);
|
|
});
|
|
|
|
it("deduplicates exact duplicate metadata without merging case-distinct members", () => {
|
|
const candidates: CompletionAssistantCandidate[] = [
|
|
{ name: "MixedCase", kind: "function", signature: "p INT" },
|
|
{ name: "MixedCase", kind: "function", signature: "p INT" },
|
|
{ name: "MIXEDCASE", kind: "function", signature: "p INT" },
|
|
{ name: "", kind: "procedure" },
|
|
];
|
|
const result = buildPackageMemberNodes(packageNode(), candidates, "xugu");
|
|
|
|
expect(result.flatMap((node) => node.children ?? []).map((node) => node.objectName)).toEqual(["MixedCase", "MIXEDCASE"]);
|
|
});
|
|
|
|
it("keeps non-Xugu package members flat", () => {
|
|
const result = buildPackageMemberNodes(
|
|
packageNode(),
|
|
[
|
|
{ name: "calculate", kind: "procedure", signature: null },
|
|
{ name: "lookup", kind: "function", signature: null },
|
|
],
|
|
"oracle",
|
|
);
|
|
|
|
expect(result.map((node) => [node.type, node.label])).toEqual([
|
|
["procedure", "calculate"],
|
|
["function", "lookup"],
|
|
]);
|
|
});
|
|
});
|