diff --git a/api/src/main/java/com/todoroo/andlib/utility/DateUtilities.java b/api/src/main/java/com/todoroo/andlib/utility/DateUtilities.java index 9b2471580..5881cd050 100644 --- a/api/src/main/java/com/todoroo/andlib/utility/DateUtilities.java +++ b/api/src/main/java/com/todoroo/andlib/utility/DateUtilities.java @@ -12,7 +12,6 @@ import android.text.format.DateUtils; import org.joda.time.DateTime; import org.tasks.api.R; -import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; @@ -199,6 +198,10 @@ public class DateUtilities { return getDateString(date) + " " + getTimeString(context, date); } + public static String getRelativeDay(Context context, long date) { + return DateUtilities.getRelativeDay(context, date, true); + } + /** * @return yesterday, today, tomorrow, or null */ @@ -227,28 +230,7 @@ public class DateUtilities { } public static boolean isEndOfMonth(Date d) { - int date = d.getDate(); - if (date < 28) { - return false; - } - - int month = d.getMonth(); - if (month == Calendar.FEBRUARY) { - return date >= 28; - } - - if (month == Calendar.APRIL || month == Calendar.JUNE || month == Calendar.SEPTEMBER || month == Calendar.NOVEMBER) { - return date >= 30; - } - - return date >= 31; - } - - /** - * Calls getRelativeDay with abbreviated parameter defaulted to true - */ - public static String getRelativeDay(Context context, long date) { - return DateUtilities.getRelativeDay(context, date, true); + return d.getDate() == new DateTime(d).dayOfMonth().getMaximumValue(); } private static final Calendar calendar = Calendar.getInstance(); @@ -261,37 +243,11 @@ public class DateUtilities { return calendar.getTimeInMillis(); } - private static long clearTime(Date date) { + static long clearTime(Date date) { date.setTime(date.getTime() / 1000L * 1000); date.setHours(0); date.setMinutes(0); date.setSeconds(0); return date.getTime(); } - - public static boolean isoStringHasTime(String iso8601String) { - return iso8601String.length() > 10; - } - - public static long parseIso8601(String iso8601String) throws ParseException { - if (iso8601String == null) { - return 0; - } - String formatString; - if (isoStringHasTime(iso8601String)) { // Time exists - iso8601String = iso8601String.replace("Z", "+00:00"); //$NON-NLS-1$ //$NON-NLS-2$ - try { - iso8601String = iso8601String.substring(0, 22) + iso8601String.substring(23); - } catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - throw new ParseException("Invalid ISO 8601 length for string " + iso8601String, 0); //$NON-NLS-1$ - } - formatString = "yyyy-MM-dd'T'HH:mm:ssZ"; //$NON-NLS-1$ - } else { - formatString = "yyyy-MM-dd"; //$NON-NLS-1$ - } - - Date result = new SimpleDateFormat(formatString).parse(iso8601String); - return result.getTime(); - } } diff --git a/astrid/src/test/java/com/todoroo/andlib/utility/DateUtilitiesTest.java b/astrid/src/test/java/com/todoroo/andlib/utility/DateUtilitiesTest.java index 04621dda6..33c1182c6 100644 --- a/astrid/src/test/java/com/todoroo/andlib/utility/DateUtilitiesTest.java +++ b/astrid/src/test/java/com/todoroo/andlib/utility/DateUtilitiesTest.java @@ -5,6 +5,8 @@ */ package com.todoroo.andlib.utility; +import android.content.Context; + import com.todoroo.andlib.test.TodorooRobolectricTestCase; import org.joda.time.DateTime; @@ -13,15 +15,21 @@ import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.tasks.Snippet; -import java.text.ParseException; -import java.util.Calendar; import java.util.Date; -import java.util.TimeZone; +import static com.todoroo.andlib.utility.DateUtilities.clearTime; +import static com.todoroo.andlib.utility.DateUtilities.getRelativeDay; +import static com.todoroo.andlib.utility.DateUtilities.getStartOfDay; +import static com.todoroo.andlib.utility.DateUtilities.isEndOfMonth; import static com.todoroo.andlib.utility.DateUtilities.oneMonthFromNow; +import static org.joda.time.DateTime.now; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.robolectric.Robolectric.getShadowApplication; import static org.tasks.Freeze.freezeAt; +import static org.tasks.Freeze.freezeClock; +import static org.tasks.date.DateTimeUtils.currentTimeMillis; import static org.tasks.date.DateTimeUtils.newDate; @RunWith(RobolectricTestRunner.class) @@ -38,13 +46,13 @@ public class DateUtilitiesTest extends TodorooRobolectricTestCase { Date d = newDate(); set24Hour(false); - for(int i = 0; i < 24; i++) { + for (int i = 0; i < 24; i++) { d.setHours(i); DateUtilities.getTimeString(getContext(), d); } set24Hour(true); - for(int i = 0; i < 24; i++) { + for (int i = 0; i < 24; i++) { d.setHours(i); DateUtilities.getTimeString(getContext(), d); } @@ -58,7 +66,7 @@ public class DateUtilitiesTest extends TodorooRobolectricTestCase { public void run() { Date d = newDate(); - for(int i = 0; i < 12; i++) { + for (int i = 0; i < 12; i++) { d.setMonth(i); DateUtilities.getDateString(d); } @@ -66,47 +74,6 @@ public class DateUtilitiesTest extends TodorooRobolectricTestCase { }); } - @Test - public void testParseISO8601() { - String withTime = "2013-01-28T13:17:02+00:00"; - long date; - Calendar cal = Calendar.getInstance(); - try { - date = DateUtilities.parseIso8601(withTime); - cal.setTimeInMillis(date); - cal.setTimeZone(TimeZone.getTimeZone("UTC")); - } catch (ParseException e) { - e.printStackTrace(); - fail("Parse exception"); - } - assertEquals(2013, cal.get(Calendar.YEAR)); - assertEquals(0, cal.get(Calendar.MONTH)); - assertEquals(28, cal.get(Calendar.DATE)); - assertEquals(13, cal.get(Calendar.HOUR_OF_DAY)); - assertEquals(17, cal.get(Calendar.MINUTE)); - assertEquals(2, cal.get(Calendar.SECOND)); - } - - @Test - public void testParseISO8601NoTime() { - String withTime = "2013-01-28"; - long date; - Calendar cal = Calendar.getInstance(); - try { - date = DateUtilities.parseIso8601(withTime); - cal.setTimeInMillis(date); - } catch (ParseException e) { - e.printStackTrace(); - fail("Parse exception"); - } - assertEquals(2013, cal.get(Calendar.YEAR)); - assertEquals(0, cal.get(Calendar.MONTH)); - assertEquals(28, cal.get(Calendar.DATE)); - assertEquals(0, cal.get(Calendar.HOUR_OF_DAY)); - assertEquals(0, cal.get(Calendar.MINUTE)); - assertEquals(0, cal.get(Calendar.SECOND)); - } - @Test public void oneMonthFromStartOfDecember() { DateTime now = new DateTime(2013, 12, 1, 12, 19, 45, 192); @@ -146,4 +113,82 @@ public class DateUtilitiesTest extends TodorooRobolectricTestCase { assertEquals(expected, oneMonthFromNow()); }}); } + + @Test + public void clearTimeFromDate() { + DateTime now = new DateTime(2014, 1, 3, 10, 34, 32, 98); + assertEquals( + now.withMillisOfDay(0).getMillis(), + clearTime(new Date(now.getMillis()))); + } + + @Test + public void shouldGetStartOfDay() { + DateTime now = new DateTime(2014, 1, 3, 10, 41, 41, 520); + assertEquals( + now.withMillisOfDay(0).getMillis(), + getStartOfDay(now.getMillis())); + } + + @Test + public void checkEndOfMonth() { + assertTrue(isEndOfMonth(newDate(2014, 1, 31))); + assertTrue(isEndOfMonth(newDate(2014, 2, 28))); + assertTrue(isEndOfMonth(newDate(2014, 3, 31))); + assertTrue(isEndOfMonth(newDate(2014, 4, 30))); + assertTrue(isEndOfMonth(newDate(2014, 5, 31))); + assertTrue(isEndOfMonth(newDate(2014, 6, 30))); + assertTrue(isEndOfMonth(newDate(2014, 7, 31))); + assertTrue(isEndOfMonth(newDate(2014, 8, 31))); + assertTrue(isEndOfMonth(newDate(2014, 9, 30))); + assertTrue(isEndOfMonth(newDate(2014, 10, 31))); + assertTrue(isEndOfMonth(newDate(2014, 11, 30))); + assertTrue(isEndOfMonth(newDate(2014, 12, 31))); + } + + @Test + public void notTheEndOfTheMonth() { + for(int month = 1 ; month <= 12 ; month++) { + int lastDay = new DateTime(2014, month, 1, 0, 0, 0, 0).dayOfMonth().getMaximumValue(); + for(int day = 1 ; day < lastDay ; day++) { + assertFalse(isEndOfMonth(newDate(2014, month, day))); + } + } + } + + @Test + public void checkEndOfMonthDuringLeapYear() { + assertFalse(isEndOfMonth(newDate(2016, 2, 28))); + assertTrue(isEndOfMonth(newDate(2016, 2, 29))); + } + + @Test + public void relativeDayIsToday() { + final Context context = getShadowApplication().getApplicationContext(); + freezeClock().thawAfter(new Snippet() {{ + final long today = currentTimeMillis(); + assertEquals("today", getRelativeDay(context, today)); + assertEquals("today", getRelativeDay(context, today, false)); + }}); + } + + @Test + public void relativeDayIsTomorrow() { + final Context context = getShadowApplication().getApplicationContext(); + freezeClock().thawAfter(new Snippet() {{ + final long tomorrow = now().plusDays(1).getMillis(); + assertEquals("tmrw", getRelativeDay(context, tomorrow)); + assertEquals("tomorrow", getRelativeDay(context, tomorrow, false)); + }}); + } + + @Test + public void relativeDayIsYesterday() { + final Context context = getShadowApplication().getApplicationContext(); + freezeClock().thawAfter(new Snippet() {{ + final long yesterday = now().minusDays(1).getMillis(); + assertEquals("yest", getRelativeDay(context, yesterday)); + assertEquals("yesterday", getRelativeDay(context, yesterday, false)); + }}); + } } diff --git a/astrid/src/test/java/com/todoroo/astrid/data/TaskTest.java b/astrid/src/test/java/com/todoroo/astrid/data/TaskTest.java index 841ab149c..0bffd6c39 100644 --- a/astrid/src/test/java/com/todoroo/astrid/data/TaskTest.java +++ b/astrid/src/test/java/com/todoroo/astrid/data/TaskTest.java @@ -6,8 +6,12 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import org.tasks.Snippet; +import static com.todoroo.astrid.data.Task.COMPLETION_DATE; +import static com.todoroo.astrid.data.Task.DELETION_DATE; import static com.todoroo.astrid.data.Task.DUE_DATE; +import static com.todoroo.astrid.data.Task.HIDE_UNTIL; import static com.todoroo.astrid.data.Task.URGENCY_DAY_AFTER; import static com.todoroo.astrid.data.Task.URGENCY_IN_TWO_WEEKS; import static com.todoroo.astrid.data.Task.URGENCY_NEXT_MONTH; @@ -24,6 +28,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.tasks.Freeze.freezeAt; import static org.tasks.Freeze.thaw; +import static org.tasks.date.DateTimeUtils.currentTimeMillis; @RunWith(RobolectricTestRunner.class) public class TaskTest { @@ -127,4 +132,106 @@ public class TaskTest { public void doesNotHaveDueTime() { assertFalse(hasDueTime(1388469600000L)); } + + @Test + public void newTaskIsNotCompleted() { + assertFalse(new Task().isCompleted()); + } + + @Test + public void newTaskNotDeleted() { + assertFalse(new Task().isDeleted()); + } + + @Test + public void newTaskNotHidden() { + assertFalse(new Task().isHidden()); + } + + @Test + public void newTaskDoesNotHaveDueDateOrTime() { + assertFalse(new Task().hasDueDate()); + assertFalse(new Task().hasDueTime()); + } + + @Test + public void taskIsCompleted() { + Task task = new Task(); + task.setValue(COMPLETION_DATE, 1L); + assertTrue(task.isCompleted()); + } + + @Test + public void taskIsNotHiddenAtHideUntilTime() { + final long now = currentTimeMillis(); + freezeAt(now).thawAfter(new Snippet() {{ + Task task = new Task(); + task.setValue(HIDE_UNTIL, now); + assertFalse(task.isHidden()); + }}); + } + + @Test + public void taskIsHiddenBeforeHideUntilTime() { + final long now = currentTimeMillis(); + freezeAt(now).thawAfter(new Snippet() {{ + Task task = new Task(); + task.setValue(HIDE_UNTIL, now + 1); + assertTrue(task.isHidden()); + }}); + } + + @Test + public void taskIsDeleted() { + Task task = new Task(); + task.setValue(DELETION_DATE, 1L); + assertTrue(task.isDeleted()); + } + + @Test + public void taskWithNoDueDateIsOverdue() { + assertTrue(new Task().isOverdue()); + } + + @Test + public void taskNotOverdueAtDueTime() { + final long now = currentTimeMillis(); + freezeAt(now).thawAfter(new Snippet() {{ + Task task = new Task(); + task.setValue(DUE_DATE, now); + assertFalse(task.isOverdue()); + }}); + } + + @Test + public void taskIsOverduePastDueTime() { + final long dueDate = currentTimeMillis(); + freezeAt(dueDate + 1).thawAfter(new Snippet() {{ + Task task = new Task(); + task.setValue(DUE_DATE, dueDate); + assertTrue(task.isOverdue()); + }}); + } + + @Test + public void taskNotOverdueBeforeNoonOnDueDate() { + final DateTime dueDate = new DateTime().withMillisOfDay(0); + freezeAt(dueDate.plusHours(12).minusMillis(1)).thawAfter(new Snippet() {{ + Task task = new Task(); + task.setValue(DUE_DATE, dueDate.getMillis()); + assertFalse(task.hasDueTime()); + assertFalse(task.isOverdue()); + }}); + } + + @Test + public void taskOverdueAtNoonOnDueDate() { + final DateTime dueDate = new DateTime().withMillisOfDay(0); + freezeAt(dueDate.plusHours(12)).thawAfter(new Snippet() {{ + Task task = new Task(); + task.setValue(DUE_DATE, dueDate.getMillis()); + assertFalse(task.hasDueTime()); + assertTrue(task.isOverdue()); + }}); + } } diff --git a/astrid/src/test/java/org/tasks/Freeze.java b/astrid/src/test/java/org/tasks/Freeze.java index d10b77b84..07e5724d9 100644 --- a/astrid/src/test/java/org/tasks/Freeze.java +++ b/astrid/src/test/java/org/tasks/Freeze.java @@ -3,8 +3,14 @@ package org.tasks; import org.joda.time.DateTime; import org.joda.time.DateTimeUtils; +import static org.joda.time.DateTime.now; + public class Freeze { + public static Freeze freezeClock() { + return freezeAt(now()); + } + public static Freeze freezeAt(DateTime dateTime) { return freezeAt(dateTime.getMillis()); }