فهرست منبع

Fix timezone handling for meal replay

Sam King 11 ماه پیش
والد
کامیت
5bd058c572

+ 0 - 4
Trio.xcodeproj/project.pbxproj

@@ -318,7 +318,6 @@
 		3BEA3AE32D58F79700A67A1D /* JSONCompare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEA3ADC2D58F79700A67A1D /* JSONCompare.swift */; };
 		3BEF6AB12D9731660076089D /* MealHistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEF6AB02D9731530076089D /* MealHistoryTests.swift */; };
 		3BEF6AB32D97316F0076089D /* MealTotalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEF6AB22D97316A0076089D /* MealTotalTests.swift */; };
-		3BEF6AB52D9750330076089D /* meal-input-sim.json in Resources */ = {isa = PBXBuildFile; fileRef = 3BEF6AB42D9750330076089D /* meal-input-sim.json */; };
 		3BEF6AB72D9750780076089D /* MealJsonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEF6AB62D9750710076089D /* MealJsonTests.swift */; };
 		3BF424C72DF4805A0017CFD9 /* AutosensError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF424C62DF480550017CFD9 /* AutosensError.swift */; };
 		3BF8D0C12D5175BE001B3F84 /* ProfileJsNativeCompareTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF8D0C02D5175B3001B3F84 /* ProfileJsNativeCompareTests.swift */; };
@@ -1213,7 +1212,6 @@
 		3BEA3ADE2D58F79700A67A1D /* OrefFunction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrefFunction.swift; sourceTree = "<group>"; };
 		3BEF6AB02D9731530076089D /* MealHistoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealHistoryTests.swift; sourceTree = "<group>"; };
 		3BEF6AB22D97316A0076089D /* MealTotalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealTotalTests.swift; sourceTree = "<group>"; };
-		3BEF6AB42D9750330076089D /* meal-input-sim.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "meal-input-sim.json"; sourceTree = "<group>"; };
 		3BEF6AB62D9750710076089D /* MealJsonTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealJsonTests.swift; sourceTree = "<group>"; };
 		3BF424C62DF480550017CFD9 /* AutosensError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutosensError.swift; sourceTree = "<group>"; };
 		3BF768BD6264FF7D71D66767 /* NightscoutConfigProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NightscoutConfigProvider.swift; sourceTree = "<group>"; };
@@ -2776,7 +2774,6 @@
 			children = (
 				3B8B5D2C2DF5234C00365ED3 /* autosens */,
 				3BF92F392D86F1AA006B545A /* iob-error-log.json */,
-				3BEF6AB42D9750330076089D /* meal-input-sim.json */,
 			);
 			path = json;
 			sourceTree = "<group>";
@@ -4331,7 +4328,6 @@
 				3BF92F312D86DEE9006B545A /* meal.js in Resources */,
 				3BF92F322D86DEE9006B545A /* glucose-get-last.js in Resources */,
 				3BF92F332D86DEE9006B545A /* iob.js in Resources */,
-				3BEF6AB52D9750330076089D /* meal-input-sim.json in Resources */,
 				3BF92F352D86DEE9006B545A /* basal-set-temp.js in Resources */,
 				3BF92F362D86DEE9006B545A /* autotune-core.js in Resources */,
 				3BC0AA3B2DA74C87000DF7B7 /* iob-total.js in Resources */,

+ 25 - 46
TrioTests/OpenAPSSwiftTests/MealJsonTests.swift

@@ -5,58 +5,24 @@ import Testing
 @Suite("Meal testing using JSON inputs", .serialized) struct MealJsonTests {
     let timeZoneForTests = TimeZoneForTests()
 
-    @Test("Test against simulator inputs") func simulatorInputs() throws {
-        let testBundle = Bundle(for: BundleReference.self)
-        let path = testBundle.path(forResource: "meal-input-sim", ofType: "json")!
-        let data = try Data(contentsOf: URL(fileURLWithPath: path))
-
-        // this file stores an object with JSON encoded strings (so double encoded)
-        let jsonInputs = try JSONSerialization.jsonObject(with: data) as! [String: Any]
-
-        let pumpHistory = try JSONBridge.pumpHistory(from: jsonInputs["pumpHistory"] as! String)
-        let profile = try JSONBridge.profile(from: jsonInputs["profile"] as! String)
-        let basalProfile = try JSONBridge.basalProfile(from: jsonInputs["basalProfile"] as! String)
-        let clock = try JSONBridge.clock(from: jsonInputs["clock"] as! String)
-
-        let decoder = JSONCoding.decoder
-        var jsonData = (jsonInputs["carbs"] as! String).data(using: .utf8)!
-        let carbHistory: [CarbsEntry] = try decoder.decode([CarbsEntry].self, from: jsonData)
-
-        jsonData = (jsonInputs["glucose"] as! String).data(using: .utf8)!
-        let glucoseHistory: [BloodGlucose] = try decoder.decode([BloodGlucose].self, from: jsonData)
-
-        jsonData = (jsonInputs["meal"] as! String).data(using: .utf8)!
-        let mealResultFromJs = try decoder.decode(ComputedCarbs.self, from: jsonData)
-
-        let mealResult = try MealGenerator.generate(
-            pumpHistory: pumpHistory,
-            profile: profile,
-            basalProfile: basalProfile,
-            clock: clock,
-            carbHistory: carbHistory,
-            glucoseHistory: glucoseHistory
-        )
-
-        #expect(mealResult?.mealCOB == mealResultFromJs.mealCOB)
-        #expect(mealResult?.carbs == mealResultFromJs.carbs)
-        #expect(mealResult?.currentDeviation == mealResultFromJs.currentDeviation)
-        // https://github.com/nightscout/Trio-dev/issues/539
-        // Ignore this check due to Issue 539
-        // #expect(mealResult?.allDeviations == mealResultFromJs.allDeviations)
-        #expect(mealResult?.maxDeviation == mealResultFromJs.maxDeviation)
-        #expect(mealResult?.slopeFromMaxDeviation == mealResultFromJs.slopeFromMaxDeviation)
-        #expect(mealResult?.minDeviation == mealResultFromJs.minDeviation)
-        #expect(mealResult!.slopeFromMinDeviation.isWithin(0.01, of: mealResultFromJs.slopeFromMinDeviation))
-    }
-
     @Test(
         "Meal should produce same results for fixed JS",
         .enabled(if: true)
     ) func replayErrorInputs() async throws {
+        // Note: This test case can only test one timezone per invocation
+        // so you need to manually change this to try out errors from
+        // different timezones
+        let testingTimezone = "Europe/Berlin"
         let files = try await HttpFiles.listFiles()
+        var skippedTimezones = Set<String>()
         for filePath in files {
             let algorithmComparison = try await HttpFiles.downloadFile(at: filePath)
             print("Checking \(filePath) @ \(algorithmComparison.createdAt)")
+            guard algorithmComparison.timezone == testingTimezone else {
+                print("Skipping timezone \(algorithmComparison.timezone)")
+                skippedTimezones.insert(algorithmComparison.timezone)
+                continue
+            }
             guard let mealInputs = algorithmComparison.mealInput else {
                 print("Skipping, no mealInputs found")
                 if let str = algorithmComparison.comparisonError {
@@ -71,9 +37,18 @@ import Testing
             timeZoneForTests.setTimezone(identifier: algorithmComparison.timezone)
 
             try await checkFixedJsAgainstSwift(mealInputs: mealInputs)
-
+            print("Checked \(filePath) \(algorithmComparison.timezone)")
             timeZoneForTests.resetTimezone()
         }
+
+        if skippedTimezones.isEmpty {
+            print("Didn't skip any timezones")
+        } else {
+            print("Skipped timezones:")
+            for timezone in skippedTimezones {
+                print("  - \(timezone)")
+            }
+        }
     }
 
     func checkFixedJsAgainstSwift(mealInputs: MealInputs) async throws {
@@ -123,7 +98,7 @@ import Testing
         // this test is meant for one-off analysis so it's ok to hard code
         // a file, just make sure to _not_ check in updates to this to
         // avoid polluting our change logs
-        let algorithmComparison = try await HttpFiles.downloadFile(at: "/files/02273a81-c2ed-461b-8d4e-b9b085227f61.1.json")
+        let algorithmComparison = try await HttpFiles.downloadFile(at: "/files/7a8a377e-f483-46a5-adbb-290baa04801b.3.json")
         let mealInputs = algorithmComparison.mealInput!
 
         let encoder = JSONCoding.encoder
@@ -135,6 +110,8 @@ import Testing
         print("Writing to: \(outputURL.path)")
         try output.write(to: outputURL)
 
+        timeZoneForTests.setTimezone(identifier: algorithmComparison.timezone)
+
         let (mealResultSwift, _) = OpenAPSSwift.meal(
             pumphistory: mealInputs.pumpHistory,
             profile: try JSONBridge.to(mealInputs.profile),
@@ -168,5 +145,7 @@ import Testing
         case let .failure(error):
             print(error.localizedDescription)
         }
+
+        timeZoneForTests.resetTimezone()
     }
 }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 16
TrioTests/OpenAPSSwiftTests/json/meal-input-sim.json