stable test for recurring days
This commit is contained in:
parent
55836799da
commit
d9e7d617e1
@ -12,6 +12,7 @@ import org.json.JSONObject;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
import static com.philliphsu.clock2.DaysOfWeek.NUM_DAYS;
|
||||||
import static com.philliphsu.clock2.DaysOfWeek.SATURDAY;
|
import static com.philliphsu.clock2.DaysOfWeek.SATURDAY;
|
||||||
import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
|||||||
*/
|
*/
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class Alarm implements JsonSerializable {
|
public abstract class Alarm implements JsonSerializable {
|
||||||
private static final int MAX_MINUTES_CAN_SNOOZE = 30; // TODO: Delete this along with all snooze stuff.
|
private static final int MAX_MINUTES_CAN_SNOOZE = 30;
|
||||||
|
|
||||||
// JSON property names
|
// JSON property names
|
||||||
private static final String KEY_SNOOZING_UNTIL_MILLIS = "snoozing_until_millis";
|
private static final String KEY_SNOOZING_UNTIL_MILLIS = "snoozing_until_millis";
|
||||||
@ -82,7 +83,7 @@ public abstract class Alarm implements JsonSerializable {
|
|||||||
.id(-1)
|
.id(-1)
|
||||||
.hour(0)
|
.hour(0)
|
||||||
.minutes(0)
|
.minutes(0)
|
||||||
.recurringDays(new boolean[DaysOfWeek.NUM_DAYS])
|
.recurringDays(new boolean[NUM_DAYS])
|
||||||
.label("")
|
.label("")
|
||||||
.ringtone("")
|
.ringtone("")
|
||||||
.vibrates(false);
|
.vibrates(false);
|
||||||
@ -146,26 +147,57 @@ public abstract class Alarm implements JsonSerializable {
|
|||||||
calendar.set(Calendar.MINUTE, minutes());
|
calendar.set(Calendar.MINUTE, minutes());
|
||||||
calendar.set(Calendar.SECOND, 0);
|
calendar.set(Calendar.SECOND, 0);
|
||||||
calendar.set(Calendar.MILLISECOND, 0);
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
|
if (!hasRecurrence()) {
|
||||||
if (calendar.getTimeInMillis() <= System.currentTimeMillis()) {
|
if (calendar.getTimeInMillis() <= System.currentTimeMillis()) {
|
||||||
// The specified time has passed for today
|
// The specified time has passed for today
|
||||||
// TODO: This should be wrapped in an if (!hasRecurrence())?
|
|
||||||
calendar.add(Calendar.HOUR_OF_DAY, 24);
|
calendar.add(Calendar.HOUR_OF_DAY, 24);
|
||||||
// TODO: Else, compute ring time for the next closest recurring day
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Compute the ring time just for the next closest recurring day.
|
||||||
|
// Remember that day constants defined in the Calendar class are not zero-based like ours, so we have to
|
||||||
|
// compensate with an offset of magnitude one, with the appropriate sign based on the situation.
|
||||||
|
int weekdayToday = calendar.get(Calendar.DAY_OF_WEEK);
|
||||||
|
int numDaysFromToday = -1;
|
||||||
|
|
||||||
/* // Not fully thought out or completed!
|
for (int i = weekdayToday; i <= Calendar.SATURDAY; i++) {
|
||||||
// TODO: Compute ring time for the next closest recurring day
|
if (isRecurring(i - 1 /*match up with our day constant*/)) {
|
||||||
for (int i = 0; i < NUM_DAYS; i++) {
|
if (i == weekdayToday) {
|
||||||
// The constants for the days defined in Calendar are
|
if (calendar.getTimeInMillis() > System.currentTimeMillis()) {
|
||||||
// not zero-based, but we are, so we must add 1.
|
// The normal ring time has not passed yet
|
||||||
int day = i + 1; // day for this index
|
numDaysFromToday = 0;
|
||||||
int calendarDay = mCalendar.get(Calendar.DAY_OF_WEEK);
|
break;
|
||||||
if (mRecurringDays[day]) {
|
}
|
||||||
mCalendar.add(Calendar.DAY_OF_WEEK, day);
|
} else {
|
||||||
|
numDaysFromToday = i - weekdayToday;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
// Not computed yet
|
||||||
|
if (numDaysFromToday < 0) {
|
||||||
|
for (int i = Calendar.SUNDAY; i < weekdayToday; i++) {
|
||||||
|
if (isRecurring(i - 1 /*match up with our day constant*/)) {
|
||||||
|
numDaysFromToday = Calendar.SATURDAY - weekdayToday + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still not computed yet. The only recurring day is weekdayToday,
|
||||||
|
// and its normal ring time has already passed.
|
||||||
|
if (numDaysFromToday < 0 && isRecurring(weekdayToday - 1)
|
||||||
|
&& calendar.getTimeInMillis() <= System.currentTimeMillis()) {
|
||||||
|
numDaysFromToday = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numDaysFromToday < 0)
|
||||||
|
throw new IllegalStateException("How did we get here?");
|
||||||
|
|
||||||
|
calendar.add(Calendar.HOUR_OF_DAY, 24 * numDaysFromToday);
|
||||||
|
}
|
||||||
|
|
||||||
return calendar.getTimeInMillis();
|
return calendar.getTimeInMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,14 +270,16 @@ public abstract class Alarm implements JsonSerializable {
|
|||||||
this.id(++idCount); // TOneverDO: change to post-increment without also adding offset of 1 to idCount in rebuild()
|
this.id(++idCount); // TOneverDO: change to post-increment without also adding offset of 1 to idCount in rebuild()
|
||||||
Alarm alarm = autoBuild();
|
Alarm alarm = autoBuild();
|
||||||
checkTime(alarm.hour(), alarm.minutes());
|
checkTime(alarm.hour(), alarm.minutes());
|
||||||
|
checkRecurringDaysArrayLength(alarm.recurringDays());
|
||||||
return alarm;
|
return alarm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Should only be called when recreating an instance from JSON */
|
/** <b>Should only be called when recreating an instance from JSON</b> */
|
||||||
private Alarm rebuild() {
|
private Alarm rebuild() {
|
||||||
Alarm alarm = autoBuild();
|
Alarm alarm = autoBuild();
|
||||||
idCount = alarm.id(); // prevent future instances from id collision
|
idCount = alarm.id(); // prevent future instances from id collision
|
||||||
checkTime(alarm.hour(), alarm.minutes());
|
checkTime(alarm.hour(), alarm.minutes());
|
||||||
|
checkRecurringDaysArrayLength(alarm.recurringDays());
|
||||||
return alarm;
|
return alarm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,4 +295,10 @@ public abstract class Alarm implements JsonSerializable {
|
|||||||
throw new IllegalStateException("Hour and minutes invalid");
|
throw new IllegalStateException("Hour and minutes invalid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkRecurringDaysArrayLength(boolean[] b) {
|
||||||
|
if (b.length != NUM_DAYS) {
|
||||||
|
throw new IllegalStateException("Invalid length for recurring days array");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import java.util.Arrays;
|
|||||||
/**
|
/**
|
||||||
* Created by Phillip Hsu on 5/30/2016.
|
* Created by Phillip Hsu on 5/30/2016.
|
||||||
*/
|
*/
|
||||||
public class DaysOfWeek {
|
public class DaysOfWeek implements DaysOfWeekHelper {
|
||||||
private static final String TAG = "DaysOfWeek";
|
private static final String TAG = "DaysOfWeek";
|
||||||
// DAY_OF_WEEK constants in Calendar class not zero-based
|
// DAY_OF_WEEK constants in Calendar class not zero-based
|
||||||
public static final int SUNDAY = 0;
|
public static final int SUNDAY = 0;
|
||||||
@ -56,14 +56,14 @@ public class DaysOfWeek {
|
|||||||
return sAppContext.getString(LABELS_RES[weekDay]);
|
return sAppContext.getString(LABELS_RES[weekDay]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the week day at {@code position} within the user-defined week */
|
@Override
|
||||||
public int weekDayAt(int position) {
|
public int weekDayAt(int position) {
|
||||||
if (position < 0 || position > 6)
|
if (position < 0 || position > 6)
|
||||||
throw new ArrayIndexOutOfBoundsException("Ordinal day out of range");
|
throw new ArrayIndexOutOfBoundsException("Ordinal day out of range");
|
||||||
return DAYS[position];
|
return DAYS[position];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the position of the {@code weekDay} within the user-defined week */
|
@Override
|
||||||
public int positionOf(int weekDay) {
|
public int positionOf(int weekDay) {
|
||||||
if (weekDay < SUNDAY || weekDay > SATURDAY)
|
if (weekDay < SUNDAY || weekDay > SATURDAY)
|
||||||
throw new ArrayIndexOutOfBoundsException("Week day ("+weekDay+") out of range");
|
throw new ArrayIndexOutOfBoundsException("Week day ("+weekDay+") out of range");
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
package com.philliphsu.clock2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Phillip Hsu on 6/9/2016.
|
||||||
|
*/
|
||||||
|
public interface DaysOfWeekHelper {
|
||||||
|
/** @return the week day at {@code position} within the user-defined week */
|
||||||
|
int weekDayAt(int position);
|
||||||
|
|
||||||
|
/** @return the position of the {@code weekDay} within the user-defined week */
|
||||||
|
int positionOf(int weekDay);
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import org.junit.Test;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
import static com.philliphsu.clock2.DaysOfWeek.SATURDAY;
|
||||||
import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
||||||
import static java.lang.System.out;
|
import static java.lang.System.out;
|
||||||
import static java.util.Calendar.HOUR_OF_DAY;
|
import static java.util.Calendar.HOUR_OF_DAY;
|
||||||
@ -25,14 +26,14 @@ public class AlarmTest {
|
|||||||
Alarm alarm = Alarm.builder().build();
|
Alarm alarm = Alarm.builder().build();
|
||||||
|
|
||||||
// Some true, some false
|
// Some true, some false
|
||||||
for (int i = SUNDAY; i <= DaysOfWeek.SATURDAY; i++) {
|
for (int i = SUNDAY; i <= SATURDAY; i++) {
|
||||||
alarm.setRecurring(i, i % 2 == 0);
|
alarm.setRecurring(i, i % 2 == 0);
|
||||||
assertTrue(alarm.isRecurring(i) == (i % 2 == 0));
|
assertTrue(alarm.isRecurring(i) == (i % 2 == 0));
|
||||||
}
|
}
|
||||||
assertTrue(alarm.hasRecurrence());
|
assertTrue(alarm.hasRecurrence());
|
||||||
|
|
||||||
// All false
|
// All false
|
||||||
for (int i = DaysOfWeek.SUNDAY; i <= DaysOfWeek.SATURDAY; i++) {
|
for (int i = SUNDAY; i <= SATURDAY; i++) {
|
||||||
alarm.setRecurring(i, false);
|
alarm.setRecurring(i, false);
|
||||||
assertFalse(alarm.isRecurring(i));
|
assertFalse(alarm.isRecurring(i));
|
||||||
}
|
}
|
||||||
@ -82,6 +83,116 @@ public class AlarmTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void alarm_RingsAt_RecurringDays_ReturnsCorrectRingTime() {
|
||||||
|
Calendar cal = new GregorianCalendar();
|
||||||
|
int weekDayToday = cal.get(Calendar.DAY_OF_WEEK);
|
||||||
|
|
||||||
|
for (int h = 0; h < 24; h++) {
|
||||||
|
for (int m = 0; m < 60; m++) {
|
||||||
|
for (int d = SUNDAY; d <= SATURDAY; d++) {
|
||||||
|
out.println(String.format("Testing %02d:%02d for day %d", h, m, d));
|
||||||
|
int hC = cal.get(HOUR_OF_DAY); // Current hour
|
||||||
|
int mC = cal.get(MINUTE); // Current minute
|
||||||
|
Alarm a = Alarm.builder().hour(h).minutes(m).build();
|
||||||
|
a.setRecurring(d, true);
|
||||||
|
long calculatedRingTime;
|
||||||
|
boolean calculatedToNextDay = true;
|
||||||
|
if (h <= hC) {
|
||||||
|
if (m <= mC) {
|
||||||
|
calculatedRingTime = (23 - hC + h) * 3600000 + (60 - mC + m) * 60000;
|
||||||
|
} else {
|
||||||
|
calculatedRingTime = (m - mC) * 60000;
|
||||||
|
if (h < hC) {
|
||||||
|
calculatedRingTime += (24 - hC + h) * 3600000;
|
||||||
|
} else {
|
||||||
|
// h == hC
|
||||||
|
calculatedToNextDay = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m <= mC) {
|
||||||
|
calculatedRingTime = (h - hC - 1) * 3600000 + (60 - mC + m) * 60000;
|
||||||
|
} else {
|
||||||
|
calculatedRingTime = (h - hC) * 3600000 + (m - mC) * 60000;
|
||||||
|
}
|
||||||
|
calculatedToNextDay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int day = d + 1; // Match up with day constant defined in Calendar class
|
||||||
|
int amount = calculatedToNextDay ? d : day; // the amount to add on
|
||||||
|
if (day > weekDayToday) {
|
||||||
|
calculatedRingTime += 24 * (amount - weekDayToday) * 3600000;
|
||||||
|
} else if (day < weekDayToday) {
|
||||||
|
calculatedRingTime += 24 * (Calendar.SATURDAY - weekDayToday + amount) * 3600000;
|
||||||
|
} else {
|
||||||
|
long initialTime = cal.getTimeInMillis();
|
||||||
|
// Temporarily add on whatever we have so far
|
||||||
|
cal.setTimeInMillis(initialTime + calculatedRingTime);
|
||||||
|
cal.set(SECOND, 0);
|
||||||
|
cal.set(MILLISECOND, 0);
|
||||||
|
if (calculatedToNextDay) {
|
||||||
|
// Temporarily subtract off a whole day's worth of millis
|
||||||
|
cal.add(HOUR_OF_DAY, -24);
|
||||||
|
}
|
||||||
|
if (cal.getTimeInMillis() <= System.currentTimeMillis()) {
|
||||||
|
calculatedRingTime += 24 * (calculatedToNextDay ? 6 : 7) * 3600000;
|
||||||
|
}
|
||||||
|
cal.setTimeInMillis(initialTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
cal.setTimeInMillis(cal.getTimeInMillis() + calculatedRingTime);
|
||||||
|
cal.set(SECOND, 0);
|
||||||
|
cal.set(MILLISECOND, 0);
|
||||||
|
assertEquals(a.ringsAt(), cal.getTimeInMillis());
|
||||||
|
// VERY IMPORTANT TO RESET AT THE END!!!!
|
||||||
|
cal.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void alarm_RingsAt_AllRecurringDays_ReturnsCorrectRingTime() {
|
||||||
|
// The results of this test should be the same as the normal ringsAt test:
|
||||||
|
// alarm_RingsAt_ReturnsCorrectRingTime().
|
||||||
|
GregorianCalendar now = new GregorianCalendar();
|
||||||
|
for (int h = 0; h < 24; h++) {
|
||||||
|
for (int m = 0; m < 60; m++) {
|
||||||
|
out.println(String.format("Testing %02d:%02d", h, m));
|
||||||
|
int hC = now.get(HOUR_OF_DAY); // Current hour
|
||||||
|
int mC = now.get(MINUTE); // Current minute
|
||||||
|
Alarm a = Alarm.builder().hour(h).minutes(m).build();
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
a.setRecurring(i, true);
|
||||||
|
}
|
||||||
|
long calculatedRingTime;
|
||||||
|
if (h <= hC) {
|
||||||
|
if (m <= mC) {
|
||||||
|
calculatedRingTime = (23-hC+h)*3600000 + (60-mC+m)*60000;
|
||||||
|
} else {
|
||||||
|
calculatedRingTime = (m-mC)*60000;
|
||||||
|
if (h < hC) {
|
||||||
|
calculatedRingTime += (24-hC+h)*3600000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m <= mC) {
|
||||||
|
calculatedRingTime = (h-hC-1)*3600000+(60-mC+m)*60000;
|
||||||
|
} else {
|
||||||
|
calculatedRingTime = (h-hC)*3600000+(m-mC)*60000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
now.setTimeInMillis(now.getTimeInMillis() + calculatedRingTime);
|
||||||
|
now.set(SECOND, 0);
|
||||||
|
now.set(MILLISECOND, 0);
|
||||||
|
assertEquals(a.ringsAt(), now.getTimeInMillis());
|
||||||
|
// VERY IMPORTANT TO RESET AT THE END!!!! THIS TOOK A WHOLE FUCKING DAY OF BUG HUNTING!!!
|
||||||
|
now.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void snoozeAlarm_AssertEquals_SnoozingUntilMillis_CorrespondsToWallClock() {
|
public void snoozeAlarm_AssertEquals_SnoozingUntilMillis_CorrespondsToWallClock() {
|
||||||
Calendar cal = new GregorianCalendar();
|
Calendar cal = new GregorianCalendar();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user