DetermineBasalGlucoseFallingFasterThanExpectedTests.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import Foundation
  2. import Testing
  3. @testable import Trio
  4. /// These tests should be an exact copy of the JS tests here:
  5. /// - https://github.com/kingst/trio-oref/blob/dev-fixes-for-swift-comparison/tests/determine-basal-glucose-falling-faster-than-expected.test.js
  6. @Suite("DosingEngine.glucoseFallingFasterThanExpected") struct DetermineBasalGlucoseFallingFasterThanExpectedTests {
  7. private func defaultProfile() -> Profile {
  8. var profile = Profile()
  9. profile.minBg = 90
  10. profile.targetBg = 100
  11. profile.currentBasal = 1.0
  12. profile.maxDailyBasal = 1.3
  13. profile.maxBasal = 3.5
  14. profile.sens = 50
  15. profile.outUnits = .mgdL
  16. return profile
  17. }
  18. private func defaultGlucoseStatus() -> GlucoseStatus {
  19. GlucoseStatus(
  20. delta: 5,
  21. glucose: 100,
  22. noise: 1,
  23. shortAvgDelta: 0,
  24. longAvgDelta: 0,
  25. date: Date(),
  26. lastCalIndex: nil,
  27. device: "test"
  28. )
  29. }
  30. private func callGlucoseFallingFasterThanExpected(
  31. eventualGlucose: Decimal = 100,
  32. minGlucose: Decimal? = nil,
  33. minDelta: Decimal = 4,
  34. expectedDelta: Decimal = 5,
  35. glucoseStatus: GlucoseStatus? = nil,
  36. currentTemp: TempBasal = TempBasal(duration: 0, rate: 0, temp: .absolute, timestamp: Date()),
  37. basal: Decimal? = nil,
  38. smbIsEnabled: Bool = false,
  39. profile: Profile? = nil,
  40. determination: Determination? = nil
  41. ) throws -> (shouldSetTempBasal: Bool, determination: Determination) {
  42. let testProfile = profile ?? defaultProfile()
  43. let testDetermination = determination ?? Determination(
  44. id: nil,
  45. reason: "",
  46. units: nil,
  47. insulinReq: nil,
  48. eventualBG: nil,
  49. sensitivityRatio: nil,
  50. rate: nil,
  51. duration: nil,
  52. iob: nil,
  53. cob: nil,
  54. predictions: nil,
  55. deliverAt: nil,
  56. carbsReq: nil,
  57. temp: nil,
  58. bg: nil,
  59. reservoir: nil,
  60. isf: nil,
  61. timestamp: nil,
  62. tdd: nil,
  63. current_target: nil,
  64. minDelta: nil,
  65. expectedDelta: nil,
  66. minGuardBG: nil,
  67. minPredBG: nil,
  68. threshold: nil,
  69. carbRatio: nil,
  70. received: nil
  71. )
  72. return try DosingEngine.glucoseFallingFasterThanExpected(
  73. eventualGlucose: eventualGlucose,
  74. minGlucose: minGlucose ?? testProfile.minBg!,
  75. minDelta: minDelta,
  76. expectedDelta: expectedDelta,
  77. glucoseStatus: glucoseStatus ?? defaultGlucoseStatus(),
  78. currentTemp: currentTemp,
  79. basal: basal ?? testProfile.currentBasal!,
  80. smbIsEnabled: smbIsEnabled,
  81. profile: testProfile,
  82. determination: testDetermination
  83. )
  84. }
  85. @Test("Guard: minDelta not less than expectedDelta") func testMinDeltaNotLessThanExpected() throws {
  86. let (shouldSet, determination) = try callGlucoseFallingFasterThanExpected(minDelta: 5, expectedDelta: 5)
  87. #expect(shouldSet == false)
  88. #expect(determination.reason == "")
  89. }
  90. @Test("Guard: SMB is enabled") func testSmbIsEnabled() throws {
  91. let (shouldSet, determination) = try callGlucoseFallingFasterThanExpected(smbIsEnabled: true)
  92. #expect(shouldSet == false)
  93. #expect(determination.reason == "")
  94. }
  95. @Test("Continue current temp") func testContinueCurrentTemp() throws {
  96. let profile = defaultProfile()
  97. let currentTemp = TempBasal(duration: 20, rate: profile.currentBasal!, temp: .absolute, timestamp: Date())
  98. let (shouldSet, determination) = try callGlucoseFallingFasterThanExpected(
  99. currentTemp: currentTemp,
  100. basal: profile.currentBasal!,
  101. profile: profile
  102. )
  103. #expect(shouldSet == true)
  104. #expect(determination.rate == nil) // No change
  105. #expect(determination.reason.contains("temp \(currentTemp.rate) ~ req \(profile.currentBasal!)U/hr."))
  106. }
  107. @Test("Set new temp") func testSetNewTemp() throws {
  108. let profile = defaultProfile()
  109. let currentTemp = TempBasal(duration: 10, rate: 1.0, temp: .absolute, timestamp: Date())
  110. let basal: Decimal = 1.2
  111. let (shouldSet, determination) = try callGlucoseFallingFasterThanExpected(
  112. currentTemp: currentTemp,
  113. basal: basal,
  114. profile: profile
  115. )
  116. #expect(shouldSet == true)
  117. #expect(determination.rate == basal)
  118. #expect(determination.duration == 30)
  119. #expect(determination.reason.contains("setting current basal of \(basal) as temp."))
  120. }
  121. }