diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java index 7211ec15e..497a9af16 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java @@ -122,22 +122,28 @@ public abstract class CheckmarkList } /** - * Starting from the oldest interval, this function tries to slide the + * Starting from the second newest interval, this function tries to slide the * intervals backwards into the past, so that gaps are eliminated and - * streaks are maximized. When it detects that sliding an interval - * would not help fixing any gap, it leaves the interval unchanged. + * streaks are maximized. */ static void snapIntervalsTogether(@NonNull ArrayList intervals) { - for (int i = 1; i < intervals.size(); i++) + int n = intervals.size(); + for (int i = n - 2; i >= 0; i--) { Interval curr = intervals.get(i); - Interval prev = intervals.get(i - 1); + Interval next = intervals.get(i + 1); - int gap = prev.end.daysUntil(curr.begin) - 1; - if (gap <= 0 || curr.end.minus(gap).isOlderThan(curr.center)) continue; - intervals.set(i, new Interval(curr.begin.minus(gap), curr.center, - curr.end.minus(gap))); + int gapNextToCurrent = next.begin.daysUntil(curr.end); + int gapCenterToEnd = curr.center.daysUntil(curr.end); + + if (gapNextToCurrent >= 0) + { + int shift = Math.min(gapCenterToEnd, gapNextToCurrent + 1); + intervals.set(i, new Interval(curr.begin.minus(shift), + curr.center, + curr.end.minus(shift))); + } } } diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java index 02ad7acf7..09bbe2eaf 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java @@ -319,16 +319,31 @@ public class CheckmarkListTest extends BaseUnitTest public void test_snapIntervalsTogether_1() throws Exception { ArrayList original = new ArrayList<>(); - original.add(new CheckmarkList.Interval(day(40), day(40), day(34))); - original.add(new CheckmarkList.Interval(day(25), day(25), day(19))); - original.add(new CheckmarkList.Interval(day(16), day(16), day(10))); + original.add(new CheckmarkList.Interval(day(27), day(27), day(21))); + original.add(new CheckmarkList.Interval(day(20), day(20), day(14))); + original.add(new CheckmarkList.Interval(day(12), day(12), day(6))); original.add(new CheckmarkList.Interval(day(8), day(8), day(2))); ArrayList expected = new ArrayList<>(); - expected.add(new CheckmarkList.Interval(day(40), day(40), day(34))); - expected.add(new CheckmarkList.Interval(day(25), day(25), day(19))); - expected.add(new CheckmarkList.Interval(day(18), day(16), day(12))); - expected.add(new CheckmarkList.Interval(day(11), day(8), day(5))); + expected.add(new CheckmarkList.Interval(day(29), day(27), day(23))); + expected.add(new CheckmarkList.Interval(day(22), day(20), day(16))); + expected.add(new CheckmarkList.Interval(day(15), day(12), day(9))); + expected.add(new CheckmarkList.Interval(day(8), day(8), day(2))); + + CheckmarkList.snapIntervalsTogether(original); + assertThat(original, equalTo(expected)); + } + + @Test + public void test_snapIntervalsTogether_2() throws Exception + { + ArrayList original = new ArrayList<>(); + original.add(new CheckmarkList.Interval(day(11), day(8), day(5))); + original.add(new CheckmarkList.Interval(day(6), day(4), day(0))); + + ArrayList expected = new ArrayList<>(); + expected.add(new CheckmarkList.Interval(day(13), day(8), day(7))); + expected.add(new CheckmarkList.Interval(day(6), day(4), day(0))); CheckmarkList.snapIntervalsTogether(original); assertThat(original, equalTo(expected)); diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java index 0270a7e29..e5d9db1a3 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java @@ -153,9 +153,9 @@ public class ScoreListTest extends BaseUnitTest habit.getScores().groupBy(DateUtils.TruncateField.MONTH, Calendar.SATURDAY); assertThat(list.size(), equalTo(5)); - assertThat(list.get(0).getValue(), closeTo(0.653659, E)); - assertThat(list.get(1).getValue(), closeTo(0.622715, E)); - assertThat(list.get(2).getValue(), closeTo(0.520997, E)); + assertThat(list.get(0).getValue(), closeTo(0.687724, E)); + assertThat(list.get(1).getValue(), closeTo(0.636747, E)); + assertThat(list.get(2).getValue(), closeTo(0.533860, E)); } @Test