From b1a06df7f80183941222a5e16fc8fe14dc3bd496 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Wed, 23 Nov 2016 05:58:46 -0500 Subject: [PATCH] Implement automatic sorting for SQLHabitList --- .../org/isoron/uhabits/BaseAndroidTest.java | 4 +- .../org/isoron/uhabits/HabitFixtures.java | 6 + .../isoron/uhabits/models/HabitListTest.java | 240 ++++++++++++++++++ .../models/sqlite/SQLiteHabitListTest.java | 50 ---- .../models/sqlite/SQLiteHabitList.java | 24 +- 5 files changed, 271 insertions(+), 53 deletions(-) create mode 100644 app/src/androidTest/java/org/isoron/uhabits/models/HabitListTest.java diff --git a/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java b/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java index edb28d55d..912009ece 100644 --- a/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java +++ b/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java @@ -63,6 +63,8 @@ public class BaseAndroidTest protected AndroidTestComponent component; + protected ModelFactory modelFactory; + @Before public void setUp() { @@ -89,7 +91,7 @@ public class BaseAndroidTest taskRunner = component.getTaskRunner(); logger = component.getHabitsLogger(); - ModelFactory modelFactory = component.getModelFactory(); + modelFactory = component.getModelFactory(); fixtures = new HabitFixtures(modelFactory, habitList); latch = new CountDownLatch(1); diff --git a/app/src/androidTest/java/org/isoron/uhabits/HabitFixtures.java b/app/src/androidTest/java/org/isoron/uhabits/HabitFixtures.java index bd5928ecc..7a6e51281 100644 --- a/app/src/androidTest/java/org/isoron/uhabits/HabitFixtures.java +++ b/app/src/androidTest/java/org/isoron/uhabits/HabitFixtures.java @@ -39,12 +39,18 @@ public class HabitFixtures } public Habit createEmptyHabit() + { + return createEmptyHabit(null); + } + + public Habit createEmptyHabit(Long id) { Habit habit = modelFactory.buildHabit(); habit.setName("Meditate"); habit.setDescription("Did you meditate this morning?"); habit.setColor(3); habit.setFrequency(Frequency.DAILY); + habit.setId(id); habitList.add(habit); return habit; } diff --git a/app/src/androidTest/java/org/isoron/uhabits/models/HabitListTest.java b/app/src/androidTest/java/org/isoron/uhabits/models/HabitListTest.java new file mode 100644 index 000000000..92f71a3f4 --- /dev/null +++ b/app/src/androidTest/java/org/isoron/uhabits/models/HabitListTest.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * 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 . + */ + +package org.isoron.uhabits.models; + +import android.support.test.runner.*; +import android.test.suitebuilder.annotation.*; + +import org.hamcrest.*; +import org.isoron.uhabits.*; +import org.junit.*; +import org.junit.runner.*; + +import java.io.*; +import java.util.*; + +import static junit.framework.Assert.*; +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.*; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.isoron.uhabits.models.HabitList.Order.*; + +@SuppressWarnings("JavaDoc") +@RunWith(AndroidJUnit4.class) +@MediumTest +public class HabitListTest extends BaseAndroidTest +{ + private ArrayList habitsArray; + + private HabitList activeHabits; + + private HabitList reminderHabits; + + @Override + public void setUp() + { + super.setUp(); + habitList.removeAll(); + + habitsArray = new ArrayList<>(); + + for (int i = 0; i < 10; i++) + { + Habit habit = fixtures.createEmptyHabit((long) i); + habitsArray.add(habit); + + if (i % 3 == 0) + habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY)); + + habitList.update(habit); + } + + 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_size() + { + assertThat(habitList.size(), equalTo(10)); + } + + @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_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); + assertNotNull(h); + actualPositions[j] = habitList.indexOf(h); + } + + assertThat(actualPositions, equalTo(expectedPosition[i])); + } + } + + @Test + public void test_writeCSV() throws IOException + { + habitList.removeAll(); + + 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); + + habitList.update(h1); + habitList.update(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(); + habitList.writeCSV(writer); + + MatcherAssert.assertThat(writer.toString(), equalTo(expectedCSV)); + } + + @Test + public void test_ordering() + { + habitList.removeAll(); + + Habit h3 = fixtures.createEmptyHabit(); + h3.setName("C Habit"); + h3.setColor(0); + habitList.update(h3); + + Habit h1 = fixtures.createEmptyHabit(); + h1.setName("A Habit"); + h1.setColor(2); + habitList.update(h1); + + Habit h4 = fixtures.createEmptyHabit(); + h4.setName("D Habit"); + h4.setColor(1); + habitList.update(h4); + + Habit h2 = fixtures.createEmptyHabit(); + h2.setName("B Habit"); + h2.setColor(2); + habitList.update(h2); + + habitList.setOrder(BY_POSITION); + assertThat(habitList.getByPosition(0), equalTo(h3)); + assertThat(habitList.getByPosition(1), equalTo(h1)); + assertThat(habitList.getByPosition(2), equalTo(h4)); + assertThat(habitList.getByPosition(3), equalTo(h2)); + + habitList.setOrder(BY_NAME); + assertThat(habitList.getByPosition(0), equalTo(h1)); + assertThat(habitList.getByPosition(1), equalTo(h2)); + assertThat(habitList.getByPosition(2), equalTo(h3)); + assertThat(habitList.getByPosition(3), equalTo(h4)); + + habitList.remove(h1); + habitList.add(h1); + assertThat(habitList.getByPosition(0), equalTo(h1)); + + habitList.setOrder(BY_COLOR); + assertThat(habitList.getByPosition(0), equalTo(h3)); + assertThat(habitList.getByPosition(1), equalTo(h4)); + assertThat(habitList.getByPosition(2), equalTo(h1)); + assertThat(habitList.getByPosition(3), equalTo(h2)); + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java b/app/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java index ae51ed1f5..5308fc61c 100644 --- a/app/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java +++ b/app/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java @@ -125,17 +125,6 @@ public class SQLiteHabitListTest extends BaseAndroidTest assertThat(habits.get(3).getName(), equalTo("habit 3")); } -// @Test -// public void testGetAll_withoutArchived() -// { -// List habits = habitList.toList(); -// assertThat(habits.size(), equalTo(5)); -// assertThat(habits.get(3).getName(), equalTo("habit 7")); -// -// List another = habitList.toList(); -// assertThat(habits, equalTo(another)); -// } - @Test public void testGetById() { @@ -178,45 +167,6 @@ public class SQLiteHabitListTest extends BaseAndroidTest assertThat(habitList.indexOf(h2), equalTo(-1)); } - @Test - public void test_reorder() - { - // Same as HabitListTest.java - // TODO: remove duplication - - 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); - assertNotNull(h); - actualPositions[j] = habitList.indexOf(h); - } - - assertThat(actualPositions, equalTo(expectedPosition[i])); - } - } - private HabitRecord getRecord(long id) { return new Select() diff --git a/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteHabitList.java b/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteHabitList.java index 921209192..dde89c7a0 100644 --- a/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteHabitList.java +++ b/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteHabitList.java @@ -43,6 +43,8 @@ public class SQLiteHabitList extends HabitList private final ModelFactory modelFactory; + private Order order; + public SQLiteHabitList(@NonNull ModelFactory modelFactory) { super(); @@ -50,6 +52,7 @@ public class SQLiteHabitList extends HabitList if (cache == null) cache = new HashMap<>(); sqlite = new SQLiteUtils<>(HabitRecord.class); + order = Order.BY_POSITION; } protected SQLiteHabitList(@NonNull ModelFactory modelFactory, @@ -60,6 +63,7 @@ public class SQLiteHabitList extends HabitList if (cache == null) cache = new HashMap<>(); sqlite = new SQLiteUtils<>(HabitRecord.class); + order = Order.BY_POSITION; } public static SQLiteHabitList getInstance( @@ -254,7 +258,23 @@ public class SQLiteHabitList extends HabitList private void appendOrderBy(StringBuilder query) { - query.append("order by position "); + switch (order) + { + case BY_POSITION: + query.append("order by position "); + break; + + case BY_NAME: + query.append("order by name "); + break; + + case BY_COLOR: + query.append("order by color "); + break; + + default: + throw new IllegalStateException(); + } } private void appendSelect(StringBuilder query) @@ -293,6 +313,6 @@ public class SQLiteHabitList extends HabitList @Override public void setOrder(Order order) { - throw new NotImplementedException("Not implemented"); + this.order = order; } }