BasalRateScheduleTests.swift 6.0 KB

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