mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Write tests for CSV export
This commit is contained in:
@@ -29,6 +29,9 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.isoron.uhabits.models.Checkmark.CHECKED_EXPLICITLY;
|
import static org.isoron.uhabits.models.Checkmark.CHECKED_EXPLICITLY;
|
||||||
@@ -140,6 +143,27 @@ public class CheckmarkListTest
|
|||||||
assertThat(nonDailyHabit.checkmarks.getTodayValue(), equalTo(UNCHECKED));
|
assertThat(nonDailyHabit.checkmarks.getTodayValue(), equalTo(UNCHECKED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writeCSV() throws IOException
|
||||||
|
{
|
||||||
|
String expectedCSV =
|
||||||
|
"2015-01-16,2\n" +
|
||||||
|
"2015-01-17,2\n" +
|
||||||
|
"2015-01-18,1\n" +
|
||||||
|
"2015-01-19,0\n" +
|
||||||
|
"2015-01-20,2\n" +
|
||||||
|
"2015-01-21,2\n" +
|
||||||
|
"2015-01-22,2\n" +
|
||||||
|
"2015-01-23,1\n" +
|
||||||
|
"2015-01-24,0\n" +
|
||||||
|
"2015-01-25,2\n";
|
||||||
|
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
nonDailyHabit.checkmarks.writeCSV(writer);
|
||||||
|
|
||||||
|
assertThat(writer.toString(), equalTo(expectedCSV));
|
||||||
|
}
|
||||||
|
|
||||||
private void travelInTime(int days)
|
private void travelInTime(int days)
|
||||||
{
|
{
|
||||||
DateHelper.setFixedLocalTime(HabitFixtures.FIXED_LOCAL_TIME +
|
DateHelper.setFixedLocalTime(HabitFixtures.FIXED_LOCAL_TIME +
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package org.isoron.uhabits.unit.models;
|
package org.isoron.uhabits.unit.models;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.helpers.ColorHelper;
|
||||||
import org.isoron.uhabits.helpers.DateHelper;
|
import org.isoron.uhabits.helpers.DateHelper;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ public class HabitFixtures
|
|||||||
public static Habit createNonDailyHabit()
|
public static Habit createNonDailyHabit()
|
||||||
{
|
{
|
||||||
Habit habit = new Habit();
|
Habit habit = new Habit();
|
||||||
|
habit.name = "Wake up early";
|
||||||
|
habit.description = "Did you wake up before 6am?";
|
||||||
habit.freqNum = 2;
|
habit.freqNum = 2;
|
||||||
habit.freqDen = 3;
|
habit.freqDen = 3;
|
||||||
habit.save();
|
habit.save();
|
||||||
@@ -48,6 +51,9 @@ public class HabitFixtures
|
|||||||
public static Habit createEmptyHabit()
|
public static Habit createEmptyHabit()
|
||||||
{
|
{
|
||||||
Habit habit = new Habit();
|
Habit habit = new Habit();
|
||||||
|
habit.name = "Meditate";
|
||||||
|
habit.description = "Did you meditate this morning?";
|
||||||
|
habit.color = ColorHelper.palette[3];
|
||||||
habit.freqNum = 1;
|
habit.freqNum = 1;
|
||||||
habit.freqDen = 1;
|
habit.freqDen = 1;
|
||||||
habit.save();
|
habit.save();
|
||||||
|
|||||||
@@ -23,12 +23,15 @@ import android.graphics.Color;
|
|||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
|
||||||
|
import org.hamcrest.MatcherAssert;
|
||||||
import org.isoron.uhabits.helpers.DateHelper;
|
import org.isoron.uhabits.helpers.DateHelper;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -353,4 +356,21 @@ public class HabitTest
|
|||||||
h.clearReminder();
|
h.clearReminder();
|
||||||
assertThat(h.hasReminder(), is(false));
|
assertThat(h.hasReminder(), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writeCSV() throws IOException
|
||||||
|
{
|
||||||
|
HabitFixtures.createEmptyHabit();
|
||||||
|
HabitFixtures.createNonDailyHabit();
|
||||||
|
|
||||||
|
String expectedCSV =
|
||||||
|
"Name,Description,NumRepetitions,Interval,Color\n" +
|
||||||
|
"Meditate,Did you meditate this morning?,1,1,#AFB42B\n" +
|
||||||
|
"Wake up early,Did you wake up before 6am?,2,3,#00897B\n";
|
||||||
|
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
Habit.writeCSV(Habit.getAll(true), writer);
|
||||||
|
|
||||||
|
MatcherAssert.assertThat(writer.toString(), equalTo(expectedCSV));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
@@ -130,6 +133,30 @@ public class ScoreListTest
|
|||||||
assertThat(actualValues, equalTo(expectedValues));
|
assertThat(actualValues, equalTo(expectedValues));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writeCSV() throws IOException
|
||||||
|
{
|
||||||
|
HabitFixtures.purgeHabits();
|
||||||
|
Habit habit = HabitFixtures.createNonDailyHabit();
|
||||||
|
|
||||||
|
String expectedCSV =
|
||||||
|
"2015-01-16,0.0519\n" +
|
||||||
|
"2015-01-17,0.1021\n" +
|
||||||
|
"2015-01-18,0.0986\n" +
|
||||||
|
"2015-01-19,0.0952\n" +
|
||||||
|
"2015-01-20,0.1439\n" +
|
||||||
|
"2015-01-21,0.1909\n" +
|
||||||
|
"2015-01-22,0.2364\n" +
|
||||||
|
"2015-01-23,0.2283\n" +
|
||||||
|
"2015-01-24,0.2205\n" +
|
||||||
|
"2015-01-25,0.2649\n";
|
||||||
|
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
habit.scores.writeCSV(writer);
|
||||||
|
|
||||||
|
assertThat(writer.toString(), equalTo(expectedCSV));
|
||||||
|
}
|
||||||
|
|
||||||
private void toggleRepetitions(final int from, final int to)
|
private void toggleRepetitions(final int from, final int to)
|
||||||
{
|
{
|
||||||
DatabaseHelper.executeAsTransaction(new DatabaseHelper.Command()
|
DatabaseHelper.executeAsTransaction(new DatabaseHelper.Command()
|
||||||
|
|||||||
@@ -22,18 +22,13 @@ package org.isoron.uhabits.unit.models;
|
|||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.models.Checkmark;
|
||||||
|
import org.isoron.uhabits.models.Score;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.hamcrest.core.IsNot.not;
|
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.models.Score;
|
|
||||||
import org.isoron.uhabits.models.Checkmark;
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public class CheckmarkList
|
|||||||
public int[] getValues(long fromTimestamp, long toTimestamp)
|
public int[] getValues(long fromTimestamp, long toTimestamp)
|
||||||
{
|
{
|
||||||
compute(fromTimestamp, toTimestamp);
|
compute(fromTimestamp, toTimestamp);
|
||||||
|
|
||||||
if(fromTimestamp > toTimestamp) return new int[0];
|
if(fromTimestamp > toTimestamp) return new int[0];
|
||||||
|
|
||||||
String query = "select value, timestamp from Checkmarks where " +
|
String query = "select value, timestamp from Checkmarks where " +
|
||||||
@@ -127,6 +128,21 @@ public class CheckmarkList
|
|||||||
return getValues(fromTimestamp, toTimestamp);
|
return getValues(fromTimestamp, toTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes and stores one checkmark for each day, since the first repetition until today.
|
||||||
|
* Days that already have a corresponding checkmark are skipped.
|
||||||
|
*/
|
||||||
|
protected void computeAll()
|
||||||
|
{
|
||||||
|
Repetition oldestRep = habit.repetitions.getOldest();
|
||||||
|
if(oldestRep == null) return;
|
||||||
|
|
||||||
|
Long fromTimestamp = oldestRep.timestamp;
|
||||||
|
Long toTimestamp = DateHelper.getStartOfToday();
|
||||||
|
|
||||||
|
compute(fromTimestamp, toTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes and stores one checkmark for each day that falls inside the specified interval of
|
* Computes and stores one checkmark for each day that falls inside the specified interval of
|
||||||
* time. Days that already have a corresponding checkmark are skipped.
|
* time. Days that already have a corresponding checkmark are skipped.
|
||||||
@@ -234,8 +250,18 @@ public class CheckmarkList
|
|||||||
else return Checkmark.UNCHECKED;
|
else return Checkmark.UNCHECKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the entire list of checkmarks to the given writer, in CSV format. There is one
|
||||||
|
* line for each checkmark. Each line contains two fields: timestamp and value.
|
||||||
|
*
|
||||||
|
* @param out the writer where the CSV will be output
|
||||||
|
* @throws IOException in case write operations fail
|
||||||
|
*/
|
||||||
|
|
||||||
public void writeCSV(Writer out) throws IOException
|
public void writeCSV(Writer out) throws IOException
|
||||||
{
|
{
|
||||||
|
computeAll();
|
||||||
|
|
||||||
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
||||||
|
|
||||||
String query = "select timestamp, value from checkmarks where habit = ? order by timestamp";
|
String query = "select timestamp, value from checkmarks where habit = ? order by timestamp";
|
||||||
@@ -255,5 +281,6 @@ public class CheckmarkList
|
|||||||
} while(cursor.moveToNext());
|
} while(cursor.moveToNext());
|
||||||
|
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
out.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
package org.isoron.uhabits.models;
|
package org.isoron.uhabits.models;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
@@ -34,16 +33,13 @@ import com.activeandroid.query.From;
|
|||||||
import com.activeandroid.query.Select;
|
import com.activeandroid.query.Select;
|
||||||
import com.activeandroid.query.Update;
|
import com.activeandroid.query.Update;
|
||||||
import com.activeandroid.util.SQLiteUtils;
|
import com.activeandroid.util.SQLiteUtils;
|
||||||
import com.opencsv.CSVReader;
|
|
||||||
import com.opencsv.CSVWriter;
|
import com.opencsv.CSVWriter;
|
||||||
|
|
||||||
import org.isoron.uhabits.helpers.ColorHelper;
|
import org.isoron.uhabits.helpers.ColorHelper;
|
||||||
import org.isoron.uhabits.helpers.DateHelper;
|
import org.isoron.uhabits.helpers.DateHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -478,9 +474,18 @@ public class Habit extends Model
|
|||||||
reminderDays = DateHelper.ALL_WEEK_DAYS;
|
reminderDays = DateHelper.ALL_WEEK_DAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the list of habits to the given writer, in CSV format. There is one line for each
|
||||||
|
* habit, containing the fields name, description, frequency numerator, frequency denominator
|
||||||
|
* and color. The color is written in HTML format (#000000).
|
||||||
|
*
|
||||||
|
* @param habits the list of habits to write
|
||||||
|
* @param out the writer that will receive the result
|
||||||
|
* @throws IOException if write operations fail
|
||||||
|
*/
|
||||||
public static void writeCSV(List<Habit> habits, Writer out) throws IOException
|
public static void writeCSV(List<Habit> habits, Writer out) throws IOException
|
||||||
{
|
{
|
||||||
String header[] = { "Name", "Description", "FrequencyNumerator", "FrequencyDenominator", "Color" };
|
String header[] = { "Name", "Description", "NumRepetitions", "Interval", "Color" };
|
||||||
|
|
||||||
CSVWriter csv = new CSVWriter(out);
|
CSVWriter csv = new CSVWriter(out);
|
||||||
csv.writeNext(header, false);
|
csv.writeNext(header, false);
|
||||||
@@ -494,24 +499,4 @@ public class Habit extends Model
|
|||||||
|
|
||||||
csv.close();
|
csv.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Habit> parseCSV(Reader in)
|
|
||||||
{
|
|
||||||
CSVReader csv = new CSVReader(in);
|
|
||||||
List<Habit> habits = new LinkedList<>();
|
|
||||||
|
|
||||||
for(String cols[] : csv)
|
|
||||||
{
|
|
||||||
Habit habit = new Habit();
|
|
||||||
|
|
||||||
habit.name = cols[0];
|
|
||||||
habit.description = cols[1];
|
|
||||||
habit.freqNum = Integer.parseInt(cols[2]);
|
|
||||||
habit.freqDen = Integer.parseInt(cols[3]);
|
|
||||||
habit.color = Color.parseColor(cols[4]);
|
|
||||||
habits.add(habit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return habits;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,6 +99,19 @@ public class ScoreList
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes and saves the scores that are missing since the first repetition of the habit.
|
||||||
|
*/
|
||||||
|
private void computeAll()
|
||||||
|
{
|
||||||
|
Repetition oldestRep = habit.repetitions.getOldest();
|
||||||
|
if(oldestRep == null) return;
|
||||||
|
|
||||||
|
long fromTimestamp = oldestRep.timestamp;
|
||||||
|
long toTimestamp = DateHelper.getStartOfToday();
|
||||||
|
compute(fromTimestamp, toTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes and saves the scores that are missing inside a given time interval. Scores that
|
* Computes and saves the scores that are missing inside a given time interval. Scores that
|
||||||
* have already been computed are skipped, therefore there is no harm in calling this function
|
* have already been computed are skipped, therefore there is no harm in calling this function
|
||||||
@@ -285,6 +298,8 @@ public class ScoreList
|
|||||||
|
|
||||||
public void writeCSV(Writer out) throws IOException
|
public void writeCSV(Writer out) throws IOException
|
||||||
{
|
{
|
||||||
|
computeAll();
|
||||||
|
|
||||||
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
||||||
|
|
||||||
String query = "select timestamp, score from score where habit = ? order by timestamp";
|
String query = "select timestamp, score from score where habit = ? order by timestamp";
|
||||||
@@ -298,11 +313,12 @@ public class ScoreList
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
String timestamp = dateFormat.format(new Date(cursor.getLong(0)));
|
String timestamp = dateFormat.format(new Date(cursor.getLong(0)));
|
||||||
String score = String.format("%.2f", ((float) cursor.getInt(1)) / Score.MAX_VALUE);
|
String score = String.format("%.4f", ((float) cursor.getInt(1)) / Score.MAX_VALUE);
|
||||||
out.write(String.format("%s,%s\n", timestamp, score));
|
out.write(String.format("%s,%s\n", timestamp, score));
|
||||||
|
|
||||||
} while(cursor.moveToNext());
|
} while(cursor.moveToNext());
|
||||||
|
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
out.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user