CachedGlucoseObjectTests.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //
  2. // CachedGlucoseObjectTests.swift
  3. // LoopKitTests
  4. //
  5. // Copyright © 2018 LoopKit Authors. All rights reserved.
  6. //
  7. import XCTest
  8. import HealthKit
  9. @testable import LoopKit
  10. class CachedGlucoseObjectTests: PersistenceControllerTestCase {
  11. func testSyncVersionGet() {
  12. cacheStore.managedObjectContext.performAndWait {
  13. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  14. object.primitiveSyncVersion = NSNumber(integerLiteral: 3)
  15. XCTAssertEqual(object.syncVersion, 3)
  16. }
  17. }
  18. func testSyncVersionGetNil() {
  19. cacheStore.managedObjectContext.performAndWait {
  20. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  21. object.primitiveSyncVersion = nil
  22. XCTAssertNil(object.syncVersion)
  23. }
  24. }
  25. func testSyncVersionSet() {
  26. cacheStore.managedObjectContext.performAndWait {
  27. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  28. object.syncVersion = 5
  29. XCTAssertEqual(object.primitiveSyncVersion, NSNumber(integerLiteral: 5))
  30. }
  31. }
  32. func testSyncVersionSetNil() {
  33. cacheStore.managedObjectContext.performAndWait {
  34. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  35. object.syncVersion = nil
  36. XCTAssertNil(object.primitiveSyncVersion)
  37. }
  38. }
  39. }
  40. class CachedGlucoseObjectModificationTests: PersistenceControllerTestCase {
  41. func testHasUpdatedModificationCounter() {
  42. cacheStore.managedObjectContext.performAndWait {
  43. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  44. object.setDefaultValues()
  45. XCTAssertTrue(object.hasUpdatedModificationCounter)
  46. try! cacheStore.managedObjectContext.save()
  47. XCTAssertFalse(object.hasUpdatedModificationCounter)
  48. }
  49. }
  50. func testUpdateModificationCounter() {
  51. cacheStore.managedObjectContext.performAndWait {
  52. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  53. object.modificationCounter = -1
  54. object.updateModificationCounter()
  55. XCTAssertNotEqual(object.modificationCounter, -1)
  56. }
  57. }
  58. func testAwakeFromInsertUpdatesModificationCounter() {
  59. func testHasUpdatedModificationCounter() {
  60. cacheStore.managedObjectContext.performAndWait {
  61. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  62. XCTAssertTrue(object.hasUpdatedModificationCounter)
  63. }
  64. }
  65. }
  66. func testWillSaveUpdatesModificationCounter() {
  67. func testHasUpdatedModificationCounter() {
  68. cacheStore.managedObjectContext.performAndWait {
  69. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  70. XCTAssertTrue(object.hasUpdatedModificationCounter)
  71. object.setDefaultValues()
  72. object.modificationCounter = -1
  73. try! cacheStore.managedObjectContext.save()
  74. XCTAssertEqual(object.modificationCounter, -1)
  75. object.uuid = UUID()
  76. try! cacheStore.managedObjectContext.save()
  77. XCTAssertNotEqual(object.modificationCounter, -1)
  78. }
  79. }
  80. }
  81. func testWillSaveDoesNotUpdateModificationCounterIfManuallyUpdated() {
  82. func testHasUpdatedModificationCounter() {
  83. cacheStore.managedObjectContext.performAndWait {
  84. let object = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  85. XCTAssertTrue(object.hasUpdatedModificationCounter)
  86. object.setDefaultValues()
  87. object.modificationCounter = -1
  88. try! cacheStore.managedObjectContext.save()
  89. XCTAssertEqual(object.modificationCounter, -1)
  90. object.uuid = UUID()
  91. object.modificationCounter = -2
  92. try! cacheStore.managedObjectContext.save()
  93. XCTAssertEqual(object.modificationCounter, -2)
  94. }
  95. }
  96. }
  97. }
  98. class CachedGlucoseObjectConstraintTests: PersistenceControllerTestCase {
  99. func testUUIDUniqueConstraint() {
  100. cacheStore.managedObjectContext.performAndWait {
  101. let uuid = UUID()
  102. let object1 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  103. object1.setDefaultValues()
  104. object1.uuid = uuid
  105. try! cacheStore.managedObjectContext.save()
  106. let object2 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  107. object2.setDefaultValues()
  108. object2.uuid = uuid
  109. try! cacheStore.managedObjectContext.save()
  110. let objects: [CachedGlucoseObject] = cacheStore.managedObjectContext.all()
  111. XCTAssertEqual(1, objects.count)
  112. }
  113. }
  114. func testSyncIdentifierUniqueConstraint() {
  115. cacheStore.managedObjectContext.performAndWait {
  116. let uuid = UUID()
  117. let object1 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  118. object1.setDefaultValues()
  119. object1.syncIdentifier = uuid.uuidString
  120. try! cacheStore.managedObjectContext.save()
  121. let object2 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  122. object2.setDefaultValues()
  123. object2.syncIdentifier = uuid.uuidString
  124. try! cacheStore.managedObjectContext.save()
  125. let objects: [CachedGlucoseObject] = cacheStore.managedObjectContext.all()
  126. XCTAssertEqual(1, objects.count)
  127. }
  128. }
  129. func testAllUniqueConstraints() {
  130. cacheStore.managedObjectContext.performAndWait {
  131. let uuid = UUID()
  132. let object1 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  133. object1.setDefaultValues()
  134. object1.uuid = uuid
  135. object1.syncIdentifier = uuid.uuidString
  136. try! cacheStore.managedObjectContext.save()
  137. let object2 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  138. object2.setDefaultValues()
  139. object2.uuid = uuid
  140. object2.syncIdentifier = uuid.uuidString
  141. try! cacheStore.managedObjectContext.save()
  142. let objects: [CachedGlucoseObject] = cacheStore.managedObjectContext.all()
  143. XCTAssertEqual(1, objects.count)
  144. }
  145. }
  146. func testSaveWithDefaultValues() {
  147. cacheStore.managedObjectContext.performAndWait {
  148. let object1 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  149. object1.setDefaultValues()
  150. try! cacheStore.managedObjectContext.save()
  151. let object2 = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  152. object2.setDefaultValues()
  153. try! cacheStore.managedObjectContext.save()
  154. let objects: [CachedGlucoseObject] = cacheStore.managedObjectContext.all()
  155. XCTAssertEqual(2, objects.count)
  156. }
  157. }
  158. }
  159. class CachedGlucoseObjectQuantityTests: PersistenceControllerTestCase {
  160. func testQuantity() throws {
  161. cacheStore.managedObjectContext.performAndWait {
  162. let cachedGlucoseObject = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  163. cachedGlucoseObject.value = 123.45
  164. cachedGlucoseObject.unitString = HKUnit.milligramsPerDeciliter.unitString
  165. XCTAssertEqual(cachedGlucoseObject.quantity, HKQuantity(unit: .milligramsPerDeciliter, doubleValue: 123.45))
  166. }
  167. }
  168. }
  169. class CachedGlucoseObjectEncodableTests: PersistenceControllerTestCase {
  170. func testEncodable() throws {
  171. cacheStore.managedObjectContext.performAndWait {
  172. let cachedGlucoseObject = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  173. cachedGlucoseObject.uuid = UUID(uuidString: "2A67A303-5203-4CB8-8263-79498265368E")!
  174. cachedGlucoseObject.provenanceIdentifier = "238E41EA-9576-4981-A1A4-51E10228584F"
  175. cachedGlucoseObject.syncIdentifier = "7723A0EE-F6D5-46E0-BBFE-1DEEBF8ED6F2"
  176. cachedGlucoseObject.syncVersion = 2
  177. cachedGlucoseObject.value = 98.7
  178. cachedGlucoseObject.unitString = HKUnit.milligramsPerDeciliter.unitString
  179. cachedGlucoseObject.startDate = dateFormatter.date(from: "2020-05-14T22:38:14Z")!
  180. cachedGlucoseObject.isDisplayOnly = false
  181. cachedGlucoseObject.wasUserEntered = true
  182. cachedGlucoseObject.modificationCounter = 123
  183. try! assertCachedGlucoseObjectEncodable(cachedGlucoseObject, encodesJSON: """
  184. {
  185. "isDisplayOnly" : false,
  186. "modificationCounter" : 123,
  187. "provenanceIdentifier" : "238E41EA-9576-4981-A1A4-51E10228584F",
  188. "startDate" : "2020-05-14T22:38:14Z",
  189. "syncIdentifier" : "7723A0EE-F6D5-46E0-BBFE-1DEEBF8ED6F2",
  190. "syncVersion" : 2,
  191. "unitString" : "mg/dL",
  192. "uuid" : "2A67A303-5203-4CB8-8263-79498265368E",
  193. "value" : 98.700000000000003,
  194. "wasUserEntered" : true
  195. }
  196. """
  197. )
  198. }
  199. }
  200. func testEncodableOptional() throws {
  201. cacheStore.managedObjectContext.performAndWait {
  202. let cachedGlucoseObject = CachedGlucoseObject(context: cacheStore.managedObjectContext)
  203. cachedGlucoseObject.provenanceIdentifier = "238E41EA-9576-4981-A1A4-51E10228584F"
  204. cachedGlucoseObject.value = 87.6
  205. cachedGlucoseObject.unitString = HKUnit.milligramsPerDeciliter.unitString
  206. cachedGlucoseObject.startDate = dateFormatter.date(from: "2020-05-14T22:38:14Z")!
  207. cachedGlucoseObject.isDisplayOnly = true
  208. cachedGlucoseObject.wasUserEntered = false
  209. cachedGlucoseObject.modificationCounter = 234
  210. try! assertCachedGlucoseObjectEncodable(cachedGlucoseObject, encodesJSON: """
  211. {
  212. "isDisplayOnly" : true,
  213. "modificationCounter" : 234,
  214. "provenanceIdentifier" : "238E41EA-9576-4981-A1A4-51E10228584F",
  215. "startDate" : "2020-05-14T22:38:14Z",
  216. "unitString" : "mg/dL",
  217. "value" : 87.599999999999994,
  218. "wasUserEntered" : false
  219. }
  220. """
  221. )
  222. }
  223. }
  224. private func assertCachedGlucoseObjectEncodable(_ original: CachedGlucoseObject, encodesJSON string: String) throws {
  225. let data = try encoder.encode(original)
  226. XCTAssertEqual(String(data: data, encoding: .utf8), string)
  227. }
  228. private let dateFormatter = ISO8601DateFormatter()
  229. private let encoder: JSONEncoder = {
  230. let encoder = JSONEncoder()
  231. encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
  232. encoder.dateEncodingStrategy = .iso8601
  233. return encoder
  234. }()
  235. }
  236. extension CachedGlucoseObject {
  237. fileprivate func setDefaultValues() {
  238. self.uuid = UUID()
  239. self.provenanceIdentifier = "CachedGlucoseObjectTests"
  240. self.syncIdentifier = UUID().uuidString
  241. self.syncVersion = 2
  242. self.value = 99.9
  243. self.unitString = HKUnit.milligramsPerDeciliter.unitString
  244. self.startDate = Date()
  245. self.isDisplayOnly = false
  246. self.wasUserEntered = false
  247. self.condition = nil
  248. self.trend = .up
  249. self.trendRate = HKQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: 1.0)
  250. }
  251. }