From 2f09ff775239b3c933c0a612b133a90d6152bf35 Mon Sep 17 00:00:00 2001 From: Ng Tze Henn <tzehenn@gmail.com> Date: Tue, 19 Oct 2021 16:10:44 +0800 Subject: [PATCH 1/7] Add Recurring Tasks --- .../logic/commands/AddTaskCommand.java | 6 +- .../logic/commands/ViewTasksCommand.java | 3 + .../logic/parser/AddTaskCommandParser.java | 10 ++- .../seedu/address/logic/parser/CliSyntax.java | 1 + .../address/logic/parser/ParserUtil.java | 10 +++ .../java/seedu/address/model/AddressBook.java | 1 + .../seedu/address/model/task/DateTime.java | 5 ++ .../seedu/address/model/task/Recurrence.java | 77 +++++++++++++++++++ .../java/seedu/address/model/task/Status.java | 4 +- .../java/seedu/address/model/task/Task.java | 52 +++++++++++-- .../seedu/address/model/task/TaskList.java | 56 ++++++++++++++ .../address/storage/JsonAdaptedTask.java | 21 ++++- src/main/java/seedu/address/ui/TaskCard.java | 5 +- src/main/resources/view/TaskListCard.fxml | 1 + .../invalidTaskAddressBook.json | 3 +- .../typicalTasksAddressBook.json | 21 +++-- .../logic/commands/RemindCommandTest.java | 5 ++ .../logic/commands/TaskCommandTestUtil.java | 8 ++ .../parser/AddTaskCommandParserTest.java | 6 +- .../address/model/task/DateTimeTest.java | 2 +- .../address/model/task/RecurrenceTest.java | 44 +++++++++++ .../address/model/task/TaskListTest.java | 68 ++++++++++++++++ .../seedu/address/model/task/TaskTest.java | 8 +- .../seedu/address/testutil/TaskBuilder.java | 15 +++- .../seedu/address/testutil/TypicalTasks.java | 36 +++++++-- 25 files changed, 429 insertions(+), 39 deletions(-) create mode 100644 src/main/java/seedu/address/model/task/Recurrence.java create mode 100644 src/test/java/seedu/address/model/task/RecurrenceTest.java diff --git a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java index 5f02442b13b..4c88bcaf7ac 100644 --- a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java @@ -4,6 +4,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DATE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_RECURRING; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_TIME; import seedu.address.logic.commands.exceptions.CommandException; @@ -22,9 +23,10 @@ public class AddTaskCommand extends Command { + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "Khong Guan " + " " + PREFIX_NAME + "Swee Choon" - + " " + PREFIX_TASK_DESC + "Scheduled 3rd Pfizer shot" + + " " + PREFIX_TASK_DESC + "Weekly Taiji" + " " + PREFIX_TASK_DATE + "2021-10-10" - + " " + PREFIX_TASK_TIME + "14:30"; + + " " + PREFIX_TASK_TIME + "14:30" + + " " + PREFIX_TASK_RECURRING + "week"; public static final String MESSAGE_SUCCESS = "New task added: %1$s"; diff --git a/src/main/java/seedu/address/logic/commands/ViewTasksCommand.java b/src/main/java/seedu/address/logic/commands/ViewTasksCommand.java index b1d385d74f5..7db148573e2 100644 --- a/src/main/java/seedu/address/logic/commands/ViewTasksCommand.java +++ b/src/main/java/seedu/address/logic/commands/ViewTasksCommand.java @@ -6,6 +6,9 @@ import seedu.address.logic.commands.CommandResult.ListDisplayChange; import seedu.address.model.Model; +/** + * Lists all tasks in the address book to the user. + */ public class ViewTasksCommand extends Command { public static final String COMMAND_WORD = "viewTasks"; diff --git a/src/main/java/seedu/address/logic/parser/AddTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/AddTaskCommandParser.java index f67df8f04b7..4c3e6aec523 100644 --- a/src/main/java/seedu/address/logic/parser/AddTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddTaskCommandParser.java @@ -4,6 +4,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DATE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_RECURRING; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_TIME; import java.util.Set; @@ -14,6 +15,8 @@ import seedu.address.model.person.Name; import seedu.address.model.task.DateTime; import seedu.address.model.task.Description; +import seedu.address.model.task.Recurrence; +import seedu.address.model.task.Recurrence.RecurrenceType; import seedu.address.model.task.Task; /** @@ -28,7 +31,8 @@ public class AddTaskCommandParser implements Parser<AddTaskCommand> { */ public AddTaskCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_TASK_DESC, PREFIX_TASK_DATE, PREFIX_TASK_TIME); + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_TASK_DESC, PREFIX_TASK_DATE, PREFIX_TASK_TIME, + PREFIX_TASK_RECURRING); if (!arePrefixesPresent(argMultimap, PREFIX_TASK_DESC, PREFIX_TASK_DATE, PREFIX_TASK_TIME) || !argMultimap.getPreamble().isEmpty()) { @@ -40,8 +44,10 @@ public AddTaskCommand parse(String args) throws ParseException { DateTime dateTime = ParserUtil.parseDateTime( argMultimap.getValue(PREFIX_TASK_DATE).get(), argMultimap.getValue(PREFIX_TASK_TIME).get()); + Recurrence recurrence = ParserUtil.parseRecurrence( + argMultimap.getValue(PREFIX_TASK_RECURRING).orElse(RecurrenceType.NONE.name())); - Task task = new Task(description, dateTime, relatedNames); + Task task = new Task(description, dateTime, relatedNames, recurrence); return new AddTaskCommand(task); } diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index c10ab2fc51c..848974f4204 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -20,5 +20,6 @@ public class CliSyntax { public static final Prefix PREFIX_TASK_DESC = new Prefix("desc/"); public static final Prefix PREFIX_TASK_DATE = new Prefix("date/"); public static final Prefix PREFIX_TASK_TIME = new Prefix("time/"); + public static final Prefix PREFIX_TASK_RECURRING = new Prefix("recur/"); } diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index a41973c6452..f3a65dc0798 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -21,6 +21,7 @@ import seedu.address.model.tag.Tag; import seedu.address.model.task.DateTime; import seedu.address.model.task.Description; +import seedu.address.model.task.Recurrence; /** * Contains utility methods used for parsing strings in the various *Parser classes. @@ -249,4 +250,13 @@ public static DateTime parseDateTime(String date, String time) throws ParseExcep } return new DateTime(trimmedDate, trimmedTime); } + + public static Recurrence parseRecurrence(String recurrenceType) throws ParseException { + requireNonNull(recurrenceType); + String trimmedRecurrenceType = recurrenceType.trim().toUpperCase(); + if (!Recurrence.isValidRecurrence(trimmedRecurrenceType)) { + throw new ParseException(Recurrence.MESSAGE_CONSTRAINTS); + } + return new Recurrence(trimmedRecurrenceType); + } } diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 08acb045087..0d7c0c6ff77 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -144,6 +144,7 @@ public ObservableList<Elderly> getElderlyList() { @Override public ObservableList<Task> getTaskList() { + tasks.changeDateOfPastRecurringTasks(); return tasks.asUnmodifiableObservableList(); } diff --git a/src/main/java/seedu/address/model/task/DateTime.java b/src/main/java/seedu/address/model/task/DateTime.java index af2001642eb..d63beb98ade 100644 --- a/src/main/java/seedu/address/model/task/DateTime.java +++ b/src/main/java/seedu/address/model/task/DateTime.java @@ -42,6 +42,11 @@ public DateTime(String date, String time) { } } + public DateTime(LocalDate date, LocalTime time) { + this.date = date; + this.time = time; + } + /** * Returns true if a given string is a valid date. */ diff --git a/src/main/java/seedu/address/model/task/Recurrence.java b/src/main/java/seedu/address/model/task/Recurrence.java new file mode 100644 index 00000000000..71a5e3bcae0 --- /dev/null +++ b/src/main/java/seedu/address/model/task/Recurrence.java @@ -0,0 +1,77 @@ +package seedu.address.model.task; + +import seedu.address.model.person.Age; + +import java.util.Objects; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents if a task is a recurring task in NurseyBook. + * Guarantees: immutable; is valid as declared in {@link #isValidRecurrence(String)} + */ +public class Recurrence { + public static final String MESSAGE_CONSTRAINTS = "Recurrence can only be of type day, week or month and " + + "is case-insensitive. It cannot be null."; + + /** + * The first character of the Description must not be a whitespace, + * otherwise " " (a blank string) becomes a valid input. + */ + public static final String VALIDATION_REGEX = "\\bNONE|DAY|WEEK|MONTH\\b"; + + private boolean isRecurring; + + private RecurrenceType recurrenceType; + + public enum RecurrenceType { + NONE, DAY, WEEK, MONTH + } + + public Recurrence(String recurrenceTypeStr) { + requireNonNull(recurrenceTypeStr); + recurrenceTypeStr = recurrenceTypeStr.toUpperCase(); + checkArgument(isValidRecurrence(recurrenceTypeStr), MESSAGE_CONSTRAINTS); + this.isRecurring = !recurrenceTypeStr.equals(RecurrenceType.NONE.name()); + this.recurrenceType = RecurrenceType.valueOf(recurrenceTypeStr); + } + + /** + * Returns true if a given string is a valid recurrence type. + */ + public static boolean isValidRecurrence(String test) { + return test.matches(VALIDATION_REGEX); + } + + public boolean isRecurring() { + return isRecurring; + } + +// public void setRecurring(boolean recurring) { +// isRecurring = recurring; +// } + + public RecurrenceType getRecurrenceType() { + return recurrenceType; + } + + @Override + public String toString() { + return recurrenceType.name(); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof Recurrence // instanceof handles nulls + && isRecurring == ((Recurrence) other).isRecurring) // both booleans are the same + && recurrenceType.equals(((Recurrence) other).recurrenceType); // state check + } + + @Override + public int hashCode() { + return Objects.hash(isRecurring, recurrenceType); + } + +} diff --git a/src/main/java/seedu/address/model/task/Status.java b/src/main/java/seedu/address/model/task/Status.java index 0972e47baa1..9d0a1b9b9e5 100644 --- a/src/main/java/seedu/address/model/task/Status.java +++ b/src/main/java/seedu/address/model/task/Status.java @@ -12,13 +12,13 @@ public class Status { public static final String MESSAGE_CONSTRAINTS = "Status can take either 'true' or 'false' as its values and" + "is case-insensitive. It cannot be null."; - /* + /** * The first character of the Description must not be a whitespace, * otherwise " " (a blank string) becomes a valid input. */ public static final String VALIDATION_REGEX = "^(?i)(true|false)$"; - /* + /** * If a task is completed/done, isDone will be true. Else, it will be false. */ public final boolean isDone; diff --git a/src/main/java/seedu/address/model/task/Task.java b/src/main/java/seedu/address/model/task/Task.java index 13e6591d4f6..287e50add96 100644 --- a/src/main/java/seedu/address/model/task/Task.java +++ b/src/main/java/seedu/address/model/task/Task.java @@ -10,9 +10,10 @@ public class Task implements Comparable<Task> { private final Description desc; - private final DateTime dateTime; + private DateTime dateTime; private final Status status; private final Set<Name> relatedNames = new HashSet<>(); + private final Recurrence recurrence; /** * Creates a Task object. @@ -26,6 +27,22 @@ public Task(Description desc, DateTime dt, Set<Name> names) { this.dateTime = dt; this.relatedNames.addAll(names); this.status = new Status("false"); + this.recurrence = new Recurrence(Recurrence.RecurrenceType.NONE.name()); + } + + /** + * Creates a Task object. + * + * @param desc the description of the task + * @param dt the date and time of the task + * @param names the names of people associated with the task + */ + public Task(Description desc, DateTime dt, Set<Name> names, Recurrence recurrence) { + this.desc = desc; + this.dateTime = dt; + this.relatedNames.addAll(names); + this.status = new Status("false"); + this.recurrence = recurrence; } /** @@ -41,6 +58,15 @@ public Task(Description desc, DateTime dt, Set<Name> names, Status status) { this.dateTime = dt; this.relatedNames.addAll(names); this.status = status; + this.recurrence = new Recurrence(Recurrence.RecurrenceType.NONE.name()); + } + + public Task(Description desc, DateTime dt, Set<Name> names, Status status, Recurrence recurrence) { + this.desc = desc; + this.dateTime = dt; + this.relatedNames.addAll(names); + this.status = status; + this.recurrence = recurrence; } /** @@ -49,12 +75,14 @@ public Task(Description desc, DateTime dt, Set<Name> names, Status status) { * @return same task object that has been marked as done */ public Task markAsDone() { - if (isTaskDone()) { + return new Task(desc, dateTime, relatedNames, new Status("true"), recurrence); + } - } - return new Task(desc, dateTime, relatedNames, new Status("true")); + public Task markAsUndone() { + return new Task(desc, dateTime, relatedNames, new Status("false"), recurrence); } + /** * Returns task description of this task. * @@ -91,6 +119,19 @@ public Status getStatus() { return status; } + /** + * Returns the recurrence type of this task. + * + * @return task recurrence type + */ + public Recurrence getRecurrence() { + return recurrence; + } + + public void setDateTime(DateTime dt) { + this.dateTime = dt; + } + /** * Returns true if task dateTime is after the date given in the argument. * @@ -139,7 +180,8 @@ public boolean equals(Object obj) { return other.getDesc().equals(this.desc) && other.getDateTime().equals(this.dateTime) && other.getRelatedNames().equals(this.relatedNames) - && other.getStatus().equals(this.status); + && other.getStatus().equals(this.status) + && other.getRecurrence().equals(this.recurrence); } return false; } diff --git a/src/main/java/seedu/address/model/task/TaskList.java b/src/main/java/seedu/address/model/task/TaskList.java index b3892e6ee27..588e5228a21 100644 --- a/src/main/java/seedu/address/model/task/TaskList.java +++ b/src/main/java/seedu/address/model/task/TaskList.java @@ -3,6 +3,11 @@ import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -10,6 +15,7 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import seedu.address.model.task.exceptions.TaskNotFoundException; +import seedu.address.model.task.Recurrence.RecurrenceType; /** * A list of tasks that does not allow nulls. @@ -55,6 +61,14 @@ public void markTaskAsDone(Task toMark) { setTask(toMark, toMark.markAsDone()); } + /** + * Mark the task {@code target} in the list as undone. + * {@code target} must exist in the list. + */ + public void markTaskAsUndone(Task toMark) { + setTask(toMark, toMark.markAsUndone()); + } + /** * Replaces this list with the list from {@code replacement}. */ @@ -82,6 +96,48 @@ public void remove(Task toRemove) { } } + public void changeDateOfPastRecurringTasks() { + LocalDateTime currentDateTime = LocalDateTime.now(); + + for (Task t : this.internalList) { + Recurrence recurrence = t.getRecurrence(); + if (recurrence.isRecurring()) { + RecurrenceType recurrenceType = recurrence.getRecurrenceType(); + assert(recurrenceType != RecurrenceType.NONE); + DateTime taskDateTime = t.getDateTime(); + LocalDate taskDate = taskDateTime.date; + LocalTime taskTime = taskDateTime.time; + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy HH mm"); + String inputString = String.format("%02d", taskDate.getDayOfMonth()) + " " + + String.format("%02d", taskDate.getMonthValue()) + " " + + String.format("%02d", taskDate.getYear()) + " " + + String.format("%02d", taskTime.getHour()) + " " + + String.format("%02d", taskTime.getMinute()); + LocalDateTime taskLocalDateTime = LocalDateTime.parse(inputString, dtf); + long daysBetween = Duration.between(taskLocalDateTime, currentDateTime).toDays(); + // if task dateTime is before current dateTime + if (daysBetween > 0) { + LocalDateTime taskNewLocalDateTime; + if (recurrenceType == RecurrenceType.DAY) { + taskNewLocalDateTime = taskLocalDateTime.plusDays(daysBetween + 1); + } else if (recurrenceType == RecurrenceType.WEEK) { + int daysToAdd = (int) (daysBetween / 7) * 7 + 7; + taskNewLocalDateTime = taskLocalDateTime.plusDays(daysToAdd); + } else { + // assume its + 4 weeks + int daysToAdd = (int) (daysBetween / 28) * 28 + 28; + taskNewLocalDateTime = taskLocalDateTime.plusDays(daysToAdd); + } + // time is fixed + t.setDateTime( + new DateTime(taskNewLocalDateTime.toLocalDate(), taskLocalDateTime.toLocalTime())); + } + this.markTaskAsUndone(t); + } + } + internalList.sort(Comparator.naturalOrder()); + } + /** * Returns the backing list as an unmodifiable {@code ObservableList}. */ diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTask.java b/src/main/java/seedu/address/storage/JsonAdaptedTask.java index 684908ba7eb..0f8bd3805f8 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedTask.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedTask.java @@ -13,6 +13,7 @@ import seedu.address.model.person.Name; import seedu.address.model.task.DateTime; import seedu.address.model.task.Description; +import seedu.address.model.task.Recurrence; import seedu.address.model.task.Status; import seedu.address.model.task.Task; @@ -24,14 +25,15 @@ public class JsonAdaptedTask { private final String date; private final String time; private final String status; + private final String recurrence; /** * Constructs a {@code JsonAdaptedTask} with the given task details. */ @JsonCreator public JsonAdaptedTask(@JsonProperty("names") List<String> names, @JsonProperty("description") String description, - @JsonProperty("date") String date, @JsonProperty("time") String time, - @JsonProperty("status") String status) { + @JsonProperty("date") String date, @JsonProperty("time") String time, + @JsonProperty("status") String status, @JsonProperty("recurrence") String recurrence) { if (names != null) { this.names.addAll(names); } @@ -39,6 +41,7 @@ public JsonAdaptedTask(@JsonProperty("names") List<String> names, @JsonProperty( this.date = date; this.time = time; this.status = status; + this.recurrence = recurrence; } /** @@ -52,6 +55,7 @@ public JsonAdaptedTask(Task source) { .map(name -> name.fullName) .collect(Collectors.toList())); status = source.getStatus().toString(); + recurrence = source.getRecurrence().toString(); } /** @@ -97,8 +101,19 @@ public Task toModelType() throws IllegalValueException { final Status modelStatus = new Status(status); + if (recurrence == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, + Status.class.getSimpleName())); + } + + if (!Recurrence.isValidRecurrence(recurrence)) { + throw new IllegalValueException(Recurrence.MESSAGE_CONSTRAINTS); + } + + final Recurrence modelRecurrence = new Recurrence(recurrence); + final Set<Name> modelNames = new HashSet<>(relatedNames); - return new Task(modelDesc, modelDt, modelNames, modelStatus); + return new Task(modelDesc, modelDt, modelNames, modelStatus, modelRecurrence); } } diff --git a/src/main/java/seedu/address/ui/TaskCard.java b/src/main/java/seedu/address/ui/TaskCard.java index 66dd37cdad3..cb0f7f1e812 100644 --- a/src/main/java/seedu/address/ui/TaskCard.java +++ b/src/main/java/seedu/address/ui/TaskCard.java @@ -28,12 +28,14 @@ public class TaskCard extends UiPart<Region> { @FXML private Label time; @FXML + private Label recurring; + @FXML private FlowPane names; @FXML private CheckBox status; /** - * Creates a {@code ElderlyCode} with the given {@code Elderly} and index to display. + * Creates a {@code TaskCard} with the given {@code Task} and index to display. */ public TaskCard(Task task, int displayedIndex) { super(FXML); @@ -46,6 +48,7 @@ public TaskCard(Task task, int displayedIndex) { .forEach(name -> names.getChildren().add(new Label(name.fullName))); status.setSelected(task.isTaskDone()); status.setDisable(true); + recurring.setText("Recurring: " + task.getRecurrence()); } @Override diff --git a/src/main/resources/view/TaskListCard.fxml b/src/main/resources/view/TaskListCard.fxml index 0302120f3af..155e81b416e 100644 --- a/src/main/resources/view/TaskListCard.fxml +++ b/src/main/resources/view/TaskListCard.fxml @@ -27,6 +27,7 @@ <FlowPane fx:id="names" /> <Label fx:id="date" styleClass="cell_small_label" text="\$date" /> <Label fx:id="time" styleClass="cell_small_label" text="\$time" /> + <Label fx:id="recurring" styleClass="cell_small_label" text="\$recurring" /> </VBox> </GridPane> </HBox> diff --git a/src/test/data/JsonSerializableAddressBookTest/invalidTaskAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/invalidTaskAddressBook.json index 0b3c057ad47..a96307f3574 100644 --- a/src/test/data/JsonSerializableAddressBookTest/invalidTaskAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/invalidTaskAddressBook.json @@ -4,6 +4,7 @@ "description": "Bring insulin shots", "date": "30 July 201", "time": "9382", - "status": "true" + "status": "true", + "recurrence" : "rubbish" } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalTasksAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalTasksAddressBook.json index fe2e3482be3..557bb4be8cd 100644 --- a/src/test/data/JsonSerializableAddressBookTest/typicalTasksAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/typicalTasksAddressBook.json @@ -8,7 +8,8 @@ "description": "Bring insulin shots", "date": "2020-11-01", "time": "19:45", - "status": "false" + "status": "false", + "recurrence" : "NONE" }, { "names": [ "Alex Andre" @@ -16,30 +17,28 @@ "description": "Bring insulin shots", "date": "2022-01-31", "time": "19:45", - "status": "false" + "status": "false", + "recurrence" : "NONE" }, { "names": [], "description": "Do paperwork", "date": "2022-01-31", "time": "10:20", - "status": "false" + "status": "false", + "recurrence" : "MONTH" }, { "names": ["Yasmine George"], "description": "Physiotherapy with yoga ball", "date": "2021-09-13", "time": "15:30", - "status": "true" - }, { - "names": [], - "description": "Apply leave with HR", - "date": "2021-10-01", - "time": "00:00", - "status": "true" + "status": "true", + "recurrence" : "NONE" }, { "names": ["Khong Guan", "Swee Choon"], "description": "3rd shot for Pfizer", "date": "2021-10-30", "time": "18:00", - "status": "false" + "status": "false", + "recurrence" : "NONE" } ] } diff --git a/src/test/java/seedu/address/logic/commands/RemindCommandTest.java b/src/test/java/seedu/address/logic/commands/RemindCommandTest.java index e185585f527..7177672ca6f 100644 --- a/src/test/java/seedu/address/logic/commands/RemindCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/RemindCommandTest.java @@ -13,7 +13,10 @@ import java.time.LocalDate; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import javafx.beans.Observable; +import javafx.collections.ObservableList; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -96,6 +99,8 @@ public void execute_validDate_tasksFound() { CommandResult expectedCommandResult = new CommandResult(MESSAGE_SUCCESS, CommandResult.ListDisplayChange.TASK); expectedModel.updateFilteredTaskList(predicate); assertCommandSuccess(command, model, expectedCommandResult, expectedModel); + ObservableList<Task> temp = model.getFilteredTaskList(); + List<Task> list = Arrays.asList(DO_PAPERWORK, ALEX_INSULIN); assertEquals(Arrays.asList(DO_PAPERWORK, ALEX_INSULIN), model.getFilteredTaskList()); } diff --git a/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java b/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java index 2d80e701d55..5de6af161d3 100644 --- a/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java @@ -1,9 +1,12 @@ package seedu.address.logic.commands; +import seedu.address.model.task.Recurrence.RecurrenceType; + import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DATE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_RECURRING; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_TIME; public class TaskCommandTestUtil extends CommandTestUtil { @@ -24,8 +27,13 @@ public class TaskCommandTestUtil extends CommandTestUtil { public static final String TIME_DESC_SEVENPM = " " + PREFIX_TASK_TIME + VALID_TIME_SEVENPM; public static final String NAME_DESC_KEITH = " " + PREFIX_NAME + VALID_NAME_KEITH; public static final String NAME_DESC_ALEX = " " + PREFIX_NAME + VALID_NAME_ALEX; + public static final String RECUR_NONE = " " + PREFIX_TASK_RECURRING + RecurrenceType.NONE; + public static final String RECUR_DAY = " " + PREFIX_TASK_RECURRING + RecurrenceType.DAY; + public static final String RECUR_WEEK = " " + PREFIX_TASK_RECURRING + RecurrenceType.WEEK; + public static final String RECUR_MONTH = " " + PREFIX_TASK_RECURRING + RecurrenceType.MONTH; public static final String INVALID_DESC = " " + PREFIX_TASK_DESC; public static final String INVALID_DATE = " " + PREFIX_TASK_DATE + "07-10-2009"; //should be yyyy-mm-dd public static final String INVALID_TIME = " " + PREFIX_TASK_TIME + "1900"; //should be 19:00 + public static final String INVALID_RECUR = " " + PREFIX_TASK_RECURRING + "YEAR"; // no yearly tasks } diff --git a/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java index 8c1e257d40d..db5f9f4c144 100644 --- a/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java @@ -13,6 +13,7 @@ import static seedu.address.logic.commands.TaskCommandTestUtil.INVALID_TIME; import static seedu.address.logic.commands.TaskCommandTestUtil.NAME_DESC_ALEX; import static seedu.address.logic.commands.TaskCommandTestUtil.NAME_DESC_KEITH; +import static seedu.address.logic.commands.TaskCommandTestUtil.RECUR_MONTH; import static seedu.address.logic.commands.TaskCommandTestUtil.TIME_DESC_SEVENPM; import static seedu.address.logic.commands.TaskCommandTestUtil.TIME_DESC_TENAM; import static seedu.address.logic.commands.TaskCommandTestUtil.VALID_DATE_NOV; @@ -31,7 +32,9 @@ import seedu.address.model.person.Name; import seedu.address.model.task.DateTime; import seedu.address.model.task.Description; +import seedu.address.model.task.Recurrence; import seedu.address.model.task.Task; +import seedu.address.model.task.Recurrence.RecurrenceType; import seedu.address.testutil.TaskBuilder; public class AddTaskCommandParserTest { @@ -68,7 +71,8 @@ public void parse_allFieldsPresent_success() { public void parse_optionalFieldsMissing_success() { // zero tags Task expectedTask = new TaskBuilder(DO_PAPERWORK).build(); - assertParseSuccess(parser, DESC_PAPERWORK + DATE_DESC_JAN + TIME_DESC_TENAM, + assertParseSuccess(parser, DESC_PAPERWORK + DATE_DESC_JAN + TIME_DESC_TENAM + + RECUR_MONTH, new AddTaskCommand(expectedTask)); } diff --git a/src/test/java/seedu/address/model/task/DateTimeTest.java b/src/test/java/seedu/address/model/task/DateTimeTest.java index 6b58597b23b..d83e51073d7 100644 --- a/src/test/java/seedu/address/model/task/DateTimeTest.java +++ b/src/test/java/seedu/address/model/task/DateTimeTest.java @@ -9,7 +9,7 @@ class DateTimeTest { @Test public void constructor_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new DateTime(null, null)); + assertThrows(NullPointerException.class, () -> new DateTime((String) null, (String) null)); } @Test diff --git a/src/test/java/seedu/address/model/task/RecurrenceTest.java b/src/test/java/seedu/address/model/task/RecurrenceTest.java new file mode 100644 index 00000000000..b2307ee2f13 --- /dev/null +++ b/src/test/java/seedu/address/model/task/RecurrenceTest.java @@ -0,0 +1,44 @@ +package seedu.address.model.task; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.testutil.Assert.assertThrows; + +public class RecurrenceTest { + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new Recurrence(null)); + } + + @Test + public void constructor_invalidRecurrence_throwsIllegalArgumentException() { + String invalidStatus = "a"; + assertThrows(IllegalArgumentException.class, () -> new Recurrence(invalidStatus)); + } + + @Test + public void isValidRecurrence() { + // null status + assertThrows(NullPointerException.class, () -> Recurrence.isValidRecurrence(null)); + + // invalid statuses + assertFalse(Recurrence.isValidRecurrence("d1y")); // non-matching words + assertFalse(Recurrence.isValidRecurrence("days")); // extra letters + assertFalse(Recurrence.isValidRecurrence(" d a ys ")); // extra spaces + + // valid statuses + assertTrue(Recurrence.isValidRecurrence("NONE")); + assertTrue(Recurrence.isValidRecurrence("MONTH")); + } + + @Test + public void equals() { + Recurrence completedRecurrence = new Recurrence("DAY"); + assertTrue(completedRecurrence.equals(new Recurrence("day"))); // all lower case + assertTrue(completedRecurrence.equals(new Recurrence("dAy"))); // mix of lower and upper cases + + assertFalse(completedRecurrence.equals(new Recurrence("WEEK"))); + } +} diff --git a/src/test/java/seedu/address/model/task/TaskListTest.java b/src/test/java/seedu/address/model/task/TaskListTest.java index 5d1d0cf3a86..9d1811d810b 100644 --- a/src/test/java/seedu/address/model/task/TaskListTest.java +++ b/src/test/java/seedu/address/model/task/TaskListTest.java @@ -6,8 +6,14 @@ import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalTasks.ALEX_INSULIN; import static seedu.address.testutil.TypicalTasks.APPLY_LEAVE; +import static seedu.address.testutil.TypicalTasks.APPLY_LEAVE_LATE_TIME; +import static seedu.address.testutil.TypicalTasks.APPLY_LEAVE_MONTH_RECURRENCE; +import static seedu.address.testutil.TypicalTasks.APPLY_LEAVE_WEEK_RECURRENCE; import static seedu.address.testutil.TypicalTasks.DO_PAPERWORK; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.Collections; import java.util.List; @@ -107,4 +113,66 @@ public void sortsAddedTasks_byDateTime() { expectedTaskList.add(ALEX_INSULIN); assertEquals(expectedTaskList, taskList); } + + @Test + public void changeDateOfPastRecurringTasks_forDayRecurring() { + TaskList taskList = new TaskList(); + taskList.add(APPLY_LEAVE_LATE_TIME); // date: "2021-10-01", time: "23:50" + // (which is most probably past current time) DAY RECURRING + taskList.changeDateOfPastRecurringTasks(); + Task task1 = taskList.asUnmodifiableObservableList().get(0); + LocalDateTime currentDateTime1 = LocalDateTime.now(); + assertEquals(new DateTime(currentDateTime1.toLocalDate(), LocalTime.of(23, 50)), task1.getDateTime()); + + taskList = new TaskList(); + taskList.add(APPLY_LEAVE); // date: "2021-10-01", time: "00:00" (which is most probably before current time) + // DAY RECURRING + taskList.changeDateOfPastRecurringTasks(); + Task task2 = taskList.asUnmodifiableObservableList().get(0); + LocalDateTime currentDateTime2 = LocalDateTime.now(); + assertEquals(new DateTime(currentDateTime2.toLocalDate().plusDays(1), + LocalTime.of(0, 0)), task2.getDateTime()); + } + + @Test + public void changeDateOfPastRecurringTasks_forWeekRecurring() { + TaskList taskList = new TaskList(); + taskList.add(APPLY_LEAVE_WEEK_RECURRENCE); // date: "2021-09-30", time: "23:50" + // (which is most probably past current time) DAY RECURRING + LocalDate date = LocalDate.of(2021, 9, 30); + LocalTime time = LocalTime.of(23, 50); + Task task1 = taskList.asUnmodifiableObservableList().get(0); + LocalDateTime currentDateTime1 = LocalDateTime.now(); + int daysDiff = currentDateTime1.getDayOfYear() - date.getDayOfYear(); + int daysToAdd = 7 - daysDiff % 7; + taskList.changeDateOfPastRecurringTasks(); + assertEquals(new DateTime(currentDateTime1.toLocalDate().plusDays(daysToAdd), time), + task1.getDateTime()); + } + + @Test + public void changeDateOfPastRecurringTasks_forMonthRecurring() { + TaskList taskList = new TaskList(); + taskList.add(APPLY_LEAVE_MONTH_RECURRENCE); // date: "2021-07-30", time: "23:50" + LocalDate date = LocalDate.of(2021, 7, 30); + LocalTime time = LocalTime.of(23, 50); + // (which is most probably past current time) DAY RECURRING + Task task1 = taskList.asUnmodifiableObservableList().get(0); + LocalDateTime currentDateTime1 = LocalDateTime.now(); + int daysDiff = currentDateTime1.getDayOfYear() - date.getDayOfYear(); + int daysToAdd = 28 - daysDiff % 28; + taskList.changeDateOfPastRecurringTasks(); + assertEquals(new DateTime(currentDateTime1.toLocalDate().plusDays(daysToAdd), time), + task1.getDateTime()); + } + + @Test + public void changeDateOfPastRecurringTasks_changedToUndoneTasks() { + TaskList taskList = new TaskList(); + taskList.add(APPLY_LEAVE_MONTH_RECURRENCE); // date: "2021-07-30", time: "23:50" + // (which is most probably past current time) DAY RECURRING + taskList.changeDateOfPastRecurringTasks(); + Task newTask1 = taskList.asUnmodifiableObservableList().get(0); + assertFalse(newTask1.getStatus().isDone); + } } diff --git a/src/test/java/seedu/address/model/task/TaskTest.java b/src/test/java/seedu/address/model/task/TaskTest.java index 6458a85156a..a31252782a7 100644 --- a/src/test/java/seedu/address/model/task/TaskTest.java +++ b/src/test/java/seedu/address/model/task/TaskTest.java @@ -18,6 +18,7 @@ import org.junit.jupiter.api.Test; import seedu.address.testutil.TaskBuilder; +import seedu.address.model.task.Recurrence.RecurrenceType; public class TaskTest { @@ -29,7 +30,8 @@ public void equals() { // same values -> returns true assertTrue(keithInsulin.equals(KEITH_INSULIN)); Task alexToKeith = new TaskBuilder(ALEX_INSULIN).withNames(VALID_NAME_KEITH) - .withDateTime(VALID_DATE_NOV, VALID_TIME_SEVENPM).withStatus("false").build(); + .withDateTime(VALID_DATE_NOV, VALID_TIME_SEVENPM).withStatus("false") + .withRecurrence(RecurrenceType.NONE.name()).build(); assertTrue(keithInsulin.equals(alexToKeith)); // same object -> returns true @@ -65,6 +67,10 @@ public void equals() { // different status -> returns false editedTask = new TaskBuilder(keithInsulin).withStatus("true").build(); assertFalse(keithInsulin.equals(editedTask)); + + // different recurrence -> returns false + editedTask = new TaskBuilder(keithInsulin).withRecurrence(RecurrenceType.MONTH.name()).build(); + assertFalse(keithInsulin.equals(editedTask)); } @Test diff --git a/src/test/java/seedu/address/testutil/TaskBuilder.java b/src/test/java/seedu/address/testutil/TaskBuilder.java index 1c5ecc4c452..83df516f7db 100644 --- a/src/test/java/seedu/address/testutil/TaskBuilder.java +++ b/src/test/java/seedu/address/testutil/TaskBuilder.java @@ -8,6 +8,7 @@ import seedu.address.model.person.Name; import seedu.address.model.task.DateTime; import seedu.address.model.task.Description; +import seedu.address.model.task.Recurrence; import seedu.address.model.task.Status; import seedu.address.model.task.Task; @@ -17,11 +18,13 @@ public class TaskBuilder { public static final String DEFAULT_DATE = "2069-06-09"; public static final String DEFAULT_TIME = "18:09"; public static final String DEFAULT_STATUS = "false"; + public static final String DEFAULT_RECURRENCE = Recurrence.RecurrenceType.NONE.name(); private Description desc; private DateTime dateTime; private Set<Name> names; private Status status; + private Recurrence recurrence; /** * Creates a {@code TaskBuilder} with the default details. @@ -31,6 +34,7 @@ public TaskBuilder() { dateTime = new DateTime(DEFAULT_DATE, DEFAULT_TIME); names = new HashSet<>(); status = new Status(DEFAULT_STATUS); + recurrence = new Recurrence(DEFAULT_RECURRENCE); } /** @@ -41,6 +45,7 @@ public TaskBuilder(Task taskToCopy) { dateTime = taskToCopy.getDateTime(); names = new HashSet<>(taskToCopy.getRelatedNames()); status = taskToCopy.getStatus(); + recurrence = taskToCopy.getRecurrence(); } /** @@ -77,10 +82,18 @@ public TaskBuilder withStatus(String status) { return this; } + /** + * Sets the {@code DateTime} of the {@code Task} that we are building. + */ + public TaskBuilder withRecurrence(String recurrence) { + this.recurrence = new Recurrence(recurrence); + return this; + } + /** * Returns task object created with fields of the taskBuilder */ public Task build() { - return new Task(desc, dateTime, names, status); + return new Task(desc, dateTime, names, status, recurrence); } } diff --git a/src/test/java/seedu/address/testutil/TypicalTasks.java b/src/test/java/seedu/address/testutil/TypicalTasks.java index 4136af97af7..02bc3a9bad6 100644 --- a/src/test/java/seedu/address/testutil/TypicalTasks.java +++ b/src/test/java/seedu/address/testutil/TypicalTasks.java @@ -14,27 +14,47 @@ import java.util.List; import seedu.address.model.AddressBook; +import seedu.address.model.task.Recurrence.RecurrenceType; import seedu.address.model.task.Task; public class TypicalTasks { public static final Task KEITH_INSULIN = new TaskBuilder().withDesc(VALID_DESC_MEDICINE) - .withDateTime(VALID_DATE_NOV, VALID_TIME_SEVENPM).withNames(VALID_NAME_KEITH).build(); + .withDateTime(VALID_DATE_NOV, VALID_TIME_SEVENPM).withNames(VALID_NAME_KEITH) + .withRecurrence(RecurrenceType.NONE.name()) + .build(); public static final Task ALEX_INSULIN = new TaskBuilder().withDesc(VALID_DESC_MEDICINE) - .withDateTime(VALID_DATE_JAN, VALID_TIME_SEVENPM).withNames(VALID_NAME_ALEX).build(); + .withDateTime(VALID_DATE_JAN, VALID_TIME_SEVENPM).withNames(VALID_NAME_ALEX) + .withRecurrence(RecurrenceType.NONE.name()).build(); public static final Task DO_PAPERWORK = new TaskBuilder().withDesc(VALID_DESC_PAPERWORK) - .withDateTime(VALID_DATE_JAN, VALID_TIME_TENAM).build(); + .withDateTime(VALID_DATE_JAN, VALID_TIME_TENAM).withRecurrence(RecurrenceType.MONTH.name()).build(); public static final Task YASMINE_PHYSIO = new TaskBuilder().withDesc("Physiotherapy with yoga ball") - .withDateTime("2021-09-13", "15:30").withNames("Yasmine George").withStatus("true").build(); + .withDateTime("2021-09-13", "15:30").withNames("Yasmine George").withStatus("true") + .withRecurrence(RecurrenceType.NONE.name()).build(); + public static final Task KG_SC_VACCINE = new TaskBuilder().withDesc("3rd shot for Pfizer") + .withDateTime("2021-10-30", "18:00").withNames("Khong Guan", "Swee Choon").withStatus("false") + .withRecurrence(RecurrenceType.NONE.name()).build(); + + // Extra test cases public static final Task APPLY_LEAVE = new TaskBuilder().withDesc("Apply leave with HR") - .withDateTime("2021-10-01", "00:00").withStatus("true").build(); + .withDateTime("2021-10-01", "00:00").withStatus("true") + .withRecurrence(RecurrenceType.DAY.name()).build(); - public static final Task KG_SC_VACCINE = new TaskBuilder().withDesc("3rd shot for Pfizer") - .withDateTime("2021-10-30", "18:00").withNames("Khong Guan", "Swee Choon").build(); + public static final Task APPLY_LEAVE_LATE_TIME = new TaskBuilder().withDesc("Apply leave with HR") + .withDateTime("2021-10-01", "23:50").withStatus("true") + .withRecurrence(RecurrenceType.DAY.name()).build(); + + public static final Task APPLY_LEAVE_WEEK_RECURRENCE = new TaskBuilder().withDesc("Apply leave with HR") + .withDateTime("2021-09-30", "23:50").withStatus("true") + .withRecurrence(RecurrenceType.WEEK.name()).build(); + + public static final Task APPLY_LEAVE_MONTH_RECURRENCE = new TaskBuilder().withDesc("Apply leave with HR") + .withDateTime("2021-07-30", "23:50").withStatus("true") + .withRecurrence(RecurrenceType.MONTH.name()).build(); /** * Returns an {@code AddressBook} with all the typical tasks. @@ -49,6 +69,6 @@ public static AddressBook getTypicalAddressBook() { public static List<Task> getTypicalTasks() { return new ArrayList<>(Arrays.asList(KEITH_INSULIN, ALEX_INSULIN, DO_PAPERWORK, - YASMINE_PHYSIO, APPLY_LEAVE, KG_SC_VACCINE)); + YASMINE_PHYSIO, KG_SC_VACCINE)); } } From 2c0272c296ebb339242a3333ad6d3459d4fd3e77 Mon Sep 17 00:00:00 2001 From: Ng Tze Henn <tzehenn@gmail.com> Date: Tue, 19 Oct 2021 16:31:01 +0800 Subject: [PATCH 2/7] Fix Checkstyle Issues --- .../seedu/address/logic/parser/ParserUtil.java | 10 ++++++++-- .../java/seedu/address/model/task/DateTime.java | 6 ++++++ .../java/seedu/address/model/task/Recurrence.java | 15 +++++++-------- src/main/java/seedu/address/model/task/Task.java | 10 ++++++++++ .../java/seedu/address/model/task/TaskList.java | 12 ++++++++++-- .../address/logic/commands/RemindCommandTest.java | 3 +-- .../logic/commands/TaskCommandTestUtil.java | 5 ++--- .../logic/parser/AddTaskCommandParserTest.java | 2 -- .../seedu/address/model/task/RecurrenceTest.java | 4 ++-- .../java/seedu/address/model/task/TaskTest.java | 2 +- 10 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index f3a65dc0798..fed0f38df4d 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -233,10 +233,10 @@ public static Description parseDesc(String description) throws ParseException { } /** - * Parses a {@code String description} into an {@code Description}. + * Parses a {@code String date} and {@code String time} into an {@code DateTime}. * Leading and trailing whitespaces will be trimmed. * - * @throws ParseException if the given {@code description} is invalid. + * @throws ParseException if the given {@code date} and {@code time} is invalid. */ public static DateTime parseDateTime(String date, String time) throws ParseException { requireAllNonNull(date, time); @@ -251,6 +251,12 @@ public static DateTime parseDateTime(String date, String time) throws ParseExcep return new DateTime(trimmedDate, trimmedTime); } + /** + * Parses a {@code String recurrenceType} into an {@code Recurrence}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code recurrenceType} is invalid. + */ public static Recurrence parseRecurrence(String recurrenceType) throws ParseException { requireNonNull(recurrenceType); String trimmedRecurrenceType = recurrenceType.trim().toUpperCase(); diff --git a/src/main/java/seedu/address/model/task/DateTime.java b/src/main/java/seedu/address/model/task/DateTime.java index d63beb98ade..b41a8b28c1c 100644 --- a/src/main/java/seedu/address/model/task/DateTime.java +++ b/src/main/java/seedu/address/model/task/DateTime.java @@ -42,6 +42,12 @@ public DateTime(String date, String time) { } } + /** + * Constructs an {@code DateTime}. + * + * @param date A valid date. + * @param time A valid time. + */ public DateTime(LocalDate date, LocalTime time) { this.date = date; this.time = time; diff --git a/src/main/java/seedu/address/model/task/Recurrence.java b/src/main/java/seedu/address/model/task/Recurrence.java index 71a5e3bcae0..c14aadedc23 100644 --- a/src/main/java/seedu/address/model/task/Recurrence.java +++ b/src/main/java/seedu/address/model/task/Recurrence.java @@ -1,12 +1,10 @@ package seedu.address.model.task; -import seedu.address.model.person.Age; - -import java.util.Objects; - import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.AppUtil.checkArgument; +import java.util.Objects; + /** * Represents if a task is a recurring task in NurseyBook. * Guarantees: immutable; is valid as declared in {@link #isValidRecurrence(String)} @@ -29,6 +27,11 @@ public enum RecurrenceType { NONE, DAY, WEEK, MONTH } + /** + * Constructs an {@code Recurrence}. + * + * @param recurrenceTypeStr A valid recurrence type. + */ public Recurrence(String recurrenceTypeStr) { requireNonNull(recurrenceTypeStr); recurrenceTypeStr = recurrenceTypeStr.toUpperCase(); @@ -48,10 +51,6 @@ public boolean isRecurring() { return isRecurring; } -// public void setRecurring(boolean recurring) { -// isRecurring = recurring; -// } - public RecurrenceType getRecurrenceType() { return recurrenceType; } diff --git a/src/main/java/seedu/address/model/task/Task.java b/src/main/java/seedu/address/model/task/Task.java index 287e50add96..1bb2194c602 100644 --- a/src/main/java/seedu/address/model/task/Task.java +++ b/src/main/java/seedu/address/model/task/Task.java @@ -36,6 +36,7 @@ public Task(Description desc, DateTime dt, Set<Name> names) { * @param desc the description of the task * @param dt the date and time of the task * @param names the names of people associated with the task + * @param recurrence the recurrence type of the task */ public Task(Description desc, DateTime dt, Set<Name> names, Recurrence recurrence) { this.desc = desc; @@ -61,6 +62,15 @@ public Task(Description desc, DateTime dt, Set<Name> names, Status status) { this.recurrence = new Recurrence(Recurrence.RecurrenceType.NONE.name()); } + /** + * Creates a Task object. + * + * @param desc the description of the task + * @param dt the date and time of the task + * @param names the names of people associated with the task + * @param status the completion status of the task + * @param recurrence the recurrence type of the task + */ public Task(Description desc, DateTime dt, Set<Name> names, Status status, Recurrence recurrence) { this.desc = desc; this.dateTime = dt; diff --git a/src/main/java/seedu/address/model/task/TaskList.java b/src/main/java/seedu/address/model/task/TaskList.java index 588e5228a21..4f0bda7a41f 100644 --- a/src/main/java/seedu/address/model/task/TaskList.java +++ b/src/main/java/seedu/address/model/task/TaskList.java @@ -14,8 +14,8 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import seedu.address.model.task.exceptions.TaskNotFoundException; import seedu.address.model.task.Recurrence.RecurrenceType; +import seedu.address.model.task.exceptions.TaskNotFoundException; /** * A list of tasks that does not allow nulls. @@ -96,6 +96,14 @@ public void remove(Task toRemove) { } } + /** + * If a recurring task's original DateTime is before the current {@code DateTime}, + * changes the task's {@code DateTime} to the next earliest {@code DateTime}, + * according to whether is it a {@code DAY}, {@code WEEK} or {@code MONTH} recurrence type. + * At the same time, after changing the {@code DateTime}, + * it also maintains the sorted order of tasks according to {@code DateTime}. + * All tasks which had their {@code DateTime} changed will also have their status's {@code isDone} as false. + */ public void changeDateOfPastRecurringTasks() { LocalDateTime currentDateTime = LocalDateTime.now(); @@ -116,7 +124,7 @@ public void changeDateOfPastRecurringTasks() { LocalDateTime taskLocalDateTime = LocalDateTime.parse(inputString, dtf); long daysBetween = Duration.between(taskLocalDateTime, currentDateTime).toDays(); // if task dateTime is before current dateTime - if (daysBetween > 0) { + if (daysBetween > 0) { LocalDateTime taskNewLocalDateTime; if (recurrenceType == RecurrenceType.DAY) { taskNewLocalDateTime = taskLocalDateTime.plusDays(daysBetween + 1); diff --git a/src/test/java/seedu/address/logic/commands/RemindCommandTest.java b/src/test/java/seedu/address/logic/commands/RemindCommandTest.java index 7177672ca6f..eb302eb459a 100644 --- a/src/test/java/seedu/address/logic/commands/RemindCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/RemindCommandTest.java @@ -15,11 +15,10 @@ import java.util.Collections; import java.util.List; -import javafx.beans.Observable; -import javafx.collections.ObservableList; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import javafx.collections.ObservableList; import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; diff --git a/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java b/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java index 5de6af161d3..26c519d54d7 100644 --- a/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/TaskCommandTestUtil.java @@ -1,14 +1,13 @@ package seedu.address.logic.commands; - -import seedu.address.model.task.Recurrence.RecurrenceType; - import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DATE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_RECURRING; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_TIME; +import seedu.address.model.task.Recurrence.RecurrenceType; + public class TaskCommandTestUtil extends CommandTestUtil { public static final String VALID_DESC_PAPERWORK = "Do paperwork"; public static final String VALID_DESC_MEDICINE = "Bring insulin shots"; diff --git a/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java index db5f9f4c144..27088607af0 100644 --- a/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddTaskCommandParserTest.java @@ -32,9 +32,7 @@ import seedu.address.model.person.Name; import seedu.address.model.task.DateTime; import seedu.address.model.task.Description; -import seedu.address.model.task.Recurrence; import seedu.address.model.task.Task; -import seedu.address.model.task.Recurrence.RecurrenceType; import seedu.address.testutil.TaskBuilder; public class AddTaskCommandParserTest { diff --git a/src/test/java/seedu/address/model/task/RecurrenceTest.java b/src/test/java/seedu/address/model/task/RecurrenceTest.java index b2307ee2f13..de617baff4e 100644 --- a/src/test/java/seedu/address/model/task/RecurrenceTest.java +++ b/src/test/java/seedu/address/model/task/RecurrenceTest.java @@ -1,11 +1,11 @@ package seedu.address.model.task; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static seedu.address.testutil.Assert.assertThrows; +import org.junit.jupiter.api.Test; + public class RecurrenceTest { @Test public void constructor_null_throwsNullPointerException() { diff --git a/src/test/java/seedu/address/model/task/TaskTest.java b/src/test/java/seedu/address/model/task/TaskTest.java index a31252782a7..81dbc90cc57 100644 --- a/src/test/java/seedu/address/model/task/TaskTest.java +++ b/src/test/java/seedu/address/model/task/TaskTest.java @@ -17,8 +17,8 @@ import org.junit.jupiter.api.Test; -import seedu.address.testutil.TaskBuilder; import seedu.address.model.task.Recurrence.RecurrenceType; +import seedu.address.testutil.TaskBuilder; public class TaskTest { From 3b30f75dd1063ff47254d65c165f82b5827994ee Mon Sep 17 00:00:00 2001 From: Ng Tze Henn <tzehenn@gmail.com> Date: Thu, 21 Oct 2021 21:22:47 +0800 Subject: [PATCH 3/7] Refactor Code --- .../logic/commands/AddTaskCommand.java | 29 +++++--- .../seedu/address/model/task/TaskList.java | 69 +++++++++++-------- .../address/model/task/TaskListTest.java | 4 +- 3 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java index a3177ed6db8..170ebfc58d0 100644 --- a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java @@ -1,7 +1,16 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_AGE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GENDER; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOK_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_RELATIONSHIP; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ROOM_NUM; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DATE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_RECURRING; @@ -20,14 +29,18 @@ public class AddTaskCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a task to the address book. " + "Parameters: " - + "[" + PREFIX_NAME + "NAME]...\n" - + "Example: " + COMMAND_WORD - + " " + PREFIX_NAME + "Khong Guan " - + " " + PREFIX_NAME + "Swee Choon" - + " " + PREFIX_TASK_DESC + "Weekly Taiji" - + " " + PREFIX_TASK_DATE + "2021-10-10" - + " " + PREFIX_TASK_TIME + "14:30" - + " " + PREFIX_TASK_RECURRING + "week"; + + "[" + PREFIX_NAME + "NAME]..." + + PREFIX_TASK_DESC + "DESCRIPTION " + + PREFIX_TASK_DATE + "DATE " + + PREFIX_TASK_TIME + "TIME " + + "[" + PREFIX_TASK_RECURRING + "RECURRENCE_TYPE]\n" + + "Example: " + COMMAND_WORD + " " + + PREFIX_NAME + "Khong Guan " + + PREFIX_NAME + "Swee Choon " + + PREFIX_TASK_DESC + "Weekly Taiji " + + PREFIX_TASK_DATE + "2021-10-10 " + + PREFIX_TASK_TIME + "14:30 " + + PREFIX_TASK_RECURRING + "week"; public static final String MESSAGE_SUCCESS = "New task added: %1$s"; diff --git a/src/main/java/seedu/address/model/task/TaskList.java b/src/main/java/seedu/address/model/task/TaskList.java index 4f0bda7a41f..9352efb9fba 100644 --- a/src/main/java/seedu/address/model/task/TaskList.java +++ b/src/main/java/seedu/address/model/task/TaskList.java @@ -112,40 +112,53 @@ public void changeDateOfPastRecurringTasks() { if (recurrence.isRecurring()) { RecurrenceType recurrenceType = recurrence.getRecurrenceType(); assert(recurrenceType != RecurrenceType.NONE); - DateTime taskDateTime = t.getDateTime(); - LocalDate taskDate = taskDateTime.date; - LocalTime taskTime = taskDateTime.time; - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy HH mm"); - String inputString = String.format("%02d", taskDate.getDayOfMonth()) + " " - + String.format("%02d", taskDate.getMonthValue()) + " " - + String.format("%02d", taskDate.getYear()) + " " - + String.format("%02d", taskTime.getHour()) + " " - + String.format("%02d", taskTime.getMinute()); - LocalDateTime taskLocalDateTime = LocalDateTime.parse(inputString, dtf); - long daysBetween = Duration.between(taskLocalDateTime, currentDateTime).toDays(); - // if task dateTime is before current dateTime - if (daysBetween > 0) { - LocalDateTime taskNewLocalDateTime; - if (recurrenceType == RecurrenceType.DAY) { - taskNewLocalDateTime = taskLocalDateTime.plusDays(daysBetween + 1); - } else if (recurrenceType == RecurrenceType.WEEK) { - int daysToAdd = (int) (daysBetween / 7) * 7 + 7; - taskNewLocalDateTime = taskLocalDateTime.plusDays(daysToAdd); - } else { - // assume its + 4 weeks - int daysToAdd = (int) (daysBetween / 28) * 28 + 28; - taskNewLocalDateTime = taskLocalDateTime.plusDays(daysToAdd); - } - // time is fixed - t.setDateTime( - new DateTime(taskNewLocalDateTime.toLocalDate(), taskLocalDateTime.toLocalTime())); - } + + changeTaskDate(currentDateTime, t, recurrenceType); this.markTaskAsUndone(t); } } + // Re-sorts task list when task date is changed internalList.sort(Comparator.naturalOrder()); } + private void changeTaskDate(LocalDateTime currentDateTime, Task t, + RecurrenceType recurrenceType) { + DateTime taskDateTime = t.getDateTime(); + LocalDate taskDate = taskDateTime.date; + LocalTime taskTime = taskDateTime.time; + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy HH mm"); + String inputString = String.format("%02d", taskDate.getDayOfMonth()) + " " + + String.format("%02d", taskDate.getMonthValue()) + " " + + String.format("%02d", taskDate.getYear()) + " " + + String.format("%02d", taskTime.getHour()) + " " + + String.format("%02d", taskTime.getMinute()); + LocalDateTime taskLocalDateTime = LocalDateTime.parse(inputString, dtf); + long daysBetween = Duration.between(taskLocalDateTime, currentDateTime).toDays(); + + // if task dateTime is before current dateTime + if (daysBetween > 0) { + changeTaskDateBasedOnRecurrence(t, recurrenceType, taskLocalDateTime, daysBetween); + } + } + + private void changeTaskDateBasedOnRecurrence(Task t, RecurrenceType recurrenceType, + LocalDateTime taskLocalDateTime, long daysBetween) { + LocalDateTime taskNewLocalDateTime; + if (recurrenceType == RecurrenceType.DAY) { + taskNewLocalDateTime = taskLocalDateTime.plusDays(daysBetween + 1); + } else if (recurrenceType == RecurrenceType.WEEK) { + int daysToAdd = (int) (daysBetween / 7) * 7 + 7; + taskNewLocalDateTime = taskLocalDateTime.plusDays(daysToAdd); + } else { + // assume its + 4 weeks + int daysToAdd = (int) (daysBetween / 28) * 28 + 28; + taskNewLocalDateTime = taskLocalDateTime.plusDays(daysToAdd); + } + // time is fixed + t.setDateTime( + new DateTime(taskNewLocalDateTime.toLocalDate(), taskLocalDateTime.toLocalTime())); + } + /** * Returns the backing list as an unmodifiable {@code ObservableList}. */ diff --git a/src/test/java/seedu/address/model/task/TaskListTest.java b/src/test/java/seedu/address/model/task/TaskListTest.java index 9d1811d810b..a97cb80c172 100644 --- a/src/test/java/seedu/address/model/task/TaskListTest.java +++ b/src/test/java/seedu/address/model/task/TaskListTest.java @@ -144,7 +144,7 @@ public void changeDateOfPastRecurringTasks_forWeekRecurring() { Task task1 = taskList.asUnmodifiableObservableList().get(0); LocalDateTime currentDateTime1 = LocalDateTime.now(); int daysDiff = currentDateTime1.getDayOfYear() - date.getDayOfYear(); - int daysToAdd = 7 - daysDiff % 7; + int daysToAdd = daysDiff % 7 == 0 ? 0 : 7 - daysDiff % 7; taskList.changeDateOfPastRecurringTasks(); assertEquals(new DateTime(currentDateTime1.toLocalDate().plusDays(daysToAdd), time), task1.getDateTime()); @@ -160,7 +160,7 @@ public void changeDateOfPastRecurringTasks_forMonthRecurring() { Task task1 = taskList.asUnmodifiableObservableList().get(0); LocalDateTime currentDateTime1 = LocalDateTime.now(); int daysDiff = currentDateTime1.getDayOfYear() - date.getDayOfYear(); - int daysToAdd = 28 - daysDiff % 28; + int daysToAdd = daysDiff % 28 == 0 ? 0 : 28 - daysDiff % 28; taskList.changeDateOfPastRecurringTasks(); assertEquals(new DateTime(currentDateTime1.toLocalDate().plusDays(daysToAdd), time), task1.getDateTime()); From aaff456fa7b9e0690fa278c710359700baa701d2 Mon Sep 17 00:00:00 2001 From: Ng Tze Henn <tzehenn@gmail.com> Date: Thu, 21 Oct 2021 21:23:01 +0800 Subject: [PATCH 4/7] Update UG for add recurring tasks --- docs/UserGuide.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 9f99caf3fa8..8275a22fc7b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -35,7 +35,7 @@ NurseyBook is a **desktop app made for nurses in nursing homes to aid them in ma * **`clear`** : Deletes all contacts. * **`exit`** : Exits the app. - + 1. Refer to the [Features](#features) below for details of each command. @@ -88,7 +88,7 @@ Examples: * `addElderly en/John a/77 g/M r/420 t/diabetes` * `addElderly en/John a/77 g/M r/420 t/diabetes nn/Timothy rs/Son` - + ### Edit an elderly's details: `editElderly` Edit the details of a specific elderly. @@ -175,10 +175,14 @@ Format: `viewTasks` Adds a task to the task list. -Format: `addTask [en/ELDERLY_NAME]... desc/DESCRIPTION date/DATE time/TIME` +:bulb: **Tip:** +You can add a recurring task to the list! <br> +There are a few recurring options available namely: `DAY`, `WEEK` and `MONTH` (4 weeks later from the previous date). Tasks that have passed their original date will have their date automatically changed to the new date based on the recurrence type of the task. + +Format: `addTask [en/ELDERLY_NAME]... desc/DESCRIPTION date/DATE time/TIME [recur/RECURRENCE_TYPE]` Example: -`addTask en/John desc/check insulin level date/2021-09-25 time/19:22` +`addTask en/John desc/check insulin level date/2021-09-25 time/19:22 recur/week` ### Delete task: `deleteTask` @@ -209,7 +213,7 @@ Examples: ### View reminders: `remind` -Shows the list of upcoming tasks (that are coming up in the next three days), such as the required +Shows the list of upcoming tasks (that are coming up in the next three days), such as the required medical needs for those under the user's care. Format: `remind` From 15defa3e2a8995949df0dff341c27908ff39ac3e Mon Sep 17 00:00:00 2001 From: Ng Tze Henn <tzehenn@gmail.com> Date: Thu, 21 Oct 2021 21:24:50 +0800 Subject: [PATCH 5/7] Fix Checkstyle Errors --- .../seedu/address/logic/commands/AddTaskCommand.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java index 170ebfc58d0..e64b5779307 100644 --- a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java @@ -1,16 +1,7 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_AGE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_GENDER; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NOK_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_RELATIONSHIP; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ROOM_NUM; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DATE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_RECURRING; From 677662412b90f25674b7d0ce7687ed0a770cddcb Mon Sep 17 00:00:00 2001 From: Ng Tze Henn <tzehenn@gmail.com> Date: Thu, 21 Oct 2021 21:32:27 +0800 Subject: [PATCH 6/7] Fix Github Failing CI --- src/main/java/seedu/address/logic/commands/AddTaskCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java index e64b5779307..82ede52c6d9 100644 --- a/src/main/java/seedu/address/logic/commands/AddTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTaskCommand.java @@ -48,7 +48,6 @@ public AddTaskCommand(Task t) { @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - model.addTask(toAdd); return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd), ListDisplayChange.TASK); } From c053d51e8da943e1f2009fba0dc630c74ddf46db Mon Sep 17 00:00:00 2001 From: Ng Tze Henn <tzehenn@gmail.com> Date: Thu, 21 Oct 2021 22:22:11 +0800 Subject: [PATCH 7/7] Fix Test Case Fails --- .../seedu/address/logic/commands/FindTaskCommandTest.java | 5 ++--- src/test/java/seedu/address/testutil/TypicalTasks.java | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/FindTaskCommandTest.java b/src/test/java/seedu/address/logic/commands/FindTaskCommandTest.java index 5571243fb67..ef0bf7be594 100644 --- a/src/test/java/seedu/address/logic/commands/FindTaskCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindTaskCommandTest.java @@ -5,7 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static seedu.address.commons.core.Messages.MESSAGE_TASKS_LISTED_OVERVIEW; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalTasks.APPLY_LEAVE; import static seedu.address.testutil.TypicalTasks.KG_SC_VACCINE; import static seedu.address.testutil.TypicalTasks.YASMINE_PHYSIO; import static seedu.address.testutil.TypicalTasks.getTypicalAddressBook; @@ -69,7 +68,7 @@ public void execute_zeroKeywords_noTasksFound() { @Test public void execute_multipleKeywords_multipleTasksFound() { - String expectedMessage = String.format(MESSAGE_TASKS_LISTED_OVERVIEW, 3); + String expectedMessage = String.format(MESSAGE_TASKS_LISTED_OVERVIEW, 2); CommandResult expectedCommandResult = new CommandResult(expectedMessage, CommandResult.ListDisplayChange.TASK); DescriptionContainsKeywordPredicate predicate = preparePredicate("Yoga Leave Pfizer"); @@ -77,7 +76,7 @@ public void execute_multipleKeywords_multipleTasksFound() { expectedModel.updateFilteredTaskList(predicate); assertCommandSuccess(command, model, expectedCommandResult, expectedModel); - assertEquals(Arrays.asList(YASMINE_PHYSIO, APPLY_LEAVE, KG_SC_VACCINE), model.getFilteredTaskList()); + assertEquals(Arrays.asList(YASMINE_PHYSIO, KG_SC_VACCINE), model.getFilteredTaskList()); } /** diff --git a/src/test/java/seedu/address/testutil/TypicalTasks.java b/src/test/java/seedu/address/testutil/TypicalTasks.java index 02bc3a9bad6..43f030b94ab 100644 --- a/src/test/java/seedu/address/testutil/TypicalTasks.java +++ b/src/test/java/seedu/address/testutil/TypicalTasks.java @@ -39,11 +39,12 @@ public class TypicalTasks { .withDateTime("2021-10-30", "18:00").withNames("Khong Guan", "Swee Choon").withStatus("false") .withRecurrence(RecurrenceType.NONE.name()).build(); - // Extra test cases public static final Task APPLY_LEAVE = new TaskBuilder().withDesc("Apply leave with HR") .withDateTime("2021-10-01", "00:00").withStatus("true") .withRecurrence(RecurrenceType.DAY.name()).build(); + // Extra test cases + public static final Task APPLY_LEAVE_LATE_TIME = new TaskBuilder().withDesc("Apply leave with HR") .withDateTime("2021-10-01", "23:50").withStatus("true") .withRecurrence(RecurrenceType.DAY.name()).build();