DetermineBasalSmbMicroBolusTests.swift 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import Foundation
  2. import Testing
  3. @testable import Trio
  4. @Suite("determineBasal SMB microbolus behavior") struct DetermineBasalSmbMicroBolusTests {
  5. private func buildInputs(lastBolusOffsetMinutes: Decimal) -> (
  6. profile: Profile,
  7. preferences: Preferences,
  8. currentTemp: TempBasal,
  9. iobData: [IobResult],
  10. mealData: ComputedCarbs,
  11. autosensData: Autosens,
  12. reservoirData: Decimal,
  13. glucoseStatus: GlucoseStatus,
  14. trioCustomOrefVariables: TrioCustomOrefVariables,
  15. microBolusAllowed: Bool,
  16. currentTime: Date
  17. ) {
  18. let now = Date()
  19. var profile = Profile()
  20. profile.currentBasal = 1.0
  21. profile.maxDailyBasal = 1.5
  22. profile.maxBasal = 3.0
  23. profile.minBg = 90
  24. profile.maxBg = 160
  25. profile.targetBg = 100
  26. profile.sens = 40
  27. profile.carbRatio = 10
  28. profile.thresholdSetting = 70
  29. profile.maxIob = 6
  30. profile.enableSMBAlways = true
  31. profile.bolusIncrement = 0.1
  32. profile.enableSMBHighBg = true
  33. profile.enableSMBHighBgTarget = 140
  34. var preferences = Preferences()
  35. preferences.curve = .rapidActing
  36. preferences.useCustomPeakTime = false
  37. let currentTemp = TempBasal(duration: 0, rate: 0, temp: .absolute, timestamp: now)
  38. let lastBolusTime = UInt64(
  39. now
  40. .addingTimeInterval(TimeInterval(-60 * NSDecimalNumber(decimal: lastBolusOffsetMinutes).doubleValue))
  41. .timeIntervalSince1970 * 1000
  42. )
  43. let iobData = [IobResult(
  44. iob: 0.2,
  45. activity: 0,
  46. basaliob: 0.2,
  47. bolusiob: 0,
  48. netbasalinsulin: 0,
  49. bolusinsulin: 0,
  50. time: now,
  51. iobWithZeroTemp: IobResult.IobWithZeroTemp(
  52. iob: 0.2,
  53. activity: 0,
  54. basaliob: 0.2,
  55. bolusiob: 0,
  56. netbasalinsulin: 0,
  57. bolusinsulin: 0,
  58. time: now
  59. ),
  60. lastBolusTime: lastBolusTime,
  61. lastTemp: IobResult.LastTemp(
  62. rate: 0,
  63. timestamp: now,
  64. started_at: now,
  65. date: UInt64(now.timeIntervalSince1970 * 1000),
  66. duration: 30
  67. )
  68. )]
  69. let mealData = ComputedCarbs(
  70. carbs: 0,
  71. mealCOB: 0,
  72. currentDeviation: 0,
  73. maxDeviation: 0,
  74. minDeviation: 0,
  75. slopeFromMaxDeviation: 0,
  76. slopeFromMinDeviation: 0,
  77. allDeviations: [0, 0, 0, 0, 0],
  78. lastCarbTime: 0
  79. )
  80. let autosensData = Autosens(ratio: 1.0, newisf: nil)
  81. let glucoseStatus = GlucoseStatus(
  82. delta: 5,
  83. glucose: 190,
  84. noise: 1,
  85. shortAvgDelta: 5,
  86. longAvgDelta: 5,
  87. date: now,
  88. lastCalIndex: nil,
  89. device: "test"
  90. )
  91. let trioCustomOrefVariables = TrioCustomOrefVariables(
  92. average_total_data: 0,
  93. weightedAverage: 0,
  94. currentTDD: 0,
  95. past2hoursAverage: 0,
  96. date: now,
  97. overridePercentage: 100,
  98. useOverride: false,
  99. duration: 0,
  100. unlimited: false,
  101. overrideTarget: 0,
  102. smbIsOff: false,
  103. advancedSettings: false,
  104. isfAndCr: false,
  105. isf: false,
  106. cr: false,
  107. smbIsScheduledOff: false,
  108. start: 0,
  109. end: 0,
  110. smbMinutes: 30,
  111. uamMinutes: 30
  112. )
  113. return (
  114. profile: profile,
  115. preferences: preferences,
  116. currentTemp: currentTemp,
  117. iobData: iobData,
  118. mealData: mealData,
  119. autosensData: autosensData,
  120. reservoirData: 0,
  121. glucoseStatus: glucoseStatus,
  122. trioCustomOrefVariables: trioCustomOrefVariables,
  123. microBolusAllowed: true,
  124. currentTime: now
  125. )
  126. }
  127. @Test("Applies SMB microbolus when interval has elapsed") func testMicrobolusWhenIntervalElapsed() throws {
  128. let inputs = buildInputs(lastBolusOffsetMinutes: 10)
  129. let determination = try DeterminationGenerator.determineBasal(
  130. profile: inputs.profile,
  131. preferences: inputs.preferences,
  132. currentTemp: inputs.currentTemp,
  133. iobData: inputs.iobData,
  134. mealData: inputs.mealData,
  135. autosensData: inputs.autosensData,
  136. reservoirData: inputs.reservoirData,
  137. glucoseStatus: inputs.glucoseStatus,
  138. microBolusAllowed: inputs.microBolusAllowed,
  139. trioCustomOrefVariables: inputs.trioCustomOrefVariables,
  140. currentTime: inputs.currentTime
  141. )
  142. #expect(determination?.units ?? 0 > 0)
  143. #expect(determination?.reason.contains("Microbolusing") ?? false)
  144. }
  145. @Test("Waits for SMB interval before another microbolus") func testWaitsForInterval() throws {
  146. let inputs = buildInputs(lastBolusOffsetMinutes: 1)
  147. let determination = try DeterminationGenerator.determineBasal(
  148. profile: inputs.profile,
  149. preferences: inputs.preferences,
  150. currentTemp: inputs.currentTemp,
  151. iobData: inputs.iobData,
  152. mealData: inputs.mealData,
  153. autosensData: inputs.autosensData,
  154. reservoirData: inputs.reservoirData,
  155. glucoseStatus: inputs.glucoseStatus,
  156. microBolusAllowed: inputs.microBolusAllowed,
  157. trioCustomOrefVariables: inputs.trioCustomOrefVariables,
  158. currentTime: inputs.currentTime
  159. )
  160. #expect(determination?.units == nil || determination?.units == 0)
  161. #expect(determination?.reason.contains("Waiting") ?? false)
  162. }
  163. }