BasalRateScheduleTests.swift 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //
  2. // BasalRateScheduleTests.swift
  3. // Naterade
  4. //
  5. // Created by Nathan Racklyeft on 2/5/16.
  6. // Copyright © 2016 Nathan Racklyeft. All rights reserved.
  7. //
  8. import XCTest
  9. @testable import LoopKit
  10. func ==<T: Equatable>(lhs: RepeatingScheduleValue<T>, rhs: RepeatingScheduleValue<T>) -> Bool {
  11. return lhs.startTime == rhs.startTime && lhs.value == rhs.value
  12. }
  13. func ==<T: Equatable>(lhs: AbsoluteScheduleValue<T>, rhs: AbsoluteScheduleValue<T>) -> Bool {
  14. return lhs.startDate == rhs.startDate && lhs.endDate == rhs.endDate && lhs.value == rhs.value
  15. }
  16. func ==<T: Equatable>(lhs: ArraySlice<AbsoluteScheduleValue<T>>, rhs: ArraySlice<AbsoluteScheduleValue<T>>) -> Bool {
  17. guard lhs.count == rhs.count else {
  18. return false
  19. }
  20. for (l, r) in zip(lhs, rhs) {
  21. if !(l == r) {
  22. return false
  23. }
  24. }
  25. return true
  26. }
  27. class BasalRateScheduleTests: XCTestCase {
  28. var items: [RepeatingScheduleValue<Double>]!
  29. override func setUp() {
  30. super.setUp()
  31. let path = Bundle(for: type(of: self)).path(forResource: "basal", ofType: "json")!
  32. let fixture = try! JSONSerialization.jsonObject(with: Data(contentsOf: URL(fileURLWithPath: path)), options: []) as! [JSONDictionary]
  33. items = fixture.map {
  34. return RepeatingScheduleValue(startTime: TimeInterval(minutes: $0["minutes"] as! Double), value: $0["rate"] as! Double)
  35. }
  36. }
  37. func testBasalScheduleRanges() {
  38. let therapyTimeZone = TimeZone(secondsFromGMT: -6*60*60)!
  39. let schedule = BasalRateSchedule(dailyItems: items, timeZone: therapyTimeZone)!
  40. var calendar = Calendar(identifier: .gregorian)
  41. calendar.timeZone = therapyTimeZone
  42. let midnight = calendar.startOfDay(for: Date())
  43. var absoluteItems: [AbsoluteScheduleValue<Double>] = (0..<items.count).map {
  44. let endTime = ($0 + 1) < items.count ? items[$0 + 1].startTime : .hours(24)
  45. return AbsoluteScheduleValue(
  46. startDate: midnight.addingTimeInterval(items[$0].startTime),
  47. endDate: midnight.addingTimeInterval(endTime),
  48. value: items[$0].value
  49. )
  50. }
  51. absoluteItems += (0..<items.count).map {
  52. let endTime = ($0 + 1) < items.count ? items[$0 + 1].startTime : .hours(24)
  53. return AbsoluteScheduleValue(
  54. startDate: midnight.addingTimeInterval(items[$0].startTime + .hours(24)),
  55. endDate: midnight.addingTimeInterval(endTime + .hours(24)),
  56. value: items[$0].value
  57. )
  58. }
  59. XCTAssert(
  60. absoluteItems[0..<items.count] ==
  61. schedule.between(
  62. start: midnight,
  63. end: midnight.addingTimeInterval(TimeInterval(hours: 24))
  64. )[0..<items.count]
  65. )
  66. let twentyThree30 = midnight.addingTimeInterval(TimeInterval(hours: 23)).addingTimeInterval(TimeInterval(minutes: 30))
  67. XCTAssert(
  68. absoluteItems[0..<items.count] ==
  69. schedule.between(
  70. start: midnight,
  71. end: twentyThree30
  72. )[0..<items.count]
  73. )
  74. XCTAssert(
  75. absoluteItems[0..<items.count + 1] ==
  76. schedule.between(
  77. start: midnight,
  78. end: midnight.addingTimeInterval(TimeInterval(hours: 24) + TimeInterval(1))
  79. )[0..<items.count + 1]
  80. )
  81. XCTAssert(
  82. absoluteItems[items.count - 1..<items.count * 2] ==
  83. schedule.between(
  84. start: twentyThree30,
  85. end: twentyThree30.addingTimeInterval(TimeInterval(hours: 24))
  86. )[0..<items.count + 1]
  87. )
  88. XCTAssert(
  89. absoluteItems[0..<1] ==
  90. schedule.between(
  91. start: midnight,
  92. end: midnight.addingTimeInterval(TimeInterval(hours: 1))
  93. )[0..<1]
  94. )
  95. XCTAssert(
  96. absoluteItems[1..<3] ==
  97. schedule.between(
  98. start: midnight.addingTimeInterval(TimeInterval(hours: 4)),
  99. end: midnight.addingTimeInterval(TimeInterval(hours: 9))
  100. )[0..<2]
  101. )
  102. XCTAssert(
  103. absoluteItems[5..<6] ==
  104. schedule.between(
  105. start: midnight.addingTimeInterval(TimeInterval(hours: 16)),
  106. end: midnight.addingTimeInterval(TimeInterval(hours: 20))
  107. )[0..<1]
  108. )
  109. XCTAssert(
  110. schedule.between(
  111. start: midnight.addingTimeInterval(TimeInterval(hours: 4)),
  112. end: midnight.addingTimeInterval(TimeInterval(hours: 3))
  113. ).isEmpty
  114. )
  115. }
  116. func testTotalDelivery() {
  117. let schedule = BasalRateSchedule(dailyItems: items, timeZone: nil)!
  118. XCTAssertEqual(20.275, schedule.total(), accuracy: 1e-14)
  119. }
  120. func testRawValueSerialization() {
  121. let schedule = BasalRateSchedule(dailyItems: items, timeZone: nil)!
  122. let reSchedule = BasalRateSchedule(rawValue: schedule.rawValue)!
  123. let calendar = Calendar.current
  124. let midnight = calendar.startOfDay(for: Date())
  125. XCTAssertEqual(reSchedule.timeZone.secondsFromGMT(), schedule.timeZone.secondsFromGMT())
  126. XCTAssertEqual(reSchedule.value(at: midnight), schedule.value(at: midnight))
  127. let threethirty = midnight.addingTimeInterval(TimeInterval(hours: 3.5))
  128. XCTAssertEqual(reSchedule.value(at: threethirty), schedule.value(at: threethirty))
  129. let fourthirty = midnight.addingTimeInterval(TimeInterval(hours: 4.5))
  130. XCTAssertEqual(reSchedule.value(at: fourthirty), schedule.value(at: fourthirty))
  131. }
  132. }