| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- import Foundation
- import Testing
- @testable import Trio
- @Suite("Calculate Total IOB Tests") struct CalculateIobTotalTests {
- // Helper function to create a basic treatment
- func createTreatment(insulin: Decimal, timestamp: Date) -> ComputedPumpHistoryEvent {
- ComputedPumpHistoryEvent.forTest(
- type: .bolus,
- timestamp: timestamp,
- insulin: insulin
- )
- }
- // Helper function to create a basic profile
- func createProfile(
- dia: Decimal = 5,
- curve: InsulinCurve = .rapidActing,
- useCustomPeakTime: Bool = false,
- insulinPeakTime: Decimal = 0
- ) -> Profile {
- var profile = Profile()
- profile.curve = curve
- profile.useCustomPeakTime = useCustomPeakTime
- profile.insulinPeakTime = insulinPeakTime
- profile.dia = dia
- return profile
- }
- @Test("should return zero values when no treatments provided") func returnZeroForNoTreatments() async throws {
- let now = Date()
- let result = try IobCalculation.iobTotal(
- treatments: [],
- profile: createProfile(),
- time: now
- )
- #expect(result.iob == 0)
- #expect(result.activity == 0)
- #expect(result.basaliob == 0)
- #expect(result.bolusiob == 0)
- }
- @Test("should calculate total IOB with rapid-acting insulin bolus") func calculateTotalRapidActing() async throws {
- let now = Date()
- let thirtyMinsAgo = now - 30.minutesToSeconds
- let treatments = [createTreatment(insulin: 2, timestamp: thirtyMinsAgo)]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 5, curve: .rapidActing),
- time: now
- )
- #expect(result.iob.isWithin(0.1, of: 1.8))
- #expect(result.bolusiob.isWithin(0.1, of: 1.8))
- #expect(result.basaliob == 0)
- }
- @Test("should calculate total IOB with ultra-rapid insulin bolus") func calculateTotalUltraRapid() async throws {
- let now = Date()
- let thirtyMinsAgo = now - 30.minutesToSeconds
- let treatments = [createTreatment(insulin: 2, timestamp: thirtyMinsAgo)]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 5, curve: .ultraRapid),
- time: now
- )
- #expect(result.iob.isWithin(0.001, of: 1.769))
- #expect(result.bolusiob.isWithin(0.001, of: 1.769))
- #expect(result.basaliob == 0)
- }
- @Test("should calculate total IOB with basal insulin") func calculateTotalBasal() async throws {
- let now = Date()
- let thirtyMinsAgo = now - 30.minutesToSeconds
- let treatments = [createTreatment(insulin: -0.05, timestamp: thirtyMinsAgo)]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 5, curve: .rapidActing),
- time: now
- )
- #expect(result.basaliob.isWithin(0.001, of: -0.046))
- #expect(result.bolusiob == 0)
- }
- @Test("should handle multiple treatments of different types") func handleMultipleTreatments() async throws {
- let now = Date()
- let treatments = [
- createTreatment(insulin: 2.0, timestamp: now - 30.minutesToSeconds),
- createTreatment(insulin: 0.05, timestamp: now - 20.minutesToSeconds),
- createTreatment(insulin: 1.0, timestamp: now - 10.minutesToSeconds)
- ]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 5, curve: .rapidActing),
- time: now
- )
- #expect(result.basaliob.isWithin(0.001, of: 0.048))
- #expect(result.bolusinsulin == 3.0)
- #expect(result.netbasalinsulin == 0.05)
- }
- @Test("should handle custom peak times for rapid-acting insulin") func handleCustomPeakRapidActing() async throws {
- let now = Date()
- let thirtyMinsAgo = now - 30.minutesToSeconds
- let treatments = [createTreatment(insulin: 2.0, timestamp: thirtyMinsAgo)]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(
- dia: 5,
- curve: .rapidActing,
- useCustomPeakTime: true,
- insulinPeakTime: 100
- ),
- time: now
- )
- #expect(result.iob.isWithin(0.001, of: 1.898))
- }
- @Test("should handle custom peak times for ultra-rapid insulin") func handleCustomPeakUltraRapid() async throws {
- let now = Date()
- let thirtyMinsAgo = now - 30.minutesToSeconds
- let treatments = [createTreatment(insulin: 2.0, timestamp: thirtyMinsAgo)]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(
- dia: 5,
- curve: .ultraRapid,
- useCustomPeakTime: true,
- insulinPeakTime: 80
- ),
- time: now
- )
- #expect(result.iob.isWithin(0.001, of: 1.863))
- }
- @Test("should ignore future treatments") func ignoreFutureTreatments() async throws {
- let now = Date()
- let treatments = [
- createTreatment(insulin: 2.0, timestamp: now + 30.minutesToSeconds),
- createTreatment(insulin: 1.0, timestamp: now - 10.minutesToSeconds)
- ]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 5, curve: .rapidActing),
- time: now
- )
- #expect(result.bolusinsulin == 1.0)
- }
- @Test("should ignore treatments older than DIA") func ignoreOldTreatments() async throws {
- let now = Date()
- let sixHoursAgo = now - 6.hoursToSeconds
- let treatments = [createTreatment(insulin: 2.0, timestamp: sixHoursAgo)]
- let result = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 5, curve: .rapidActing),
- time: now
- )
- #expect(result.iob == 0)
- #expect(result.activity == 0)
- }
- @Test("should enforce minimum DIA of 5 hours for both insulin types") func enforceMinimumDIA() async throws {
- let now = Date()
- let fourHoursAgo = now - 4.hoursToSeconds
- let treatments = [createTreatment(insulin: 2.0, timestamp: fourHoursAgo)]
- // Test rapid-acting
- let rapidResult = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 4, curve: .rapidActing),
- time: now
- )
- #expect(rapidResult.iob > 0)
- // Test ultra-rapid
- let ultraResult = try IobCalculation.iobTotal(
- treatments: treatments,
- profile: createProfile(dia: 4, curve: .ultraRapid),
- time: now
- )
- #expect(ultraResult.iob > 0)
- }
- }
|