Files
kangkang/康康Tests/CaptureServiceJSONTests.swift
link2026 1b01923c8e feat(capture): 统一报告捕获流程并集成视觉语言模型识别
- 替换 QuickCaptureFlow 和 ArchiveFlow 为 UnifiedCaptureFlow 统一流程
- 新增 VLSession 封装 Qwen2.5-VL 模型进行图像文本推理
- 实现 AIRuntime 中 VL 模型的准备和分析功能
- 添加 VLPrompts 定义体检化验单识别的 JSON 输出模板
- 创建 CaptureReviewForm 提供 VL 解析结果的可编辑表单界面
- 集成 VisionKit 文档扫描器支持真机多页文档扫描
- 为模拟器实现 PhotosPicker 回退方案选择已有照片
- 在 RootView 中统一使用 UnifiedCaptureFlow 处理快速和归档流程
- 添加 CustomMetricEditor 支持自定义监测指标的创建编辑删除
- 扩展 KangkangApp 模型配置以支持新数据类型
- 实现档案列表中症状结束功能通过时间线行点击触发
2026-05-26 11:18:00 +08:00

113 lines
4.7 KiB
Swift

import Testing
import Foundation
@testable import
struct CaptureServiceJSONTests {
@Test func parsesCleanJSON() throws {
let raw = """
{"title":"","type":"checkup","report_date":"2026-04-12","institution":"","page_count":2,"summary":"","indicators":[{"name":"LDL-C","value":"3.84","unit":"mmol/L","range":"< 3.40","status":"high"}]}
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.title == "春检")
#expect(parsed.typeRaw == ReportType.checkup.rawValue)
#expect(parsed.institution == "协和")
#expect(parsed.pageCount == 2)
#expect(parsed.indicators.count == 1)
#expect(parsed.indicators.first?.status == .high)
}
@Test func stripsMarkdownCodeFence() throws {
let raw = """
```json
{"title":"x","type":"lab","report_date":"2026-05-01","institution":"","page_count":1,"summary":"","indicators":[]}
```
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.title == "x")
#expect(parsed.typeRaw == ReportType.lab.rawValue)
#expect(parsed.indicators.isEmpty)
}
@Test func extractsObjectAfterLeadingText() throws {
let raw = """
好的,识别结果如下:
{"title":"y","type":"lab","report_date":"2026-05-01","institution":"","page_count":1,"summary":"","indicators":[]}
以上。
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.title == "y")
}
@Test func handlesNestedBraces() throws {
let raw = """
{"title":"y","type":"lab","report_date":"2026-05-01","institution":"","page_count":1,"summary":"{x}","indicators":[]}
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.summary == "含嵌套{x}对象")
}
@Test func handlesEscapedQuotesInStrings() throws {
let raw = #"{"title":"y \"内嵌\" 引号","type":"lab","report_date":"2026-05-01","institution":"","page_count":1,"summary":"","indicators":[]}"#
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.title == #"y "内嵌" "#)
}
@Test func fillsDefaultsForMissingFields() throws {
// 缺 title / type / report_date / institution / summary / page_count
let raw = """
{"indicators":[{"name":"X","value":"1","unit":"","range":"","status":"normal"}]}
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.title == "") // 默认值
#expect(parsed.typeRaw == ReportType.other.rawValue)
#expect(parsed.indicators.count == 1)
}
@Test func skipsIndicatorsWithEmptyName() throws {
let raw = """
{"title":"t","type":"lab","report_date":"2026-05-01","institution":"","page_count":1,"summary":"","indicators":[
{"name":"","value":"1","unit":"","range":"","status":"normal"},
{"name":" ","value":"1","unit":"","range":"","status":"normal"},
{"name":"OK","value":"1","unit":"","range":"","status":"normal"}
]}
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.indicators.count == 1)
#expect(parsed.indicators.first?.name == "OK")
}
@Test func malformedJSONThrows() {
let raw = " JSON"
#expect(throws: CaptureError.self) {
_ = try CaptureService.parseReportJSON(raw)
}
}
@Test func valueAsNumberStillParses() throws {
let raw = """
{"title":"t","type":"lab","report_date":"2026-05-01","institution":"","page_count":1,"summary":"","indicators":[{"name":"X","value":3.84,"unit":"","range":"","status":"high"}]}
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.indicators.first?.value == "3.84")
}
@Test func unknownStatusFallsBackToNormal() throws {
let raw = """
{"title":"t","type":"lab","report_date":"2026-05-01","institution":"","page_count":1,"summary":"","indicators":[{"name":"X","value":"1","unit":"","range":"","status":"abnormal"}]}
"""
let parsed = try CaptureService.parseReportJSON(raw)
#expect(parsed.indicators.first?.status == .normal)
}
@Test func badReportDateFallsBackToNow() throws {
let raw = """
{"title":"t","type":"lab","report_date":"昨天","institution":"","page_count":1,"summary":"","indicators":[]}
"""
let parsed = try CaptureService.parseReportJSON(raw)
let now = Date()
let diff = abs(parsed.reportDate.timeIntervalSince(now))
#expect(diff < 5) // 5 秒内算 .now
}
}