Repository: st3v3nmw/obsidian-spaced-repetition
Pull request #1147 (2024-10-21 07:21:39)

refactor: make fuzzing less aggressive

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/st3v3nmw/obsidian-spaced-repetition/pull/1147?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi) Report
Attention: Patch coverage is `75.00000%` with `2 lines` in your changes missing coverage. Please review.
> Project coverage is 92.96%. Comparing base [(`e201b84`)](https://app.codecov.io/gh/st3v3nmw/obsidian-spaced-repetition/commit/e201b8424cacc5973e194da15cefd7e703783597?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi) to head [(`84aa9e8`)](https://app.codecov.io/gh/st3v3nmw/obsidian-spaced-repetition/commit/84aa9e88a4c6088cfe5701568f5a613eb34e059e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi).

| [Files with missing lines](https://app.codecov.io/gh/st3v3nmw/obsidian-spaced-repetition/pull/1147?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi) | Patch % | Lines |
|---|---|---|
| [src/algorithms/osr/note-scheduling.ts](https://app.codecov.io/gh/st3v3nmw/obsidian-spaced-repetition/pull/1147?src=pr&el=tree&filepath=src%2Falgorithms%2Fosr%2Fnote-scheduling.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi#diff-c3JjL2FsZ29yaXRobXMvb3NyL25vdGUtc2NoZWR1bGluZy50cw==) | 75.00% | [2 Missing :warning: ](https://app.codecov.io/gh/st3v3nmw/obsidian-spaced-repetition/pull/1147?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #1147      +/-   ##
==========================================
+ Coverage   92.89%   92.96%   +0.07%     
==========================================
  Files          42       42              
  Lines        4558     4561       +3     
  Branches      369      371       +2     
==========================================
+ Hits         4234     4240       +6     
+ Misses        322      319       -3     
  Partials        2        2              
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/st3v3nmw/obsidian-spaced-repetition/pull/1147?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Stephen+Mwangi).


Patch:
diff --git a/src/algorithms/osr/note-scheduling.ts b/src/algorithms/osr/note-scheduling.ts
index 3df9ef7..0fd90b4 100644
--- a/src/algorithms/osr/note-scheduling.ts
+++ b/src/algorithms/osr/note-scheduling.ts
@@ -37,11 +37,14 @@ export function osrSchedule(
     if (settings.loadBalance && dueDateHistogram !== undefined) {
         interval = Math.round(interval);
         // disable fuzzing for small intervals
-        if (interval > 4) {
-            let fuzz = 0;
-            if (interval < 7) fuzz = 1;
-            else if (interval < 30) fuzz = Math.max(2, Math.floor(interval * 0.15));
-            else fuzz = Math.max(4, Math.floor(interval * 0.05));
+        if (interval > 7) {
+            let fuzz: number;
+            // 3 day window: day - 1 <= x <= day + 1
+            if (interval <= 21) fuzz = 1;
+            // up to a week window: day - 3 <= x <= day + 3
+            else if (interval <= 180) fuzz = Math.min(3, Math.floor(interval * 0.05));
+            // up to a 2 weeks window: day - 7 <= x <= day + 7
+            else fuzz = Math.min(7, Math.floor(interval * 0.025));
 
             interval = dueDateHistogram.findLeastUsedIntervalOverRange(interval, fuzz);
         }


Test patch:
diff --git a/tests/unit/scheduling.test.ts b/tests/unit/scheduling.test.ts
index 984f9dc..557d093 100644
--- a/tests/unit/scheduling.test.ts
+++ b/tests/unit/scheduling.test.ts
@@ -129,7 +129,7 @@ test("Test load balancing, small interval (load balancing disabled)", () => {
 });
 
 test("Test load balancing", () => {
-    // interval < 7
+    // interval <= 7
     let dueDates = new DueDateHistogram({
         5: 2,
     });
@@ -144,12 +144,33 @@ test("Test load balancing", () => {
         ),
     ).toEqual({
         ease: DEFAULT_SETTINGS.baseEase,
-        interval: 4,
+        interval: 5,
+    });
+
+    // 7 < interval <= 21
+    dueDates = new DueDateHistogram({
+        17: 4,
+        18: 5,
+        19: 3,
+    });
+    expect(
+        osrSchedule(
+            ReviewResponse.Good,
+            7,
+            DEFAULT_SETTINGS.baseEase,
+            0,
+            DEFAULT_SETTINGS,
+            dueDates,
+        ),
+    ).toEqual({
+        ease: DEFAULT_SETTINGS.baseEase,
+        interval: 19,
     });
 
-    // 7 <= interval < 30
+    // 21 < interval <= 180
     dueDates = new DueDateHistogram({
-        25: 2,
+        23: 5,
+        26: 1,
     });
     expect(
         osrSchedule(
@@ -162,10 +183,9 @@ test("Test load balancing", () => {
         ),
     ).toEqual({
         ease: DEFAULT_SETTINGS.baseEase,
-        interval: 24,
+        interval: 25,
     });
 
-    // interval >= 30
     dueDates = new DueDateHistogram({
         2: 5,
         59: 8,
@@ -191,6 +211,32 @@ test("Test load balancing", () => {
         ease: DEFAULT_SETTINGS.baseEase,
         interval: 66,
     });
+
+    // interval > 180
+    dueDates = new DueDateHistogram({
+        1245: 7,
+        1246: 4,
+        1247: 2,
+        1248: 9,
+        1249: 5,
+        1250: 4,
+        1251: 1,
+        1252: 1,
+        1254: 1,
+    });
+    expect(
+        osrSchedule(
+            ReviewResponse.Good,
+            500,
+            DEFAULT_SETTINGS.baseEase,
+            0,
+            DEFAULT_SETTINGS,
+            dueDates,
+        ),
+    ).toEqual({
+        ease: DEFAULT_SETTINGS.baseEase,
+        interval: 1253,
+    });
 });
 
 test("Test textInterval - desktop", () => {