Files
kangkang/康康Tests/SeriesBucketTests.swift

111 lines
4.5 KiB
Swift

import Testing
import Foundation
@testable import
struct SeriesBucketTests {
private func makeIndicator(
name: String = "测试",
value: String,
unit: String = "mmol/L",
range: String = "",
status: IndicatorStatus = .normal,
capturedAt: Date,
seriesKey: String?
) -> Indicator {
Indicator(name: name, value: value, unit: unit, range: range,
status: status, capturedAt: capturedAt,
seriesKey: seriesKey)
}
@Test func indicatorsWithoutSeriesKeyFoldIntoLabBucket() {
// lab : seriesKey name+unit , minPoints
let now = Date()
let items = [
makeIndicator(value: "5.0", capturedAt: now.addingTimeInterval(-86_400), seriesKey: nil),
makeIndicator(value: "5.2", capturedAt: now, seriesKey: nil),
]
let buckets = SeriesBucket.build(from: items)
#expect(buckets.count == 1)
#expect(buckets.first?.kind == .lab)
#expect(buckets.first?.lines.first?.points.count == 2)
}
@Test func filtersOutSeriesWithFewerThanMinPoints() {
let now = Date()
let items = [
makeIndicator(value: "5.0", capturedAt: now, seriesKey: "glucose.fasting"),
]
let buckets = SeriesBucket.build(from: items, minPoints: 2)
#expect(buckets.isEmpty)
}
@Test func singleSeriesBucketSortedAscending() {
let day = { (offset: Int) -> Date in
Calendar.current.date(byAdding: .day, value: offset, to: .now)!
}
let items = [
makeIndicator(value: "5.5", capturedAt: day(-3), seriesKey: "glucose.fasting"),
makeIndicator(value: "5.2", capturedAt: day(-1), seriesKey: "glucose.fasting"),
makeIndicator(value: "5.8", capturedAt: day(-2), seriesKey: "glucose.fasting"),
]
let buckets = SeriesBucket.build(from: items)
#expect(buckets.count == 1)
let line = try! #require(buckets.first?.lines.first)
// sorted ascending -3, -2, -1
let values = line.points.map(\.value)
#expect(values == [5.5, 5.8, 5.2])
}
@Test func bloodPressureMergesIntoSingleBucket() {
let now = Date()
let day = { (offset: Int) -> Date in
Calendar.current.date(byAdding: .day, value: offset, to: now)!
}
let items = [
makeIndicator(value: "125", capturedAt: day(-2), seriesKey: "bp.systolic"),
makeIndicator(value: "82", capturedAt: day(-2), seriesKey: "bp.diastolic"),
makeIndicator(value: "130", capturedAt: day(-1), seriesKey: "bp.systolic"),
makeIndicator(value: "85", capturedAt: day(-1), seriesKey: "bp.diastolic"),
]
let buckets = SeriesBucket.build(from: items)
let bp = try! #require(buckets.first { $0.id == "bp" })
#expect(bp.lines.count == 2)
#expect(bp.title == "血压")
#expect(bp.lines.contains { $0.seriesKey == "bp.systolic" })
#expect(bp.lines.contains { $0.seriesKey == "bp.diastolic" })
}
@Test func mixedSeriesProducesMultipleBucketsSortedByRecency() {
let cal = Calendar.current
let day = { (offset: Int) -> Date in
cal.date(byAdding: .day, value: offset, to: .now)!
}
let items = [
// weight
makeIndicator(value: "68", capturedAt: day(-10), seriesKey: "weight"),
makeIndicator(value: "67", capturedAt: day(-7), seriesKey: "weight"),
// glucose
makeIndicator(value: "5.1", capturedAt: day(-2), seriesKey: "glucose.fasting"),
makeIndicator(value: "5.3", capturedAt: day(-1), seriesKey: "glucose.fasting"),
]
let buckets = SeriesBucket.build(from: items)
#expect(buckets.count == 2)
// glucose
#expect(buckets.first?.id == "glucose.fasting")
#expect(buckets.last?.id == "weight")
}
@Test func nonNumericValueDropped() {
let now = Date()
let items = [
makeIndicator(value: "", capturedAt: now, seriesKey: "weight"),
makeIndicator(value: "68", capturedAt: now, seriesKey: "weight"),
makeIndicator(value: "67", capturedAt: now.addingTimeInterval(60), seriesKey: "weight"),
]
let buckets = SeriesBucket.build(from: items)
let line = try! #require(buckets.first?.lines.first)
#expect(line.points.count == 2) // ""
}
}