BasalRateScheduleTests.swift 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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 schedule = BasalRateSchedule(dailyItems: items, timeZone: nil)!
  39. let calendar = Calendar.current
  40. let midnight = calendar.startOfDay(for: Date())
  41. var absoluteItems: [AbsoluteScheduleValue<Double>] = (0..<items.count).map {
  42. let endTime = ($0 + 1) < items.count ? items[$0 + 1].startTime : .hours(24)
  43. return AbsoluteScheduleValue(
  44. startDate: midnight.addingTimeInterval(items[$0].startTime),
  45. endDate: midnight.addingTimeInterval(endTime),
  46. value: items[$0].value
  47. )
  48. }
  49. absoluteItems += (0..<items.count).map {
  50. let endTime = ($0 + 1) < items.count ? items[$0 + 1].startTime : .hours(24)
  51. return AbsoluteScheduleValue(
  52. startDate: midnight.addingTimeInterval(items[$0].startTime + .hours(24)),
  53. endDate: midnight.addingTimeInterval(endTime + .hours(24)),
  54. value: items[$0].value
  55. )
  56. }
  57. XCTAssert(
  58. absoluteItems[0..<items.count] ==
  59. schedule.between(
  60. start: midnight,
  61. end: midnight.addingTimeInterval(TimeInterval(hours: 24))
  62. )[0..<items.count]
  63. )
  64. let twentyThree30 = midnight.addingTimeInterval(TimeInterval(hours: 23)).addingTimeInterval(TimeInterval(minutes: 30))
  65. XCTAssert(
  66. absoluteItems[0..<items.count] ==
  67. schedule.between(
  68. start: midnight,
  69. end: twentyThree30
  70. )[0..<items.count]
  71. )
  72. XCTAssert(
  73. absoluteItems[0..<items.count + 1] ==
  74. schedule.between(
  75. start: midnight,
  76. end: midnight.addingTimeInterval(TimeInterval(hours: 24) + TimeInterval(1))
  77. )[0..<items.count + 1]
  78. )
  79. XCTAssert(
  80. absoluteItems[items.count - 1..<items.count * 2] ==
  81. schedule.between(
  82. start: twentyThree30,
  83. end: twentyThree30.addingTimeInterval(TimeInterval(hours: 24))
  84. )[0..<items.count + 1]
  85. )
  86. XCTAssert(
  87. absoluteItems[0..<1] ==
  88. schedule.between(
  89. start: midnight,
  90. end: midnight.addingTimeInterval(TimeInterval(hours: 1))
  91. )[0..<1]
  92. )
  93. XCTAssert(
  94. absoluteItems[1..<3] ==
  95. schedule.between(
  96. start: midnight.addingTimeInterval(TimeInterval(hours: 4)),
  97. end: midnight.addingTimeInterval(TimeInterval(hours: 9))
  98. )[0..<2]
  99. )
  100. XCTAssert(
  101. absoluteItems[5..<6] ==
  102. schedule.between(
  103. start: midnight.addingTimeInterval(TimeInterval(hours: 16)),
  104. end: midnight.addingTimeInterval(TimeInterval(hours: 20))
  105. )[0..<1]
  106. )
  107. XCTAssert(
  108. schedule.between(
  109. start: midnight.addingTimeInterval(TimeInterval(hours: 4)),
  110. end: midnight.addingTimeInterval(TimeInterval(hours: 3))
  111. ).isEmpty
  112. )
  113. }
  114. func testTotalDelivery() {
  115. let schedule = BasalRateSchedule(dailyItems: items, timeZone: nil)!
  116. XCTAssertEqual(20.275, schedule.total(), accuracy: 1e-14)
  117. }
  118. func testRawValueSerialization() {
  119. let schedule = BasalRateSchedule(dailyItems: items, timeZone: nil)!
  120. let reSchedule = BasalRateSchedule(rawValue: schedule.rawValue)!
  121. let calendar = Calendar.current
  122. let midnight = calendar.startOfDay(for: Date())
  123. XCTAssertEqual(reSchedule.timeZone.secondsFromGMT(), schedule.timeZone.secondsFromGMT())
  124. XCTAssertEqual(reSchedule.value(at: midnight), schedule.value(at: midnight))
  125. let threethirty = midnight.addingTimeInterval(TimeInterval(hours: 3.5))
  126. XCTAssertEqual(reSchedule.value(at: threethirty), schedule.value(at: threethirty))
  127. let fourthirty = midnight.addingTimeInterval(TimeInterval(hours: 4.5))
  128. XCTAssertEqual(reSchedule.value(at: fourthirty), schedule.value(at: fourthirty))
  129. }
  130. }