DetermineBasalDeltaCalculationTests.swift 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import Foundation
  2. import Testing
  3. @testable import Trio
  4. @Suite("Determination: Expected Delta Calculation Tests") struct ExpectedDeltaTests {
  5. /// When delta is smaller than one 5-min block, only glucoseImpact is returned.
  6. @Test("no change when delta < 24 blocks") func deltaSmallerThanBlock() {
  7. let result = DeterminationGenerator.calculateExpectedDelta(
  8. targetGlucose: Decimal(120),
  9. eventualGlucose: Decimal(100),
  10. glucoseImpact: Decimal(2)
  11. )
  12. // delta = 20; Int(20)/24 = 0 → result = 2 + 0 = 2.0
  13. #expect(result == Decimal(2.0))
  14. }
  15. /// When delta spans exactly one block, adds 1 to glucoseImpact.
  16. @Test("one block delta") func deltaExactlyOneBlock() {
  17. let result = DeterminationGenerator.calculateExpectedDelta(
  18. targetGlucose: Decimal(124),
  19. eventualGlucose: Decimal(100),
  20. glucoseImpact: Decimal(1.5)
  21. )
  22. // delta = 24; Int(24)/24 = 1 → result = 1.5 + 1 = 2.5
  23. #expect(result == Decimal(2.5))
  24. }
  25. /// When delta spans multiple blocks, uses integer division.
  26. @Test("multi-block delta") func deltaMultipleBlocks() {
  27. let result = DeterminationGenerator.calculateExpectedDelta(
  28. targetGlucose: Decimal(140),
  29. eventualGlucose: Decimal(100),
  30. glucoseImpact: Decimal(0)
  31. )
  32. // delta = 40; Int(40)/24 = 1 → result = 0 + 1 = 1.0
  33. #expect(result == Decimal(1.0))
  34. }
  35. /// Negative delta yields negative adjustment when blocks exceed delta.
  36. @Test("negative delta") func negativeDelta() {
  37. let result = DeterminationGenerator.calculateExpectedDelta(
  38. targetGlucose: Decimal(80),
  39. eventualGlucose: Decimal(100),
  40. glucoseImpact: Decimal(0)
  41. )
  42. // delta = -20; Int(-20)/24 = 0 (trunc toward zero) → result = 0 + 0 = 0.0
  43. #expect(result == Decimal(0.0))
  44. }
  45. /// Fractional delta is truncated before block division.
  46. @Test("fractional delta truncation") func fractionalDelta() {
  47. let result = DeterminationGenerator.calculateExpectedDelta(
  48. targetGlucose: Decimal(string: "125.5")!,
  49. eventualGlucose: Decimal(100),
  50. glucoseImpact: Decimal(0)
  51. )
  52. // delta = 25.5; Int(25.5)=25; 25/24=1 → result = 1.0
  53. #expect(result == Decimal(1.0))
  54. }
  55. /// Rounding to one decimal place works when glucoseImpact has two decimals.
  56. @Test("rounding one decimal place") func roundingOneDecimal() {
  57. let result = DeterminationGenerator.calculateExpectedDelta(
  58. targetGlucose: Decimal(124),
  59. eventualGlucose: Decimal(100),
  60. glucoseImpact: Decimal(string: "1.27")!
  61. )
  62. // delta=24 → blocks=1; adjustment=1; 1.27+1=2.27 → rounded to 2.3
  63. #expect(result == Decimal(string: "2.3")!)
  64. }
  65. /// Extreme high eventual glucose produces a large negative expected delta.
  66. @Test("extreme high eventual glucose") func extremeHighEventual() {
  67. let result = DeterminationGenerator.calculateExpectedDelta(
  68. targetGlucose: Decimal(120),
  69. eventualGlucose: Decimal(350),
  70. glucoseImpact: Decimal(0)
  71. )
  72. // delta = 120 - 350 = -230; Int(-230)/24 = -9 → result = 0 + (-9) = -9.0
  73. #expect(result == Decimal(string: "-9.0")!)
  74. }
  75. /// Extreme low eventual glucose produces a positive expected delta.
  76. @Test("extreme low eventual glucose") func extremeLowEventual() {
  77. let result = DeterminationGenerator.calculateExpectedDelta(
  78. targetGlucose: Decimal(120),
  79. eventualGlucose: Decimal(39),
  80. glucoseImpact: Decimal(0)
  81. )
  82. // delta = 81; Int(81)/24 = 3 → result = 0 + 3 = 3.0
  83. #expect(result == Decimal(string: "3.0")!)
  84. }
  85. /// Invalid low‐unit input (<39 mg/dL) falls back to only using glucoseImpact.
  86. @Test("invalid low input treated as only impact") func invalidLowInput() {
  87. let result = DeterminationGenerator.calculateExpectedDelta(
  88. targetGlucose: Decimal(5), // e.g. mmol/L mistakenly passed
  89. eventualGlucose: Decimal(3),
  90. glucoseImpact: Decimal(string: "1.7")!
  91. )
  92. // delta = 2; Int(2)/24 = 0 → result = 1.7 + 0 = 1.7
  93. #expect(result == Decimal(string: "1.7")!)
  94. }
  95. }