mirror of https://github.com/iSoron/uhabits.git
parent
c904e22c0f
commit
3f74c77755
@ -1,243 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.core.models;
|
|
||||||
|
|
||||||
import androidx.annotation.*;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.core.utils.*;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class RepetitionList
|
|
||||||
{
|
|
||||||
protected Habit habit;
|
|
||||||
|
|
||||||
private final ArrayList<Entry> list = new ArrayList<>();
|
|
||||||
|
|
||||||
public void setHabit(Habit habit)
|
|
||||||
{
|
|
||||||
this.habit = habit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a checkmark to the list.
|
|
||||||
* <p>
|
|
||||||
* Any implementation of this method must call observable.notifyListeners()
|
|
||||||
* after the checkmark has been added.
|
|
||||||
*
|
|
||||||
* @param entry the checkmark to be added.
|
|
||||||
*/
|
|
||||||
public void add(Entry entry)
|
|
||||||
{
|
|
||||||
list.add(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of checkmarks that happened within the given time
|
|
||||||
* interval.
|
|
||||||
* <p>
|
|
||||||
* The list is sorted by timestamp in increasing order. That is, the first
|
|
||||||
* element corresponds to oldest timestamp, while the last element
|
|
||||||
* corresponds to the newest. The endpoints of the interval are included.
|
|
||||||
*
|
|
||||||
* @param fromTimestamp timestamp of the beginning of the interval
|
|
||||||
* @param toTimestamp timestamp of the end of the interval
|
|
||||||
* @return list of checkmarks within given time interval
|
|
||||||
*/
|
|
||||||
public List<Entry> getByInterval(Timestamp fromTimestamp, Timestamp toTimestamp)
|
|
||||||
{
|
|
||||||
ArrayList<Entry> filtered = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Entry r : list)
|
|
||||||
{
|
|
||||||
Timestamp t = r.getTimestamp();
|
|
||||||
if (t.isOlderThan(fromTimestamp) || t.isNewerThan(toTimestamp)) continue;
|
|
||||||
filtered.add(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(filtered,
|
|
||||||
(r1, r2) -> r1.getTimestamp().compareTo(r2.getTimestamp()));
|
|
||||||
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the checkmark that has the given timestamp, or null if none
|
|
||||||
* exists.
|
|
||||||
*
|
|
||||||
* @param timestamp the checkmark timestamp.
|
|
||||||
* @return the checkmark that has the given timestamp.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public Entry getByTimestamp(Timestamp timestamp)
|
|
||||||
{
|
|
||||||
for (Entry r : list)
|
|
||||||
if (r.getTimestamp().equals(timestamp)) return r;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a checkmark with the given timestamp exists, return its value. Otherwise, returns
|
|
||||||
* Checkmark.NO for boolean habits and zero for numerical habits.
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public int getValue(Timestamp timestamp)
|
|
||||||
{
|
|
||||||
Entry check = getByTimestamp(timestamp);
|
|
||||||
if (check == null) return Entry.UNKNOWN;
|
|
||||||
return check.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the oldest checkmark in the list.
|
|
||||||
* <p>
|
|
||||||
* If the list is empty, returns null. Repetitions in the future are
|
|
||||||
* discarded.
|
|
||||||
*
|
|
||||||
* @return oldest checkmark in the list, or null if list is empty.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public Entry getOldest()
|
|
||||||
{
|
|
||||||
Timestamp oldestTimestamp = Timestamp.ZERO.plus(1000000);
|
|
||||||
Entry oldestRep = null;
|
|
||||||
|
|
||||||
for (Entry rep : list)
|
|
||||||
{
|
|
||||||
if (rep.getTimestamp().isOlderThan(oldestTimestamp))
|
|
||||||
{
|
|
||||||
oldestRep = rep;
|
|
||||||
oldestTimestamp = rep.getTimestamp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return oldestRep;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the newest checkmark in the list.
|
|
||||||
* <p>
|
|
||||||
* If the list is empty, returns null. Repetitions in the past are
|
|
||||||
* discarded.
|
|
||||||
*
|
|
||||||
* @return newest checkmark in the list, or null if list is empty.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public Entry getNewest()
|
|
||||||
{
|
|
||||||
Timestamp newestTimestamp = Timestamp.ZERO;
|
|
||||||
Entry newestRep = null;
|
|
||||||
|
|
||||||
for (Entry rep : list)
|
|
||||||
{
|
|
||||||
if (rep.getTimestamp().isNewerThan(newestTimestamp))
|
|
||||||
{
|
|
||||||
newestRep = rep;
|
|
||||||
newestTimestamp = rep.getTimestamp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newestRep;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the total number of successful checkmarks for each month, from the first
|
|
||||||
* checkmark until today, grouped by day of week.
|
|
||||||
* <p>
|
|
||||||
* The checkmarks are returned in a HashMap. The key is the timestamp for
|
|
||||||
* the first day of the month, at midnight (00:00). The value is an integer
|
|
||||||
* array with 7 entries. The first entry contains the total number of
|
|
||||||
* successful checkmarks during the specified month that occurred on a Saturday. The
|
|
||||||
* second entry corresponds to Sunday, and so on. If there are no
|
|
||||||
* successful checkmarks during a certain month, the value is null.
|
|
||||||
*
|
|
||||||
* @return total number of checkmarks by month versus day of week
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public HashMap<Timestamp, Integer[]> getWeekdayFrequency()
|
|
||||||
{
|
|
||||||
List<Entry> entries =
|
|
||||||
getByInterval(Timestamp.ZERO, DateUtils.getTodayWithOffset());
|
|
||||||
HashMap<Timestamp, Integer[]> map = new HashMap<>();
|
|
||||||
|
|
||||||
for (Entry e : entries)
|
|
||||||
{
|
|
||||||
if (!habit.isNumerical() && e.getValue() != Entry.YES_MANUAL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Calendar date = e.getTimestamp().toCalendar();
|
|
||||||
int weekday = e.getTimestamp().getWeekday();
|
|
||||||
date.set(Calendar.DAY_OF_MONTH, 1);
|
|
||||||
|
|
||||||
Timestamp timestamp = new Timestamp(date.getTimeInMillis());
|
|
||||||
Integer[] list = map.get(timestamp);
|
|
||||||
|
|
||||||
if (list == null)
|
|
||||||
{
|
|
||||||
list = new Integer[7];
|
|
||||||
Arrays.fill(list, 0);
|
|
||||||
map.put(timestamp, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
list[weekday]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a given checkmark from the list.
|
|
||||||
* <p>
|
|
||||||
* If the list does not contain the checkmark, it is unchanged.
|
|
||||||
* <p>
|
|
||||||
* Any implementation of this method must call observable.notifyListeners()
|
|
||||||
* after the checkmark has been added.
|
|
||||||
*
|
|
||||||
* @param entry the checkmark to be removed
|
|
||||||
*/
|
|
||||||
public void remove(@NonNull Entry entry)
|
|
||||||
{
|
|
||||||
list.remove(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public long getTotalCount()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
for (Entry rep : list)
|
|
||||||
if (rep.getValue() == Entry.YES_MANUAL)
|
|
||||||
count++;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(Timestamp timestamp, int value)
|
|
||||||
{
|
|
||||||
Entry check = getByTimestamp(timestamp);
|
|
||||||
if (check != null) remove(check);
|
|
||||||
add(new Entry(timestamp, value));
|
|
||||||
habit.invalidateNewerThan(timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAll()
|
|
||||||
{
|
|
||||||
list.clear();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 Á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.core.models.sqlite;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.*;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.core.database.*;
|
|
||||||
import org.isoron.uhabits.core.models.*;
|
|
||||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
|
||||||
import org.jetbrains.annotations.*;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of a {@link RepetitionList} that is backed by SQLite.
|
|
||||||
*/
|
|
||||||
public class SQLiteRepetitionList extends RepetitionList
|
|
||||||
{
|
|
||||||
private final Repository<EntryRecord> repository;
|
|
||||||
|
|
||||||
private boolean loaded = false;
|
|
||||||
|
|
||||||
public SQLiteRepetitionList(@NonNull ModelFactory modelFactory)
|
|
||||||
{
|
|
||||||
repository = modelFactory.buildRepetitionListRepository();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadRecords()
|
|
||||||
{
|
|
||||||
if (loaded) return;
|
|
||||||
loaded = true;
|
|
||||||
|
|
||||||
check(habit.getId());
|
|
||||||
List<EntryRecord> records =
|
|
||||||
repository.findAll("where habit = ? order by timestamp",
|
|
||||||
habit.getId().toString());
|
|
||||||
|
|
||||||
for (EntryRecord rec : records)
|
|
||||||
super.add(rec.toEntry());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(Entry entry)
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
super.add(entry);
|
|
||||||
check(habit.getId());
|
|
||||||
EntryRecord record = new EntryRecord();
|
|
||||||
record.habitId = habit.getId();
|
|
||||||
record.copyFrom(entry);
|
|
||||||
repository.save(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Entry> getByInterval(Timestamp timeFrom, Timestamp timeTo)
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
return super.getByInterval(timeFrom, timeTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Entry getByTimestamp(Timestamp timestamp)
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
return super.getByTimestamp(timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Entry getOldest()
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
return super.getOldest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Entry getNewest()
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
return super.getNewest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove(@NonNull Entry entry)
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
super.remove(entry);
|
|
||||||
check(habit.getId());
|
|
||||||
repository.execSQL(
|
|
||||||
"delete from repetitions where habit = ? and timestamp = ?",
|
|
||||||
habit.getId(), entry.getTimestamp().getUnixTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAll()
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
super.removeAll();
|
|
||||||
check(habit.getId());
|
|
||||||
repository.execSQL("delete from repetitions where habit = ?",
|
|
||||||
habit.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalCount()
|
|
||||||
{
|
|
||||||
loadRecords();
|
|
||||||
return super.getTotalCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract("null -> fail")
|
|
||||||
private void check(Long value)
|
|
||||||
{
|
|
||||||
if (value == null) throw new RuntimeException("null check failed");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,468 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 Á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.core.models;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.core.*;
|
|
||||||
import org.isoron.uhabits.core.utils.*;
|
|
||||||
import org.junit.*;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import nl.jqno.equalsverifier.*;
|
|
||||||
|
|
||||||
import static java.util.Calendar.*;
|
|
||||||
import static org.hamcrest.MatcherAssert.*;
|
|
||||||
import static org.hamcrest.core.IsEqual.*;
|
|
||||||
import static org.isoron.uhabits.core.models.Entry.*;
|
|
||||||
import static org.isoron.uhabits.core.utils.DateUtils.TruncateField.MONTH;
|
|
||||||
import static org.isoron.uhabits.core.utils.DateUtils.TruncateField.QUARTER;
|
|
||||||
import static org.isoron.uhabits.core.utils.DateUtils.TruncateField.YEAR;
|
|
||||||
|
|
||||||
public class EntryListTest extends BaseUnitTest
|
|
||||||
{
|
|
||||||
private long dayLength;
|
|
||||||
|
|
||||||
private Timestamp today;
|
|
||||||
|
|
||||||
private Habit nonDailyHabit;
|
|
||||||
|
|
||||||
private Habit emptyHabit;
|
|
||||||
|
|
||||||
private Habit numericalHabit;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception
|
|
||||||
{
|
|
||||||
super.setUp();
|
|
||||||
|
|
||||||
nonDailyHabit = fixtures.createShortHabit();
|
|
||||||
habitList.add(nonDailyHabit);
|
|
||||||
|
|
||||||
emptyHabit = fixtures.createEmptyHabit();
|
|
||||||
habitList.add(emptyHabit);
|
|
||||||
|
|
||||||
numericalHabit = fixtures.createNumericalHabit();
|
|
||||||
habitList.add(numericalHabit);
|
|
||||||
today = DateUtils.getToday();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_buildCheckmarksFromIntervals_1() throws Exception
|
|
||||||
{
|
|
||||||
Entry entries[] = new Entry[]{
|
|
||||||
new Entry(day(10), YES_MANUAL),
|
|
||||||
new Entry(day(5), YES_MANUAL),
|
|
||||||
new Entry(day(2), YES_MANUAL),
|
|
||||||
new Entry(day(1), YES_MANUAL),
|
|
||||||
};
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> intervals = new ArrayList<>();
|
|
||||||
intervals.add(new EntryList.Interval(day(10), day(8), day(8)));
|
|
||||||
intervals.add(new EntryList.Interval(day(6), day(5), day(4)));
|
|
||||||
intervals.add(new EntryList.Interval(day(2), day(2), day(1)));
|
|
||||||
|
|
||||||
List<Entry> expected = new ArrayList<>();
|
|
||||||
expected.add(new Entry(day(0), UNKNOWN));
|
|
||||||
expected.add(new Entry(day(1), YES_MANUAL));
|
|
||||||
expected.add(new Entry(day(2), YES_MANUAL));
|
|
||||||
expected.add(new Entry(day(3), UNKNOWN));
|
|
||||||
expected.add(new Entry(day(4), YES_AUTO));
|
|
||||||
expected.add(new Entry(day(5), YES_MANUAL));
|
|
||||||
expected.add(new Entry(day(6), YES_AUTO));
|
|
||||||
expected.add(new Entry(day(7), UNKNOWN));
|
|
||||||
expected.add(new Entry(day(8), YES_AUTO));
|
|
||||||
expected.add(new Entry(day(9), YES_AUTO));
|
|
||||||
expected.add(new Entry(day(10), YES_MANUAL));
|
|
||||||
|
|
||||||
List<Entry> actual =
|
|
||||||
EntryList.buildEntriesFromInterval(entries, intervals);
|
|
||||||
assertThat(actual, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_buildCheckmarksFromIntervals_2() throws Exception
|
|
||||||
{
|
|
||||||
Entry entries[] = new Entry[]{
|
|
||||||
new Entry(day(0), YES_MANUAL),
|
|
||||||
};
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> intervals = new ArrayList<>();
|
|
||||||
intervals.add(new EntryList.Interval(day(0), day(0), day(-10)));
|
|
||||||
|
|
||||||
List<Entry> expected = new ArrayList<>();
|
|
||||||
expected.add(new Entry(day(0), YES_MANUAL));
|
|
||||||
|
|
||||||
List<Entry> actual =
|
|
||||||
EntryList.buildEntriesFromInterval(entries, intervals);
|
|
||||||
assertThat(actual, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_buildIntervals_1() throws Exception
|
|
||||||
{
|
|
||||||
Entry entries[] = new Entry[]{
|
|
||||||
new Entry(day(23), YES_MANUAL),
|
|
||||||
new Entry(day(18), YES_MANUAL),
|
|
||||||
new Entry(day(8), YES_MANUAL),
|
|
||||||
};
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> expected = new ArrayList<>();
|
|
||||||
expected.add(new EntryList.Interval(day(23), day(23), day(17)));
|
|
||||||
expected.add(new EntryList.Interval(day(18), day(18), day(12)));
|
|
||||||
expected.add(new EntryList.Interval(day(8), day(8), day(2)));
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> actual;
|
|
||||||
actual = EntryList.buildIntervals(Frequency.WEEKLY, entries);
|
|
||||||
assertThat(actual, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_buildIntervals_2() throws Exception
|
|
||||||
{
|
|
||||||
Entry entries[] = new Entry[]{
|
|
||||||
new Entry(day(23), YES_MANUAL),
|
|
||||||
new Entry(day(18), YES_MANUAL),
|
|
||||||
new Entry(day(8), YES_MANUAL),
|
|
||||||
};
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> expected = new ArrayList<>();
|
|
||||||
expected.add(new EntryList.Interval(day(23), day(23), day(23)));
|
|
||||||
expected.add(new EntryList.Interval(day(18), day(18), day(18)));
|
|
||||||
expected.add(new EntryList.Interval(day(8), day(8), day(8)));
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> actual;
|
|
||||||
actual = EntryList.buildIntervals(Frequency.DAILY, entries);
|
|
||||||
assertThat(actual, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_buildIntervals_3() throws Exception
|
|
||||||
{
|
|
||||||
Entry entries[] = new Entry[]{
|
|
||||||
new Entry(day(23), YES_MANUAL),
|
|
||||||
new Entry(day(22), YES_MANUAL),
|
|
||||||
new Entry(day(18), YES_MANUAL),
|
|
||||||
new Entry(day(15), YES_MANUAL),
|
|
||||||
new Entry(day(8), YES_MANUAL),
|
|
||||||
};
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> expected = new ArrayList<>();
|
|
||||||
expected.add(new EntryList.Interval(day(23), day(22), day(17)));
|
|
||||||
expected.add(new EntryList.Interval(day(22), day(18), day(16)));
|
|
||||||
expected.add(new EntryList.Interval(day(18), day(15), day(12)));
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> actual;
|
|
||||||
actual =
|
|
||||||
EntryList.buildIntervals(Frequency.TWO_TIMES_PER_WEEK, entries);
|
|
||||||
assertThat(actual, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_buildIntervals_4() throws Exception
|
|
||||||
{
|
|
||||||
Entry[] entries = new Entry[]{
|
|
||||||
new Entry(day(30), YES_MANUAL),
|
|
||||||
new Entry(day(20), SKIP),
|
|
||||||
new Entry(day(10), YES_MANUAL),
|
|
||||||
};
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> expected = new ArrayList<>();
|
|
||||||
expected.add(new EntryList.Interval(day(30), day(30), day(28)));
|
|
||||||
expected.add(new EntryList.Interval(day(10), day(10), day(8)));
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> actual;
|
|
||||||
actual = EntryList.buildIntervals(new Frequency(1, 3), entries);
|
|
||||||
assertThat(actual, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getAllValues_moveBackwardsInTime()
|
|
||||||
{
|
|
||||||
travelInTime(-3);
|
|
||||||
|
|
||||||
int[] expectedValues = {
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL
|
|
||||||
};
|
|
||||||
|
|
||||||
int[] actualValues = nonDailyHabit.getComputedEntries().getAllValues();
|
|
||||||
|
|
||||||
assertThat(actualValues, equalTo(expectedValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getAllValues_moveForwardInTime()
|
|
||||||
{
|
|
||||||
travelInTime(3);
|
|
||||||
|
|
||||||
int[] expectedValues = {
|
|
||||||
UNKNOWN,
|
|
||||||
UNKNOWN,
|
|
||||||
UNKNOWN,
|
|
||||||
YES_MANUAL,
|
|
||||||
NO,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL
|
|
||||||
};
|
|
||||||
|
|
||||||
int[] actualValues = nonDailyHabit.getComputedEntries().getAllValues();
|
|
||||||
|
|
||||||
assertThat(actualValues, equalTo(expectedValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getAllValues_withEmptyHabit()
|
|
||||||
{
|
|
||||||
int[] expectedValues = new int[0];
|
|
||||||
int[] actualValues = emptyHabit.getComputedEntries().getAllValues();
|
|
||||||
|
|
||||||
assertThat(actualValues, equalTo(expectedValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getAllValues_withNonDailyHabit()
|
|
||||||
{
|
|
||||||
int[] expectedValues = {
|
|
||||||
YES_MANUAL,
|
|
||||||
NO,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL
|
|
||||||
};
|
|
||||||
|
|
||||||
int[] actualValues = nonDailyHabit.getComputedEntries().getAllValues();
|
|
||||||
|
|
||||||
assertThat(actualValues, equalTo(expectedValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getByInterval_withNumericalHabits() throws Exception
|
|
||||||
{
|
|
||||||
EntryList entries = numericalHabit.getComputedEntries();
|
|
||||||
|
|
||||||
List<Entry> expected =
|
|
||||||
Arrays.asList(new Entry(day(1), 200), new Entry(day(2), 0),
|
|
||||||
new Entry(day(3), 300), new Entry(day(4), 0),
|
|
||||||
new Entry(day(5), 400));
|
|
||||||
|
|
||||||
List<Entry> actual = entries.getByInterval(day(5), day(1));
|
|
||||||
assertThat(actual, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getTodayValue()
|
|
||||||
{
|
|
||||||
EntryList entries = nonDailyHabit.getComputedEntries();
|
|
||||||
|
|
||||||
travelInTime(-1);
|
|
||||||
assertThat(entries.getTodayValue(), equalTo(NO));
|
|
||||||
|
|
||||||
travelInTime(0);
|
|
||||||
assertThat(entries.getTodayValue(), equalTo(YES_MANUAL));
|
|
||||||
|
|
||||||
travelInTime(1);
|
|
||||||
assertThat(entries.getTodayValue(), equalTo(UNKNOWN));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getValues_withInvalidInterval()
|
|
||||||
{
|
|
||||||
int values[] = nonDailyHabit
|
|
||||||
.getComputedEntries()
|
|
||||||
.getValues(new Timestamp(0L).plus(100), new Timestamp(0L));
|
|
||||||
assertThat(values, equalTo(new int[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getValues_withValidInterval()
|
|
||||||
{
|
|
||||||
Timestamp from = today.minus(15);
|
|
||||||
Timestamp to = today.minus(5);
|
|
||||||
|
|
||||||
int[] expectedValues = {
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_AUTO,
|
|
||||||
YES_MANUAL,
|
|
||||||
YES_MANUAL,
|
|
||||||
UNKNOWN,
|
|
||||||
UNKNOWN,
|
|
||||||
UNKNOWN,
|
|
||||||
UNKNOWN,
|
|
||||||
UNKNOWN,
|
|
||||||
UNKNOWN
|
|
||||||
};
|
|
||||||
|
|
||||||
int[] actualValues = nonDailyHabit.getComputedEntries().getValues(from, to);
|
|
||||||
assertThat(actualValues, equalTo(expectedValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_snapIntervalsTogether_1() throws Exception
|
|
||||||
{
|
|
||||||
ArrayList<EntryList.Interval> original = new ArrayList<>();
|
|
||||||
original.add(new EntryList.Interval(day(27), day(27), day(21)));
|
|
||||||
original.add(new EntryList.Interval(day(20), day(20), day(14)));
|
|
||||||
original.add(new EntryList.Interval(day(12), day(12), day(6)));
|
|
||||||
original.add(new EntryList.Interval(day(8), day(8), day(2)));
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> expected = new ArrayList<>();
|
|
||||||
expected.add(new EntryList.Interval(day(29), day(27), day(23)));
|
|
||||||
expected.add(new EntryList.Interval(day(22), day(20), day(16)));
|
|
||||||
expected.add(new EntryList.Interval(day(15), day(12), day(9)));
|
|
||||||
expected.add(new EntryList.Interval(day(8), day(8), day(2)));
|
|
||||||
|
|
||||||
EntryList.snapIntervalsTogether(original);
|
|
||||||
assertThat(original, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_snapIntervalsTogether_2() throws Exception
|
|
||||||
{
|
|
||||||
ArrayList<EntryList.Interval> original = new ArrayList<>();
|
|
||||||
original.add(new EntryList.Interval(day(11), day(8), day(5)));
|
|
||||||
original.add(new EntryList.Interval(day(6), day(4), day(0)));
|
|
||||||
|
|
||||||
ArrayList<EntryList.Interval> expected = new ArrayList<>();
|
|
||||||
expected.add(new EntryList.Interval(day(13), day(8), day(7)));
|
|
||||||
expected.add(new EntryList.Interval(day(6), day(4), day(0)));
|
|
||||||
|
|
||||||
EntryList.snapIntervalsTogether(original);
|
|
||||||
assertThat(original, equalTo(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_writeCSV() throws IOException
|
|
||||||
{
|
|
||||||
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";
|
|
||||||
|
|
||||||
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
nonDailyHabit.getComputedEntries().writeCSV(writer);
|
|
||||||
|
|
||||||
assertThat(writer.toString(), equalTo(expectedCSV));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Timestamp day(int offset)
|
|
||||||
{
|
|
||||||
return DateUtils.getToday().minus(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void travelInTime(int days)
|
|
||||||
{
|
|
||||||
DateUtils.setFixedLocalTime(
|
|
||||||
FIXED_LOCAL_TIME + days * Timestamp.DAY_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEquals() throws Exception
|
|
||||||
{
|
|
||||||
EqualsVerifier.forClass(Entry.class).verify();
|
|
||||||
EqualsVerifier.forClass(Timestamp.class).verify();
|
|
||||||
EqualsVerifier.forClass(EntryList.Interval.class).verify();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGroupBy() throws Exception
|
|
||||||
{
|
|
||||||
Habit habit = fixtures.createLongNumericalHabit(timestamp(2014, JUNE, 1));
|
|
||||||
EntryList entries = habit.getComputedEntries();
|
|
||||||
|
|
||||||
List<Entry> byMonth = entries.groupBy(MONTH, Calendar.SATURDAY);
|
|
||||||
assertThat(byMonth.size(), equalTo(25)); // from 2013-01-01 to 2015-01-01
|
|
||||||
assertThat(byMonth.get(0), equalTo(new Entry(timestamp(2015, JANUARY, 1), 0)));
|
|
||||||
assertThat(byMonth.get(6), equalTo(new Entry(timestamp(2014, JULY, 1), 0)));
|
|
||||||
assertThat(byMonth.get(12), equalTo(new Entry(timestamp(2014, JANUARY, 1), 1706)));
|
|
||||||
assertThat(byMonth.get(18), equalTo(new Entry(timestamp(2013, JULY, 1), 1379)));
|
|
||||||
|
|
||||||
List<Entry> byQuarter = entries.groupBy(QUARTER, Calendar.SATURDAY);
|
|
||||||
assertThat(byQuarter.size(), equalTo(9)); // from 2013-Q1 to 2015-Q1
|
|
||||||
assertThat(byQuarter.get(0), equalTo(new Entry(timestamp(2015, JANUARY, 1), 0)));
|
|
||||||
assertThat(byQuarter.get(4), equalTo(new Entry(timestamp(2014, JANUARY, 1), 4964)));
|
|
||||||
assertThat(byQuarter.get(8), equalTo(new Entry(timestamp(2013, JANUARY, 1), 4975)));
|
|
||||||
|
|
||||||
List<Entry> byYear = entries.groupBy(YEAR, Calendar.SATURDAY);
|
|
||||||
assertThat(byYear.size(), equalTo(3)); // from 2013 to 2015
|
|
||||||
assertThat(byYear.get(0), equalTo(new Entry(timestamp(2015, JANUARY, 1), 0)));
|
|
||||||
assertThat(byYear.get(1), equalTo(new Entry(timestamp(2014, JANUARY, 1), 8227)));
|
|
||||||
assertThat(byYear.get(2), equalTo(new Entry(timestamp(2013, JANUARY, 1), 16172)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetTodayValue() throws Exception
|
|
||||||
{
|
|
||||||
Habit habit = fixtures.createLongNumericalHabit(timestamp(2014, JUNE, 1));
|
|
||||||
EntryList checkmarks = habit.getComputedEntries();
|
|
||||||
|
|
||||||
DateUtils.setFixedLocalTime(unixTime(2050, MAY, 1));
|
|
||||||
assertThat(checkmarks.getTodayValue(), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(SATURDAY), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisMonthValue(), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisQuarterValue(), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisYearValue(), equalTo(0));
|
|
||||||
|
|
||||||
DateUtils.setFixedLocalTime(unixTime(2014, JUNE, 6));
|
|
||||||
assertThat(checkmarks.getTodayValue(), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(SATURDAY), equalTo(230));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(SUNDAY), equalTo(230));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(MONDAY), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisMonthValue(), equalTo(230));
|
|
||||||
assertThat(checkmarks.getThisQuarterValue(), equalTo(3263));
|
|
||||||
assertThat(checkmarks.getThisYearValue(), equalTo(8227));
|
|
||||||
|
|
||||||
DateUtils.setFixedLocalTime(unixTime(2014, JUNE, 1));
|
|
||||||
assertThat(checkmarks.getTodayValue(), equalTo(230));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(SATURDAY), equalTo(230));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(SUNDAY), equalTo(230));
|
|
||||||
assertThat(checkmarks.getThisMonthValue(), equalTo(230));
|
|
||||||
|
|
||||||
DateUtils.setFixedLocalTime(unixTime(2014, MAY, 16));
|
|
||||||
assertThat(checkmarks.getTodayValue(), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(SATURDAY), equalTo(419));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(THURSDAY), equalTo(134));
|
|
||||||
assertThat(checkmarks.getThisMonthValue(), equalTo(1006));
|
|
||||||
|
|
||||||
DateUtils.setFixedLocalTime(unixTime(2000, MAY, 1));
|
|
||||||
assertThat(checkmarks.getTodayValue(), equalTo(UNKNOWN));
|
|
||||||
assertThat(checkmarks.getThisWeekValue(SATURDAY), equalTo(0));
|
|
||||||
assertThat(checkmarks.getThisMonthValue(), equalTo(0));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 Á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.core.models;
|
|
||||||
|
|
||||||
import androidx.annotation.*;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.core.*;
|
|
||||||
import org.isoron.uhabits.core.utils.*;
|
|
||||||
import org.junit.*;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static java.util.Calendar.*;
|
|
||||||
import static org.hamcrest.MatcherAssert.*;
|
|
||||||
import static org.hamcrest.core.IsEqual.*;
|
|
||||||
import static org.isoron.uhabits.core.models.Entry.*;
|
|
||||||
|
|
||||||
public class RepetitionListTest extends BaseUnitTest
|
|
||||||
{
|
|
||||||
@NonNull
|
|
||||||
private RepetitionList reps;
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private Habit habit;
|
|
||||||
|
|
||||||
private Timestamp today;
|
|
||||||
|
|
||||||
private long day;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception
|
|
||||||
{
|
|
||||||
super.setUp();
|
|
||||||
habit = fixtures.createEmptyHabit();
|
|
||||||
reps = habit.getOriginalEntries();
|
|
||||||
|
|
||||||
today = DateUtils.getToday();
|
|
||||||
|
|
||||||
reps.setValue(today.minus(3), YES_MANUAL);
|
|
||||||
reps.setValue(today.minus(2), YES_MANUAL);
|
|
||||||
reps.setValue(today, YES_MANUAL);
|
|
||||||
reps.setValue(today.minus(7), YES_MANUAL);
|
|
||||||
reps.setValue(today.minus(5), YES_MANUAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception
|
|
||||||
{
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getOldest()
|
|
||||||
{
|
|
||||||
Entry check = reps.getOldest();
|
|
||||||
assertThat(check.getTimestamp(), equalTo(today.minus(7)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_getWeekDayFrequency()
|
|
||||||
{
|
|
||||||
habit = fixtures.createEmptyHabit();
|
|
||||||
reps = habit.getOriginalEntries();
|
|
||||||
|
|
||||||
Random random = new Random(123L);
|
|
||||||
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 = DateUtils.getStartOfTodayCalendar();
|
|
||||||
|
|
||||||
// Sets the current date to the end of November
|
|
||||||
day.set(2015, NOVEMBER, 30, 12, 0, 0);
|
|
||||||
DateUtils.setFixedLocalTime(day.getTimeInMillis());
|
|
||||||
|
|
||||||
// Add repetitions randomly from January to December
|
|
||||||
day.set(2015, JANUARY, 1, 0, 0, 0);
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Leave the month of March empty, to check that it returns null
|
|
||||||
if (month == MARCH) continue;
|
|
||||||
|
|
||||||
reps.setValue(new Timestamp(day), YES_MANUAL);
|
|
||||||
|
|
||||||
// Repetitions in December should not be counted
|
|
||||||
if (month == DECEMBER) continue;
|
|
||||||
|
|
||||||
weekdayCount[month][week]++;
|
|
||||||
monthCount[month]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
day.add(Calendar.DAY_OF_YEAR, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<Timestamp, Integer[]> freq = reps.getWeekdayFrequency();
|
|
||||||
|
|
||||||
// Repetitions until November should be counted correctly
|
|
||||||
for (int month = 0; month < 11; month++)
|
|
||||||
{
|
|
||||||
day.set(2015, month, 1, 0, 0, 0);
|
|
||||||
Integer actualCount[] = freq.get(new Timestamp(day));
|
|
||||||
if (monthCount[month] == 0) assertThat(actualCount, equalTo(null));
|
|
||||||
else assertThat(actualCount, equalTo(weekdayCount[month]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repetitions in December should be discarded
|
|
||||||
day.set(2015, DECEMBER, 1, 0, 0, 0);
|
|
||||||
assertThat(freq.get(new Timestamp(day)), equalTo(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_setValue()
|
|
||||||
{
|
|
||||||
assertThat(reps.getValue(today), equalTo(YES_MANUAL));
|
|
||||||
reps.setValue(today, NO);
|
|
||||||
assertThat(reps.getValue(today), equalTo(NO));
|
|
||||||
|
|
||||||
habit.setType(Habit.NUMBER_HABIT);
|
|
||||||
reps.setValue(today, 100);
|
|
||||||
assertThat(reps.getValue(today), equalTo(100));
|
|
||||||
|
|
||||||
reps.setValue(today, 500);
|
|
||||||
assertThat(reps.getValue(today), equalTo(500));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 Á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.core.models.sqlite;
|
|
||||||
|
|
||||||
import androidx.annotation.*;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.core.*;
|
|
||||||
import org.isoron.uhabits.core.database.*;
|
|
||||||
import org.isoron.uhabits.core.models.*;
|
|
||||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
|
||||||
import org.isoron.uhabits.core.test.*;
|
|
||||||
import org.isoron.uhabits.core.utils.*;
|
|
||||||
import org.junit.*;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static junit.framework.TestCase.*;
|
|
||||||
import static org.hamcrest.MatcherAssert.*;
|
|
||||||
import static org.hamcrest.core.IsEqual.*;
|
|
||||||
import static org.isoron.uhabits.core.models.Entry.*;
|
|
||||||
|
|
||||||
public class SQLiteRepetitionListTest extends BaseUnitTest
|
|
||||||
{
|
|
||||||
private Habit habit;
|
|
||||||
|
|
||||||
private Timestamp today;
|
|
||||||
|
|
||||||
private RepetitionList originalCheckmarks;
|
|
||||||
|
|
||||||
private long day;
|
|
||||||
|
|
||||||
private Repository<EntryRecord> repository;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception
|
|
||||||
{
|
|
||||||
super.setUp();
|
|
||||||
|
|
||||||
Database db = buildMemoryDatabase();
|
|
||||||
modelFactory = new SQLModelFactory(db);
|
|
||||||
habitList = modelFactory.buildHabitList();
|
|
||||||
fixtures = new HabitFixtures(modelFactory, habitList);
|
|
||||||
repository = new Repository<>(EntryRecord.class, db);
|
|
||||||
habit = fixtures.createLongHabit();
|
|
||||||
|
|
||||||
originalCheckmarks = habit.getOriginalEntries();
|
|
||||||
today = DateUtils.getToday();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAdd()
|
|
||||||
{
|
|
||||||
EntryRecord record = getByTimestamp(today.plus(1));
|
|
||||||
assertNull(record);
|
|
||||||
|
|
||||||
Entry rep = new Entry(today.plus(1), YES_MANUAL);
|
|
||||||
habit.getOriginalEntries().add(rep);
|
|
||||||
|
|
||||||
record = getByTimestamp(today.plus(1));
|
|
||||||
assertNotNull(record);
|
|
||||||
assertThat(record.value, equalTo(YES_MANUAL));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetByInterval()
|
|
||||||
{
|
|
||||||
List<Entry> checks =
|
|
||||||
originalCheckmarks.getByInterval(today.minus(10), today);
|
|
||||||
|
|
||||||
assertThat(checks.size(), equalTo(8));
|
|
||||||
assertThat(checks.get(0).getTimestamp(), equalTo(today.minus(10)));
|
|
||||||
assertThat(checks.get(4).getTimestamp(), equalTo(today.minus(5)));
|
|
||||||
assertThat(checks.get(5).getTimestamp(), equalTo(today.minus(3)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetByTimestamp()
|
|
||||||
{
|
|
||||||
Entry rep = originalCheckmarks.getByTimestamp(today);
|
|
||||||
assertNotNull(rep);
|
|
||||||
assertThat(rep.getTimestamp(), equalTo(today));
|
|
||||||
|
|
||||||
rep = originalCheckmarks.getByTimestamp(today.minus(2));
|
|
||||||
assertNull(rep);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetOldest()
|
|
||||||
{
|
|
||||||
Entry rep = originalCheckmarks.getOldest();
|
|
||||||
assertNotNull(rep);
|
|
||||||
assertThat(rep.getTimestamp(), equalTo(today.minus(120)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetOldest_withEmptyHabit()
|
|
||||||
{
|
|
||||||
Habit empty = fixtures.createEmptyHabit();
|
|
||||||
Entry rep = empty.getOriginalEntries().getOldest();
|
|
||||||
assertNull(rep);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemove()
|
|
||||||
{
|
|
||||||
EntryRecord record = getByTimestamp(today);
|
|
||||||
assertNotNull(record);
|
|
||||||
|
|
||||||
Entry rep = record.toEntry();
|
|
||||||
originalCheckmarks.remove(rep);
|
|
||||||
|
|
||||||
record = getByTimestamp(today);
|
|
||||||
assertNull(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private EntryRecord getByTimestamp(Timestamp timestamp)
|
|
||||||
{
|
|
||||||
String query = "where habit = ? and timestamp = ?";
|
|
||||||
String params[] = {
|
|
||||||
Long.toString(habit.getId()), Long.toString(timestamp.getUnixTime())
|
|
||||||
};
|
|
||||||
|
|
||||||
return repository.findFirst(query, params);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue