mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-09 18:48:51 -06:00
Implement alternative checkmark algorithm
Fix failing tests
This commit is contained in:
@@ -24,33 +24,153 @@ import org.isoron.uhabits.core.utils.*;
|
||||
import org.junit.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.core.IsEqual.*;
|
||||
import static org.isoron.uhabits.core.models.Checkmark.*;
|
||||
import static org.isoron.uhabits.core.models.Checkmark.CHECKED_EXPLICITLY;
|
||||
import static org.isoron.uhabits.core.models.Checkmark.CHECKED_IMPLICITLY;
|
||||
import static org.isoron.uhabits.core.models.Checkmark.UNCHECKED;
|
||||
|
||||
public class CheckmarkListTest extends BaseUnitTest
|
||||
{
|
||||
// 8:00am, January 25th, 2015 (UTC)
|
||||
private long fixed_local_time = 1422172800000L;
|
||||
private long dayLength;
|
||||
|
||||
private long today;
|
||||
|
||||
private Habit nonDailyHabit;
|
||||
|
||||
private Habit emptyHabit;
|
||||
|
||||
private Habit numericalHabit;
|
||||
|
||||
@Override
|
||||
public void setUp()
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
DateUtils.setFixedLocalTime(fixed_local_time);
|
||||
dayLength = DateUtils.millisecondsInOneDay;
|
||||
today = DateUtils.getStartOfToday();
|
||||
|
||||
fixtures.createShortHabit();
|
||||
nonDailyHabit = fixtures.createShortHabit();
|
||||
habitList.add(nonDailyHabit);
|
||||
|
||||
emptyHabit = fixtures.createEmptyHabit();
|
||||
habitList.add(emptyHabit);
|
||||
|
||||
numericalHabit = fixtures.createNumericalHabit();
|
||||
habitList.add(numericalHabit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_buildCheckmarksFromIntervals_1() throws Exception
|
||||
{
|
||||
Repetition reps[] = new Repetition[]{
|
||||
new Repetition(day(10), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(5), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(2), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(1), CHECKED_EXPLICITLY),
|
||||
};
|
||||
|
||||
ArrayList<CheckmarkList.Interval> intervals = new ArrayList<>();
|
||||
intervals.add(new CheckmarkList.Interval(day(10), day(8), day(8)));
|
||||
intervals.add(new CheckmarkList.Interval(day(6), day(5), day(4)));
|
||||
intervals.add(new CheckmarkList.Interval(day(2), day(2), day(1)));
|
||||
|
||||
List<Checkmark> expected = new ArrayList<>();
|
||||
expected.add(new Checkmark(day(0), UNCHECKED));
|
||||
expected.add(new Checkmark(day(1), CHECKED_EXPLICITLY));
|
||||
expected.add(new Checkmark(day(2), CHECKED_EXPLICITLY));
|
||||
expected.add(new Checkmark(day(3), UNCHECKED));
|
||||
expected.add(new Checkmark(day(4), CHECKED_IMPLICITLY));
|
||||
expected.add(new Checkmark(day(5), CHECKED_EXPLICITLY));
|
||||
expected.add(new Checkmark(day(6), CHECKED_IMPLICITLY));
|
||||
expected.add(new Checkmark(day(7), UNCHECKED));
|
||||
expected.add(new Checkmark(day(8), CHECKED_IMPLICITLY));
|
||||
expected.add(new Checkmark(day(9), CHECKED_IMPLICITLY));
|
||||
expected.add(new Checkmark(day(10), CHECKED_EXPLICITLY));
|
||||
|
||||
List<Checkmark> actual =
|
||||
CheckmarkList.buildCheckmarksFromIntervals(reps, intervals);
|
||||
assertThat(actual, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_buildCheckmarksFromIntervals_2() throws Exception
|
||||
{
|
||||
Repetition reps[] = new Repetition[]{
|
||||
new Repetition(day(0), CHECKED_EXPLICITLY),
|
||||
};
|
||||
|
||||
ArrayList<CheckmarkList.Interval> intervals = new ArrayList<>();
|
||||
intervals.add(new CheckmarkList.Interval(day(0), day(0), day(-10)));
|
||||
|
||||
List<Checkmark> expected = new ArrayList<>();
|
||||
expected.add(new Checkmark(day(0), CHECKED_EXPLICITLY));
|
||||
|
||||
List<Checkmark> actual =
|
||||
CheckmarkList.buildCheckmarksFromIntervals(reps, intervals);
|
||||
assertThat(actual, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_buildIntervals_1() throws Exception
|
||||
{
|
||||
Repetition reps[] = new Repetition[]{
|
||||
new Repetition(day(23), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(18), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(8), CHECKED_EXPLICITLY),
|
||||
};
|
||||
|
||||
ArrayList<CheckmarkList.Interval> expected = new ArrayList<>();
|
||||
expected.add(new CheckmarkList.Interval(day(23), day(23), day(17)));
|
||||
expected.add(new CheckmarkList.Interval(day(18), day(18), day(12)));
|
||||
expected.add(new CheckmarkList.Interval(day(8), day(8), day(2)));
|
||||
|
||||
ArrayList<CheckmarkList.Interval> actual;
|
||||
actual = CheckmarkList.buildIntervals(Frequency.WEEKLY, reps);
|
||||
assertThat(actual, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_buildIntervals_2() throws Exception
|
||||
{
|
||||
Repetition reps[] = new Repetition[]{
|
||||
new Repetition(day(23), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(18), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(8), CHECKED_EXPLICITLY),
|
||||
};
|
||||
|
||||
ArrayList<CheckmarkList.Interval> expected = new ArrayList<>();
|
||||
expected.add(new CheckmarkList.Interval(day(23), day(23), day(23)));
|
||||
expected.add(new CheckmarkList.Interval(day(18), day(18), day(18)));
|
||||
expected.add(new CheckmarkList.Interval(day(8), day(8), day(8)));
|
||||
|
||||
ArrayList<CheckmarkList.Interval> actual;
|
||||
actual = CheckmarkList.buildIntervals(Frequency.DAILY, reps);
|
||||
assertThat(actual, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_buildIntervals_3() throws Exception
|
||||
{
|
||||
Repetition reps[] = new Repetition[]{
|
||||
new Repetition(day(23), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(22), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(18), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(15), CHECKED_EXPLICITLY),
|
||||
new Repetition(day(8), CHECKED_EXPLICITLY),
|
||||
};
|
||||
|
||||
ArrayList<CheckmarkList.Interval> expected = new ArrayList<>();
|
||||
expected.add(new CheckmarkList.Interval(day(23), day(22), day(17)));
|
||||
expected.add(new CheckmarkList.Interval(day(22), day(18), day(16)));
|
||||
expected.add(new CheckmarkList.Interval(day(18), day(15), day(12)));
|
||||
|
||||
ArrayList<CheckmarkList.Interval> actual;
|
||||
actual =
|
||||
CheckmarkList.buildIntervals(Frequency.TWO_TIMES_PER_WEEK, reps);
|
||||
assertThat(actual, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -62,7 +182,7 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
UNCHECKED,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY
|
||||
@@ -73,7 +193,6 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
assertThat(actualValues, equalTo(expectedValues));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test_getAllValues_moveForwardInTime()
|
||||
{
|
||||
@@ -89,7 +208,7 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
UNCHECKED,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY
|
||||
@@ -119,7 +238,7 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
UNCHECKED,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY
|
||||
@@ -130,20 +249,33 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
assertThat(actualValues, equalTo(expectedValues));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_getByInterval_withNumericalHabits() throws Exception
|
||||
{
|
||||
CheckmarkList checkmarks = numericalHabit.getCheckmarks();
|
||||
|
||||
List<Checkmark> expected =
|
||||
Arrays.asList(new Checkmark(day(1), 200), new Checkmark(day(2), 0),
|
||||
new Checkmark(day(3), 300), new Checkmark(day(4), 0),
|
||||
new Checkmark(day(5), 400));
|
||||
|
||||
List<Checkmark> actual = checkmarks.getByInterval(day(5), day(1));
|
||||
assertThat(actual, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_getTodayValue()
|
||||
{
|
||||
CheckmarkList checkmarks = nonDailyHabit.getCheckmarks();
|
||||
|
||||
travelInTime(-1);
|
||||
assertThat(nonDailyHabit.getCheckmarks().getTodayValue(),
|
||||
equalTo(UNCHECKED));
|
||||
assertThat(checkmarks.getTodayValue(), equalTo(UNCHECKED));
|
||||
|
||||
travelInTime(0);
|
||||
assertThat(nonDailyHabit.getCheckmarks().getTodayValue(),
|
||||
equalTo(CHECKED_EXPLICITLY));
|
||||
assertThat(checkmarks.getTodayValue(), equalTo(CHECKED_EXPLICITLY));
|
||||
|
||||
travelInTime(1);
|
||||
assertThat(nonDailyHabit.getCheckmarks().getTodayValue(),
|
||||
equalTo(UNCHECKED));
|
||||
assertThat(checkmarks.getTodayValue(), equalTo(UNCHECKED));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -156,14 +288,12 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
@Test
|
||||
public void test_getValues_withValidInterval()
|
||||
{
|
||||
long from =
|
||||
DateUtils.getStartOfToday() - 15 * DateUtils.millisecondsInOneDay;
|
||||
long to =
|
||||
DateUtils.getStartOfToday() - 5 * DateUtils.millisecondsInOneDay;
|
||||
long from = today - 15 * dayLength;
|
||||
long to = today - 5 * dayLength;
|
||||
|
||||
int[] expectedValues = {
|
||||
CHECKED_EXPLICITLY,
|
||||
UNCHECKED,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_IMPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
CHECKED_EXPLICITLY,
|
||||
@@ -180,18 +310,31 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
assertThat(actualValues, equalTo(expectedValues));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_snapIntervalsTogether_1() throws Exception
|
||||
{
|
||||
ArrayList<CheckmarkList.Interval> 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(8), day(8), day(2)));
|
||||
|
||||
ArrayList<CheckmarkList.Interval> 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)));
|
||||
|
||||
CheckmarkList.snapIntervalsTogether(original);
|
||||
assertThat(original, equalTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_writeCSV() throws IOException
|
||||
{
|
||||
String expectedCSV = "2015-01-25,2\n" +
|
||||
"2015-01-24,0\n" +
|
||||
"2015-01-23,1\n" +
|
||||
"2015-01-22,2\n" +
|
||||
"2015-01-21,2\n" +
|
||||
"2015-01-20,2\n" +
|
||||
"2015-01-19,0\n" +
|
||||
"2015-01-18,1\n" +
|
||||
"2015-01-17,2\n" +
|
||||
String expectedCSV = "2015-01-25,2\n2015-01-24,0\n2015-01-23,1\n" +
|
||||
"2015-01-22,2\n2015-01-21,2\n2015-01-20,2\n" +
|
||||
"2015-01-19,1\n2015-01-18,1\n2015-01-17,2\n" +
|
||||
"2015-01-16,2\n";
|
||||
|
||||
|
||||
@@ -201,9 +344,15 @@ public class CheckmarkListTest extends BaseUnitTest
|
||||
assertThat(writer.toString(), equalTo(expectedCSV));
|
||||
}
|
||||
|
||||
private long day(int offset)
|
||||
{
|
||||
return DateUtils.getStartOfToday() -
|
||||
offset * DateUtils.millisecondsInOneDay;
|
||||
}
|
||||
|
||||
private void travelInTime(int days)
|
||||
{
|
||||
DateUtils.setFixedLocalTime(
|
||||
fixed_local_time + days * DateUtils.millisecondsInOneDay);
|
||||
FIXED_LOCAL_TIME + days * DateUtils.millisecondsInOneDay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,28 @@ public class ScoreListTest extends BaseUnitTest
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_getValues()
|
||||
{
|
||||
toggleRepetitions(0, 20);
|
||||
|
||||
long today = DateUtils.getStartOfToday();
|
||||
long day = DateUtils.millisecondsInOneDay;
|
||||
|
||||
long from = today - 4 * day;
|
||||
long to = today - 2 * day;
|
||||
|
||||
double[] expected = {
|
||||
0.617008, 0.596033, 0.573909,
|
||||
};
|
||||
|
||||
double[] actual = habit.getScores().getValues(from, to);
|
||||
assertThat(actual.length, equalTo(expected.length));
|
||||
|
||||
for (int i = 0; i < actual.length; i++)
|
||||
assertThat(actual[i], closeTo(expected[i], E));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_groupBy()
|
||||
{
|
||||
@@ -133,9 +155,9 @@ public class ScoreListTest extends BaseUnitTest
|
||||
habit.getScores().groupBy(DateUtils.TruncateField.MONTH);
|
||||
|
||||
assertThat(list.size(), equalTo(5));
|
||||
assertThat(list.get(0).getValue(), closeTo(0.549096, E));
|
||||
assertThat(list.get(1).getValue(), closeTo(0.480098, E));
|
||||
assertThat(list.get(2).getValue(), closeTo(0.377885, E));
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -157,16 +179,11 @@ public class ScoreListTest extends BaseUnitTest
|
||||
{
|
||||
Habit habit = fixtures.createShortHabit();
|
||||
|
||||
String expectedCSV = "2015-01-25,0.2372\n" +
|
||||
"2015-01-24,0.2096\n" +
|
||||
"2015-01-23,0.2172\n" +
|
||||
"2015-01-22,0.1889\n" +
|
||||
"2015-01-21,0.1595\n" +
|
||||
"2015-01-20,0.1291\n" +
|
||||
"2015-01-19,0.0976\n" +
|
||||
"2015-01-18,0.1011\n" +
|
||||
"2015-01-17,0.0686\n" +
|
||||
"2015-01-16,0.0349\n";
|
||||
String expectedCSV = "2015-01-25,0.2654\n2015-01-24,0.2389\n" +
|
||||
"2015-01-23,0.2475\n2015-01-22,0.2203\n" +
|
||||
"2015-01-21,0.1921\n2015-01-20,0.1628\n" +
|
||||
"2015-01-19,0.1325\n2015-01-18,0.1011\n" +
|
||||
"2015-01-17,0.0686\n2015-01-16,0.0349\n";
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
habit.getScores().writeCSV(writer);
|
||||
@@ -174,30 +191,6 @@ public class ScoreListTest extends BaseUnitTest
|
||||
assertThat(writer.toString(), equalTo(expectedCSV));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_getValues()
|
||||
{
|
||||
toggleRepetitions(0, 20);
|
||||
|
||||
long today = DateUtils.getStartOfToday();
|
||||
long day = DateUtils.millisecondsInOneDay;
|
||||
|
||||
long from = today - 4 * day;
|
||||
long to = today - 2 * day;
|
||||
|
||||
double[] expected = {
|
||||
0.617008,
|
||||
0.596033,
|
||||
0.573909,
|
||||
};
|
||||
|
||||
double[] actual = habit.getScores().getValues(from, to);
|
||||
assertThat(actual.length, equalTo(expected.length));
|
||||
|
||||
for(int i = 0; i < actual.length; i++)
|
||||
assertThat(actual[i], closeTo(expected[i], E));
|
||||
}
|
||||
|
||||
private void toggleRepetitions(final int from, final int to)
|
||||
{
|
||||
RepetitionList reps = habit.getRepetitions();
|
||||
|
||||
@@ -99,6 +99,7 @@ public class ListHabitsBehaviorTest extends BaseUnitTest
|
||||
when(system.getCSVOutputDir()).thenReturn(outputDir);
|
||||
behavior.onExportCSV();
|
||||
verify(screen).showMessage(COULD_NOT_EXPORT);
|
||||
assertTrue(outputDir.delete());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user