Refactor and write unit tests for RepetitionList

This commit is contained in:
2016-03-13 13:55:16 -04:00
parent 144524e53b
commit 1a18bb939d
6 changed files with 268 additions and 42 deletions

View File

@@ -42,33 +42,13 @@ public class CheckmarkListTest
Habit nonDailyHabit;
private Habit emptyHabit;
public static final long FIXED_LOCAL_TIME = 1422172800000L; // 8:00am, January 25th, 2015 (UTC)
@Before
public void prepare()
{
DateHelper.setFixedLocalTime(FIXED_LOCAL_TIME);
createNonDailyHabit();
emptyHabit = new Habit();
emptyHabit.save();
}
private void createNonDailyHabit()
{
nonDailyHabit = new Habit();
nonDailyHabit.freqNum = 2;
nonDailyHabit.freqDen = 3;
nonDailyHabit.save();
boolean check[] = { true, false, false, true, true, true, false, false, true, true };
long timestamp = DateHelper.getStartOfToday();
for(boolean c : check)
{
if(c) nonDailyHabit.repetitions.toggle(timestamp);
timestamp -= DateHelper.millisecondsInOneDay;
}
HabitFixtures.purgeHabits();
DateHelper.setFixedLocalTime(HabitFixtures.FIXED_LOCAL_TIME);
nonDailyHabit = HabitFixtures.createNonDailyHabit();
emptyHabit = HabitFixtures.createEmptyHabit();
}
@After
@@ -162,6 +142,7 @@ public class CheckmarkListTest
private void travelInTime(int days)
{
DateHelper.setFixedLocalTime(FIXED_LOCAL_TIME + days * DateHelper.millisecondsInOneDay);
DateHelper.setFixedLocalTime(HabitFixtures.FIXED_LOCAL_TIME +
days * DateHelper.millisecondsInOneDay);
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.unit.models;
import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.models.Habit;
public class HabitFixtures
{
public static final long FIXED_LOCAL_TIME = 1422172800000L; // 8:00am, January 25th, 2015 (UTC)
public static boolean NON_DAILY_HABIT_CHECKS[] = { true, false, false, true, true, true, false,
false, true, true };
static Habit createNonDailyHabit()
{
Habit habit = new Habit();
habit.freqNum = 2;
habit.freqDen = 3;
habit.save();
long timestamp = DateHelper.getStartOfToday();
for(boolean c : NON_DAILY_HABIT_CHECKS)
{
if(c) habit.repetitions.toggle(timestamp);
timestamp -= DateHelper.millisecondsInOneDay;
}
return habit;
}
static Habit createEmptyHabit()
{
Habit habit = new Habit();
habit.save();
return habit;
}
static void purgeHabits()
{
for(Habit h : Habit.getAll(true))
h.cascadeDelete();
}
}

View File

@@ -40,8 +40,7 @@ public class HabitTest
@Before
public void prepare()
{
for(Habit h : Habit.getAll(true))
h.cascadeDelete();
HabitFixtures.purgeHabits();
}
@Test

View File

@@ -0,0 +1,162 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.unit.models;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.models.Habit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Random;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class RepetitionListTest
{
Habit habit;
private Habit emptyHabit;
@Before
public void prepare()
{
HabitFixtures.purgeHabits();
DateHelper.setFixedLocalTime(HabitFixtures.FIXED_LOCAL_TIME);
habit = HabitFixtures.createNonDailyHabit();
emptyHabit = HabitFixtures.createEmptyHabit();
}
@After
public void tearDown()
{
DateHelper.setFixedLocalTime(null);
}
@Test
public void contains_testNonDailyHabit()
{
long current = DateHelper.getStartOfToday();
for(boolean b : HabitFixtures.NON_DAILY_HABIT_CHECKS)
{
assertThat(habit.repetitions.contains(current), equalTo(b));
current -= DateHelper.millisecondsInOneDay;
}
for(int i = 0; i < 3; i++)
{
assertThat(habit.repetitions.contains(current), equalTo(false));
current -= DateHelper.millisecondsInOneDay;
}
}
@Test
public void delete_test()
{
long timestamp = DateHelper.getStartOfToday();
assertThat(habit.repetitions.contains(timestamp), equalTo(true));
habit.repetitions.delete(timestamp);
assertThat(habit.repetitions.contains(timestamp), equalTo(false));
}
@Test
public void toggle_test()
{
long timestamp = DateHelper.getStartOfToday();
assertThat(habit.repetitions.contains(timestamp), equalTo(true));
habit.repetitions.toggle(timestamp);
assertThat(habit.repetitions.contains(timestamp), equalTo(false));
habit.repetitions.toggle(timestamp);
assertThat(habit.repetitions.contains(timestamp), equalTo(true));
}
@Test
public void getWeekDayFrequency_test()
{
Random random = new Random();
Integer weekdayCount[][] = new Integer[12][7];
Integer monthCount[] = new Integer[12];
Arrays.fill(monthCount, 0);
for(Integer row[] : weekdayCount)
Arrays.fill(row, 0);
GregorianCalendar day = DateHelper.getStartOfTodayCalendar();
// Sets the current date to the end of November
day.set(2015, 10, 30);
DateHelper.setFixedLocalTime(day.getTimeInMillis());
// Add repetitions randomly from January to December
// Leaves the month of March empty, to check that it returns null
day.set(2015, 0, 1);
for(int i = 0; i < 365; i ++)
{
if(random.nextBoolean())
{
int month = day.get(Calendar.MONTH);
int week = day.get(Calendar.DAY_OF_WEEK) % 7;
if(month != 2)
{
if (month <= 10)
{
weekdayCount[month][week]++;
monthCount[month]++;
}
emptyHabit.repetitions.toggle(day.getTimeInMillis());
}
}
day.add(Calendar.DAY_OF_YEAR, 1);
}
HashMap<Long, Integer[]> freq = emptyHabit.repetitions.getWeekdayFrequency();
// Repetitions until November should be counted correctly
for(int month = 0; month < 11; month++)
{
day.set(2015, month, 1);
Integer actualCount[] = freq.get(day.getTimeInMillis());
if(monthCount[month] == 0)
assertThat(actualCount, equalTo(null));
else
assertThat(actualCount, equalTo(weekdayCount[month]));
}
// Repetitions in December should be discarded
day.set(2015, 11, 1);
assertThat(freq.get(day.getTimeInMillis()), equalTo(null));
}
}