Reorganize tests

This commit is contained in:
2017-05-25 15:59:03 -04:00
parent cb4ab3b436
commit 29d1de46e7
50 changed files with 324 additions and 335 deletions

View File

@@ -1,37 +1,24 @@
/*
* 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/>.
*/
apply plugin: 'java'
dependencies {
compileOnly 'javax.annotation:jsr250-api:1.0'
compileOnly 'com.google.auto.factory:auto-factory:1.0-beta3'
implementation 'com.google.dagger:dagger:2.11-rc2'
implementation 'com.android.support:support-annotations:25.3.1'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation 'org.apache.commons:commons-lang3:3.5'
implementation 'com.google.code.gson:gson:2.7'
testImplementation 'junit:junit:4+'
testImplementation 'org.hamcrest:hamcrest-library:1.4-atlassian-1'
testImplementation 'org.mockito:mockito-core:2.8.9'
testImplementation 'org.json:json:20160810'
implementation ('com.opencsv:opencsv:3.9') {
exclude group: 'commons-logging', module: 'commons-logging'
}
compile 'junit:junit:4.12'
}
sourceCompatibility = "1.8"

View File

@@ -19,20 +19,8 @@
package org.isoron.uhabits.tasks;
import org.isoron.uhabits.*;
import dagger.*;
@Module
public class SingleThreadTaskRunner implements TaskRunner
{
@Provides
@AppScope
public static TaskRunner provideTaskRunner()
{
return new SingleThreadTaskRunner();
}
@Override
public void addListener(Listener listener)
{

View File

@@ -0,0 +1,77 @@
/*
* 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.utils;
import org.isoron.uhabits.*;
import java.util.*;
import java.util.concurrent.*;
import javax.inject.*;
/**
* A class that emits events when a new day starts.
*/
@AppScope
public class MidnightTimer
{
private final List<MidnightListener> listeners;
private ScheduledExecutorService executor;
@Inject
public MidnightTimer()
{
this.listeners = new LinkedList<>();
}
public synchronized void addListener(MidnightListener listener)
{
this.listeners.add(listener);
}
public synchronized void onPause()
{
executor.shutdownNow();
}
public synchronized void onResume()
{
executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> notifyListeners(),
DateUtils.millisecondsUntilTomorrow() + 1000,
DateUtils.millisecondsInOneDay, TimeUnit.MILLISECONDS);
}
public synchronized void removeListener(MidnightListener listener)
{
this.listeners.remove(listener);
}
private synchronized void notifyListeners()
{
for (MidnightListener l : listeners) l.atMidnight();
}
public interface MidnightListener
{
void atMidnight();
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.models.memory.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import java.util.*;
public class BaseUnitTest
{
protected HabitList habitList;
protected HabitFixtures fixtures;
protected MemoryModelFactory modelFactory;
@Before
public void setUp()
{
// 8:00am, January 25th, 2015 (UTC)
long fixed_local_time = 1422172800000L;
DateUtils.setFixedLocalTime(fixed_local_time);
modelFactory = new MemoryModelFactory();
habitList = modelFactory.buildHabitList();
fixtures = new HabitFixtures(modelFactory);
}
@After
public void tearDown()
{
DateUtils.setFixedLocalTime(null);
}
public long timestamp(int year, int month, int day)
{
GregorianCalendar cal = DateUtils.getStartOfTodayCalendar();
cal.set(year, month, day);
return cal.getTimeInMillis();
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
import java.util.*;
import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
public class ArchiveHabitsCommandTest extends BaseUnitTest
{
private ArchiveHabitsCommand command;
private Habit habit;
@Override
@Before
public void setUp()
{
super.setUp();
habit = fixtures.createShortHabit();
habitList.add(habit);
command = new ArchiveHabitsCommand(habitList,
Collections.singletonList(habit));
}
@Test
public void testExecuteUndoRedo()
{
assertFalse(habit.isArchived());
command.execute();
assertTrue(habit.isArchived());
command.undo();
assertFalse(habit.isArchived());
command.execute();
assertTrue(habit.isArchived());
}
@Test
public void testRecord()
{
ArchiveHabitsCommand.Record rec = command.toRecord();
ArchiveHabitsCommand other = rec.toCommand(habitList);
assertThat(other.selected, equalTo(command.selected));
assertThat(other.getId(), equalTo(command.getId()));
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
import java.util.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
public class ChangeHabitColorCommandTest extends BaseUnitTest
{
private ChangeHabitColorCommand command;
private LinkedList<Habit> selected;
@Override
@Before
public void setUp()
{
super.setUp();
selected = new LinkedList<>();
for (int i = 0; i < 3; i++)
{
Habit habit = fixtures.createShortHabit();
habit.setColor(i + 1);
selected.add(habit);
habitList.add(habit);
}
command = new ChangeHabitColorCommand(habitList, selected, 0);
}
@Test
public void testExecuteUndoRedo()
{
checkOriginalColors();
command.execute();
checkNewColors();
command.undo();
checkOriginalColors();
command.execute();
checkNewColors();
}
@Test
public void testRecord()
{
ChangeHabitColorCommand.Record rec = command.toRecord();
ChangeHabitColorCommand other = rec.toCommand(habitList);
assertThat(other.getId(), equalTo(command.getId()));
assertThat(other.newColor, equalTo(command.newColor));
assertThat(other.selected, equalTo(command.selected));
}
private void checkNewColors()
{
for (Habit h : selected)
assertThat(h.getColor(), equalTo(0));
}
private void checkOriginalColors()
{
int k = 0;
for (Habit h : selected)
assertThat(h.getColor(), equalTo(++k));
}
}

View File

@@ -0,0 +1,86 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
import static junit.framework.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
public class CreateHabitCommandTest extends BaseUnitTest
{
private CreateHabitCommand command;
private Habit model;
@Override
@Before
public void setUp()
{
super.setUp();
model = fixtures.createEmptyHabit();
model.setName("New habit");
model.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
command = new CreateHabitCommand(modelFactory, habitList, model);
}
@Test
public void testExecuteUndoRedo()
{
assertTrue(habitList.isEmpty());
command.execute();
assertThat(habitList.size(), equalTo(1));
Habit habit = habitList.getByPosition(0);
Long id = habit.getId();
assertThat(habit.getName(), equalTo(model.getName()));
command.undo();
assertTrue(habitList.isEmpty());
command.execute();
assertThat(habitList.size(), equalTo(1));
habit = habitList.getByPosition(0);
Long newId = habit.getId();
assertThat(id, equalTo(newId));
assertThat(habit.getName(), equalTo(model.getName()));
}
@Test
public void testRecord()
{
command.execute();
CreateHabitCommand.Record rec = command.toRecord();
CreateHabitCommand other = rec.toCommand(modelFactory, habitList);
assertThat(other.getId(), equalTo(command.getId()));
assertThat(other.savedId, equalTo(command.savedId));
assertThat(other.model.getData(), equalTo(command.model.getData()));
}
}

View File

@@ -0,0 +1,84 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.isoron.uhabits.models.Checkmark.CHECKED_EXPLICITLY;
public class CreateRepetitionCommandTest extends BaseUnitTest
{
private CreateRepetitionCommand command;
private Habit habit;
private long today;
@Override
@Before
public void setUp()
{
super.setUp();
habit = fixtures.createShortHabit();
habitList.add(habit);
today = DateUtils.getStartOfToday();
command = new CreateRepetitionCommand(habit, today, 100);
}
@Test
public void testExecuteUndoRedo()
{
RepetitionList reps = habit.getRepetitions();
Repetition rep = reps.getByTimestamp(today);
assertNotNull(rep);
assertEquals(CHECKED_EXPLICITLY, rep.getValue());
command.execute();
rep = reps.getByTimestamp(today);
assertNotNull(rep);
assertEquals(100, rep.getValue());
command.undo();
rep = reps.getByTimestamp(today);
assertNotNull(rep);
assertEquals(CHECKED_EXPLICITLY, rep.getValue());
}
@Test
public void testRecord()
{
CreateRepetitionCommand.Record rec = command.toRecord();
CreateRepetitionCommand other = rec.toCommand(habitList);
assertThat(command.getId(), equalTo(other.getId()));
assertThat(command.timestamp, equalTo(other.timestamp));
assertThat(command.value, equalTo(other.value));
assertThat(command.habit, equalTo(other.habit));
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
import org.junit.rules.*;
import java.util.*;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
public class DeleteHabitsCommandTest extends BaseUnitTest
{
private DeleteHabitsCommand command;
private LinkedList<Habit> selected;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Override
@Before
public void setUp()
{
super.setUp();
selected = new LinkedList<>();
// Habits that should be deleted
for (int i = 0; i < 3; i++)
{
Habit habit = fixtures.createShortHabit();
habitList.add(habit);
selected.add(habit);
}
// Extra habit that should not be deleted
Habit extraHabit = fixtures.createShortHabit();
extraHabit.setName("extra");
habitList.add(extraHabit);
command = new DeleteHabitsCommand(habitList, selected);
}
@Test
public void testExecuteUndoRedo()
{
assertThat(habitList.size(), equalTo(4));
command.execute();
assertThat(habitList.size(), equalTo(1));
assertThat(habitList.getByPosition(0).getName(), equalTo("extra"));
thrown.expect(UnsupportedOperationException.class);
command.undo();
}
@Test
public void testRecord()
{
DeleteHabitsCommand.Record rec = command.toRecord();
DeleteHabitsCommand other = rec.toCommand(habitList);
assertThat(other.getId(), equalTo(command.getId()));
assertThat(other.selected, equalTo(command.selected));
}
}

View File

@@ -0,0 +1,115 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
public class EditHabitCommandTest extends BaseUnitTest
{
private EditHabitCommand command;
private Habit habit;
private Habit modified;
@Override
@Before
public void setUp()
{
super.setUp();
habit = fixtures.createShortHabit();
habit.setName("original");
habit.setFrequency(Frequency.DAILY);
habitList.add(habit);
modified = fixtures.createEmptyHabit();
modified.copyFrom(habit);
modified.setName("modified");
habitList.add(modified);
}
@Test
public void testExecuteUndoRedo()
{
command =
new EditHabitCommand(modelFactory, habitList, habit, modified);
double originalScore = habit.getScores().getTodayValue();
assertThat(habit.getName(), equalTo("original"));
command.execute();
assertThat(habit.getName(), equalTo("modified"));
assertThat(habit.getScores().getTodayValue(), equalTo(originalScore));
command.undo();
assertThat(habit.getName(), equalTo("original"));
assertThat(habit.getScores().getTodayValue(), equalTo(originalScore));
command.execute();
assertThat(habit.getName(), equalTo("modified"));
assertThat(habit.getScores().getTodayValue(), equalTo(originalScore));
}
@Test
public void testExecuteUndoRedo_withModifiedInterval()
{
modified.setFrequency(Frequency.TWO_TIMES_PER_WEEK);
command =
new EditHabitCommand(modelFactory, habitList, habit, modified);
double originalScore = habit.getScores().getTodayValue();
assertThat(habit.getName(), equalTo("original"));
command.execute();
assertThat(habit.getName(), equalTo("modified"));
assertThat(habit.getScores().getTodayValue(),
lessThan(originalScore));
command.undo();
assertThat(habit.getName(), equalTo("original"));
assertThat(habit.getScores().getTodayValue(), equalTo(originalScore));
command.execute();
assertThat(habit.getName(), equalTo("modified"));
assertThat(habit.getScores().getTodayValue(),
lessThan(originalScore));
}
@Test
public void testRecord()
{
command =
new EditHabitCommand(modelFactory, habitList, habit, modified);
EditHabitCommand.Record rec = command.toRecord();
EditHabitCommand other = rec.toCommand(modelFactory, habitList);
assertThat(other.getId(), equalTo(command.getId()));
assertThat(other.savedId, equalTo(command.savedId));
assertThat(other.original.getData(), equalTo(command.original.getData()));
assertThat(other.modified.getData(), equalTo(command.modified.getData()));
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
public class ToggleRepetitionCommandTest extends BaseUnitTest
{
private ToggleRepetitionCommand command;
private Habit habit;
private long today;
@Override
@Before
public void setUp()
{
super.setUp();
habit = fixtures.createShortHabit();
habitList.add(habit);
today = DateUtils.getStartOfToday();
command = new ToggleRepetitionCommand(habit, today);
}
@Test
public void testExecuteUndoRedo()
{
assertTrue(habit.getRepetitions().containsTimestamp(today));
command.execute();
assertFalse(habit.getRepetitions().containsTimestamp(today));
command.undo();
assertTrue(habit.getRepetitions().containsTimestamp(today));
command.execute();
assertFalse(habit.getRepetitions().containsTimestamp(today));
}
@Test
public void testRecord()
{
ToggleRepetitionCommand.Record rec = command.toRecord();
ToggleRepetitionCommand other = rec.toCommand(habitList);
assertThat(command.getId(), equalTo(other.getId()));
assertThat(command.timestamp, equalTo(other.timestamp));
assertThat(command.habit, equalTo(other.habit));
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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.commands;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
import java.util.*;
import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
public class UnarchiveHabitsCommandTest extends BaseUnitTest
{
private UnarchiveHabitsCommand command;
private Habit habit;
@Override
@Before
public void setUp()
{
super.setUp();
habit = fixtures.createShortHabit();
habit.setArchived(true);
habitList.add(habit);
command = new UnarchiveHabitsCommand(habitList, Collections
.singletonList
(habit));
}
@Test
public void testExecuteUndoRedo()
{
assertTrue(habit.isArchived());
command.execute();
assertFalse(habit.isArchived());
command.undo();
assertTrue(habit.isArchived());
command.execute();
assertFalse(habit.isArchived());
}
@Test
public void testRecord()
{
UnarchiveHabitsCommand.Record rec = command.toRecord();
UnarchiveHabitsCommand other = rec.toCommand(habitList);
assertThat(other.selected, equalTo(command.selected));
assertThat(other.getId(), equalTo(command.getId()));
}
}

View File

@@ -0,0 +1,209 @@
/*
* 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.models;
import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import java.io.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.IsEqual.*;
import static org.isoron.uhabits.models.Checkmark.*;
public class CheckmarkListTest extends BaseUnitTest
{
// 8:00am, January 25th, 2015 (UTC)
private long fixed_local_time = 1422172800000L;
private Habit nonDailyHabit;
private Habit emptyHabit;
@Override
public void setUp()
{
super.setUp();
DateUtils.setFixedLocalTime(fixed_local_time);
fixtures.createShortHabit();
nonDailyHabit = fixtures.createShortHabit();
habitList.add(nonDailyHabit);
emptyHabit = fixtures.createEmptyHabit();
habitList.add(emptyHabit);
}
@Test
public void test_getAllValues_moveBackwardsInTime()
{
travelInTime(-3);
int[] expectedValues = {
CHECKED_EXPLICITLY,
CHECKED_EXPLICITLY,
CHECKED_EXPLICITLY,
UNCHECKED,
CHECKED_IMPLICITLY,
CHECKED_EXPLICITLY,
CHECKED_EXPLICITLY
};
int[] actualValues = nonDailyHabit.getCheckmarks().getAllValues();
assertThat(actualValues, equalTo(expectedValues));
}
@Test
public void test_getAllValues_moveForwardInTime()
{
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.getCheckmarks().getAllValues();
assertThat(actualValues, equalTo(expectedValues));
}
@Test
public void test_getAllValues_withEmptyHabit()
{
int[] expectedValues = new int[0];
int[] actualValues = emptyHabit.getCheckmarks().getAllValues();
assertThat(actualValues, equalTo(expectedValues));
}
@Test
public void test_getAllValues_withNonDailyHabit()
{
int[] expectedValues = {
CHECKED_EXPLICITLY,
UNCHECKED,
CHECKED_IMPLICITLY,
CHECKED_EXPLICITLY,
CHECKED_EXPLICITLY,
CHECKED_EXPLICITLY,
UNCHECKED,
CHECKED_IMPLICITLY,
CHECKED_EXPLICITLY,
CHECKED_EXPLICITLY
};
int[] actualValues = nonDailyHabit.getCheckmarks().getAllValues();
assertThat(actualValues, equalTo(expectedValues));
}
@Test
public void test_getTodayValue()
{
travelInTime(-1);
assertThat(nonDailyHabit.getCheckmarks().getTodayValue(),
equalTo(UNCHECKED));
travelInTime(0);
assertThat(nonDailyHabit.getCheckmarks().getTodayValue(),
equalTo(CHECKED_EXPLICITLY));
travelInTime(1);
assertThat(nonDailyHabit.getCheckmarks().getTodayValue(),
equalTo(UNCHECKED));
}
@Test
public void test_getValues_withInvalidInterval()
{
int values[] = nonDailyHabit.getCheckmarks().getValues(100L, -100L);
assertThat(values, equalTo(new int[0]));
}
@Test
public void test_getValues_withValidInterval()
{
long from =
DateUtils.getStartOfToday() - 15 * DateUtils.millisecondsInOneDay;
long to =
DateUtils.getStartOfToday() - 5 * DateUtils.millisecondsInOneDay;
int[] expectedValues = {
CHECKED_EXPLICITLY,
UNCHECKED,
CHECKED_IMPLICITLY,
CHECKED_EXPLICITLY,
CHECKED_EXPLICITLY,
UNCHECKED,
UNCHECKED,
UNCHECKED,
UNCHECKED,
UNCHECKED,
UNCHECKED
};
int[] actualValues = nonDailyHabit.getCheckmarks().getValues(from, to);
assertThat(actualValues, equalTo(expectedValues));
}
@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" +
"2015-01-16,2\n";
StringWriter writer = new StringWriter();
nonDailyHabit.getCheckmarks().writeCSV(writer);
assertThat(writer.toString(), equalTo(expectedCSV));
}
private void travelInTime(int days)
{
DateUtils.setFixedLocalTime(
fixed_local_time + days * DateUtils.millisecondsInOneDay);
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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.models;
import org.isoron.uhabits.utils.*;
public class HabitFixtures
{
public boolean NON_DAILY_HABIT_CHECKS[] = {
true, false, false, true, true, true, false, false, true, true
};
private final ModelFactory modelFactory;
public HabitFixtures(ModelFactory modelFactory)
{
this.modelFactory = modelFactory;
}
public Habit createEmptyHabit()
{
Habit habit = modelFactory.buildHabit();
habit.setName("Meditate");
habit.setDescription("Did you meditate this morning?");
habit.setColor(3);
habit.setFrequency(Frequency.DAILY);
return habit;
}
public Habit createLongHabit()
{
Habit habit = createEmptyHabit();
habit.setFrequency(new Frequency(3, 7));
habit.setColor(4);
long day = DateUtils.millisecondsInOneDay;
long today = DateUtils.getStartOfToday();
int marks[] = { 0, 1, 3, 5, 7, 8, 9, 10, 12, 14, 15, 17, 19, 20, 26, 27,
28, 50, 51, 52, 53, 54, 58, 60, 63, 65, 70, 71, 72, 73, 74, 75, 80,
81, 83, 89, 90, 91, 95, 102, 103, 108, 109, 120};
for (int mark : marks)
habit.getRepetitions().toggleTimestamp(today - mark * day);
return habit;
}
public Habit createShortHabit()
{
Habit habit = modelFactory.buildHabit();
habit.setName("Wake up early");
habit.setDescription("Did you wake up before 6am?");
habit.setFrequency(new Frequency(2, 3));
long timestamp = DateUtils.getStartOfToday();
for (boolean c : NON_DAILY_HABIT_CHECKS)
{
if (c) habit.getRepetitions().toggleTimestamp(timestamp);
timestamp -= DateUtils.millisecondsInOneDay;
}
return habit;
}
}

View File

@@ -0,0 +1,229 @@
/*
* 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.models;
import org.hamcrest.*;
import org.isoron.uhabits.*;
import org.junit.*;
import java.io.*;
import java.util.*;
import static org.hamcrest.CoreMatchers.*;
import static org.isoron.uhabits.models.HabitList.Order.*;
import static org.junit.Assert.*;
@SuppressWarnings("JavaDoc")
public class HabitListTest extends BaseUnitTest
{
private ArrayList<Habit> habitsArray;
private HabitList activeHabits;
private HabitList reminderHabits;
@Override
public void setUp()
{
super.setUp();
habitsArray = new ArrayList<>();
for (int i = 0; i < 10; i++)
{
Habit habit = fixtures.createEmptyHabit();
habitList.add(habit);
habitsArray.add(habit);
if (i % 3 == 0)
habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
}
habitsArray.get(0).setArchived(true);
habitsArray.get(1).setArchived(true);
habitsArray.get(4).setArchived(true);
habitsArray.get(7).setArchived(true);
activeHabits = habitList.getFiltered(new HabitMatcherBuilder().build());
reminderHabits = habitList.getFiltered(new HabitMatcherBuilder()
.setArchivedAllowed(true)
.setReminderRequired(true)
.build());
}
@Test
public void test_countActive()
{
assertThat(activeHabits.size(), equalTo(6));
}
@Test
public void test_getByPosition()
{
assertThat(habitList.getByPosition(0), equalTo(habitsArray.get(0)));
assertThat(habitList.getByPosition(3), equalTo(habitsArray.get(3)));
assertThat(habitList.getByPosition(9), equalTo(habitsArray.get(9)));
assertThat(activeHabits.getByPosition(0), equalTo(habitsArray.get(2)));
}
@Test
public void test_getHabitsWithReminder()
{
assertThat(reminderHabits.size(), equalTo(4));
assertThat(reminderHabits.getByPosition(1),
equalTo(habitsArray.get(3)));
}
@Test
public void test_get_withInvalidId()
{
assertThat(habitList.getById(100L), is(nullValue()));
}
@Test
public void test_get_withValidId()
{
Habit habit1 = habitsArray.get(0);
Habit habit2 = habitList.getById(habit1.getId());
assertThat(habit1, equalTo(habit2));
}
@Test
public void test_ordering()
{
HabitList list = modelFactory.buildHabitList();
Habit h1 = fixtures.createEmptyHabit();
h1.setName("A Habit");
h1.setColor(2);
Habit h2 = fixtures.createEmptyHabit();
h2.setName("B Habit");
h2.setColor(2);
Habit h3 = fixtures.createEmptyHabit();
h3.setName("C Habit");
h3.setColor(0);
Habit h4 = fixtures.createEmptyHabit();
h4.setName("D Habit");
h4.setColor(1);
list.add(h3);
list.add(h1);
list.add(h4);
list.add(h2);
list.setOrder(BY_POSITION);
assertThat(list.getByPosition(0), equalTo(h3));
assertThat(list.getByPosition(1), equalTo(h1));
assertThat(list.getByPosition(2), equalTo(h4));
assertThat(list.getByPosition(3), equalTo(h2));
list.setOrder(BY_NAME);
assertThat(list.getByPosition(0), equalTo(h1));
assertThat(list.getByPosition(1), equalTo(h2));
assertThat(list.getByPosition(2), equalTo(h3));
assertThat(list.getByPosition(3), equalTo(h4));
list.remove(h1);
list.add(h1);
assertThat(list.getByPosition(0), equalTo(h1));
list.setOrder(BY_COLOR);
assertThat(list.getByPosition(0), equalTo(h3));
assertThat(list.getByPosition(1), equalTo(h4));
assertThat(list.getByPosition(2), equalTo(h1));
assertThat(list.getByPosition(3), equalTo(h2));
}
@Test
public void test_reorder()
{
int operations[][] = {
{ 5, 2 }, { 3, 7 }, { 4, 4 }, { 3, 2 }
};
int expectedPosition[][] = {
{ 0, 1, 3, 4, 5, 2, 6, 7, 8, 9 },
{ 0, 1, 7, 3, 4, 2, 5, 6, 8, 9 },
{ 0, 1, 7, 3, 4, 2, 5, 6, 8, 9 },
{ 0, 1, 7, 2, 4, 3, 5, 6, 8, 9 },
};
for (int i = 0; i < operations.length; i++)
{
int from = operations[i][0];
int to = operations[i][1];
Habit fromHabit = habitList.getByPosition(from);
Habit toHabit = habitList.getByPosition(to);
habitList.reorder(fromHabit, toHabit);
int actualPositions[] = new int[10];
for (int j = 0; j < 10; j++)
{
Habit h = habitList.getById(j);
if (h == null) fail();
actualPositions[j] = habitList.indexOf(h);
}
assertThat(actualPositions, equalTo(expectedPosition[i]));
}
}
@Test
public void test_size()
{
assertThat(habitList.size(), equalTo(10));
}
@Test
public void test_writeCSV() throws IOException
{
HabitList list = modelFactory.buildHabitList();
Habit h1 = fixtures.createEmptyHabit();
h1.setName("Meditate");
h1.setDescription("Did you meditate this morning?");
h1.setFrequency(Frequency.DAILY);
h1.setColor(3);
Habit h2 = fixtures.createEmptyHabit();
h2.setName("Wake up early");
h2.setDescription("Did you wake up before 6am?");
h2.setFrequency(new Frequency(2, 3));
h2.setColor(5);
list.add(h1);
list.add(h2);
String expectedCSV =
"Position,Name,Description,NumRepetitions,Interval,Color\n" +
"001,Meditate,Did you meditate this morning?,1,1,#AFB42B\n" +
"002,Wake up early,Did you wake up before 6am?,2,3,#00897B\n";
StringWriter writer = new StringWriter();
list.writeCSV(writer);
MatcherAssert.assertThat(writer.toString(), equalTo(expectedCSV));
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.models;
import org.isoron.uhabits.*;
import org.junit.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
public class HabitTest extends BaseUnitTest
{
@Override
public void setUp()
{
super.setUp();
}
@Test
public void testConstructor_default()
{
Habit habit = modelFactory.buildHabit();
assertFalse(habit.isArchived());
assertThat(habit.hasReminder(), is(false));
assertNotNull(habit.getStreaks());
assertNotNull(habit.getScores());
assertNotNull(habit.getRepetitions());
assertNotNull(habit.getCheckmarks());
}
@Test
public void test_copyAttributes()
{
Habit model = modelFactory.buildHabit();
model.setArchived(true);
model.setColor(0);
model.setFrequency(new Frequency(10, 20));
model.setReminder(new Reminder(8, 30, new WeekdayList(1)));
Habit habit = modelFactory.buildHabit();
habit.copyFrom(model);
assertThat(habit.isArchived(), is(model.isArchived()));
assertThat(habit.getColor(), is(model.getColor()));
assertThat(habit.getFrequency(), equalTo(model.getFrequency()));
assertThat(habit.getReminder(), equalTo(model.getReminder()));
}
@Test
public void test_hasReminder_clearReminder()
{
Habit h = modelFactory.buildHabit();
assertThat(h.hasReminder(), is(false));
h.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
assertThat(h.hasReminder(), is(true));
h.clearReminder();
assertThat(h.hasReminder(), is(false));
}
}

View File

@@ -0,0 +1,171 @@
/*
* 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.models;
import android.support.annotation.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import java.util.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.Is.*;
import static org.hamcrest.core.IsEqual.*;
import static org.mockito.Mockito.*;
public class RepetitionListTest extends BaseUnitTest
{
@NonNull
private RepetitionList reps;
@NonNull
private Habit habit;
private long today;
private long day;
@NonNull
private ModelObservable.Listener listener;
@Override
@Before
public void setUp()
{
super.setUp();
habit = fixtures.createEmptyHabit();
reps = habit.getRepetitions();
today = DateUtils.getStartOfToday();
day = DateUtils.millisecondsInOneDay;
reps.toggleTimestamp(today - 3 * day);
reps.toggleTimestamp(today - 2 * day);
reps.toggleTimestamp(today);
reps.toggleTimestamp(today - 7 * day);
reps.toggleTimestamp(today - 5 * day);
listener = mock(ModelObservable.Listener.class);
reps.getObservable().addListener(listener);
}
@Override
@After
public void tearDown()
{
super.tearDown();
}
@Test
public void test_contains()
{
assertThat(reps.containsTimestamp(today), is(true));
assertThat(reps.containsTimestamp(today - 2 * day), is(true));
assertThat(reps.containsTimestamp(today - 3 * day), is(true));
assertThat(reps.containsTimestamp(today - day), is(false));
assertThat(reps.containsTimestamp(today - 4 * day), is(false));
}
@Test
public void test_getOldest()
{
Repetition rep = reps.getOldest();
assertThat(rep.getTimestamp(), is(equalTo(today - 7 * day)));
}
@Test
public void test_getWeekDayFrequency()
{
habit = fixtures.createEmptyHabit();
reps = habit.getRepetitions();
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 = DateUtils.getStartOfTodayCalendar();
// Sets the current date to the end of November
day.set(2015, 10, 30);
DateUtils.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]++;
}
reps.toggleTimestamp(day.getTimeInMillis());
}
}
day.add(Calendar.DAY_OF_YEAR, 1);
}
HashMap<Long, Integer[]> freq =
reps.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));
}
@Test
public void test_toggleTimestamp()
{
assertThat(reps.containsTimestamp(today), equalTo(true));
reps.toggleTimestamp(today);
assertThat(reps.containsTimestamp(today), equalTo(false));
verify(listener).onModelChange();
reset(listener);
assertThat(reps.containsTimestamp(today - day), equalTo(false));
reps.toggleTimestamp(today - day);
assertThat(reps.containsTimestamp(today - day), equalTo(true));
verify(listener).onModelChange();
}
}

View File

@@ -0,0 +1,210 @@
/*
* 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.models;
import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import java.io.*;
import java.util.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.number.IsCloseTo.*;
public class ScoreListTest extends BaseUnitTest
{
private static final double E = 1e-6;
private Habit habit;
@Override
@Before
public void setUp()
{
super.setUp();
habit = fixtures.createEmptyHabit();
}
@Test
public void test_getAll()
{
toggleRepetitions(0, 20);
double expectedValues[] = {
0.655747,
0.636894,
0.617008,
0.596033,
0.573910,
0.550574,
0.525961,
0.500000,
0.472617,
0.443734,
0.413270,
0.381137,
0.347244,
0.311495,
0.273788,
0.234017,
0.192067,
0.147820,
0.101149,
0.051922,
};
int i = 0;
for (Score s : habit.getScores())
assertThat(s.getValue(), closeTo(expectedValues[i++], E));
}
@Test
public void test_getTodayValue()
{
toggleRepetitions(0, 20);
double actual = habit.getScores().getTodayValue();
assertThat(actual, closeTo(0.655747, E));
}
@Test
public void test_getValue()
{
toggleRepetitions(0, 20);
double expectedValues[] = {
0.655747,
0.636894,
0.617008,
0.596033,
0.573910,
0.550574,
0.525961,
0.500000,
0.472617,
0.443734,
0.413270,
0.381137,
0.347244,
0.311495,
0.273788,
0.234017,
0.192067,
0.147820,
0.101149,
0.051922,
0.000000,
0.000000,
0.000000
};
ScoreList scores = habit.getScores();
long current = DateUtils.getStartOfToday();
for (double expectedValue : expectedValues)
{
assertThat(scores.getValue(current), closeTo(expectedValue, E));
current -= DateUtils.millisecondsInOneDay;
}
}
@Test
public void test_groupBy()
{
Habit habit = fixtures.createLongHabit();
List<Score> list =
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));
}
@Test
public void test_invalidateNewerThan()
{
assertThat(habit.getScores().getTodayValue(), closeTo(0.0, E));
toggleRepetitions(0, 2);
assertThat(habit.getScores().getTodayValue(), closeTo(0.101149, E));
habit.setFrequency(new Frequency(1, 2));
habit.getScores().invalidateNewerThan(0);
assertThat(habit.getScores().getTodayValue(), closeTo(0.051922, E));
}
@Test
public void test_writeCSV() throws IOException
{
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";
StringWriter writer = new StringWriter();
habit.getScores().writeCSV(writer);
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();
long today = DateUtils.getStartOfToday();
long day = DateUtils.millisecondsInOneDay;
for (int i = from; i < to; i++)
reps.toggleTimestamp(today - i * day);
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.models;
import org.isoron.uhabits.*;
import org.junit.*;
import static org.hamcrest.number.IsCloseTo.*;
import static org.isoron.uhabits.models.Score.*;
import static org.junit.Assert.*;
public class ScoreTest extends BaseUnitTest
{
private static final double E = 1e-6;
@Override
@Before
public void setUp()
{
super.setUp();
}
@Test
public void test_compute_withDailyHabit()
{
int check = 1;
double freq = 1.0;
assertThat(compute(freq, 0, check), closeTo(0.051922, E));
assertThat(compute(freq, 0.5, check), closeTo(0.525961, E));
assertThat(compute(freq, 0.75, check), closeTo(0.762981, E));
check = 0;
assertThat(compute(freq, 0, check), closeTo(0, E));
assertThat(compute(freq, 0.5, check), closeTo(0.474039, E));
assertThat(compute(freq, 0.75, check), closeTo(0.711058, E));
}
@Test
public void test_compute_withNonDailyHabit()
{
int check = 1;
double freq = 1 / 3.0;
assertThat(compute(freq, 0, check), closeTo(0.017616, E));
assertThat(compute(freq, 0.5, check), closeTo(0.508808, E));
assertThat(compute(freq, 0.75, check), closeTo(0.754404, E));
check = 0;
assertThat(compute(freq, 0, check), closeTo(0.0, E));
assertThat(compute(freq, 0.5, check), closeTo(0.491192, E));
assertThat(compute(freq, 0.75, check), closeTo(0.736788, E));
}
}

View File

@@ -0,0 +1,140 @@
/*
* 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.models;
import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import java.util.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
import static org.mockito.Mockito.*;
public class StreakListTest extends BaseUnitTest
{
private Habit habit;
private StreakList streaks;
private long day;
private long today;
private ModelObservable.Listener listener;
@Override
public void setUp()
{
super.setUp();
habit = fixtures.createLongHabit();
habit.setFrequency(Frequency.DAILY);
streaks = habit.getStreaks();
streaks.rebuild();
listener = mock(ModelObservable.Listener.class);
streaks.getObservable().addListener(listener);
today = DateUtils.getStartOfToday();
day = DateUtils.millisecondsInOneDay;
}
@Test
public void testFindBeginning_withEmptyHistory()
{
Habit habit2 = fixtures.createEmptyHabit();
Long beginning = habit2.getStreaks().findBeginning();
assertThat(beginning, is(nullValue()));
}
@Test
public void testFindBeginning_withLongHistory()
{
streaks.rebuild();
assertThat(streaks.findBeginning(), equalTo(today - day));
streaks.invalidateNewerThan(today - 20 * day);
assertThat(streaks.findBeginning(), equalTo(today - 28 * day));
streaks.invalidateNewerThan(0);
assertThat(streaks.findBeginning(), equalTo(today - 120 * day));
}
@Test
public void testGetAll() throws Exception
{
List<Streak> all = streaks.getAll();
assertThat(all.size(), equalTo(22));
assertThat(all.get(3).getEnd(), equalTo(today - 7 * day));
assertThat(all.get(3).getStart(), equalTo(today - 10 * day));
assertThat(all.get(17).getEnd(), equalTo(today - 89 * day));
assertThat(all.get(17).getStart(), equalTo(today - 91 * day));
}
@Test
public void testGetBest() throws Exception
{
List<Streak> best = streaks.getBest(4);
assertThat(best.size(), equalTo(4));
assertThat(best.get(0).getLength(), equalTo(4L));
assertThat(best.get(1).getLength(), equalTo(3L));
assertThat(best.get(2).getLength(), equalTo(5L));
assertThat(best.get(3).getLength(), equalTo(6L));
best = streaks.getBest(2);
assertThat(best.size(), equalTo(2));
assertThat(best.get(0).getLength(), equalTo(5L));
assertThat(best.get(1).getLength(), equalTo(6L));
}
@Test
public void testGetNewestComputed() throws Exception
{
Streak s = streaks.getNewestComputed();
assertThat(s.getEnd(), equalTo(today));
assertThat(s.getStart(), equalTo(today - day));
streaks.invalidateNewerThan(today - 8 * day);
s = streaks.getNewestComputed();
assertThat(s.getEnd(), equalTo(today - 12 * day));
assertThat(s.getStart(), equalTo(today - 12 * day));
}
@Test
public void testInvalidateNewer()
{
Streak s = streaks.getNewestComputed();
assertThat(s.getEnd(), equalTo(today));
streaks.invalidateNewerThan(today - 8 * day);
verify(listener).onModelChange();
s = streaks.getNewestComputed();
assertThat(s.getEnd(), equalTo(today - 12 * day));
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.models;
import org.isoron.uhabits.*;
import org.junit.*;
import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.IsEqual.*;
public class WeekdayListTest extends BaseUnitTest
{
@Test
public void test()
{
int daysInt = 124;
boolean[] daysArray = new boolean[]{
false, false, true, true, true, true, true
};
WeekdayList list = new WeekdayList(daysArray);
assertThat(list.toArray(), equalTo(daysArray));
assertThat(list.toInteger(), equalTo(daysInt));
list = new WeekdayList(daysInt);
assertThat(list.toArray(), equalTo(daysArray));
assertThat(list.toInteger(), equalTo(daysInt));
}
@Test
public void testEmpty()
{
WeekdayList list = new WeekdayList(0);
assertTrue(list.isEmpty());
assertFalse(WeekdayList.EVERY_DAY.isEmpty());
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.tasks;
import org.isoron.uhabits.*;
import org.junit.*;
import org.junit.runner.*;
import org.junit.runners.*;
import org.mockito.*;
import static org.mockito.Mockito.*;
@RunWith(JUnit4.class)
public class SingleThreadTaskRunnerTest extends BaseUnitTest
{
private SingleThreadTaskRunner runner;
private Task task;
@Override
public void setUp()
{
super.setUp();
runner = new SingleThreadTaskRunner();
task = mock(Task.class);
}
@Test
public void test()
{
runner.execute(task);
InOrder inOrder = inOrder(task);
inOrder.verify(task).onAttached(runner);
inOrder.verify(task).onPreExecute();
inOrder.verify(task).doInBackground();
inOrder.verify(task).onPostExecute();
}
}

View File

@@ -0,0 +1,150 @@
/*
* 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.utils;
import org.isoron.uhabits.*;
import org.junit.*;
import java.util.*;
import static java.util.Calendar.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
public class DateUtilsTest extends BaseUnitTest
{
@Test
public void testFormatHeaderDate()
{
long timestamp = timestamp(2015, DECEMBER, 31);
GregorianCalendar date = DateUtils.getCalendar(timestamp);
String formatted = DateUtils.formatHeaderDate(date);
assertThat(formatted, equalTo("Thu\n31"));
}
@Test
public void testTruncate_dayOfWeek()
{
DateUtils.TruncateField field = DateUtils.TruncateField.WEEK_NUMBER;
long expected = timestamp(2015, Calendar.JANUARY, 11);
long t0 = timestamp(2015, Calendar.JANUARY, 11);
long t1 = timestamp(2015, Calendar.JANUARY, 16);
long t2 = timestamp(2015, Calendar.JANUARY, 17);
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
expected = timestamp(2015, Calendar.JANUARY, 18);
t0 = timestamp(2015, Calendar.JANUARY, 18);
t1 = timestamp(2015, Calendar.JANUARY, 19);
t2 = timestamp(2015, Calendar.JANUARY, 24);
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
}
@Test
public void testTruncate_month()
{
long expected = timestamp(2016, Calendar.JUNE, 1);
long t0 = timestamp(2016, Calendar.JUNE, 1);
long t1 = timestamp(2016, Calendar.JUNE, 15);
long t2 = timestamp(2016, Calendar.JUNE, 20);
DateUtils.TruncateField field = DateUtils.TruncateField.MONTH;
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
expected = timestamp(2016, DECEMBER, 1);
t0 = timestamp(2016, DECEMBER, 1);
t1 = timestamp(2016, DECEMBER, 15);
t2 = timestamp(2016, DECEMBER, 31);
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
}
@Test
public void testTruncate_quarter()
{
DateUtils.TruncateField field = DateUtils.TruncateField.QUARTER;
long expected = timestamp(2016, JANUARY, 1);
long t0 = timestamp(2016, JANUARY, 20);
long t1 = timestamp(2016, FEBRUARY, 15);
long t2 = timestamp(2016, MARCH, 30);
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
expected = timestamp(2016, APRIL, 1);
t0 = timestamp(2016, APRIL, 1);
t1 = timestamp(2016, MAY, 30);
t2 = timestamp(2016, JUNE, 20);
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
}
@Test
public void testTruncate_year()
{
DateUtils.TruncateField field = DateUtils.TruncateField.YEAR;
long expected = timestamp(2016, JANUARY, 1);
long t0 = timestamp(2016, JANUARY, 1);
long t1 = timestamp(2016, FEBRUARY, 25);
long t2 = timestamp(2016, DECEMBER, 31);
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
expected = timestamp(2017, JANUARY, 1);
t0 = timestamp(2017, JANUARY, 1);
t1 = timestamp(2017, MAY, 30);
t2 = timestamp(2017, DECEMBER, 31);
assertThat(DateUtils.truncate(field, t0), equalTo(expected));
assertThat(DateUtils.truncate(field, t1), equalTo(expected));
assertThat(DateUtils.truncate(field, t2), equalTo(expected));
}
@Test
public void test_getDaysBetween()
{
long t1 = timestamp(2016, JANUARY, 1);
long t2 = timestamp(2016, JANUARY, 10);
long t3 = timestamp(2016, DECEMBER, 31);
assertThat(DateUtils.getDaysBetween(t1, t1), equalTo(0));
assertThat(DateUtils.getDaysBetween(t1, t2), equalTo(9));
assertThat(DateUtils.getDaysBetween(t1, t3), equalTo(365));
assertThat(DateUtils.getDaysBetween(t3, t1), equalTo(365));
}
}