import { describe, expect, it } from "vitest"; import type { Tool } from "@/stores/toolStore"; import { extractBaseToolId, filterLatestToolVersions } from "./tool-version"; describe("Tool Version Utilities", () => { describe("extractBaseToolId", () => { it("should handle simple tool IDs without version", () => { expect(extractBaseToolId("plaintools")).toBe("plaintools"); expect(extractBaseToolId("vscode")).toBe("vscode"); }); it("should extract base ID from simple versioned tools", () => { expect(extractBaseToolId("rstudio/1.1.0")).toBe("rstudio"); expect(extractBaseToolId("jupyter/2.0")).toBe("jupyter"); expect(extractBaseToolId("tool/1.2.3-beta")).toBe("tool"); }); it("should handle tool shed tools with versions", () => { expect(extractBaseToolId("toolshed.g2.bx.psu.edu/repos/owner/rstudio/interactive_rstudio/1.1.0")).toBe( "toolshed.g2.bx.psu.edu/repos/owner/rstudio/interactive_rstudio", ); expect(extractBaseToolId("toolshed.g2.bx.psu.edu/repos/devteam/bowtie2/bowtie2/2.4.2+galaxy0")).toBe( "toolshed.g2.bx.psu.edu/repos/devteam/bowtie2/bowtie2", ); }); it("should handle tool shed tools without versions", () => { expect(extractBaseToolId("toolshed.g2.bx.psu.edu/repos/owner/rstudio/interactive_rstudio")).toBe( "toolshed.g2.bx.psu.edu/repos/owner/rstudio/interactive_rstudio", ); }); it("should handle tools with slashes but no version", () => { expect(extractBaseToolId("category/subcategory/tool")).toBe("category/subcategory/tool"); expect(extractBaseToolId("test/tool/name")).toBe("test/tool/name"); }); }); describe("filterLatestToolVersions", () => { const createMockTool = (id: string, version: string, name = "Tool"): Tool => ({ id, version, name, model_class: "InteractiveTool", description: "", labels: [], edam_operations: [], edam_topics: [], hidden: false, is_workflow_compatible: true, xrefs: [], config_file: "", link: "", min_width: 0, target: "", panel_section_id: "", panel_section_name: null, form_style: "regular", }); it("should filter out older versions of tools", () => { const tools = [ createMockTool("rstudio/1.1.0", "1.1.0", "RStudio"), createMockTool("rstudio/1.2.0", "1.2.0", "RStudio"), createMockTool("rstudio/1.3.1", "1.3.1", "RStudio"), createMockTool("jupyter/2.0", "2.0", "Jupyter"), createMockTool("jupyter/2.1", "2.1", "Jupyter"), createMockTool("vscode", "1.0", "VS Code"), ]; const filtered = filterLatestToolVersions(tools); expect(filtered).toHaveLength(3); expect(filtered.find((t) => t.id.startsWith("rstudio"))?.version).toBe("1.3.1"); expect(filtered.find((t) => t.id.startsWith("jupyter"))?.version).toBe("2.1"); expect(filtered.find((t) => t.id === "vscode")?.version).toBe("1.0"); }); it("should handle tool shed tools with versioned IDs", () => { const tools = [ createMockTool( "toolshed.g2.bx.psu.edu/repos/owner/rstudio/interactive_rstudio/1.1.0", "1.1.0", "RStudio Interactive", ), createMockTool( "toolshed.g2.bx.psu.edu/repos/owner/rstudio/interactive_rstudio/1.2.0", "1.2.0", "RStudio Interactive", ), createMockTool( "toolshed.g2.bx.psu.edu/repos/owner/jupyter/interactive_jupyter/2.0", "2.0", "Jupyter Interactive", ), ]; const filtered = filterLatestToolVersions(tools); expect(filtered).toHaveLength(2); const rstudio = filtered.find((t) => t.name.includes("RStudio")); const jupyter = filtered.find((t) => t.name.includes("Jupyter")); expect(rstudio?.version).toBe("1.2.0"); expect(jupyter?.version).toBe("2.0"); }); it("should handle version formats with suffixes", () => { const tools = [ createMockTool("tool/2.0.0", "2.0.0"), createMockTool("tool/2.0.0-beta", "2.0.0-beta"), createMockTool("tool/2.0.0-alpha", "2.0.0-alpha"), ]; const filtered = filterLatestToolVersions(tools); expect(filtered).toHaveLength(1); // localeCompare with numeric option will order these as: // "2.0.0" < "2.0.0-alpha" < "2.0.0-beta" expect(filtered[0]?.version).toBe("2.0.0-beta"); }); it("should return empty array for empty input", () => { const filtered = filterLatestToolVersions([]); expect(filtered).toHaveLength(0); }); }); });