OpenAPSFixed.swift 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import Combine
  2. import Foundation
  3. import JavaScriptCore
  4. @testable import Trio
  5. /// This class provides us with an implementation of trio-oref with a number of iob bugs that are fixed.
  6. /// We can use this during testing to confirm that for an input that generated an error that a corrected
  7. /// Javascript implementation would have produced the same results
  8. final class OpenAPSFixed {
  9. private let jsWorker = JavaScriptWorker()
  10. func sortPumpHistory(pumpHistory: JSON) throws -> JSON {
  11. let pumpHistorySwift = try JSONBridge.pumpHistory(from: pumpHistory)
  12. return try JSONBridge.to(pumpHistorySwift.sorted(by: { $0.timestamp > $1.timestamp }))
  13. }
  14. func iobHistory(pumphistory: JSON, profile: JSON, clock: JSON, autosens: JSON, zeroTempDuration: JSON) async throws -> JSON {
  15. let testBundle = Bundle(for: OpenAPSFixed.self)
  16. let pumphistory: JSON = try! sortPumpHistory(pumpHistory: pumphistory)
  17. let result = try await withCheckedThrowingContinuation { continuation in
  18. jsWorker.inCommonContext { worker in
  19. worker.evaluateBatch(scripts: [
  20. Script(name: "prepare/log.js"),
  21. Script.fromTestingBundle(name: "iob-history.js", bundle: testBundle),
  22. Script.fromTestingBundle(name: "iob-history-prepare.js", bundle: testBundle)
  23. ])
  24. let result = worker.call(function: "generate", with: [
  25. pumphistory,
  26. profile,
  27. clock,
  28. autosens,
  29. zeroTempDuration
  30. ])
  31. continuation.resume(returning: result)
  32. }
  33. }
  34. return result
  35. }
  36. func mealJavascript(
  37. pumphistory: JSON,
  38. profile: JSON,
  39. basalProfile: JSON,
  40. clock: JSON,
  41. carbs: JSON,
  42. glucose: JSON
  43. ) async -> OrefFunctionResult {
  44. let testBundle = Bundle(for: OpenAPSFixed.self)
  45. do {
  46. let result = try await withCheckedThrowingContinuation { continuation in
  47. jsWorker.inCommonContext { worker in
  48. worker.evaluateBatch(scripts: [
  49. Script(name: "prepare/log.js"),
  50. Script.fromTestingBundle(name: "meal.js", bundle: testBundle),
  51. Script(name: "prepare/meal.js")
  52. ])
  53. let result = worker.call(function: "generate", with: [
  54. pumphistory,
  55. profile,
  56. clock,
  57. glucose,
  58. basalProfile,
  59. carbs
  60. ])
  61. continuation.resume(returning: result)
  62. }
  63. }
  64. return .success(result)
  65. } catch {
  66. return .failure(error)
  67. }
  68. }
  69. func iobJavascript(pumphistory: JSON, profile: JSON, clock: JSON, autosens: JSON) async -> OrefFunctionResult {
  70. do {
  71. let testBundle = Bundle(for: OpenAPSFixed.self)
  72. let pumphistory: JSON = try! sortPumpHistory(pumpHistory: pumphistory)
  73. let result = try await withCheckedThrowingContinuation { continuation in
  74. jsWorker.inCommonContext { worker in
  75. worker.evaluateBatch(scripts: [
  76. Script(name: "prepare/log.js"),
  77. Script.fromTestingBundle(name: "iob.js", bundle: testBundle),
  78. Script(name: "prepare/iob.js")
  79. ])
  80. let result = worker.call(function: "generate", with: [
  81. pumphistory,
  82. profile,
  83. clock,
  84. autosens
  85. ])
  86. continuation.resume(returning: result)
  87. }
  88. }
  89. return .success(result)
  90. } catch {
  91. return .failure(error)
  92. }
  93. }
  94. }
  95. extension Script {
  96. static func fromTestingBundle(name: String, bundle: Bundle) -> Script {
  97. let body: String
  98. if let url = bundle.url(forResource: "\(name)", withExtension: "") {
  99. do {
  100. body = try String(contentsOf: url)
  101. } catch {
  102. print("Error loading script: \(error.localizedDescription)")
  103. body = "Error loading script"
  104. }
  105. } else {
  106. print("Resource not found: javascript/\(name)")
  107. body = "Resource not found"
  108. }
  109. return Script(name: name, body: body)
  110. }
  111. }