Implement alternative checkmark algorithm

Fix failing tests
This commit is contained in:
2017-06-03 10:52:09 -04:00
parent 96e1771c25
commit ed9066f393
33 changed files with 490 additions and 476 deletions

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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