MockService.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. //
  2. // MockService.swift
  3. // MockKit
  4. //
  5. // Created by Darin Krauss on 5/17/19.
  6. // Copyright © 2019 LoopKit Authors. All rights reserved.
  7. //
  8. import os.log
  9. import LoopKit
  10. public final class MockService: Service {
  11. public static let serviceIdentifier = "MockService"
  12. public static let localizedTitle = "Simulator"
  13. public weak var serviceDelegate: ServiceDelegate?
  14. public var remoteData: Bool
  15. public var logging: Bool
  16. public var analytics: Bool
  17. public let maxHistoryItems = 1000
  18. private var lockedHistory = Locked<[String]>([])
  19. public var history: [String] {
  20. lockedHistory.value
  21. }
  22. private var dateFormatter = ISO8601DateFormatter()
  23. public init() {
  24. self.remoteData = true
  25. self.logging = true
  26. self.analytics = true
  27. }
  28. public init?(rawState: RawStateValue) {
  29. self.remoteData = rawState["remoteData"] as? Bool ?? false
  30. self.logging = rawState["logging"] as? Bool ?? false
  31. self.analytics = rawState["analytics"] as? Bool ?? false
  32. }
  33. public var rawState: RawStateValue {
  34. return [
  35. "remoteData": remoteData,
  36. "logging": logging,
  37. "analytics": analytics
  38. ]
  39. }
  40. public func completeCreate() {}
  41. public func completeUpdate() {
  42. serviceDelegate?.serviceDidUpdateState(self)
  43. }
  44. public func completeDelete() {}
  45. public func clearHistory() {
  46. lockedHistory.value = []
  47. }
  48. private func record(_ message: String) {
  49. let timestamp = self.dateFormatter.string(from: Date())
  50. lockedHistory.mutate { history in
  51. history.append("\(timestamp): \(message)")
  52. if history.count > self.maxHistoryItems {
  53. history.removeFirst(history.count - self.maxHistoryItems)
  54. }
  55. }
  56. }
  57. }
  58. extension MockService: AnalyticsService {
  59. public func recordAnalyticsEvent(_ name: String, withProperties properties: [AnyHashable: Any]?, outOfSession: Bool) {
  60. if analytics {
  61. record("[AnalyticsService] \(name) \(String(describing: properties)) \(outOfSession)")
  62. }
  63. }
  64. }
  65. extension MockService: LoggingService {
  66. public func log(_ message: StaticString, subsystem: String, category: String, type: OSLogType, _ args: [CVarArg]) {
  67. if logging {
  68. // Since this is only stored in memory, do not worry about public/private qualifiers
  69. let messageWithoutQualifiers = message.description.replacingOccurrences(of: "%{public}", with: "%").replacingOccurrences(of: "%{private}", with: "%")
  70. let messageWithArguments = String(format: messageWithoutQualifiers, arguments: args)
  71. record("[LoggingService] \(messageWithArguments)")
  72. }
  73. }
  74. }
  75. extension MockService: RemoteDataService {
  76. public func uploadCarbData(created: [SyncCarbObject], updated: [SyncCarbObject], deleted: [SyncCarbObject], completion: @escaping (Result<Bool, Error>) -> Void) {
  77. if remoteData {
  78. record("[RemoteDataService] Upload carb data (created: \(created.count), updated: \(updated.count), deleted: \(deleted.count))")
  79. }
  80. completion(.success(false))
  81. }
  82. public func uploadDoseData(_ stored: [DoseEntry], completion: @escaping (Result<Bool, Error>) -> Void) {
  83. if remoteData {
  84. record("[RemoteDataService] Upload dose data (stored: \(stored.count))")
  85. }
  86. completion(.success(false))
  87. }
  88. public func uploadDosingDecisionData(_ stored: [StoredDosingDecision], completion: @escaping (Result<Bool, Error>) -> Void) {
  89. if remoteData {
  90. let errored = stored.filter { $0.errors?.isEmpty == false }
  91. record("[RemoteDataService] Upload dosing decision data (stored: \(stored.count), errored: \(errored.count))")
  92. }
  93. completion(.success(false))
  94. }
  95. public func uploadGlucoseData(_ stored: [StoredGlucoseSample], completion: @escaping (Result<Bool, Error>) -> Void) {
  96. if remoteData {
  97. record("[RemoteDataService] Upload glucose data (stored: \(stored.count))")
  98. }
  99. completion(.success(false))
  100. }
  101. public func uploadPumpEventData(_ stored: [PersistedPumpEvent], completion: @escaping (Result<Bool, Error>) -> Void) {
  102. if remoteData {
  103. record("[RemoteDataService] Upload pump event data (stored: \(stored.count))")
  104. }
  105. completion(.success(false))
  106. }
  107. public func uploadSettingsData(_ stored: [StoredSettings], completion: @escaping (Result<Bool, Error>) -> Void) {
  108. if remoteData {
  109. record("[RemoteDataService] Upload settings data (stored: \(stored.count))")
  110. }
  111. completion(.success(false))
  112. }
  113. }