Skip to content

Commit

Permalink
Refactor and write tests for checkmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
iSoron committed Mar 14, 2016
1 parent 3d1c533 commit 144524e
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <[email protected]>
*
* 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 static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.isoron.uhabits.models.Checkmark.CHECKED_EXPLICITLY;
import static org.isoron.uhabits.models.Checkmark.CHECKED_IMPLICITLY;
import static org.isoron.uhabits.models.Checkmark.UNCHECKED;

@RunWith(AndroidJUnit4.class)
@SmallTest
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;
}
}

@After
public void tearDown()
{
DateHelper.setFixedLocalTime(null);
}

@Test
public void getAllValues_testNonDailyHabit()
{
int[] expectedValues = { CHECKED_EXPLICITLY, UNCHECKED, CHECKED_IMPLICITLY,
CHECKED_EXPLICITLY, CHECKED_EXPLICITLY, CHECKED_EXPLICITLY, UNCHECKED,
CHECKED_IMPLICITLY, CHECKED_EXPLICITLY, CHECKED_EXPLICITLY };

int[] actualValues = nonDailyHabit.checkmarks.getAllValues();

assertThat(actualValues, equalTo(expectedValues));
}

@Test
public void getAllValues_testMoveForwardInTime()
{
travelInTime(3);

int[] expectedValues = { UNCHECKED, UNCHECKED, UNCHECKED, CHECKED_EXPLICITLY, UNCHECKED,
CHECKED_IMPLICITLY, CHECKED_EXPLICITLY, CHECKED_EXPLICITLY, CHECKED_EXPLICITLY,
UNCHECKED, CHECKED_IMPLICITLY, CHECKED_EXPLICITLY, CHECKED_EXPLICITLY };

int[] actualValues = nonDailyHabit.checkmarks.getAllValues();

assertThat(actualValues, equalTo(expectedValues));
}

@Test
public void getAllValues_testMoveBackwardsInTime()
{
travelInTime(-3);

int[] expectedValues = { CHECKED_EXPLICITLY, CHECKED_EXPLICITLY, CHECKED_EXPLICITLY,
UNCHECKED, CHECKED_IMPLICITLY, CHECKED_EXPLICITLY, CHECKED_EXPLICITLY };

int[] actualValues = nonDailyHabit.checkmarks.getAllValues();

assertThat(actualValues, equalTo(expectedValues));
}

@Test
public void getAllValues_testEmptyHabit()
{
int[] expectedValues = new int[0];
int[] actualValues = emptyHabit.checkmarks.getAllValues();

assertThat(actualValues, equalTo(expectedValues));
}

@Test
public void getValues_testInvalidInterval()
{
int values[] = nonDailyHabit.checkmarks.getValues(100L, -100L);
assertThat(values, equalTo(new int[0]));
}

@Test
public void getValues_testValidInterval()
{
long from = DateHelper.getStartOfToday() - 15 * DateHelper.millisecondsInOneDay;
long to = DateHelper.getStartOfToday() - 5 * DateHelper.millisecondsInOneDay;

int[] expectedValues = { CHECKED_EXPLICITLY, UNCHECKED, CHECKED_IMPLICITLY,
CHECKED_EXPLICITLY, CHECKED_EXPLICITLY, UNCHECKED, UNCHECKED, UNCHECKED, UNCHECKED,
UNCHECKED, UNCHECKED };

int[] actualValues = nonDailyHabit.checkmarks.getValues(from, to);

assertThat(actualValues, equalTo(expectedValues));
}

@Test
public void getTodayValue_testNonDailyHabit()
{
travelInTime(-1);
assertThat(nonDailyHabit.checkmarks.getTodayValue(), equalTo(UNCHECKED));

travelInTime(0);
assertThat(nonDailyHabit.checkmarks.getTodayValue(), equalTo(CHECKED_EXPLICITLY));

travelInTime(1);
assertThat(nonDailyHabit.checkmarks.getTodayValue(), equalTo(UNCHECKED));
}

private void travelInTime(int days)
{
DateHelper.setFixedLocalTime(FIXED_LOCAL_TIME + days * DateHelper.millisecondsInOneDay);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,19 @@ public void reorderTest()
public void rebuildOrderTest()
{
List<Long> ids = new LinkedList<>();

int originalPositions[] = { 0, 1, 1, 4, 6, 8, 10, 10, 13};
int length = originalPositions.length;

for (int i = 0; i < length; i++)
for (int p : originalPositions)
{
Habit h = new Habit();
h.position = originalPositions[i];
h.position = p;
h.save();
ids.add(h.getId());
}

Habit.rebuildOrder();

for (int i = 0; i < length; i++)
for (int i = 0; i < originalPositions.length; i++)
{
Habit h = Habit.get(ids.get(i));
assertThat(h.position, is(i));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
activity = (ShowHabitActivity) getActivity();
habit = activity.habit;

habit.checkmarks.rebuild();

Button btEditHistory = (Button) view.findViewById(R.id.btEditHistory);
streakView = (HabitStreakView) view.findViewById(R.id.streakView);
scoreView = (HabitScoreView) view.findViewById(R.id.scoreView);
Expand Down
21 changes: 16 additions & 5 deletions app/src/main/java/org/isoron/uhabits/models/Checkmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,21 @@
@Table(name = "Checkmarks")
public class Checkmark extends Model
{

/**
* Indicates that there was no repetition at the timestamp, even though a repetition was
* expected.
*/
public static final int UNCHECKED = 0;

/**
* Indicates that there was no repetition at the timestamp, but one was not expected in any
* case, due to the frequency of the habit.
*/
public static final int CHECKED_IMPLICITLY = 1;

/**
* Indicates that there was a repetition at the timestamp.
*/
public static final int CHECKED_EXPLICITLY = 2;

@Column(name = "habit")
Expand All @@ -38,10 +50,9 @@ public class Checkmark extends Model
public Long timestamp;

/**
* Indicates whether there is a checkmark at the given timestamp or not, and whether the
* checkmark is explicit or implicit. An explicit checkmark indicates that there is a
* repetition at that day. An implicit checkmark indicates that there is no repetition at that
* day, but a repetition was not needed, due to the frequency of the habit.
* Indicates whether there is a repetition at the given timestamp or not, and whether the
* repetition was expected. Assumes one of the values UNCHECKED, CHECKED_EXPLICITLY or
* CHECKED_IMPLICITLY.
*/
@Column(name = "value")
public Integer value;
Expand Down
Loading

0 comments on commit 144524e

Please sign in to comment.