import { describe, expect, it } from "vitest"; import { extractStructuredJsonContent, normalizeMultimodalCorrectionReport } from "./vision"; describe("extractStructuredJsonContent", () => { it("parses JSON wrapped in markdown code fences", () => { const parsed = extractStructuredJsonContent("```json\n{\"summary\":\"ok\",\"drills\":[]}\n```"); expect(parsed).toMatchObject({ summary: "ok", drills: [] }); }); it("parses text content arrays returned by chat completions", () => { const parsed = extractStructuredJsonContent([ { type: "text", text: "{\"summary\":\"ok\",\"drills\":[]}" }, ]); expect(parsed).toMatchObject({ summary: "ok", drills: [] }); }); }); describe("normalizeMultimodalCorrectionReport", () => { it("fills missing drill arrays so markdown rendering does not crash", () => { const report = normalizeMultimodalCorrectionReport({ summary: "反手动作可继续优化", overallScore: 81, confidence: 76, drills: [ { name: "反手节奏重建", purpose: "稳定击球点", durationMinutes: 8, }, ], }); expect(report.drills[0]?.steps.length).toBeGreaterThan(0); expect(report.drills[0]?.coachingCues.length).toBeGreaterThan(0); expect(report.nextSessionFocus.length).toBeGreaterThan(0); expect(report.recommendedCaptureTips.length).toBeGreaterThan(0); }); it("maps provider-specific phaseAssessment payloads into phase findings", () => { const report = normalizeMultimodalCorrectionReport({ phaseAssessment: { preparation: "肩膀转动信息不足", contact: "无法判断击球点", }, issueTags: ["补拍侧后方连续帧"], recommendedCaptureTips: "提供连续关键帧", }); expect(report.phaseFindings.length).toBe(2); expect(report.summary).toContain("preparation"); expect(report.nextSessionFocus).toContain("补拍侧后方连续帧"); expect(report.recommendedCaptureTips).toContain("提供连续关键帧"); }); });