a reactive (signals based) hypermedia web framework (wip) stormlightlabs.github.io/volt/
hypermedia frontend signals
at main 3.0 kB view raw
1import { getLibSrcPath } from "$utils/paths.js"; 2import { readFile } from "node:fs/promises"; 3import path from "node:path"; 4import { describe, expect, it } from "vitest"; 5 6describe("docs generation", () => { 7 it("should extract function documentation", async () => { 8 const srcPath = await getLibSrcPath(); 9 const testFile = path.join(srcPath, "core", "signal.ts"); 10 const content = await readFile(testFile, "utf8"); 11 12 expect(content).toContain("Creates a new signal"); 13 expect(content).toContain("@param initialValue"); 14 expect(content).toContain("@returns A Signal object"); 15 expect(content).toContain("@example"); 16 }); 17 18 it("should extract interface documentation", async () => { 19 const srcPath = await getLibSrcPath(); 20 const typesFile = path.join(srcPath, "types", "volt.d.ts"); 21 const content = await readFile(typesFile, "utf8"); 22 23 expect(content).toContain("interface Signal"); 24 expect(content).toContain("interface ComputedSignal"); 25 }); 26 27 it("should handle JSDoc with examples", () => { 28 const jsdoc = `/** 29 * Creates a signal 30 * @example 31 * const count = signal(0); 32 * count.set(1); 33 */`; 34 35 const hasExample = jsdoc.includes("@example"); 36 expect(hasExample).toBe(true); 37 38 const lines = jsdoc.split("\n"); 39 const exampleLines: string[] = []; 40 let inExample = false; 41 42 for (const line of lines) { 43 const trimmed = line.trim().replace(/^\*\s?/, ""); 44 45 if (trimmed.startsWith("@example")) { 46 inExample = true; 47 continue; 48 } 49 50 if (trimmed.startsWith("@") && !trimmed.startsWith("@example")) { 51 inExample = false; 52 continue; 53 } 54 55 if (inExample && trimmed !== "" && !trimmed.startsWith("*/")) { 56 exampleLines.push(trimmed); 57 } 58 } 59 60 expect(exampleLines.length).toBeGreaterThan(0); 61 expect(exampleLines.join("\n")).toContain("signal(0)"); 62 }); 63 64 it("should clean up JSDoc comments", () => { 65 const jsdoc = `/** 66 * This is a description 67 * with multiple lines 68 * @param foo - description 69 */`; 70 71 const lines = jsdoc.split("\n").map((line) => line.trim()).map((line) => line.replace(/^\/\*\*\s?/, "")).map(( 72 line, 73 ) => line.replace(/^\*\s?/, "")).map((line) => line.replace(/\*\/\s*$/, "")).filter((line) => 74 !line.startsWith("@") && line !== "" 75 ); 76 77 const description = lines.join("\n").trim(); 78 79 expect(description).toContain("This is a description"); 80 expect(description).toContain("with multiple lines"); 81 expect(description).not.toContain("@param"); 82 }); 83 84 it("should parse markdown structure", () => { 85 const markdown = `# Module 86 87## Function 88 89Description here 90 91\`\`\`typescript 92function foo(): void 93\`\`\` 94 95**Example:** 96 97\`\`\`typescript 98foo(); 99\`\`\` 100`; 101 102 expect(markdown).toContain("# Module"); 103 expect(markdown).toContain("## Function"); 104 expect(markdown).toContain("**Example:**"); 105 expect(markdown).toMatch(/```typescript[\s\S]*?```/); 106 }); 107});