From 9c60e4f67327469ef7f5e35e2b58afa9ab96c18c Mon Sep 17 00:00:00 2001 From: "glm-5.1" Date: Thu, 21 May 2026 21:01:12 +0000 Subject: [PATCH] Implement analysis defaults module with default value resolution for CallStatus, NodeStatus, EdgeType, and node attributes --- src/analysis/defaults.ts | 30 ++++++++- src/analysis/index.ts | 7 +- test/analysis/defaults.test.ts | 119 +++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 test/analysis/defaults.test.ts diff --git a/src/analysis/defaults.ts b/src/analysis/defaults.ts index 8cec2e9..266d999 100644 --- a/src/analysis/defaults.ts +++ b/src/analysis/defaults.ts @@ -1 +1,29 @@ -export {}; \ No newline at end of file +import type { CallStatus, NodeStatus, EdgeType } from "../schema/enums.js"; +import type { OperationNodeAttrs } from "../schema/node.js"; + +export const defaultCallStatus: CallStatus = "pending"; + +export const defaultNodeStatus: NodeStatus = "idle"; + +export function defaultEdgeType(edgeType?: string): EdgeType { + if (edgeType !== undefined && edgeType !== null) { + return edgeType as EdgeType; + } + return "typed"; +} + +export function resolveDefaultNodeAttrs( + attrs: Partial, + defaults: Partial = {}, +): OperationNodeAttrs { + return { + name: attrs.name ?? defaults.name ?? "", + namespace: attrs.namespace ?? defaults.namespace ?? "", + version: attrs.version ?? defaults.version ?? "", + type: attrs.type ?? defaults.type ?? "query", + inputSchema: attrs.inputSchema ?? defaults.inputSchema ?? {}, + outputSchema: attrs.outputSchema ?? defaults.outputSchema ?? {}, + description: attrs.description ?? defaults.description, + tags: attrs.tags ?? defaults.tags, + }; +} \ No newline at end of file diff --git a/src/analysis/index.ts b/src/analysis/index.ts index 8cec2e9..f9ab852 100644 --- a/src/analysis/index.ts +++ b/src/analysis/index.ts @@ -1 +1,6 @@ -export {}; \ No newline at end of file +export { + defaultCallStatus, + defaultNodeStatus, + defaultEdgeType, + resolveDefaultNodeAttrs, +} from "./defaults.js"; \ No newline at end of file diff --git a/test/analysis/defaults.test.ts b/test/analysis/defaults.test.ts new file mode 100644 index 0000000..6d29122 --- /dev/null +++ b/test/analysis/defaults.test.ts @@ -0,0 +1,119 @@ +import { describe, it, expect } from "vitest"; +import { + defaultCallStatus, + defaultNodeStatus, + defaultEdgeType, + resolveDefaultNodeAttrs, +} from "../../src/analysis/defaults.js"; + +describe("analysis/defaults", () => { + describe("defaultCallStatus", () => { + it('is "pending"', () => { + expect(defaultCallStatus).toBe("pending"); + }); + }); + + describe("defaultNodeStatus", () => { + it('is "idle"', () => { + expect(defaultNodeStatus).toBe("idle"); + }); + }); + + describe("defaultEdgeType", () => { + it('returns "typed" when no argument provided', () => { + expect(defaultEdgeType()).toBe("typed"); + }); + + it('returns "typed" when undefined provided', () => { + expect(defaultEdgeType(undefined)).toBe("typed"); + }); + + it("returns the provided edge type", () => { + expect(defaultEdgeType("triggered")).toBe("triggered"); + expect(defaultEdgeType("depends_on")).toBe("depends_on"); + expect(defaultEdgeType("typed")).toBe("typed"); + expect(defaultEdgeType("sequential")).toBe("sequential"); + expect(defaultEdgeType("conditional")).toBe("conditional"); + }); + }); + + describe("resolveDefaultNodeAttrs", () => { + it("fills all required fields from defaults when attrs is empty", () => { + const defaults = { + name: "op", + namespace: "ns", + version: "1.0.0", + type: "query" as const, + inputSchema: { type: "object" }, + outputSchema: { type: "object" }, + }; + const result = resolveDefaultNodeAttrs({}, defaults); + expect(result).toEqual({ + name: "op", + namespace: "ns", + version: "1.0.0", + type: "query", + inputSchema: { type: "object" }, + outputSchema: { type: "object" }, + description: undefined, + tags: undefined, + }); + }); + + it("merges partial attrs with defaults", () => { + const defaults = { + name: "op", + namespace: "ns", + version: "1.0.0", + type: "query" as const, + inputSchema: { type: "object" }, + outputSchema: { type: "object" }, + }; + const result = resolveDefaultNodeAttrs( + { name: "custom", namespace: "other" }, + defaults, + ); + expect(result.name).toBe("custom"); + expect(result.namespace).toBe("other"); + expect(result.version).toBe("1.0.0"); + expect(result.type).toBe("query"); + }); + + it("uses built-in defaults when no defaults object provided", () => { + const result = resolveDefaultNodeAttrs({ name: "myop" }); + expect(result).toEqual({ + name: "myop", + namespace: "", + version: "", + type: "query", + inputSchema: {}, + outputSchema: {}, + description: undefined, + tags: undefined, + }); + }); + + it("preserves optional fields from attrs", () => { + const result = resolveDefaultNodeAttrs({ + name: "op", + namespace: "ns", + version: "1.0.0", + type: "mutation", + inputSchema: {}, + outputSchema: {}, + description: "test op", + tags: ["a", "b"], + }); + expect(result.description).toBe("test op"); + expect(result.tags).toEqual(["a", "b"]); + }); + + it("prefers attrs over defaults", () => { + const result = resolveDefaultNodeAttrs( + { type: "subscription" }, + { type: "query" }, + ); + expect(result.type).toBe("subscription"); + }); + }); +}); \ No newline at end of file