diff --git a/collated/main/A0139922Yunused.md b/collated/main/A0139922Yunused.md new file mode 100644 index 000000000000..d2cffa9505a0 --- /dev/null +++ b/collated/main/A0139922Yunused.md @@ -0,0 +1,2288 @@ +# A0139922Yunused +###### /java/seedu/todo/commons/util/DateUtil.java +``` java + /** + * Performs a "ceiling" operation on a LocalDateTime, and returns a new LocalDateTime + * with time set to 23:59. + * + * @param dateTime LocalDateTime for operation to be performed on. + * @return "Ceiled" LocalDateTime. + */ + public static LocalDateTime ceilDate(LocalDateTime dateTime) { + if (dateTime == null) { + return null; + } + + return dateTime.toLocalDate().atTime(23, 59); + } +``` +###### /java/seedu/todo/commons/util/DateUtil.java +``` java + /* + * Check a LocalDateTime if the time is the same as the current time + * + * @param date + * @return true if it is not the same as current time, false if it is the same as current time + */ + public static boolean checkIfTimeExist(LocalDateTime date) { + LocalDateTime currentTime = LocalDateTime.now(); + return currentTime.getHour() != date.getHour() || currentTime.getMinute() != date.getMinute(); + } + +``` +###### /java/seedu/todo/commons/util/DateUtil.java +``` java + /* + * Check a LocalDateTime if the date is the same as the current date + * + * @param date + * @return true if it is not the same as current date, false if it is the same as current date + */ + public static boolean checkIfDateExist(LocalDateTime date) { + LocalDateTime currentDate = LocalDateTime.now(); + return currentDate.getDayOfYear() != date.getDayOfYear() || currentDate.getMonth() != date.getMonth() || + currentDate.getYear() != date.getYear(); + } + +``` +###### /java/seedu/todo/commons/util/DateUtil.java +``` java + /* + * To convert LocalDateTime to 00:00 or 23:59 if not specified + * @param actualDate + * is the date that that is require for checking + * @param checkedDate + * is the date to be used for checking + * @isDateFrom + * if true, actualDate is dateFrom, false if actualDate is dateTo + * + * @return the correct date format + */ + public static LocalDateTime parseTimeStamp(LocalDateTime actualDate, LocalDateTime checkedDate, boolean isDateFrom) { + // Check for date + if (checkedDate != null && actualDate != null && checkIfDateExist(checkedDate) && !checkIfDateExist(actualDate)) { + if (!isDateFrom) { + actualDate = checkedDate.toLocalDate().atTime(actualDate.getHour(), actualDate.getMinute()); + } + } + // Check for time + if (checkedDate != null && actualDate != null && checkIfTimeExist(checkedDate) && !checkIfTimeExist(actualDate)) { + actualDate = actualDate.toLocalDate().atTime(checkedDate.getHour(), checkedDate.getMinute()); + } + if (actualDate != null && !checkIfTimeExist(actualDate)) { + if (isDateFrom) { + actualDate = floorDate(actualDate); + } else { + actualDate = ceilDate(actualDate); + } + } + return actualDate; + } +} +``` +###### /java/seedu/todo/commons/util/FilterUtil.java +``` java +/** + * Helper function to help in filtering results + */ + +public class FilterUtil { + + /*==================== Filtering Methods for Tasks ======================*/ + + /* + * Use to filter out Task items from calendarItems + * + * @param calendarItems + * List of mixture of Task and Event + * @return filteredTasks + * List containing only Task + */ + public static List filterOutTask(List calendarItems) { + List filteredTasks = new ArrayList(); + for (int i = 0; i < calendarItems.size(); i ++) { + if (calendarItems.get(i) instanceof Task) { + filteredTasks.add((Task) calendarItems.get(i)); + } + } + return filteredTasks; + } + + /** + * Filter the task list based on matching task name list + * @param tasks + * Provided list for filtering + * @param namelist + * Search and filter based on the name list + * @return filteredTasks + * List containing only Task that filtered by the item name + */ + public static List filterTaskByNames(List tasks, HashSet nameList) { + // If search list size is 0 , user not searching based on name + List filteredTasks = new ArrayList(); + if (nameList.size() == 0) { + return filteredTasks; + } + + // Loop through all the tasks + for (int i = 0; i < tasks.size(); i ++) { + Task task = tasks.get(i); + + // For every task, loop through all the name list + Iterator nameListIterator = nameList.iterator(); + while (nameListIterator.hasNext()) { + String matchingName = nameListIterator.next(); + if (matchWithFullName(task, matchingName) || matchWithSubName(task, matchingName)) { + filteredTasks.add(task); // Once found, add and break + break; + } + } + // Reset the name list for other task + nameListIterator = nameList.iterator(); + } + return filteredTasks; + } + + /** + * Filter the task list based on matching tag name list + * @param tasks + * Provided list for filtering + * @param namelist + * Search and filter based on the name list + * @return filteredTasks + * List containing only Task that filtered by the tag names + */ + public static List filterTaskByTags(List tasks, HashSet nameList) { + // If no search list is provided, user not searching based on tags + List filteredTasks = new ArrayList(); + if (nameList.size() == 0) { + return filteredTasks; + } + + // Lopp through all the tasks + for (int i = 0; i < tasks.size(); i ++) { + // Get the task tag list + Task task = tasks.get(i); + ArrayList taskTagList = task.getTagList(); + + // Loop through the tag names list + Iterator nameListIterator = nameList.iterator(); + while (nameListIterator.hasNext()) { + String currentMatchingName = nameListIterator.next(); + if (taskTagList.contains(currentMatchingName)) { + filteredTasks.add(task); // Once found a matching tag, add and break; + break; + } + } + nameListIterator = nameList.iterator(); + } + return filteredTasks; + } + + /** + * Filter the task list based on incomplete status + * @param tasks + * Provided list for filtering + * @param taskStatus + * True if searching for is completed, false if search for incomplete. + * @return filteredTasks + * List containing only Task that filtered by status (e.g. complete or incomplete) + */ + public static List filterTasksByStatus(List tasks, boolean taskStatus) { + // If tasks is empty, return immediately + if (tasks.size() == 0) { + return tasks; + } + + List filteredTasks = new ArrayList(); + // Loop through all the tasks + for (int i = 0; i < tasks.size(); i ++) { + Task task = tasks.get(i); + // Check if it is the same as the required task status + if (task.isCompleted() == taskStatus) { + filteredTasks.add(task); //Add any task has the same task status + } + } + return filteredTasks; + } + + /** + * Filter the task list based on single date + * @param tasks + * Provided list for filtering + * @param date + * Search based on this date + * @return filteredTasks + * List containing only Task that filtered by a single date + */ + public static List filterTaskBySingleDate(List tasks, LocalDateTime date) { + // If tasks is empty, return immediately + if (tasks.size() == 0) { + return tasks; + } + + ArrayList filteredTasks = new ArrayList(); + // Loop through all the tasks + Iterator iterator = tasks.iterator(); + while (iterator.hasNext()) { + Task task = iterator.next(); + // Searched date should not be null, break out if it is. + assert date != null; + // Check if task start date is the same as the searched date + date = DateUtil.floorDate(date); + LocalDateTime taskDate = DateUtil.floorDate(task.getCalendarDateTime()); + + // May have floating tasks, skip floating tasks + if (taskDate != null && taskDate.equals(date)) { + filteredTasks.add(task); + } + } + return filteredTasks; + } + + /** + * Filter the task list with a date range + * @param tasks + * Provided list for filtering + * @param startDate + * Search based on this as starting date + * @param endDate + * Search based on this as ending date + * @return filteredTasks + * List containing only Task that filtered by a range of two dates + */ + public static List filterTaskWithDateRange(List tasks, LocalDateTime startDate, LocalDateTime endDate) { + // If tasks is empty, return immediately + if (tasks.size() == 0) { + return tasks; + } + + // If start date is null, set it to MIN dateTime, user could searched by "from today" + if (startDate == null) { + startDate = LocalDateTime.MIN; + } + + // If end date is null, set it to MAX dateTime, user could searched by "to today" + if (endDate == null) { + endDate = LocalDateTime.MAX; + } + + ArrayList filteredTasks = new ArrayList(); + // Loop through all the tasks + Iterator iterator = tasks.iterator(); + while (iterator.hasNext()) { + Task task = iterator.next(); + LocalDateTime taskDate = DateUtil.floorDate(task.getDueDate()); + // May have floating task, set the date to MIN dateTime, to avoid been filtered + if (taskDate == null) { + taskDate = LocalDateTime.MIN; + } + + // Set the searched date to its min and max value + startDate = DateUtil.floorDate(startDate); + endDate = DateUtil.ceilDate(endDate); + // Compare if the task date is within the range of start and end date + if (taskDate.compareTo(startDate) >= 0 && taskDate.compareTo(endDate) <= 0) { + filteredTasks.add(task); // Add if it is within the range + } + } + return filteredTasks; + } + + /*==================== Filtering Methods for Events ======================*/ + + /* + * Use to filter out Event items from calendarItems + * + * @param calendarItems + * List of mixture of Task and Event + * @return filteredTasks + * List containing only Event + */ + public static List filterOutEvent(List calendarItems) { + List filteredEvents = new ArrayList(); + for (int i = 0; i < calendarItems.size(); i ++) { + if (calendarItems.get(i) instanceof Event) { + filteredEvents.add((Event) calendarItems.get(i)); + } + } + return filteredEvents; + } + + /** + * Filter the event list based on event name list + * @param events + * Provided list for filtering + * @param namelist + * Search and filter based on the name list + * @return filteredEvents + * List containing only Event that event name matches with the item name + */ + public static List filterEventByNames(List events, HashSet nameList) { + List filteredEvents = new ArrayList(); + // If name list size is 0, means not searching by name list + if (nameList.size() == 0) { + return filteredEvents; + } + + // Lopp through all the events + for (int i = 0; i < events.size(); i ++) { + Event event = events.get(i); + // Loop through all the name list + Iterator nameListIterator = nameList.iterator(); + while (nameListIterator.hasNext()) { + String matchingName = nameListIterator.next().toLowerCase(); + // If found a match with its full name or sub names, break + if (matchWithFullName(event, matchingName) || matchWithSubName(event, matchingName)) { + filteredEvents.add(event); + break; + } + } + // Reset the nameList for the next event + nameListIterator = nameList.iterator(); + } + return filteredEvents; + } + + /** + * Filter the event list based on tag name list + * @param events + * Provided list for filtering + * @param namelist + * Search and filter based on the name list + * @return filteredEvents + * List containing only Event that tag names matches with the tag name + */ + public static List filterEventByTags(List events, HashSet nameList) { + List filteredEvents = new ArrayList(); + // If name list size is 0, means not searching by tags + if (nameList.size() == 0) { + return filteredEvents; + } + + // Loop through all the events + for (int i = 0; i < events.size(); i ++) { + Event event = events.get(i); + // Get the tag list of the event + ArrayList taskTagList = event.getTagList(); + Iterator nameListIterator = nameList.iterator(); + // Loop through the tag names list + while (nameListIterator.hasNext()) { + String currentMatchingName = nameListIterator.next(); + // If found a match, add and break + if (taskTagList.contains(currentMatchingName)) { + filteredEvents.add(event); + break; + } + } + // Reset the tag names list for the next event + nameListIterator = nameList.iterator(); + } + return filteredEvents; + } + + /** + * Filter the event list if the event date is over + * @param events + * Provided list for filtering + * @param isEventOver + * True if searching for event that are over, false if searching for current event + * @return filteredEvents + * List containing only Event that status matches with the status, For e.g. over or current + */ + public static List filterEventsByStatus(List events, boolean eventStatus) { + // If events is empty, return immediately + if (events.size() == 0) { + return events; + } + + List filteredEvents = new ArrayList(); + // Loop through the events + for (int i = 0; i < events.size(); i ++) { + Event event = events.get(i); + // Add into filteredEvents, once the status of the event matches + if (event.isOver() == eventStatus) { + filteredEvents.add(event); + } + } + return filteredEvents; + } + + /** + * Filter the event list based on single date + * @param events + * Provided list for filtering + * @param date + * Search based on this date + * @return filteredEvents + * List containing only Event date that matches with searched date + */ + public static List filterEventBySingleDate(List events, LocalDateTime date) { + // If events is empty, return immediately + if (events.size() == 0) { + return events; + } + + ArrayList filteredEvents = new ArrayList(); + // Loop through all the events + Iterator iterator = events.iterator(); + while (iterator.hasNext()) { + Event event = iterator.next(); + // Search dates cannot be null + assert date != null; + date = DateUtil.floorDate(date); + + // Event start date should not be null + assert event.getStartDate() != null; + LocalDateTime eventDate = DateUtil.floorDate(event.getStartDate()); + + // Check against start date, if equals add it in + if (eventDate.equals(date)) { + filteredEvents.add(event); + } + } + return filteredEvents; + } + + /** + * Filter the event list with range of dates + * @param events + * Provided list for filtering + * @param startDate + * Search based on this as starting date + * @param endDate + * Search based on this as ending date + * @return filteredEvents + * List containing only Event that date fall between startDate and endDate + */ + public static List filterEventWithDateRange(List events, LocalDateTime startDate, LocalDateTime endDate) { + // If events is empty, return immediately + if (events.size() == 0) { + return events; + } + + // Set startDate to MIN, user could search "from Today" + if (startDate == null) { + startDate = LocalDateTime.MIN; + } + + // Set endDate to MaX, user could search "to Today" + if (endDate == null) { + endDate = LocalDateTime.MAX; + } + + ArrayList filteredEvents = new ArrayList(); + Iterator iterator = events.iterator(); + // Loop through all the events + while (iterator.hasNext()) { + Event event = iterator.next(); + // Event dates should not be null + assert event.getStartDate() != null; + assert event.getEndDate() != null; + LocalDateTime eventStartDate = DateUtil.floorDate(event.getStartDate()); + LocalDateTime eventEndDate = DateUtil.floorDate(event.getEndDate()); + + // Check if the event start dates and end dates is within the search dates + startDate = DateUtil.floorDate(startDate); + endDate = DateUtil.ceilDate(endDate); + if (eventStartDate.compareTo(startDate) >= 0 && eventEndDate.compareTo(endDate) <= 0) { + filteredEvents.add(event); + } + } + return filteredEvents; + } + + /*==================== Helper Methods to Check Command Conflict ===================================*/ + + /* + * To be use to check if there are more than 1 event type entered by user + * + * @return true if more than 1 event type found, false, if only 1 or 0 event type found + */ + public static boolean isItemTypeConflict(String input) { + return input.contains("task") && input.contains("event"); + } + + /*==================== Helper Methods for filtering CalendarItem name ======================*/ + + /* + * Use to check if calendarItem name starts with the matching name + * + * @return true if it calendarItem's name starts with the matching name, + * false if calendarItem's name does not starts with matching name + */ + private static boolean matchWithFullName(CalendarItem calendarItem, String matchingName) { + String taskName = calendarItem.getName().toLowerCase(); + return taskName.startsWith(matchingName.toLowerCase()); + } + + /* + * Use to check if calendarItem name split by space starts with the matching name + * + * @return true if any of the calendarItem's name that is split by space that starts with the matching name, + * false if calendarItem's name that is split by space does not starts with matching name + */ + private static boolean matchWithSubName(CalendarItem calendarItem, String matchingName) { + String[] nameBySpace = StringUtil.splitStringBySpace(calendarItem.getName()); + for (int i = 0; i < nameBySpace.length; i ++) { + if (nameBySpace[i].toLowerCase().startsWith(matchingName.toLowerCase())) { + return true; + } + } + return false; + } + +} +``` +###### /java/seedu/todo/commons/util/ParseUtil.java +``` java +/** + * Helper functions for parsing. + */ +public class ParseUtil { + private static final int TOKEN_INDEX = 0; + private static final int TOKEN_RESULT_INDEX = 1; + + /* + * To be used to check if there exist an item tagged with the token + */ + public static boolean isTokenNull(Map parsedResult, String token) { + return parsedResult.get(token) == null || parsedResult.get(token)[TOKEN_INDEX] == null; + } + /* + * To check if parsedResult with the token containing the keyword provided + * + * @return true if keyword is found, false if it is not found + */ + public static boolean doesTokenContainKeyword(Map parsedResult, String token, String keyword) { + if (!isTokenNull(parsedResult, token)) { + return parsedResult.get(token)[TOKEN_INDEX].contains(keyword); + } + return false; + } + + /* + * To be used to get input from token + * + * @return the parsed result from tokenizer + */ + public static String getTokenResult(Map parsedResult, String token) { + if(!isTokenNull(parsedResult, token)) { + return parsedResult.get(token)[TOKEN_RESULT_INDEX]; + } + return null; + } + + /** + * Extracts the natural dates from parsedResult. + * + * @param parsedResult + * @return { numOfdateFound, naturalOn, naturalFrom, naturalTo } + */ + public static String[] parseDates(Map parsedResult) { + String naturalFrom = getTokenResult(parsedResult, "timeFrom"); + String naturalTo = getTokenResult(parsedResult, "timeTo"); + String naturalOn = getTokenResult(parsedResult, "time"); + int numOfDateFound = 0; + + String [] dateResult = { null, naturalOn, naturalFrom, naturalTo }; + for (int i = 0; i < dateResult.length; i ++) { + if (dateResult[i] != null) { + numOfDateFound ++; + } + } + + if (numOfDateFound == 0) { + return null; + } else { + dateResult[0] = Integer.toString(numOfDateFound); + } + + return dateResult; + } +} +``` +###### /java/seedu/todo/commons/util/StringUtil.java +``` java + /* + * Format the display message depending on the number of tasks and events + * + * @param numTasks + * the number of tasks found + * @param numEvents + * the number of events found + * + * @return the display message for console message output + */ + public static String displayNumberOfTaskAndEventFoundWithPuralizer (int numTasks, int numEvents) { + if (numTasks != 0 && numEvents != 0) { + return String.format("%s and %s", formatNumberOfTaskWithPuralizer(numTasks), formatNumberOfEventWithPuralizer(numEvents)); + } else if (numTasks != 0) { + return formatNumberOfTaskWithPuralizer(numTasks); + } else if (numEvents != 0){ + return formatNumberOfEventWithPuralizer(numEvents); + } else { + return "No item found!"; + } + } + + /* + * Format the number of events found based on the events found + * + * @param numEvents + * the number of events found + */ + public static String formatNumberOfEventWithPuralizer (int numEvents) { + return String.format("%d %s", numEvents, pluralizer(numEvents, "event", "events")); + } + + /* + * Format the number of tasks found based on the tasks found + * + * @param numTasks + * the number of tasks found + */ + public static String formatNumberOfTaskWithPuralizer (int numTasks) { + return String.format("%d %s", numTasks, pluralizer(numTasks, "task", "tasks")); + } +``` +###### /java/seedu/todo/commons/util/StringUtil.java +``` java + /* + * Convert input into individual input by splitting with space + */ + public static String[] splitStringBySpace(String input) { + return (input == null) ? null : input.trim().split(" "); + } +} +``` +###### /java/seedu/todo/controllers/ClearController.java +``` java +/** + * Controller to clear task/event by Type + */ +public class ClearController implements Controller { + + private static final String NAME = "Clear"; + private static final String DESCRIPTION = "Clear all tasks/events or by specify date."; + private static final String COMMAND_WORD = "clear"; + + // Syntax correction to console input + public static final String COMMAND_SYNTAX = "clear \"task/event\" on \"date\""; + public static final String CLEAR_DATE_SYNTAX = "clear \"date\" [or from \"date\" to \"date\"]"; + + // Message output to console text area + public static final String MESSAGE_CLEAR_SUCCESS_FORMAT = "A total of %s deleted!"; + public static final String MESSAGE_CLEAR_NO_ITEM_FOUND = "No item found!"; + public static final String MESSAGE_CLEAR_ALL_SUCCESS = "All tasks and events have been deleted!\n" + "To undo, type \"undo\"."; + public static final String MESSAGE_CLEAR_UNABLE_TO_SUPPORT = "Unable to clear!\nCannot clear by status!"; + public static final String MESSAGE_DATE_CONFLICT = "Unable to clear!\nMore than 1 date criteria is provided!"; + public static final String MESSAGE_NO_DATE_DETECTED = "Unable to clear!\nThe natural date entered is not supported."; + public static final String MESSAGE_ITEM_TYPE_CONFLICT = "Unable to clear!\nMore than 1 item type is provided!"; + + // Use to access parsing of dates + private static final int NUM_OF_DATES_FOUND_INDEX = 0; + private static final int COMMAND_INPUT_INDEX = 0; + private static final int DATE_CRITERIA_INDEX = 0; + private static final int DATE_ON_INDEX = 1; + private static final int DATE_FROM_INDEX = 2; + private static final int DATE_TO_INDEX = 3; + + private static CommandDefinition commandDefinition = + new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX); + + public static CommandDefinition getCommandDefinition() { + return commandDefinition; + } + + @Override + public float inputConfidence(String input) { + return (StringUtil.splitStringBySpace(input.toLowerCase())[COMMAND_INPUT_INDEX]).equals(COMMAND_WORD) ? 1 : 0; + } + + /** + * Get the token definitions for use with tokenizer.
+ * This method exists primarily because Java does not support HashMap + * literals... + * + * @return tokenDefinitions + */ + private static Map getTokenDefinitions() { + Map tokenDefinitions = new HashMap(); + tokenDefinitions.put(Tokenizer.DEFAULT_TOKEN, new String[] { COMMAND_WORD }); + tokenDefinitions.put(Tokenizer.EVENT_TYPE_TOKEN, Tokenizer.EVENT_TYPE_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_TOKEN, Tokenizer.TIME_DEFINITION); + tokenDefinitions.put(Tokenizer.TASK_STATUS_TOKEN, Tokenizer.TASK_STATUS_DEFINITION); + tokenDefinitions.put(Tokenizer.EVENT_STATUS_TOKEN, Tokenizer.EVENT_STATUS_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_FROM_TOKEN, Tokenizer.TIME_FROM_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_TO_TOKEN, Tokenizer.TIME_TO_DEFINITION); + return tokenDefinitions; + } + + @Override + public void process(String input) throws ParseException { + Map parsedResult; + parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input); + TodoListDB db = TodoListDB.getInstance(); + + if (input.trim().equals(COMMAND_WORD)) { + db.destroyAllTaskAndEvents(); + Renderer.renderIndex(db, MESSAGE_CLEAR_ALL_SUCCESS); + return; // Clear all + } + + boolean isItemTypeProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.EVENT_TYPE_TOKEN); + boolean isTaskStatusProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.TASK_STATUS_TOKEN); + boolean isEventStatusProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.EVENT_STATUS_TOKEN); + + if (isErrorCommand(isTaskStatusProvided, isEventStatusProvided, input)) { + return; // Break out if found error + } + + boolean isTask = true; //default + if (isItemTypeProvided) { + isTask = ParseUtil.doesTokenContainKeyword(parsedResult, Tokenizer.EVENT_TYPE_TOKEN, "task"); + } + + LocalDateTime [] validDates = parsingDates(parsedResult); + if (validDates == null) { + return; // Break out when date conflict found + } + + // Setting up view + List tasks; //default + List events; //default + List calendarItems; + // Filter Task and Event by Type + if (!isItemTypeProvided) { + tasks = db.getAllTasks(); + events = db.getAllEvents(); + } else { + if (isTask) { + events = new ArrayList(); + tasks = db.getAllTasks(); + } else { + tasks = new ArrayList(); + events = db.getAllEvents(); + } + } + + // Filter Task and Event by date + calendarItems = filterTasksAndEventsByDate(tasks, events, parsedResult); + if (calendarItems == null) { + return; // Date conflict detected + } + tasks = FilterUtil.filterOutTask(calendarItems); + events = FilterUtil.filterOutEvent(calendarItems); + + // Show message if no items had been found + if (tasks.size() == 0 && events.size() == 0) { + Renderer.renderIndex(db, MESSAGE_CLEAR_NO_ITEM_FOUND); + return; + } + + deleteSelectedTasksAndEvents(tasks, events, db); + } + + /*====================== Helper Methods to check for Error/Syntax Command ===================*/ + + /* + * To be used to parsed dates and check for any dates conflict + * + * @return null if dates conflict detected, else return { dateCriteria, dateOn, dateFrom, dateTo } + */ + private LocalDateTime[] parsingDates(Map parsedResult) { + String[] parsedDates = ParseUtil.parseDates(parsedResult); + //date enter with COMMAND_WORD e.g list today + String date = ParseUtil.getTokenResult(parsedResult, Tokenizer.DEFAULT_TOKEN); + + if (date != null && parsedDates != null) { + Renderer.renderDisambiguation(CLEAR_DATE_SYNTAX, MESSAGE_DATE_CONFLICT); + return null; + } + + LocalDateTime dateCriteria = null; + LocalDateTime dateOn = null; + LocalDateTime dateFrom = null; + LocalDateTime dateTo = null; + + if (date != null) { + try { + dateCriteria = DateParser.parseNatural(date); + } catch (InvalidNaturalDateException e) { + Renderer.renderDisambiguation(CLEAR_DATE_SYNTAX, MESSAGE_NO_DATE_DETECTED); + return null; + } + } + + if (parsedDates != null) { + String naturalOn = parsedDates[DATE_ON_INDEX]; + String naturalFrom = parsedDates[DATE_FROM_INDEX]; + String naturalTo = parsedDates[DATE_TO_INDEX]; + if (naturalOn != null && Integer.parseInt(parsedDates[NUM_OF_DATES_FOUND_INDEX]) > 1) { + //date conflict detected + Renderer.renderDisambiguation(CLEAR_DATE_SYNTAX, MESSAGE_DATE_CONFLICT); + return null; + } + // Parse natural date using Natty. + try { + dateOn = naturalOn == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalOn)); + dateFrom = naturalFrom == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalFrom)); + dateTo = naturalTo == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalTo)); + } catch (InvalidNaturalDateException e) { + Renderer.renderDisambiguation(CLEAR_DATE_SYNTAX, MESSAGE_NO_DATE_DETECTED); + return null; + } + } + return new LocalDateTime[] { dateCriteria, dateOn, dateFrom, dateTo }; + } + + /* + * To be use to check if there are any command syntax error + * + * @return true, if there is error in command syntax, false if syntax is allowed + */ + private boolean isErrorCommand(boolean isTaskStatusProvided, boolean isEventStatusProvided, String input) { + // Check if any status is provided + if (isTaskStatusProvided || isEventStatusProvided) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_CLEAR_UNABLE_TO_SUPPORT); + return true; + } + // Check if more than 1 item type is provided + if (FilterUtil.isItemTypeConflict(input)) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_ITEM_TYPE_CONFLICT); + return true; + } + return false; + } + + /* =================== Helper methods to filter out Task and Events ==================*/ + + /* + * Filter out the selected tasks and events based on the dates + * and update tasks and events accordingly + * + * @param tasks + * List of Task items + * @param events + * List of Event items + * @param parsedResult + * parsedResult by Tokenizer + * @return + * tasks and events in a list form by date or null when date conflict found + */ + private List filterTasksAndEventsByDate(List tasks, List events, Map parsedResult) { + // Get dates from input + List calendarItems = new ArrayList(); + LocalDateTime [] validDates = parsingDates(parsedResult); + List filteredTasks = tasks; + List filteredEvents = events; + if (validDates == null) { + return null; // Break out when date conflict found + } + + // Set dates that are found, if not found value will be null + LocalDateTime dateCriteria = validDates[DATE_CRITERIA_INDEX]; + LocalDateTime dateOn = validDates[DATE_ON_INDEX]; + LocalDateTime dateFrom = validDates[DATE_FROM_INDEX]; + LocalDateTime dateTo = validDates[DATE_TO_INDEX]; + + if (dateCriteria != null) { + // Filter by single date + assert dateOn == null; + assert dateFrom == null; + assert dateTo == null; + filteredTasks = FilterUtil.filterTaskBySingleDate(tasks, dateCriteria); + filteredEvents = FilterUtil.filterEventBySingleDate(events, dateCriteria); + } + + if (dateOn != null) { + // Filter by single date + filteredTasks = FilterUtil.filterTaskBySingleDate(tasks, dateOn); + filteredEvents = FilterUtil.filterEventBySingleDate(events, dateOn); + } else if (dateFrom != null || dateTo != null) { + // Filter by range + filteredTasks = FilterUtil.filterTaskWithDateRange(tasks, dateFrom, dateTo); + filteredEvents =FilterUtil.filterEventWithDateRange(events, dateFrom, dateTo); + } + + calendarItems.addAll(filteredTasks); + calendarItems.addAll(filteredEvents); + return calendarItems; + } + + /* =============== Helper Methods to delete selected Tasks and Events ============*/ + + /* + * Delete the selected Tasks and Events , filtered out by helper methods + * + * @param tasks + * A list of Task that already been filtered for deletion + * @param events + * A list of Event that already been filtered for deletion + * @param db + * The same instance of db used to filtered out both tasks and events + */ + private void deleteSelectedTasksAndEvents(List tasks, List events, TodoListDB db) { + db.destroyAllTaskAndEventsByList(tasks, events); + String consoleMessage = String.format(MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(tasks.size(), events.size())); + Renderer.renderIndex(db, consoleMessage); + } +} +``` +###### /java/seedu/todo/controllers/FindController.java +``` java +/** + * Controller to find task/event by keyword + */ +public class FindController implements Controller { + + private static final String NAME = "Find"; + private static final String DESCRIPTION = "Find all tasks and events based on the provided keywords.\n" + + "This command will be searching with non-case sensitive keywords."; + private static final String COMMAND_WORD = "find"; + + // Syntax correction to console input + public static final String COMMAND_SYNTAX = "find \"name\" tagName \"tag\" on \"date\" \"task/event\""; + public static final String FIND_TASK_SYNTAX = "find \"name\" task \"complete/incomplete\""; + public static final String FIND_EVENT_SYNTAX = "find \"name\" event \"over/ongoing\""; + + // Message output to console text area + public static final String MESSAGE_RESULT_FOUND_FORMAT = "A total of %s found!"; + public static final String MESSAGE_NO_RESULT_FOUND = "No task or event found!"; + public static final String MESSAGE_NO_KEYWORD_FOUND = "No keyword found!"; + public static final String MESSAGE_DATE_CONFLICT = "Unable to find!\nMore than 1 date criteria is provided!"; + public static final String MESSAGE_NO_DATE_DETECTED = "Unable to find!\nThe natural date entered is not supported."; + public static final String MESSAGE_INVALID_TASK_STATUS = "Unable to find!\nTry searching with complete or incomplete"; + public static final String MESSAGE_INVALID_EVENT_STATUS = "Unable to find!\nTry searching with over or current"; + public static final String MESSAGE_ITEM_TYPE_CONFLICT = "Unable to list!\nMore than 1 item type is provided!"; + + private static final int COMMAND_INPUT_INDEX = 0; + //use to access parsing of dates + private static final int NUM_OF_DATES_FOUND_INDEX = 0; + private static final int DATE_ON_INDEX = 1; + private static final int DATE_FROM_INDEX = 2; + private static final int DATE_TO_INDEX = 3; + + private static CommandDefinition commandDefinition = + new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX); + + public static CommandDefinition getCommandDefinition() { + return commandDefinition; + } + + @Override + public float inputConfidence(String input) { + String command = StringUtil.splitStringBySpace(input.toLowerCase())[COMMAND_INPUT_INDEX]; + return (command).equals(COMMAND_WORD) ? 1 : 0; + } + + private static Map getTokenDefinitions() { + Map tokenDefinitions = new HashMap(); + tokenDefinitions.put(Tokenizer.DEFAULT_TOKEN, new String[] { COMMAND_WORD }); + tokenDefinitions.put(Tokenizer.EVENT_TYPE_TOKEN, Tokenizer.EVENT_TYPE_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_TOKEN, Tokenizer.TIME_DEFINITION); + tokenDefinitions.put(Tokenizer.TASK_STATUS_TOKEN, Tokenizer.TASK_STATUS_DEFINITION); + tokenDefinitions.put(Tokenizer.EVENT_STATUS_TOKEN, Tokenizer.EVENT_STATUS_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_FROM_TOKEN, Tokenizer.TIME_FROM_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_TO_TOKEN, Tokenizer.TIME_TO_DEFINITION); + tokenDefinitions.put(Tokenizer.ITEM_NAME_TOKEN, Tokenizer.ITEM_NAME_DEFINITION); + tokenDefinitions.put(Tokenizer.TAG_NAME_TOKEN, Tokenizer.TAG_NAME_DEFINITION); + return tokenDefinitions; + } + + @Override + public void process(String input) throws ParseException { + + Map parsedResult; + parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input); + + HashSet itemNameList = new HashSet(); + HashSet tagNameList = new HashSet(); + HashSet keywordList = new HashSet(); + + // To be use to be filter out name and tag names + updateHashList(parsedResult, keywordList, Tokenizer.DEFAULT_TOKEN); + updateHashList(parsedResult, itemNameList, Tokenizer.ITEM_NAME_TOKEN); + updateHashList(parsedResult, tagNameList, Tokenizer.TAG_NAME_TOKEN); + itemNameList.addAll(keywordList); + tagNameList.addAll(keywordList); + + // Show console output message, since no keyword found + if (keywordList.size() == 0 && itemNameList.size() == 0 && tagNameList.size() == 0) { + //No keyword provided, display error + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_NO_KEYWORD_FOUND); + return; + } + + // Check if input includes itemType and itemStatus + boolean isItemTypeProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.EVENT_TYPE_TOKEN); + boolean isTaskStatusProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.TASK_STATUS_TOKEN); + boolean isEventStatusProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.EVENT_STATUS_TOKEN); + + // Set item type + boolean isTask = true; //default + if (isItemTypeProvided) { + isTask = ParseUtil.doesTokenContainKeyword(parsedResult, Tokenizer.EVENT_TYPE_TOKEN, "task"); + } + + if (isErrorCommand(isTaskStatusProvided, isEventStatusProvided, isTask, isItemTypeProvided, input)) { + return; // Break out if found error + } + + // Setting up view + TodoListDB db = TodoListDB.getInstance(); + List tasks; //default + List events; //default + List calendarItems; + + // Filter out the tasks and events based on type and names + if (!isItemTypeProvided) { + tasks = filterByTaskNameAndTagName(itemNameList, tagNameList, db.getAllTasks()); + events = filterByEventNameAndTagName(itemNameList, tagNameList, db.getAllEvents()); + } else { + if (isTask) { + events = new ArrayList(); + tasks = filterByTaskNameAndTagName(itemNameList, tagNameList, db.getAllTasks()); + } else { + tasks = new ArrayList(); + events = filterByEventNameAndTagName(itemNameList, tagNameList, db.getAllEvents()); + } + } + + // Filter Task and Event by Status + calendarItems = filterTasksAndEventsByStatus(parsedResult, isTaskStatusProvided, isEventStatusProvided, tasks, events); + tasks = FilterUtil.filterOutTask(calendarItems); + events = FilterUtil.filterOutEvent(calendarItems); + + // Filter Task and Event by date + calendarItems = filterTasksAndEventsByDate(tasks, events, parsedResult); + if (calendarItems == null) { + return; // Date conflict detected + } + tasks = FilterUtil.filterOutTask(calendarItems); + events = FilterUtil.filterOutEvent(calendarItems); + + // Show message if no items had been found + if (tasks.size() == 0 && events.size() == 0) { + Renderer.renderIndex(db, MESSAGE_NO_RESULT_FOUND); + return; + } + + String consoleMessage = String.format(MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(tasks.size(), events.size())); + Renderer.renderSelectedIndex(db, consoleMessage, tasks, events); + } + + /*======================== Helper Methods to filter tasks and events ========================================*/ + + /* + * Filter out the selected tasks and events based on the status and update tasks and events accordingly + * + * @param parsedResult + * parsedResult by Tokenizer + * @param isTaskStatusProvided + * true if complete or incomplete is found, else false + * @param isEventStatusProvided + * true if over or current is found, else false + * @param tasks + * List of Task items + * @param events + * List of Event items + * @return + * tasks and events in a list form by status + */ + private List filterTasksAndEventsByStatus(Map parsedResult, boolean isTaskStatusProvided, + boolean isEventStatusProvided, List tasks, List events) { + List calendarItems = new ArrayList(); + // Set item status + boolean isCompleted = false; //default + boolean isOver = false; //default + List filteredTasks = tasks; + List filteredEvents = events; + + // Filter out by Task Status if provided + if (isTaskStatusProvided) { + isCompleted = !ParseUtil.doesTokenContainKeyword(parsedResult, Tokenizer.TASK_STATUS_TOKEN, "incomplete"); + filteredTasks = FilterUtil.filterTasksByStatus(tasks, isCompleted); + filteredEvents = new ArrayList(); + } + + // Filter out by Event Status if provided + if (isEventStatusProvided) { + isOver = ParseUtil.doesTokenContainKeyword(parsedResult, Tokenizer.EVENT_STATUS_TOKEN, "over"); + filteredEvents = FilterUtil.filterEventsByStatus(events, isOver); + filteredTasks = new ArrayList(); + } + calendarItems.addAll(filteredTasks); + calendarItems.addAll(filteredEvents); + return calendarItems; + } + + /* + * Filter out the selected tasks and events based on the dates + * and update tasks and events accordingly + * + * @param tasks + * List of Task items + * @param events + * List of Event items + * @param parsedResult + * parsedResult by Tokenizer + * @return + * tasks and events in a list form by date or null when date conflict found + */ + private List filterTasksAndEventsByDate(List tasks, List events, + Map parsedResult) { + // Get dates from input + List calendarItems = new ArrayList(); + LocalDateTime [] validDates = parsingDates(parsedResult); + List filteredTasks; + List filteredEvents; + if (validDates == null) { + return null; // Break out when date conflict found + } + + // Set dates that are found, if not found value will be null + LocalDateTime dateOn = validDates[DATE_ON_INDEX]; + LocalDateTime dateFrom = validDates[DATE_FROM_INDEX]; + LocalDateTime dateTo = validDates[DATE_TO_INDEX]; + + if (dateOn != null) { + // Filter by single date + filteredTasks = FilterUtil.filterTaskBySingleDate(tasks, dateOn); + filteredEvents = FilterUtil.filterEventBySingleDate(events, dateOn); + } else { + // Filter by range + filteredTasks = FilterUtil.filterTaskWithDateRange(tasks, dateFrom, dateTo); + filteredEvents = FilterUtil.filterEventWithDateRange(events, dateFrom, dateTo); + } + calendarItems.addAll(filteredTasks); + calendarItems.addAll(filteredEvents); + return calendarItems; + } + + /* + * Filter out all the events based on the name list that has been parsed. + * This method also ensure that no duplicate event will be return. + * + * @param itemNameList + * a list of item name that has been parsed from input + * @param tagNameList + * a List of tag name that has been parsed from input + * @param events + * all the events in the DB + * @return a list of Event which names or tag names is filtered with the list + */ + private List filterByEventNameAndTagName(HashSet itemNameList, HashSet tagNameList, + List events) { + HashSet mergedEvents = new HashSet(); + List eventsByNames = FilterUtil.filterEventByNames(events, itemNameList); + List eventsByTags = FilterUtil.filterEventByTags(events, tagNameList); + mergedEvents.addAll(eventsByNames); + mergedEvents.addAll(eventsByTags); + events = new ArrayList(mergedEvents); + return events; + } + + /* + * Filter out all the tasks based on the name list that has been parsed. + * This method also ensure that no duplicate task will be return. + * + * @param itemNameList + * a list of item name that has been parsed from input + * @param tagNameList + * a List of tag name that has been parsed from input + * @param tasks + * all the tasks in the DB + * @return a list of Task which names or tag names is filtered with the list + */ + private List filterByTaskNameAndTagName(HashSet itemNameList, HashSet tagNameList, + List tasks) { + HashSet mergedTasks = new HashSet(); + List tasksByNames = FilterUtil.filterTaskByNames(tasks, itemNameList); + List tasksByTags = FilterUtil.filterTaskByTags(tasks, tagNameList); + mergedTasks.addAll(tasksByNames); + mergedTasks.addAll(tasksByTags); + tasks = new ArrayList(mergedTasks); + return tasks; + } + + /** + * Extract the parsed result and update into the hashlist + * @param parsedResult + */ + private void updateHashList(Map parsedResult, HashSet hashList, + String token) { + String result = ParseUtil.getTokenResult(parsedResult, token); + // If found any matching , update list + if (result != null) { + hashList.add(result); + String[] resultArray = StringUtil.splitStringBySpace(result); + for (int i = 0; i < resultArray.length; i ++) { + hashList.add(resultArray[i]); + } + } + } + + /*============================ Helper Methods to check for Error/Syntax Command ===================*/ + + /* + * To be use to check if there are any command syntax error + * + * @return true, if there is an error in the command syntax, false if syntax is allowed + */ + private boolean isErrorCommand(boolean isTaskStatusProvided, boolean isEventStatusProvided, + boolean isTask, boolean isItemTypeProvided, String input) { + // Check if more than 1 item type is provided + if (FilterUtil.isItemTypeConflict(input)) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_ITEM_TYPE_CONFLICT); + return true; + } + if (isItemTypeProvided) { + // Task and Event Command Syntax detected + if (isTask && isEventStatusProvided) { + Renderer.renderDisambiguation(FIND_TASK_SYNTAX, MESSAGE_INVALID_TASK_STATUS); + return true; + } + if (!isTask && isTaskStatusProvided) { + Renderer.renderDisambiguation(FIND_EVENT_SYNTAX, MESSAGE_INVALID_EVENT_STATUS); + return true; + } + } + return false; + } + + /* + * To be used to parsed dates and check for any dates conflict + * + * @return null if dates conflict detected, else return { null, dateOn, dateFrom, dateTo } + */ + private LocalDateTime[] parsingDates(Map parsedResult) { + String[] parsedDates = ParseUtil.parseDates(parsedResult); + LocalDateTime dateOn = null; + LocalDateTime dateFrom = null; + LocalDateTime dateTo = null; + + if (parsedDates != null) { + String naturalOn = parsedDates[DATE_ON_INDEX]; + String naturalFrom = parsedDates[DATE_FROM_INDEX]; + String naturalTo = parsedDates[DATE_TO_INDEX]; + + if (naturalOn != null && Integer.parseInt(parsedDates[NUM_OF_DATES_FOUND_INDEX]) > 1) { + // Date conflict detected + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_DATE_CONFLICT); + return null; + } + // Parse natural date using Natty. + try { + dateOn = naturalOn == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalOn)); + dateFrom = naturalFrom == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalFrom)); + dateTo = naturalTo == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalTo)); + } catch (InvalidNaturalDateException e) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_NO_DATE_DETECTED); + return null; + } + } + return new LocalDateTime[] { null, dateOn, dateFrom, dateTo }; + } +} +``` +###### /java/seedu/todo/controllers/ListController.java +``` java +/** + * Controller to list CalendarItems + */ +public class ListController implements Controller { + + private static final String NAME = "List"; + private static final String DESCRIPTION = "List all tasks and events by type or status."; + private static final String COMMAND_SYNTAX = "list \"task complete/incomplete\" or \"event over/ongoing\"" + + "[on date] or [from date to date]"; + private static final String COMMAND_WORD = "list"; + + // Syntax correction to console input + public static final String LIST_TASK_SYNTAX = "list task \"complete/incomplete\""; + public static final String LIST_EVENT_SYNTAX = "list event \"over/current\""; + public static final String LIST_DATE_SYNTAX = "list \"date\" [or from \"date\" to \"date\"]"; + + // Message output to console text area + public static final String MESSAGE_RESULT_FOUND_FORMAT = "A total of %s found!"; + public static final String MESSAGE_NO_RESULT_FOUND = "No task or event found!"; + public static final String MESSAGE_LIST_SUCCESS = "Listing Today's, incompleted tasks and ongoing events"; + public static final String MESSAGE_INVALID_TASK_STATUS = "Unable to list!\nTry listing with complete or incomplete"; + public static final String MESSAGE_INVALID_EVENT_STATUS = "Unable to list!\nTry listing with over or current"; + public static final String MESSAGE_DATE_CONFLICT = "Unable to list!\nMore than 1 date criteria is provided!"; + public static final String MESSAGE_NO_DATE_DETECTED = "Unable to list!\nThe natural date entered is not supported."; + public static final String MESSAGE_ITEM_TYPE_CONFLICT = "Unable to list!\nMore than 1 item type is provided!"; + + // Use to access parsing of dates + private static final int NUM_OF_DATES_FOUND_INDEX = 0; + private static final int COMMAND_INPUT_INDEX = 0; + private static final int DATE_CRITERIA_INDEX = 0; + private static final int DATE_ON_INDEX = 1; + private static final int DATE_FROM_INDEX = 2; + private static final int DATE_TO_INDEX = 3; + + private static CommandDefinition commandDefinition = + new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX); + + public static CommandDefinition getCommandDefinition() { + return commandDefinition; + } + + @Override + public float inputConfidence(String input) { + return (StringUtil.splitStringBySpace(input.toLowerCase())[COMMAND_INPUT_INDEX]).equals(COMMAND_WORD) ? 1 : 0; + } + + private static Map getTokenDefinitions() { + Map tokenDefinitions = new HashMap(); + tokenDefinitions.put(Tokenizer.DEFAULT_TOKEN, new String[] { COMMAND_WORD }); + tokenDefinitions.put(Tokenizer.EVENT_TYPE_TOKEN, Tokenizer.EVENT_TYPE_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_TOKEN, Tokenizer.TIME_DEFINITION); + tokenDefinitions.put(Tokenizer.TASK_STATUS_TOKEN, Tokenizer.TASK_STATUS_DEFINITION); + tokenDefinitions.put(Tokenizer.EVENT_STATUS_TOKEN, Tokenizer.EVENT_STATUS_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_FROM_TOKEN, Tokenizer.TIME_FROM_DEFINITION); + tokenDefinitions.put(Tokenizer.TIME_TO_TOKEN, Tokenizer.TIME_TO_DEFINITION); + return tokenDefinitions; + } + + @Override + public void process(String input) throws ParseException { + + Map parsedResult; + parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input); + TodoListDB db = TodoListDB.getInstance(); + + // If input is just "list", invoke Renderer + if (input.trim().equals(COMMAND_WORD)) { + Renderer.renderIndex(db, MESSAGE_LIST_SUCCESS); + return; + } + + // Check if input includes itemType and itemStatus + boolean isItemTypeProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.EVENT_TYPE_TOKEN); + boolean isTaskStatusProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.TASK_STATUS_TOKEN); + boolean isEventStatusProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.EVENT_STATUS_TOKEN); + + // Set item type + boolean isTask = true; //default + if (isItemTypeProvided) { + isTask = ParseUtil.doesTokenContainKeyword(parsedResult, Tokenizer.EVENT_TYPE_TOKEN, "task"); + } + + if (isErrorCommand(isTaskStatusProvided, isEventStatusProvided, isTask, isItemTypeProvided, input)) { + return; // Break out if found error + } + + // Setting up view + List tasks; //default + List events; //default + List calendarItems; + // Filter Task and Event by Type + if (!isItemTypeProvided) { + tasks = db.getAllTasks(); + events = db.getAllEvents(); + } else { + if (isTask) { + events = new ArrayList(); + tasks = db.getAllTasks(); + } else { + tasks = new ArrayList(); + events = db.getAllEvents(); + } + } + + // Filter Task and Event by Status + calendarItems = filterTasksAndEventsByStatus(parsedResult, isTaskStatusProvided, isEventStatusProvided, + tasks, events); + tasks = FilterUtil.filterOutTask(calendarItems); + events = FilterUtil.filterOutEvent(calendarItems); + + // Filter Task and Event by date + calendarItems = filterTasksAndEventsByDate(tasks, events, parsedResult); + if (calendarItems == null) { + return; // Date conflict detected + } + tasks = FilterUtil.filterOutTask(calendarItems); + events = FilterUtil.filterOutEvent(calendarItems); + + // Show message if no items had been found + if (tasks.size() == 0 && events.size() == 0) { + Renderer.renderIndex(db, MESSAGE_NO_RESULT_FOUND); + return; + } + + String consoleMessage = String.format(MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(tasks.size(), events.size())); + Renderer.renderSelectedIndex(db, consoleMessage, tasks, events); + } + + /* ============================== Helper methods to filter out by criterias ================================*/ + + /* + * Filter out the selected tasks and events based on the dates + * and update tasks and events accordingly + * + * @param tasks + * List of Task items + * @param events + * List of Event items + * @param parsedResult + * Parsed result by Tokenizer, in order to filter out the dates + * @return a List of CalendarItem that is been filtered by date(s) + */ + private List filterTasksAndEventsByDate(List tasks, List events, Map parsedResult) { + // Get dates from input + List calendarItems = new ArrayList(); + LocalDateTime [] validDates = parsingDates(parsedResult); + List filteredTasks = tasks; + List filteredEvents = events; + if (validDates == null) { + return null; // Break out when date conflict found + } + + // Set dates that are found, if not found value will be null + LocalDateTime dateCriteria = validDates[DATE_CRITERIA_INDEX]; + LocalDateTime dateOn = validDates[DATE_ON_INDEX]; + LocalDateTime dateFrom = validDates[DATE_FROM_INDEX]; + LocalDateTime dateTo = validDates[DATE_TO_INDEX]; + + if (dateCriteria != null) { + // Filter by single date + assert dateOn == null; + assert dateFrom == null; + assert dateTo == null; + filteredTasks = FilterUtil.filterTaskBySingleDate(tasks, dateCriteria); + filteredEvents = FilterUtil.filterEventBySingleDate(events, dateCriteria); + } + + if (dateOn != null) { + // Filter by single date + filteredTasks = FilterUtil.filterTaskBySingleDate(tasks, dateOn); + filteredEvents = FilterUtil.filterEventBySingleDate(events, dateOn); + } else if (dateFrom != null || dateTo != null) { + // Filter by range + filteredTasks = FilterUtil.filterTaskWithDateRange(tasks, dateFrom, dateTo); + filteredEvents =FilterUtil.filterEventWithDateRange(events, dateFrom, dateTo); + } + + calendarItems.addAll(filteredTasks); + calendarItems.addAll(filteredEvents); + return calendarItems; + } + + /* + * Filter out the selected tasks and events based on the status and update tasks and events accordingly + * + * @param parsedResult + * parsedResult by Tokenizer + * @param isTaskStatusProvided + * true if complete or incomplete is found, else false + * @param isEventStatusProvided + * true if over or current is found, else false + * @param tasks + * List of Task items + * @param events + * List of Event items + * @return + * tasks and events in a list form by status + */ + private List filterTasksAndEventsByStatus(Map parsedResult, boolean isTaskStatusProvided, + boolean isEventStatusProvided, List tasks, List events) { + List calendarItems = new ArrayList(); + List filteredTasks = tasks; + List filteredEvents = events; + + // Set item status + boolean isCompleted = false; //default + boolean isOver = false; //default + + // Filter out by Task Status if provided + if (isTaskStatusProvided) { + isCompleted = !ParseUtil.doesTokenContainKeyword(parsedResult, Tokenizer.TASK_STATUS_TOKEN, "incomplete"); + filteredTasks = FilterUtil.filterTasksByStatus(tasks, isCompleted); + filteredEvents = new ArrayList(); + } + + // Filter out by Event Status if provided + if (isEventStatusProvided) { + isOver = ParseUtil.doesTokenContainKeyword(parsedResult, Tokenizer.EVENT_STATUS_TOKEN, "over"); + filteredEvents = FilterUtil.filterEventsByStatus(events, isOver); + filteredTasks = new ArrayList(); + } + calendarItems.addAll(filteredTasks); + calendarItems.addAll(filteredEvents); + return calendarItems; + } + + /*====================== Helper Methods to check for Error/Syntax Command ===================*/ + + /* + * To be use to check if there are any command syntax error + * + * @return true, if there is an error in the command syntax, false if syntax is allowed + */ + private boolean isErrorCommand(boolean isTaskStatusProvided, boolean isEventStatusProvided, + boolean isTask, boolean isItemTypeProvided, String input) { + // Check if more than 1 item type is provided + if (FilterUtil.isItemTypeConflict(input)) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_ITEM_TYPE_CONFLICT); + return true; + } + if (isItemTypeProvided) { + // Task and Event Command Syntax detected + if (isTask && isEventStatusProvided) { + Renderer.renderDisambiguation(LIST_TASK_SYNTAX, MESSAGE_INVALID_TASK_STATUS); + return true; + } + + if (!isTask && isTaskStatusProvided) { + Renderer.renderDisambiguation(LIST_EVENT_SYNTAX, MESSAGE_INVALID_EVENT_STATUS); + return true; + } + } + return false; + } + + /* + * To be used to parsed dates and check for any dates conflict + * + * @return null if dates conflict detected, else return { dateCriteria, dateOn, dateFrom, dateTo } + */ + private LocalDateTime[] parsingDates(Map parsedResult) { + String[] parsedDates = ParseUtil.parseDates(parsedResult); + + // Date enter with COMMAND_WORD e.g list today + String date = ParseUtil.getTokenResult(parsedResult, Tokenizer.DEFAULT_TOKEN); + + // Check for more than 1 date + if (date != null && parsedDates != null) { + Renderer.renderDisambiguation(LIST_DATE_SYNTAX, MESSAGE_DATE_CONFLICT); + return null; + } + + LocalDateTime dateCriteria = null; + LocalDateTime dateOn = null; + LocalDateTime dateFrom = null; + LocalDateTime dateTo = null; + + // Setting of dates value + if (date != null) { + try { + dateCriteria = DateParser.parseNatural(date); + } catch (InvalidNaturalDateException e) { + Renderer.renderDisambiguation(LIST_DATE_SYNTAX, MESSAGE_NO_DATE_DETECTED); + return null; + } + } + + if (parsedDates != null) { + String naturalOn = parsedDates[DATE_ON_INDEX]; + String naturalFrom = parsedDates[DATE_FROM_INDEX]; + String naturalTo = parsedDates[DATE_TO_INDEX]; + + if (naturalOn != null && Integer.parseInt(parsedDates[NUM_OF_DATES_FOUND_INDEX]) > 1) { + //date conflict detected + Renderer.renderDisambiguation(LIST_DATE_SYNTAX, MESSAGE_DATE_CONFLICT); + return null; + } + // Parse natural date using Natty. + try { + dateOn = naturalOn == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalOn)); + dateFrom = naturalFrom == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalFrom)); + dateTo = naturalTo == null ? null : DateUtil.floorDate(DateParser.parseNatural(naturalTo)); + } catch (InvalidNaturalDateException e) { + Renderer.renderDisambiguation(LIST_DATE_SYNTAX, MESSAGE_NO_DATE_DETECTED); + return null; + } + } + + boolean isEventStatusProvided = !ParseUtil.isTokenNull(parsedResult, Tokenizer.EVENT_STATUS_TOKEN); + // Checking of date conflict with status, for e.g. list by today over + if ((parsedDates != null || dateCriteria != null) && isEventStatusProvided ) { + //detect date conflict + Renderer.renderDisambiguation(LIST_DATE_SYNTAX, MESSAGE_DATE_CONFLICT); + return null; + } + + return new LocalDateTime[] { dateCriteria, dateOn, dateFrom, dateTo }; + } +} +``` +###### /java/seedu/todo/controllers/TagController.java +``` java +/** + * Controller to Tag a CalendarItem. + */ +public class TagController implements Controller { + + private static final String NAME = "Tag"; + private static final String DESCRIPTION = "Tag a task/event by listed index"; + public static final String COMMAND_SYNTAX = "tag "; + private static final String COMMAND_WORD = "tag"; + + public static final String TAG_FORMAT = "tag %d"; + public static final String MESSAGE_TAG_SUCCESS = "Item has been tagged successfully."; + public static final String MESSAGE_INDEX_OUT_OF_RANGE = "Could not tag task/event: Invalid index provided!"; + public static final String MESSAGE_MISSING_INDEX_AND_TAG_NAME = "Please specify the index of the item and the tag name to tag."; + public static final String MESSAGE_INDEX_NOT_NUMBER = "Index has to be a number!"; + public static final String MESSAGE_TAG_NAME_NOT_FOUND = "Could not tag task/event: Tag name not provided!"; + public static final String MESSAGE_EXCEED_TAG_SIZE = "Could not tag task/event : Tag size exceed"; + public static final String MESSAGE_TAG_NAME_EXIST = "Could not tag task/event: Tag name already exist or Duplicate Tag Names!"; + + private static final int COMMAND_INPUT_INDEX = 0; + private static final int ITEM_INDEX = 0; + private static final int TOKENIZER_DEFAULT_INDEX = 1; + + private static CommandDefinition commandDefinition = + new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX); + + public static CommandDefinition getCommandDefinition() { + return commandDefinition; + } + + @Override + public float inputConfidence(String input) { + return (StringUtil.splitStringBySpace(input.toLowerCase())[COMMAND_INPUT_INDEX]).equals(COMMAND_WORD) ? 1 : 0; + } + + /** + * Get the token definitions for use with tokenizer.
+ * This method exists primarily because Java does not support HashMap + * literals... + * + * @return tokenDefinitions + */ + private static Map getTokenDefinitions() { + Map tokenDefinitions = new HashMap(); + tokenDefinitions.put(Tokenizer.DEFAULT_TOKEN, new String[] { COMMAND_WORD }); + return tokenDefinitions; + } + + @Override + public void process(String input) throws ParseException { + + Map parsedResult; + parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input); + String param = parsedResult.get(Tokenizer.DEFAULT_TOKEN)[TOKENIZER_DEFAULT_INDEX]; + + if (param == null) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_MISSING_INDEX_AND_TAG_NAME); + return; + } + + String[] parameters = StringUtil.splitStringBySpace(param); + + // Get index and tag names. + int index = 0; + String tagNames = null; + + try { + index = Integer.decode(parameters[ITEM_INDEX]); + tagNames = param.replaceFirst(parameters[ITEM_INDEX], "").trim(); + } catch (NumberFormatException e) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_INDEX_NOT_NUMBER); + return; + } + + // Get record + EphemeralDB edb = EphemeralDB.getInstance(); + CalendarItem calendarItem = edb.getCalendarItemsByDisplayedId(index); + TodoListDB db = TodoListDB.getInstance(); + + String[] parsedTagNames = parseTags(tagNames); + + if (isErrorCommand(parameters, index, calendarItem, parsedTagNames)) { + return; // Break out once error + } + + boolean resultOfTagging = addingTagNames(parsedTagNames, calendarItem); + + // Re-render + if (resultOfTagging) { + db.addIntoTagList(parsedTagNames); + db.save(); + Renderer.renderSelectedIndex(db, MESSAGE_TAG_SUCCESS, edb.getAllDisplayedTasks(), edb.getAllDisplayedEvents()); + } else { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_EXCEED_TAG_SIZE); + } + } + + /* + * To be used to check if there are any command syntax errors + * + * @return true if error detected, else false. + */ + private boolean isErrorCommand(String[] parameters, int index, CalendarItem calendarItem, String[] parsedTagNames) { + // Check if index is out of range + if (calendarItem == null) { + Renderer.renderDisambiguation(String.format(TAG_FORMAT, index), MESSAGE_INDEX_OUT_OF_RANGE); + return true; + } + + // Check if tag name is provided + if (parameters.length <= 1) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_TAG_NAME_NOT_FOUND); + return true; + } + + // Check if tag name already exist + boolean isTagNameDuplicate = checkDuplicateTagName(parsedTagNames, calendarItem); + + if (isTagNameDuplicate) { + Renderer.renderDisambiguation(String.format(TAG_FORMAT, index), MESSAGE_TAG_NAME_EXIST); + return true; + } + + return false; + } + + /* + * To be used to add tag into the tag list that belong to the CalendarItem + * @param parsedTagNames + * tag names that are entered by user and not duplicate and do not belong to the calendarItem + * @param calendarItem + * can be task or event + * + * @return true if all tags have been added successfully, false if one of the tags is not added successfully + */ + private boolean addingTagNames(String[] parsedTagNames, CalendarItem calendarItem) { + + // If tag names parsed exceed the maximum tag list limit + if (calendarItem.getTagList().size() + parsedTagNames.length > calendarItem.getTagListLimit()) { + return false; + } + + boolean result = true; + for (int i = 0; i < parsedTagNames.length; i ++) { + result = calendarItem.addTag(parsedTagNames[i].trim()) & result; + } + return result; + } + + /* + * To be used to check if user enter any duplicate tag name and if calendarItem already has that tag name + * @param parsedTagNames + * tag names that has been split into an array + * @param calendarItem + * calendarItem that can be either a task or event + * + * @return true if tag name already exist or is entered more than once, false if it does not exist + */ + private boolean checkDuplicateTagName(String[] parsedTagNames, CalendarItem calendarItem) { + HashSet parsedTagNamesList = new HashSet(); + for (int i = 0; i < parsedTagNames.length; i ++) { + // Checking with overall tag list in db + if (calendarItem.getTagList().contains(parsedTagNames[i].trim())) { + return true; + } + // Checking with the current array, if there are duplicate tags + parsedTagNamesList.add(parsedTagNames[i]); + } + + if (parsedTagNamesList.size() != parsedTagNames.length) { + return true; + } + return false; + } + + /* + * To be used to split tag names by comma if more than one is entered + * @param tags + * tag names that is entered + * + * @return an array of tag name that is split by comma + */ + private String [] parseTags(String tags) { + return tags.split(","); + } + +} +``` +###### /java/seedu/todo/controllers/UntagController.java +``` java +/** + * Controller to untag a CalendarItem. + */ +public class UntagController implements Controller { + + private static final String NAME = "Untag"; + private static final String DESCRIPTION = "Untag a task/event by listed index"; + public static final String COMMAND_SYNTAX = "untag "; + private static final String COMMAND_WORD = "untag"; + + public static final String UNTAG_FORMAT = "untag %d"; + public static final String MESSAGE_UNTAG_SUCCESS = "Item has been untagged successfully."; + public static final String MESSAGE_INDEX_OUT_OF_RANGE = "Could not untag task/event: Invalid index provided!"; + public static final String MESSAGE_MISSING_INDEX_AND_TAG_NAME = "Please specify the index of the item and the tag name to untag."; + public static final String MESSAGE_INDEX_NOT_NUMBER = "Index has to be a number!"; + public static final String MESSAGE_TAG_NAME_NOT_FOUND = "Could not untag task/event: Tag name not provided!"; + public static final String MESSAGE_TAG_NAME_DOES_NOT_EXIST = "Could not untag task/event: Tag name does not exist!"; + public static final String MESSAGE_TAG_NAME_EXIST = "Could not untag task/event : Tag name does not exist or Duplicate Tag name detected!"; + + private static final int COMMAND_INPUT_INDEX = 0; + private static final int ITEM_INDEX = 0; + private static final int TOKENIZER_DEFAULT_INDEX = 1; + + private static CommandDefinition commandDefinition = + new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX); + + public static CommandDefinition getCommandDefinition() { + return commandDefinition; + } + + @Override + public float inputConfidence(String input) { + return (StringUtil.splitStringBySpace(input.toLowerCase())[COMMAND_INPUT_INDEX]).equals(COMMAND_WORD) ? 1 : 0; + } + + /** + * Get the token definitions for use with tokenizer.
+ * This method exists primarily because Java does not support HashMap + * literals... + * + * @return tokenDefinitions + */ + private static Map getTokenDefinitions() { + Map tokenDefinitions = new HashMap(); + tokenDefinitions.put(Tokenizer.DEFAULT_TOKEN, new String[] { COMMAND_WORD }); + return tokenDefinitions; + } + + @Override + public void process(String input) throws ParseException { + + Map parsedResult; + parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input); + + String param = parsedResult.get(Tokenizer.DEFAULT_TOKEN)[TOKENIZER_DEFAULT_INDEX]; + + if (param == null) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_MISSING_INDEX_AND_TAG_NAME); + return; + } + + String[] parameters = StringUtil.splitStringBySpace(param); + + // Get index. + int index = 0; + String tagNames = null; + try { + index = Integer.decode(parameters[ITEM_INDEX]); + tagNames = param.replaceFirst(parameters[ITEM_INDEX], "").trim(); + } catch (NumberFormatException e) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_INDEX_NOT_NUMBER); + return; + } + + // Get record + EphemeralDB edb = EphemeralDB.getInstance(); + CalendarItem calendarItem = edb.getCalendarItemsByDisplayedId(index); + TodoListDB db = TodoListDB.getInstance(); + + String[] parsedTagNames = parseTags(tagNames); + + if (isErrorCommand(parameters, index, calendarItem, parsedTagNames)) { + return; // Break out once error + } + + boolean resultOfUntagging = removingTagNames(parsedTagNames, calendarItem); + + // Re-render + if (resultOfUntagging) { + db.updateTagList(parsedTagNames); + db.save(); + Renderer.renderSelectedIndex(db, MESSAGE_UNTAG_SUCCESS, edb.getAllDisplayedTasks(), edb.getAllDisplayedEvents()); + } else { + Renderer.renderDisambiguation(String.format(UNTAG_FORMAT, index), MESSAGE_TAG_NAME_DOES_NOT_EXIST); + } + } + + /* + * To be used to check if there are any command syntax errors + * + * @return true if error detected, else false. + */ + private boolean isErrorCommand(String[] parameters, int index, CalendarItem calendarItem, String[] parsedTagNames) { + // Check if index is out of range + if (calendarItem == null) { + Renderer.renderDisambiguation(String.format(UNTAG_FORMAT, index), MESSAGE_INDEX_OUT_OF_RANGE); + return true; + } + + // Check if tag name is provided + if (parameters.length <= 1) { + Renderer.renderDisambiguation(COMMAND_SYNTAX, MESSAGE_TAG_NAME_NOT_FOUND); + return true; + } + + // Check if tag name exist + if (tagNameDoesNotExist(parsedTagNames, calendarItem)) { + Renderer.renderDisambiguation(String.format(UNTAG_FORMAT, index), MESSAGE_TAG_NAME_EXIST); + return true; + } + return false; + } + + /* + * To be used to remove tag from the tag list that belong to the CalendarItem + * @param parsedTagNames + * tag names that are entered by user and not duplicate and belong to the calendarItem + * @param calendarItem + * can be task or event + * + * @return true if all tags have been removed successfully, false if one of the tags its not removed successfully + * */ + private boolean removingTagNames(String[] parsedTagNames, CalendarItem calendarItem) { + assert parsedTagNames != null; + assert calendarItem != null; + + boolean result = true; + for (int i = 0; i < parsedTagNames.length; i ++) { + result = calendarItem.removeTag(parsedTagNames[i].trim()) & result; + } + return result; + } + + /* + * To be used to check if user enter any duplicate tag name and if calendarItem has the exact tag name + * @param parsedTagNames + * tag names that has been split into an array + * @param calendarItem + * calendarItem that can be either a task or event + * + * @return true if tag name does not exist or is entered more than once, false if it exist in the tag list + */ + private boolean tagNameDoesNotExist(String[] parsedTagNames, CalendarItem calendarItem) { + HashSet parsedTagNamesList = new HashSet(); + for (int i = 0; i < parsedTagNames.length; i ++) { + // Checking with overall tag list in db + if (!calendarItem.getTagList().contains(parsedTagNames[i].trim())) { + return true; + } + + // Checking with the current array, if there are any duplicate tag names + parsedTagNamesList.add(parsedTagNames[i]); + } + return parsedTagNamesList.size() != parsedTagNames.length; + } + + /* + * To be used to split tag names by comma if more than one is entered + * @param tags + * tag names that is entered + * + * @return an array of tag name that is split by comma + */ + private String [] parseTags(String tags) { + return tags.split(","); + } + +} +``` +###### /java/seedu/todo/models/CalendarItem.java +``` java + /** + * Returns the current tag list that belong to the CalendarItem, mainly for displaying purpose + * + * @return ArrayList tags + */ + public ArrayList getTagList(); + +``` +###### /java/seedu/todo/models/CalendarItem.java +``` java + /** + * Add a new tag in the list of tag of the calendar item. + * + * @param tagName + * @return true if it has not reached the max tag list size, false if tag list already reach the max size + */ + public boolean addTag(String tagName); + +``` +###### /java/seedu/todo/models/CalendarItem.java +``` java + /** + * Remove a existing tag in the tag list of tag of the calendar item. + * + * @param tagName + * @return true if tagName is removed successfully, false if failed to remove tagName due to unable to find + */ + public boolean removeTag(String tagName); + +``` +###### /java/seedu/todo/models/CalendarItem.java +``` java + /** + * Get the limit of the tag that is allowed for calendar item + * + * @return the limit of tag list + */ + public int getTagListLimit(); +} +``` +###### /java/seedu/todo/models/Event.java +``` java + /** + * Return the tag list that belong to the calendar item + */ + @Override + public ArrayList getTagList() { + return tagList; + } + +``` +###### /java/seedu/todo/models/Event.java +``` java + /** + * Adding the tag into the tag list that belong to the calendar item + * @param tagName + * name of the tag + * + * @return true tag name is successfully added, false if tag list if full + */ + @Override + public boolean addTag(String tagName) { + if(tagList.size() < MAX_TAG_LIST_SIZE) { + tagList.add(tagName); + return true; + } else { + return false; + } + } + +``` +###### /java/seedu/todo/models/Event.java +``` java + /** + * Removing the tag from the tag list that belong to the calendar item + * @param tagName + * name of the tag + * + * @return true tag name is successfully removed, false if tag name does not exist + */ + @Override + public boolean removeTag(String tagName) { + return tagList.remove(tagName); + } + + /** +``` +###### /java/seedu/todo/models/Event.java +``` java + /** + * Returning the maximum tag list size that is allowed + */ + @Override + public int getTagListLimit() { + return MAX_TAG_LIST_SIZE; + } + +} +``` +###### /java/seedu/todo/models/Task.java +``` java + /** + * Return the tag list that belong to the calendar item + */ + @Override + public ArrayList getTagList() { + return tagList; + } + +``` +###### /java/seedu/todo/models/Task.java +``` java + /** + * Adding the tag into the tag list that belong to the calendar item + * @param tagName + * name of the tag + * + * @return true tag name is successfully added, false if tag list if full + */ + @Override + public boolean addTag(String tagName) { + if(tagList.size() < MAX_TAG_LIST_SIZE) { + tagList.add(tagName); + return true; + } else { + return false; + } + } + +``` +###### /java/seedu/todo/models/Task.java +``` java + /** + * Removing the tag from the tag list that belong to the calendar item + * @param tagName + * name of the tag + * + * @return true tag name is successfully removed, false if tag name does not exist + */ + @Override + public boolean removeTag(String tagName) { + return tagList.remove(tagName); + } + + + /** +``` +###### /java/seedu/todo/models/Task.java +``` java + /** + * Returning the maximum tag list size that is allowed + */ + @Override + public int getTagListLimit() { + return MAX_TAG_LIST_SIZE; + } + +} +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Add into the overall Tags in the DB. + */ + public void addIntoTagList(String[] parsedTagNames) { + assert parsedTagNames != null; + for (int i = 0; i < parsedTagNames.length; i ++) { + String tagName = parsedTagNames[i].trim(); + if (tagList.get(tagName) != null) { + int currentTagCount = tagList.get(tagName); + tagList.put(tagName, currentTagCount + 1); + } else { + tagList.put(tagName, 1); + } + } + } + +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Remove from the overall Tags with a single tagName that exist in the DB. + */ + public void updateTagList(String[] parsedTagNames) { + assert parsedTagNames != null; + for (int i = 0; i < parsedTagNames.length; i ++) { + String tagName = parsedTagNames[i].trim(); + int currentTagCount = tagList.get(tagName); + + int newTagCount = currentTagCount - 1; + if (newTagCount == 0) { + tagList.remove(tagName); + } else { + tagList.put(tagName, newTagCount); + } + } + } + +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Remove from the overall Tags with a given List of CalendarItem that exist in the DB. + * @param listOfItem of type CalendarItem + */ + public void removeFromTagList(List listOfCalendarItem) { + assert listOfCalendarItem != null; + + ArrayList selectedTagList = new ArrayList(); + for (int i = 0; i < listOfCalendarItem.size(); i ++) { + selectedTagList.addAll(((CalendarItem) listOfCalendarItem.get(i)).getTagList()); + } + + updateTagList(selectedTagList.toArray(new String[0])); + } + +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Get a list of Tags in the DB. + * + * @return tagList + */ + public HashMap getTagList() { + return tagList; + } + +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Count tags which are already inserted into the db + * + * @return Number of tags + */ + public int countTagList() { + return tagList.size(); + } +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Destroys all Task and Events in the DB and persists the commit. + * + * @return true if the save was successful, false otherwise + */ + public boolean destroyAllTaskAndEvents() { + removeFromTagList(new ArrayList(tasks)); + removeFromTagList(new ArrayList(events)); + tasks = new LinkedHashSet(); + events = new LinkedHashSet(); + return save(); + } + +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Destroys Task and Events based on list in the DB and persists the commit. + * @taskLists + * List of tasks to be destroyed + * @eventLists + * List of events to be destroyed + * + * @return true if the save was successful, false otherwise + */ + public boolean destroyAllTaskAndEventsByList(List tasksList , List eventsList) { + removeFromTagList(new ArrayList(tasksList)); + removeFromTagList(new ArrayList(eventsList)); + + //removing tasks and events + tasks.removeAll(tasksList); + events.removeAll(eventsList); + return save(); + } + +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Destroys all Task in the DB and persists the commit. + * + * @return true if the save was successful, false otherwise + */ + public void destroyAllTask() { + removeFromTagList(new ArrayList(tasks)); + tasks = new LinkedHashSet(); + } +``` +###### /java/seedu/todo/models/TodoListDB.java +``` java + /** + * Destroys all Event in the DB and persists the commit. + */ + public void destroyAllEvent() { + removeFromTagList(new ArrayList(events)); + events = new LinkedHashSet(); + } +``` diff --git a/collated/test/A0139922Yreused.md b/collated/test/A0139922Yreused.md new file mode 100644 index 000000000000..057df6bcf5e6 --- /dev/null +++ b/collated/test/A0139922Yreused.md @@ -0,0 +1,235 @@ +# A0139922Yreused +###### /java/seedu/todo/guitests/FindCommandTest.java +``` java + // Date variables to be use to initialise DB + private static final LocalDateTime TODAY = LocalDateTime.now(); + private static final String TODAY_STRING = DateUtil.formatDate(TODAY); + private static final String TODAY_ISO_STRING = DateUtil.formatIsoDate(TODAY); + private static final LocalDateTime TOMORROW = LocalDateTime.now().plusDays(1); + private static final String TOMORROW_STRING = DateUtil.formatDate(TOMORROW); + private static final String TOMORROW_ISO_STRING = DateUtil.formatIsoDate(TOMORROW); + private static final LocalDateTime THE_DAY_AFTER_TOMORROW_ = LocalDateTime.now().plusDays(2); + private static final String THE_DAY_AFTER_TOMORROW_STRING = DateUtil.formatDate(THE_DAY_AFTER_TOMORROW_); + private static final String THE_DAY_AFTER_TOMORROW__ISO_STRING = DateUtil.formatIsoDate(THE_DAY_AFTER_TOMORROW_); + + // Command to be use to initialise DB + private String commandAdd1 = String.format("add task Buy Coco by \"%s 8pm\" tag personal", TODAY_STRING); + private Task task1 = new Task(); + private String commandAdd2 = String.format("add task Buy Milk by \"%s 9pm\" tag personal", TOMORROW_STRING); + private Task task2 = new Task(); + private String commandAdd3 = String.format("add event CS2103 V0.5 Demo from \"%s 4pm\" to \"%s 5pm\" tag event", + TOMORROW_STRING, TOMORROW_STRING); + private Event event3 = new Event(); + private String commandAdd4 = String.format("add event buying workshop from \"%s 8pm\" to \"%s 9pm\" tag buy", + THE_DAY_AFTER_TOMORROW_STRING, THE_DAY_AFTER_TOMORROW_STRING); + private Event event4 = new Event(); + + private int expectedNumOfTasks; + private int expectedNumOfEvents; + + // Set up DB + public FindCommandTest() { + task1.setName("Buy Coco"); + task1.setCalendarDateTime(DateUtil.parseDateTime( + String.format("%s 20:00:00", TODAY_ISO_STRING))); + task1.addTag("personal"); + task1.setCompleted(); + + task2.setName("Buy Milk"); + task2.setDueDate(DateUtil.parseDateTime( + String.format("%s 21:00:00", TOMORROW_ISO_STRING))); + task2.addTag("personal"); + + event3.setName("CS2103 V0.5 Demo"); + event3.setStartDate(DateUtil.parseDateTime( + String.format("%s 16:00:00", TOMORROW_ISO_STRING))); + event3.setEndDate(DateUtil.parseDateTime( + String.format("%s 17:00:00", TOMORROW_ISO_STRING))); + event3.addTag("event"); + + event4.setName("buying workshop"); + event4.setStartDate(DateUtil.parseDateTime( + String.format("%s 20:00:00", THE_DAY_AFTER_TOMORROW__ISO_STRING))); + event4.setEndDate(DateUtil.parseDateTime( + String.format("%s 21:00:00", THE_DAY_AFTER_TOMORROW__ISO_STRING))); + event4.addTag("buy"); + } + +``` +###### /java/seedu/todo/guitests/FindCommandTest.java +``` java + @Before + public void initFixtures() { + console.runCommand("clear"); + assertTaskVisibleAfterCmd(commandAdd1, task1); + assertTaskVisibleAfterCmd(commandAdd2, task2); + assertEventVisibleAfterCmd(commandAdd3, event3); + assertEventVisibleAfterCmd(commandAdd4, event4); + } + +``` +###### /java/seedu/todo/guitests/FindCommandTest.java +``` java + @Test + public void fixtures_test() { + console.runCommand("clear"); + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskNotVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventNotVisibleAfterCmd("list", event4); + } +``` +###### /java/seedu/todo/guitests/ListCommandTest.java +``` java + // Date variables to be use to initialise DB + private static final LocalDateTime TODAY = LocalDateTime.now(); + private static final String TODAY_STRING = DateUtil.formatDate(TODAY); + private static final String TODAY_ISO_STRING = DateUtil.formatIsoDate(TODAY); + private static final LocalDateTime TOMORROW = LocalDateTime.now().plusDays(1); + private static final String TOMORROW_STRING = DateUtil.formatDate(TOMORROW); + private static final String TOMORROW_ISO_STRING = DateUtil.formatIsoDate(TOMORROW); + private static final LocalDateTime THE_DAY_AFTER_TOMORROW_ = LocalDateTime.now().plusDays(2); + private static final String THE_DAY_AFTER_TOMORROW_STRING = DateUtil.formatDate(THE_DAY_AFTER_TOMORROW_); + private static final String THE_DAY_AFTER_TOMORROW__ISO_STRING = DateUtil.formatIsoDate(THE_DAY_AFTER_TOMORROW_); + + // Command to be use to initialise DB + private String commandAdd1 = String.format("add task Buy Coco by \"%s 8pm\"", TODAY_STRING); + private Task task1 = new Task(); + private String commandAdd2 = String.format("add task Buy Milk by \"%s 9pm\"", TOMORROW_STRING); + private Task task2 = new Task(); + private String commandAdd3 = String.format("add event CS2103 V0.5 Demo from \"%s 4pm\" to \"%s 5pm\"", + TOMORROW_STRING, TOMORROW_STRING); + private Event event3 = new Event(); + private String commandAdd4 = String.format("add event buying workshop from \"%s 8pm\" to \"%s 9pm\"", + THE_DAY_AFTER_TOMORROW_STRING, THE_DAY_AFTER_TOMORROW_STRING); + private Event event4 = new Event(); + private int expectedNumOfTasks; + private int expectedNumOfEvents; + + // Set up DB + public ListCommandTest() { + task1.setName("Buy Coco"); + task1.setCalendarDateTime(DateUtil.parseDateTime( + String.format("%s 20:00:00", TODAY_ISO_STRING))); + task1.setCompleted(); + + task2.setName("Buy Milk"); + task2.setDueDate(DateUtil.parseDateTime( + String.format("%s 21:00:00", TOMORROW_ISO_STRING))); + + event3.setName("CS2103 V0.5 Demo"); + event3.setStartDate(DateUtil.parseDateTime( + String.format("%s 16:00:00", TOMORROW_ISO_STRING))); + event3.setEndDate(DateUtil.parseDateTime( + String.format("%s 17:00:00", TOMORROW_ISO_STRING))); + + event4.setName("buying workshop"); + event4.setStartDate(DateUtil.parseDateTime( + String.format("%s 20:00:00", THE_DAY_AFTER_TOMORROW__ISO_STRING))); + event4.setEndDate(DateUtil.parseDateTime( + String.format("%s 21:00:00", THE_DAY_AFTER_TOMORROW__ISO_STRING))); + } + +``` +###### /java/seedu/todo/guitests/ListCommandTest.java +``` java + @Before + public void initFixtures() { + console.runCommand("clear"); + assertTaskVisibleAfterCmd(commandAdd1, task1); + assertTaskVisibleAfterCmd(commandAdd2, task2); + assertEventVisibleAfterCmd(commandAdd3, event3); + assertEventVisibleAfterCmd(commandAdd4, event4); + } + +``` +###### /java/seedu/todo/guitests/ListCommandTest.java +``` java + @Test + public void fixtures_test() { + console.runCommand("clear"); + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskNotVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventNotVisibleAfterCmd("list", event4); + } +``` +###### /java/seedu/todo/guitests/TagControllerTest.java +``` java + // Date variables to be use to initialise DB + private static final LocalDateTime TODAY = LocalDateTime.now(); + private static final String TODAY_STRING = DateUtil.formatDate(TODAY); + private static final String TODAY_ISO_STRING = DateUtil.formatIsoDate(TODAY); + + // Command to be use to initialise DB + private String commandAdd = String.format("add task Buy Coco by \"%s 8pm\"", TODAY_STRING); + private Task task = new Task(); + private Task taskWithoutTag = new Task(); + + // Set up DB + public TagControllerTest() { + task.setName("Buy Coco"); + task.setCalendarDateTime(DateUtil.parseDateTime( + String.format("%s 20:00:00", TODAY_ISO_STRING))); + task.addTag("personal"); + taskWithoutTag.setName("Buy Coco"); + taskWithoutTag.setCalendarDateTime(DateUtil.parseDateTime( + String.format("%s 20:00:00", TODAY_ISO_STRING))); + } + +``` +###### /java/seedu/todo/guitests/TagControllerTest.java +``` java + @Before + public void initFixtures() { + console.runCommand("clear"); + assertTaskVisibleAfterCmd(commandAdd, task); + } + + @Test + public void fixtures_test() { + console.runCommand("clear"); + assertTaskNotVisibleAfterCmd("list", task); + } +``` +###### /java/seedu/todo/guitests/UntagControllerTest.java +``` java + // Date variables to be use to initialise DB + private static final LocalDateTime TODAY = LocalDateTime.now(); + private static final String TODAY_STRING = DateUtil.formatDate(TODAY); + private static final String TODAY_ISO_STRING = DateUtil.formatIsoDate(TODAY); + + // Command to be use to initialise DB + private String commandAdd = String.format("add task Buy Coco by \"%s 8pm\"", TODAY_STRING); + private Task task = new Task(); + private Task taskWithoutTag = new Task(); + + // Set up DB + public UntagControllerTest() { + task.setName("Buy Coco"); + task.setCalendarDateTime(DateUtil.parseDateTime( + String.format("%s 20:00:00", TODAY_ISO_STRING))); + task.addTag("personal"); + taskWithoutTag.setName("Buy Coco"); + taskWithoutTag.setCalendarDateTime(DateUtil.parseDateTime( + String.format("%s 20:00:00", TODAY_ISO_STRING))); + } + +``` +###### /java/seedu/todo/guitests/UntagControllerTest.java +``` java + @Before + public void initFixtures() { + console.runCommand("clear"); + assertTaskVisibleAfterCmd(commandAdd, task); + } + +``` +###### /java/seedu/todo/guitests/UntagControllerTest.java +``` java + @Test + public void fixtures_test() { + console.runCommand("clear"); + assertTaskNotVisibleAfterCmd("list", task); + } +``` diff --git a/collated/test/A0139922Yunused.md b/collated/test/A0139922Yunused.md new file mode 100644 index 000000000000..76e5620e4647 --- /dev/null +++ b/collated/test/A0139922Yunused.md @@ -0,0 +1,2426 @@ +# A0139922Yunused +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void ceilDate_sameDate_equals() { + LocalDateTime today = LocalDateTime.now().toLocalDate().atTime(10,0); + LocalDateTime todayPlusAnHour = today.plusHours(1); + assertEquals(DateUtil.ceilDate(today), DateUtil.ceilDate(todayPlusAnHour)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void ceilDate_sameDate_not_null() { + LocalDateTime today = LocalDateTime.now().toLocalDate().atTime(10,0); + LocalDateTime todayPlusAnHour = today.plusHours(1); + assertNotNull(DateUtil.ceilDate(today)); + assertNotNull(DateUtil.ceilDate(todayPlusAnHour)); + assertEquals(DateUtil.ceilDate(today), DateUtil.ceilDate(todayPlusAnHour)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void ceilDate_differentDate_not_equals() { + LocalDateTime today = LocalDateTime.now(); + LocalDateTime tmr = LocalDateTime.now().plusDays(1); + assertNotEquals(DateUtil.ceilDate(today), DateUtil.ceilDate(tmr)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void ceilDate_differentDate_not_null() { + LocalDateTime today = LocalDateTime.now(); + LocalDateTime tmr = LocalDateTime.now().plusDays(1); + assertNotNull(DateUtil.ceilDate(today)); + assertNotNull(DateUtil.ceilDate(tmr)); + assertNotEquals(DateUtil.ceilDate(today), DateUtil.ceilDate(tmr)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + public void ceilDate_nullDate_null() { + LocalDateTime nullDate = null; + assertEquals(null, DateUtil.ceilDate(nullDate)); + } +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void formatShortDateTests_null_test() { + assertNull(DateUtil.formatShortDate(null)); + assertNotNull(DateUtil.formatShortDate(LocalDateTime.now())); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void formatTime_null_test() { + assertNull(DateUtil.formatTime(null)); + assertNotNull(DateUtil.formatTime(LocalDateTime.now())); + } +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testIfDateExist_false() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + assertFalse(DateUtil.checkIfDateExist(currentDate)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckIfDateExist_with_year_diff_true() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + // Only year is different + assertTrue(DateUtil.checkIfDateExist(currentDate.plusYears(1))); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckIfDateExist_with_month_diff_true() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + // Only month is different + assertTrue(DateUtil.checkIfDateExist(currentDate.plusMonths(1))); + assertTrue(DateUtil.checkIfDateExist(currentDate.plusMonths(12))); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckifDateExist_with_day_diff_true() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + // Only day is different + assertTrue(DateUtil.checkIfDateExist(currentDate.plusDays(1))); + assertTrue(DateUtil.checkIfDateExist(currentDate.plusDays(365))); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckifDateExist_with_day_month_diff_true() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + // Day and Month are different + currentDate = currentDate.plusDays(1); + currentDate = currentDate.plusMonths(1); + assertTrue(DateUtil.checkIfDateExist(currentDate)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckifDateExist_with_day_year_diff_true() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + // Day and Month are different + currentDate = currentDate.plusDays(1); + currentDate = currentDate.plusYears(1); + assertTrue(DateUtil.checkIfDateExist(currentDate)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckifDateExist_with_month_year_diff_true() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + // Day and Month are different + currentDate = currentDate.plusMonths(1); + currentDate = currentDate.plusYears(1); + assertTrue(DateUtil.checkIfDateExist(currentDate)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckifDateExist_equals_false() { + LocalDateTime currentDate = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfDateExist(currentDate)); + assertFalse(DateUtil.checkIfDateExist(currentDate)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testCheckIfTimeExist_false() { + LocalDateTime currentTime = LocalDateTime.now(); + assertNotNull(DateUtil.checkIfTimeExist(currentTime)); + assertFalse(DateUtil.checkIfTimeExist(currentTime)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testIfTimeExist_true() { + LocalDateTime currentTime = LocalDateTime.now().toLocalDate().atTime(10,0); + assertNotNull(DateUtil.checkIfTimeExist(currentTime)); + assertTrue(DateUtil.checkIfTimeExist(currentTime.toLocalDate().atTime(currentTime.getHour() - currentTime.getHour(), + currentTime.getMinute()))); + assertTrue(DateUtil.checkIfTimeExist(currentTime.toLocalDate().atTime(currentTime.getHour(), + currentTime.getMinute() - currentTime.getMinute()))); + assertTrue(DateUtil.checkIfTimeExist(currentTime.toLocalDate().atTime(currentTime.getHour() - currentTime.getHour(), + currentTime.getMinute() - currentTime.getMinute()))); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testParseTimeStamp_task_setTimeToMin() { + //set the time to 00:00 for task + assertNotEquals(DateUtil.parseTimeStamp(currentDay, null, true), currentDay); + assertEquals(DateUtil.parseTimeStamp(currentDay, null, true), DateUtil.floorDate(currentDay)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testParseTimeStamp_event_setTimeToMin() { + //will set the time to 00:00 for event + assertNotEquals(DateUtil.parseTimeStamp(currentDay, nextDay, true), currentDay); + assertEquals(DateUtil.parseTimeStamp(currentDay, nextDay, true), DateUtil.floorDate(currentDay)); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testParseTimeStamp_event_setTimeToMax() { + // will set the time to 23:59 + assertNotEquals(DateUtil.parseTimeStamp(nextDay, currentDay, false), nextDay); + assertEquals(DateUtil.parseTimeStamp(nextDay, currentDay, false), nextDayAt2359); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testParseTimeStamp_event_followNextDayTime() { + // will set the time to follow the nextDay + assertNotEquals(DateUtil.parseTimeStamp(currentDay, nextDayAt2Pm, true), currentDay); + assertEquals(DateUtil.parseTimeStamp(currentDay, nextDayAt2Pm, true), currentDayAt2Pm); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testParseTimeStamp_event_followCurrentDayTime() { + // will set the time to follow the currentDay + assertEquals(DateUtil.parseTimeStamp(currentDayAt2Pm, nextDay, true), currentDayAt2Pm); + assertNotEquals(DateUtil.parseTimeStamp(nextDay, currentDayAt2Pm, false), nextDay); + assertEquals(DateUtil.parseTimeStamp(nextDay, currentDayAt2Pm, false), nextDayAt2Pm); + } + +``` +###### /java/seedu/todo/commons/util/DateUtilTest.java +``` java + @Test + public void testParseTimeStamp_event_followGivenDateTime() { + // if date and time exist, will not overwrite it + assertEquals(DateUtil.parseTimeStamp(currentDayAt2Pm, nextDay, true), currentDayAt2Pm); + assertEquals(DateUtil.parseTimeStamp(currentDayAt2Pm, nextDayAt2Pm, true), currentDayAt2Pm); + assertEquals(DateUtil.parseTimeStamp(nextDayAt2Pm, currentDay, false), nextDayAt2Pm); + assertEquals(DateUtil.parseTimeStamp(nextDayAt2Pm, currentDayAt2Pm, false), nextDayAt2Pm); + } +} +``` +###### /java/seedu/todo/commons/util/FilterUtilTest.java +``` java +public class FilterUtilTest { + public static final LocalDateTime TODAY = LocalDateTime.now(); + public static final LocalDateTime TOMORROW = LocalDateTime.now().plusDays(1); + public static final LocalDateTime YESTERDAY = LocalDateTime.now().minusDays(1); + Task firstTestTask = getFirstTestTask(); + Task secondTestTask = getSecondTestTask(); + List overdueEvents = getOverdueEvents(); + List currentEvents = getCurrentEvents(); + + /* ======================== Test cases for Filtering Task Methods ========================== */ + + @Test + public void testFilterOutTask_equals() { + List calendarItems = new ArrayList(); + calendarItems.add(firstTestTask); + assertEquals(calendarItems, FilterUtil.filterOutTask(calendarItems)); + } + + @Test + public void testFilterOutTask_not_equals() { + List calendarItems = new ArrayList(); + calendarItems.add(firstTestTask); + calendarItems.addAll(overdueEvents); + assertNotEquals(calendarItems, FilterUtil.filterOutTask(calendarItems)); + } + + @Test + public void testFilterTaskByNames_filter_with_empty_taskList_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + // Empty task list with empty name list + assertEquals(tasks, FilterUtil.filterTaskByNames(tasks, nameList)); + // Empty task list with name list + nameList.add("Nothing"); + assertEquals(tasks, FilterUtil.filterTaskByNames(tasks, nameList)); + } + + @Test + public void testFilterTaskByNames_filter_by_fullname_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + + // Filter out first test task + nameList.add("Buy"); + tasks.add(firstTestTask); + assertEquals(tasks, FilterUtil.filterTaskByNames(tasks, nameList)); + + tasks.add(secondTestTask); + List filteredResult = getEmptyTaskList(); + filteredResult.add(firstTestTask); + assertEquals(filteredResult, (FilterUtil.filterTaskByNames(tasks, nameList))); + } + + @Test + public void testFilterTaskByNames_filter_by_fullname_not_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyTaskList(); + + nameList.add("Buy"); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + filteredResult.add(firstTestTask); + filteredResult.add(secondTestTask); + assertNotEquals(filteredResult, (FilterUtil.filterTaskByNames(tasks, nameList))); + } + + @Test + public void testFilterTaskByNames_filter_by_subname_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyTaskList(); + + // Filter out first test task + tasks.add(firstTestTask); + tasks.add(secondTestTask); + filteredResult.add(firstTestTask); + nameList.add("Milk"); + assertEquals(filteredResult, FilterUtil.filterTaskByNames(tasks, nameList)); + } + + @Test + public void testFilterTaskByNames_filter_by_subname_not_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyTaskList(); + + tasks.add(firstTestTask); + tasks.add(secondTestTask); + filteredResult.add(firstTestTask); + filteredResult.add(secondTestTask); + nameList.add("Milk"); + assertNotEquals(filteredResult, FilterUtil.filterTaskByNames(tasks, nameList)); + } + + @Test + public void testFilterTaskByTags_with_empty_task_list_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + // Empty task list and name list + assertEquals(tasks, FilterUtil.filterTaskByTags(tasks, nameList)); + // Empty task list + nameList.add("Nothing"); + assertEquals(tasks, FilterUtil.filterTaskByTags(tasks, nameList)); + } + + @Test + public void testFilterTaskByTags_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyTaskList(); + + // Filter out first test task + nameList.add("personal"); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + filteredResult.add(firstTestTask); + assertEquals(filteredResult, FilterUtil.filterTaskByTags(tasks, nameList)); + } + + @Test + public void testFilterTaskByTags_not_equals() { + List tasks = getEmptyTaskList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyTaskList(); + + // Filter out first test task + nameList.add("Buy"); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + filteredResult.add(firstTestTask); + assertNotEquals(filteredResult, FilterUtil.filterTaskByTags(tasks, nameList)); + } + + @Test + public void testFilterCompletedTaskList_equals() { + List tasks = getEmptyTaskList(); + // Check with empty tasks + assertEquals(tasks, FilterUtil.filterTasksByStatus(tasks, true)); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + + // Filter out completed tasks + List filteredTasks = getEmptyTaskList(); + filteredTasks.add(firstTestTask); + assertEquals(filteredTasks, FilterUtil.filterTasksByStatus(tasks, true)); + } + + @Test + public void testFilterCompletedTaskList_not_equals() { + List tasks = getEmptyTaskList(); + List filteredResult = getEmptyTaskList(); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + filteredResult.add(secondTestTask); + + // Filter out completed tasks + assertNotEquals(filteredResult, FilterUtil.filterTasksByStatus(tasks, true)); + } + + @Test + public void testFilterIncompletedTaskList_equals() { + List tasks = getEmptyTaskList(); + // Check with empty tasks + assertEquals(tasks, FilterUtil.filterTasksByStatus(tasks, false)); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + + // Filter out incomplete tasks + List filteredTasks = getEmptyTaskList(); + filteredTasks.add(secondTestTask); + assertEquals(filteredTasks, FilterUtil.filterTasksByStatus(tasks, false)); + } + + @Test + public void testFilterIncompletedTaskList_not_equals() { + List tasks = getEmptyTaskList(); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + + // Filter out incomplete tasks + List filteredTasks = getEmptyTaskList(); + filteredTasks.add(firstTestTask); + filteredTasks.add(secondTestTask); + assertNotEquals(filteredTasks, FilterUtil.filterTasksByStatus(tasks, false)); + } + + @Test + public void testFilterTaskBySingleDate_with_empty_tasks_equals() { + List tasks = getEmptyTaskList(); + assertEquals(tasks, FilterUtil.filterTaskBySingleDate(tasks, DateUtil.floorDate(TODAY))); + assertEquals(tasks, FilterUtil.filterTaskBySingleDate(tasks, null)); + } + + @Test + public void testFilterTaskBySingleDate_equals() { + List tasks = getEmptyTaskList(); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + + // Filter out first task + List filteredTasks = getEmptyTaskList(); + filteredTasks.add(firstTestTask); + assertEquals(filteredTasks, FilterUtil.filterTaskBySingleDate(filteredTasks, DateUtil.floorDate(TODAY))); + } + + @Test + public void testFilterTaskBySingleDate_not_equals() { + List tasks = getEmptyTaskList(); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + + List filteredTasks = getEmptyTaskList(); + filteredTasks.add(firstTestTask); + filteredTasks.add(firstTestTask); + assertNotEquals(filteredTasks, FilterUtil.filterTaskBySingleDate(tasks, TODAY)); + } + + @Test + public void testFilterTaskWithDateRange_with_empty_tasks_equals() { + List tasks = getEmptyTaskList(); + assertEquals(tasks, FilterUtil.filterTaskWithDateRange(tasks, + LocalDateTime.now().plusDays(3), LocalDateTime.now().plusDays(4))); + } + + @Test + public void testFilterTaskWithDateRange_out_of_range_equals() { + List tasks = getEmptyTaskList(); + tasks.add(firstTestTask); + // Filter out of range of test task + assertEquals(getEmptyTaskList(), FilterUtil.filterTaskWithDateRange(tasks, + LocalDateTime.now().plusDays(3), LocalDateTime.now().plusDays(4))); + } + + @Test + public void testFilterTaskWithDateRange_equals() { + List tasks = getEmptyTaskList(); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + + // Filter out first task + List filteredTasks = getEmptyTaskList(); + filteredTasks.add(firstTestTask); + assertEquals(filteredTasks, FilterUtil.filterTaskWithDateRange(tasks, TODAY, TODAY)); + } + + @Test + public void testFilterTaskWithDateRange_with_null_dates_equals() { + List tasks = getEmptyTaskList(); + tasks.add(firstTestTask); + tasks.add(secondTestTask); + + List filteredTasks = getEmptyTaskList(); + filteredTasks.add(firstTestTask); + filteredTasks.add(secondTestTask); + // Filter out both task + assertEquals(filteredTasks, FilterUtil.filterTaskWithDateRange(tasks, null, TOMORROW)); + assertEquals(filteredTasks, FilterUtil.filterTaskWithDateRange(tasks, YESTERDAY, null)); + } + + /* ============================= Test cases for Event Filtering Methods ==================== */ + + @Test + public void testFilterOutEvent_equals() { + List calendarItems = new ArrayList(); + calendarItems.addAll(overdueEvents); + assertEquals(calendarItems, FilterUtil.filterOutEvent(calendarItems)); + } + + @Test + public void testFilterOutEvent_not_equals() { + List calendarItems = new ArrayList(); + calendarItems.add(firstTestTask); + calendarItems.addAll(overdueEvents); + assertNotEquals(calendarItems, FilterUtil.filterOutEvent(calendarItems)); + } + + @Test + public void testFilterEventByNames_filter_with_empty_eventList_equals() { + List events = getEmptyEventList(); + HashSet nameList = new HashSet(); + // Empty event list and name list + assertEquals(events, FilterUtil.filterEventByNames(events, nameList)); + // Empty event list + nameList.add("Nothing"); + assertEquals(events, FilterUtil.filterEventByNames(events, nameList)); + } + + @Test + public void testFilterEventByNames_filter_equals() { + List events = getEmptyEventList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyEventList(); + + // Filter out overdue events + nameList.add("CS2103"); + nameList.add("Roadshow"); + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + assertEquals(filteredResult, FilterUtil.filterEventByNames(events, nameList)); + } + + @Test + public void testFilterEventByNames_filter_not_equals() { + List events = getEmptyEventList(); + HashSet nameList = new HashSet(); + events.addAll(overdueEvents); + nameList.add("Nothing"); + assertNotEquals(events, FilterUtil.filterEventByNames(events, nameList)); + } + + @Test + public void testFilterEventByTags_with_empty_event_list_equals() { + List events = getEmptyEventList(); + HashSet nameList = new HashSet(); + // Empty event list and name list + assertEquals(events, FilterUtil.filterEventByTags(events, nameList)); + // Empty event list + nameList.add("Nothing"); + assertEquals(events, FilterUtil.filterEventByTags(events, nameList)); + } + + @Test + public void testFilterEventByTags_equals() { + List events = getEmptyEventList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyEventList(); + + // Filter out overdue events + nameList.add("CS3216"); + nameList.add("CSIT"); + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + assertEquals(filteredResult, FilterUtil.filterEventByTags(events, nameList)); + } + + @Test + public void testFilterEventByTags_not_equals() { + List events = getEmptyEventList(); + HashSet nameList = new HashSet(); + List filteredResult = getEmptyEventList(); + + // Filter out overdue events + nameList.add("test"); + events.addAll(overdueEvents); + filteredResult.addAll(overdueEvents); + assertNotEquals(filteredResult, FilterUtil.filterEventByTags(events, nameList)); + } + + @Test + public void testFilterIsOverEventList_with_empty_event_list_equals() { + List events = new ArrayList(); + // Filter with empty events list + assertEquals(events, FilterUtil.filterEventsByStatus(events, true)); + } + + @Test + public void testFilterIsOverEventList_equals() { + List events = new ArrayList(); + List filteredResult = getEmptyEventList(); + + // Filter out overdue events + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + assertEquals(filteredResult, FilterUtil.filterEventsByStatus(events, true)); + } + + @Test + public void testFilterIsOverEventList_not_equals() { + List events = new ArrayList(); + List filteredResult = getEmptyEventList(); + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + filteredResult.addAll(currentEvents); + assertNotEquals(filteredResult, FilterUtil.filterEventsByStatus(events, false)); + } + + @Test + public void testFilterCurrentEventList_with_empty_event_list_equals() { + List events = new ArrayList(); + // Filter with empty events list + assertEquals(events, FilterUtil.filterEventsByStatus(events, false)); + } + + @Test + public void testFilterCurrentEventList_equals() { + List events = new ArrayList(); + List filteredResult = getEmptyEventList(); + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(currentEvents); + assertEquals(filteredResult, FilterUtil.filterEventsByStatus(events, false)); + } + + @Test + public void testFilterCurrentEventList_not_equals() { + List events = new ArrayList(); + List filteredResult = getEmptyEventList(); + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + assertNotEquals(filteredResult, FilterUtil.filterEventsByStatus(events, true)); + } + + @Test + public void testFilterEventsBySingleDate_with_empty_event_list_equals() { + List events = new ArrayList(); + // Events is empty + assertEquals(events, FilterUtil.filterEventBySingleDate(events, TODAY)); + } + + @Test + public void testFilterEventBySingleDate_equals() { + List events = new ArrayList(); + List filteredResult = getEmptyEventList(); + // Filter out overdue events + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + assertEquals(filteredResult, FilterUtil.filterEventBySingleDate(events, DateUtil.floorDate(YESTERDAY))); + } + + @Test + public void testFilterEventBySingleDate_not_equals() { + List events = new ArrayList(); + List filteredResult = getEmptyEventList(); + + // Filter out current events + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(currentEvents); + assertNotEquals(filteredResult, FilterUtil.filterEventBySingleDate(events, DateUtil.floorDate(YESTERDAY))); + } + + @Test + public void testFilterEventWithDateRange_empty_event_list_equals() { + List events = new ArrayList(); + // Events is empty + assertEquals(events, FilterUtil.filterEventWithDateRange(events, YESTERDAY, YESTERDAY)); + } + + @Test + public void testFilterEventWithDateRange_equals() { + List events = new ArrayList(); + List filteredResult = new ArrayList(); + // Filter out overdue events + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + assertEquals(filteredResult, + FilterUtil.filterEventWithDateRange(events, DateUtil.floorDate(YESTERDAY), DateUtil.ceilDate(YESTERDAY))); + } + + @Test + public void testFilterEventWithDateRange_null_dates_equals() { + List events = new ArrayList(); + List filteredResult = new ArrayList(); + // Filter out both overdue and current events + events.addAll(overdueEvents); + events.addAll(currentEvents); + filteredResult.addAll(overdueEvents); + filteredResult.addAll(currentEvents); + assertEquals(events, FilterUtil.filterEventWithDateRange(events, null, DateUtil.ceilDate(TOMORROW))); + assertEquals(events, FilterUtil.filterEventWithDateRange(events, DateUtil.floorDate(YESTERDAY), null)); + assertEquals(events, FilterUtil.filterEventWithDateRange(events, null, null)); + } + + @Test + public void testFilterEventWithDateRange_not_equals() { + List events = new ArrayList(); + List filteredResult = new ArrayList(); + // Filter out overdue events + events.addAll(currentEvents); + events.addAll(overdueEvents); + filteredResult.addAll(currentEvents); + assertNotEquals(filteredResult, + FilterUtil.filterEventWithDateRange(events, DateUtil.floorDate(YESTERDAY), DateUtil.ceilDate(YESTERDAY))); + } + + /* =================== Helper methods to be use to generate Task and Event for testing =============== */ + + private Task getFirstTestTask() { + Task task = new Task(); + task.setName("Buy Milk"); + task.setCalendarDateTime(TODAY); + task.addTag("personal"); + task.setCompleted(); + return task; + } + + private Task getSecondTestTask() { + Task task = new Task(); + task.setName("CS2103"); + task.setCalendarDateTime(TOMORROW); + task.addTag("CS2103"); + return task; + } + + private List getEmptyTaskList() { + return new ArrayList(); + } + + private List getEmptyEventList() { + return new ArrayList(); + } + + private List getOverdueEvents() { + List events = new ArrayList(); + Event event = new Event(); + event.setStartDate(YESTERDAY); + event.setEndDate(YESTERDAY); + event.setName("CS2103 V0.5"); + event.addTag("CS2103"); + events.add(event); + event.removeTag("CS2103"); + event.setName("CSIT roadshow"); + event.addTag("CSIT"); + events.add(event); + return events; + } + + private List getCurrentEvents() { + List events = new ArrayList(); + Event event = new Event(); + event.setStartDate(TODAY); + event.setEndDate(TOMORROW); + event.setName("CS3216 9th Steps"); + event.addTag("CS3216"); + events.add(event); + event.removeTag("CS3216"); + event.setName("CS3217 9th Steps"); + event.addTag("CS3217"); + events.add(event); + return events; + } +} +``` +###### /java/seedu/todo/commons/util/ParseUtilTest.java +``` java +public class ParseUtilTest { + + Map parsedResult = new HashMap(); + public static final String EMPTY_TOKEN = ""; + public static final String [] NULL_TOKEN_RESULT = new String [] { null }; + public static final String [] TOKEN_RESULT = new String [] {"test", "test1, test2"}; + + public static final String TEST_TOKEN = "test"; + public static final String TOKEN_KEYWORD_DOES_NOT_EXIST = "random"; + + public static final int TOKEN_RESULT_INDEX_ONE = 0; + public static final int TOKEN_RESULT_INDEX_TWO = 1; + + public static final String CORRECT_NATURAL_DATE = "today"; + public static final String INCORRECT_NATURAL_DATE = "todar"; + + public static final String DATE_ON_FORMAT = Tokenizer.TIME_TOKEN; + public static final String DATE_FROM_FORMAT = Tokenizer.TIME_FROM_TOKEN; + public static final String DATE_TO_FORMAT = Tokenizer.TIME_TO_TOKEN; + + @Test + public void testIsTokenNull_true() { + parsedResult.put(TEST_TOKEN, NULL_TOKEN_RESULT); + assertTrue(ParseUtil.isTokenNull(parsedResult, TEST_TOKEN)); + } + + @Test + public void testIsTokenNull_false() { + parsedResult.put(TEST_TOKEN, TOKEN_RESULT); + assertFalse(ParseUtil.isTokenNull(parsedResult, TEST_TOKEN)); + } + + @Test + public void testDoesTokenContainKeyword_true() { + parsedResult.put(TEST_TOKEN, TOKEN_RESULT); + assertTrue(ParseUtil.doesTokenContainKeyword(parsedResult, TEST_TOKEN, TOKEN_RESULT[TOKEN_RESULT_INDEX_ONE])); + } + + @Test + public void testDoesTokenContainKeyword_false() { + parsedResult.put(TEST_TOKEN, TOKEN_RESULT); + assertFalse(ParseUtil.doesTokenContainKeyword(parsedResult, TEST_TOKEN, TOKEN_KEYWORD_DOES_NOT_EXIST)); + } + + @Test + public void testDoesTokenContainKeyword_with_empty_token_false() { + parsedResult.put(TEST_TOKEN, TOKEN_RESULT); + assertFalse(ParseUtil.doesTokenContainKeyword(parsedResult, EMPTY_TOKEN, TOKEN_RESULT[TOKEN_RESULT_INDEX_ONE])); + assertFalse(ParseUtil.doesTokenContainKeyword(parsedResult, EMPTY_TOKEN, NULL_TOKEN_RESULT[TOKEN_RESULT_INDEX_ONE])); + } + + @Test + public void testGetTokenResult_not_null() { + assertNotNull(ParseUtil.getTokenResult(parsedResult, TEST_TOKEN), TOKEN_RESULT[TOKEN_RESULT_INDEX_TWO]); + } + + @Test + public void testGetTokenResult_null() { + assertNull(ParseUtil.getTokenResult(parsedResult, EMPTY_TOKEN)); + } + + @Test + public void testGetTokenResult_equals() { + parsedResult.put(TEST_TOKEN, TOKEN_RESULT); + assertEquals(ParseUtil.getTokenResult(parsedResult, TEST_TOKEN), TOKEN_RESULT[TOKEN_RESULT_INDEX_TWO]); + } + + @Test + public void testGetTokenResult_not_equals() { + parsedResult.put(TEST_TOKEN, TOKEN_RESULT); + assertNotEquals(ParseUtil.getTokenResult(parsedResult, TEST_TOKEN), TOKEN_RESULT[TOKEN_RESULT_INDEX_ONE]); + } + + @Test + public void testParseDates_with_valid_dates_not_null() { + String [] date_on_result = { "time", "today" }; + String [] incorrect_date_result = { "" , null }; + + parsedResult.put(DATE_ON_FORMAT, date_on_result); + parsedResult.put(DATE_FROM_FORMAT, incorrect_date_result); + parsedResult.put(DATE_TO_FORMAT, incorrect_date_result); + assertNotNull(ParseUtil.parseDates(parsedResult)); + } + + @Test + public void testParseDates_null() { + String [] incorrect_date_result = { "" , null }; + parsedResult.put(DATE_ON_FORMAT, incorrect_date_result); + parsedResult.put(DATE_FROM_FORMAT, incorrect_date_result); + parsedResult.put(DATE_TO_FORMAT, incorrect_date_result); + assertNull(ParseUtil.parseDates(parsedResult)); + } + + @Test + public void testParseDates_equals() { + String[] test_result = { "3", "today" , "tuesday" , "wednesday" }; + String [] date_on_result = { "time", "today" }; + String [] date_from_result = { "timeFrom" , "tuesday" }; + String [] date_to_result = { "timeTo" , "wednesday" }; + + parsedResult.put(DATE_ON_FORMAT, date_on_result); + parsedResult.put(DATE_FROM_FORMAT, date_from_result); + parsedResult.put(DATE_TO_FORMAT, date_to_result); + assertArrayEquals(test_result, ParseUtil.parseDates(parsedResult)); + } +} +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testSplitStringBySpace_null() { + assertNull(StringUtil.splitStringBySpace(null)); + } + +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testSplitStringBySpace_not_null() { + String testcase1 = "TEST TEST"; + assertNotNull(StringUtil.splitStringBySpace(testcase1)); + } + +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testSplitStringBySpace_equals() { + String testcase1 = "TEST"; + String testcase2 = "TEST TEST"; + assertArrayEquals(testcase1.split(" "), StringUtil.splitStringBySpace(testcase1)); + assertArrayEquals(testcase2.split(" "),StringUtil.splitStringBySpace(testcase2)); + } + +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testFormatNumberOfTaskWithPuralizer_equals() { + int single = 1; + assertEquals(String.format("%d task", single), StringUtil.formatNumberOfTaskWithPuralizer(single)); + int pural = 2; + assertEquals(String.format("%d tasks", pural), StringUtil.formatNumberOfTaskWithPuralizer(pural)); + } + +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testFormatNumberOfTaskWithPuralizer_not_equals() { + int single = 1; + assertNotEquals(String.format("%d tasks", single), StringUtil.formatNumberOfTaskWithPuralizer(single)); + int pural = 2; + assertNotEquals(String.format("%d task", pural), StringUtil.formatNumberOfTaskWithPuralizer(pural)); + } + +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testFormatNumberOfEventWithPuralizer_equals() { + int single = 1; + assertEquals(String.format("%d event", single), StringUtil.formatNumberOfEventWithPuralizer(single)); + int pural = 2; + assertEquals(String.format("%d events", pural), StringUtil.formatNumberOfEventWithPuralizer(pural)); + } + +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testFormatNumberOfEventWithPuralizer_not_equals() { + int single = 1; + assertNotEquals(String.format("%d events", single), StringUtil.formatNumberOfEventWithPuralizer(single)); + int pural = 2; + assertNotEquals(String.format("%d event", pural), StringUtil.formatNumberOfEventWithPuralizer(pural)); + } + +``` +###### /java/seedu/todo/commons/util/StringUtilTest.java +``` java + @Test + public void testDisplayNumberOfTaskAndEventFoundWithPuralizer_equals() { + int numTasks = 0; + int numEvents = 0; + assertEquals("No item found!", StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(numTasks, numEvents)); + numTasks = 1; + assertEquals("1 task", StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(numTasks, numEvents)); + numEvents = 1; + assertEquals("1 task and 1 event", StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(numTasks, numEvents)); + numTasks = 0; + assertEquals("1 event", StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(numTasks, numEvents)); + } +} +``` +###### /java/seedu/todo/guitests/ClearCommandTest.java +``` java + @Test + public void clear_tasks_by_single_date() { + console.runCommand("clear tasks on tmr"); + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_tasks_by_date_range() { + console.runCommand("clear tasks from today to tmr"); + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_tasks_by_date_range_with_single_date() { + console.runCommand("clear tasks from today"); + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskNotVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_events_by_single_date() { + console.runCommand("clear events on tmr"); + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_events_by_date_range() { + console.runCommand("clear events from today to tmr"); + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_events_by_date_range_with_single_date() { + console.runCommand("clear events from today"); + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 2; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventNotVisibleAfterCmd("list", event4); + } + + @Test + public void clear_by_single_date() { + console.runCommand("clear on tmr"); + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_by_date_range() { + console.runCommand("clear from today to tmr"); + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_by_date_range_with_single_date() { + console.runCommand("clear from today"); + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 2; + String expectedOutputMessage = String.format(ClearController.MESSAGE_CLEAR_SUCCESS_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskNotVisibleAfterCmd("list", task1); + assertTaskNotVisibleAfterCmd("list", task2); + assertEventNotVisibleAfterCmd("list", event3); + assertEventNotVisibleAfterCmd("list", event4); + } + + @Test + public void clear_with_invalid_date_syntax() { + console.runCommand("clear from todar"); + // For console text area to check error message + String expectedDisambiguation = ClearController.CLEAR_DATE_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + String expectedOutputMessage = formatConsoleOutputTextArea(ClearController.MESSAGE_NO_DATE_DETECTED); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_with_date_conflict() { + console.runCommand("clear by today to tmr"); + // For console text area to check error message + String expectedDisambiguation = ClearController.CLEAR_DATE_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + String expectedOutputMessage = formatConsoleOutputTextArea(ClearController.MESSAGE_DATE_CONFLICT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_with_item_type_conflict() { + console.runCommand("clear tasks events"); + // For console text area to check error message + String expectedDisambiguation = ClearController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + String expectedOutputMessage = formatConsoleOutputTextArea(ClearController.MESSAGE_ITEM_TYPE_CONFLICT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_with_invalid_command_syntax_by_event_status() { + console.runCommand("clear current events"); + // For console text area to check error message + String expectedDisambiguation = ClearController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + String expectedOutputMessage = formatConsoleOutputTextArea(ClearController.MESSAGE_CLEAR_UNABLE_TO_SUPPORT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } + + @Test + public void clear_with_invalid_command_syntax_by_task_status() { + console.runCommand("clear completed tasks"); + // For console text area to check error message + String expectedDisambiguation = ClearController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + String expectedOutputMessage = formatConsoleOutputTextArea(ClearController.MESSAGE_CLEAR_UNABLE_TO_SUPPORT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + + // Check if Tasks and Events still in the GUI + assertTaskVisibleAfterCmd("list", task1); + assertTaskVisibleAfterCmd("list", task2); + assertEventVisibleAfterCmd("list", event3); + assertEventVisibleAfterCmd("list", event4); + } +} +``` +###### /java/seedu/todo/guitests/FindCommandTest.java +``` java + */ +public class FindCommandTest extends GuiTest { +``` +###### /java/seedu/todo/guitests/FindCommandTest.java +``` java + @Test + public void find_by_name() { + String command = "find name buy"; + // To check if the tasks and events are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_tasks_by_name() { + String command = "find name buy tasks"; + // To check if the tasks are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_events_by_name() { + String command = "find name buy events"; + // To check if the events are been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_by_invalid_name() { + String command = "find name tester"; + // To check if the tasks and events are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check error message + assertEquals(console.getConsoleTextArea(), FindController.MESSAGE_NO_RESULT_FOUND); + } + + @Test + public void find_by_tag() { + String command = "find tagName buy"; + // To check if the tasks and events are been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_tasks_by_tag() { + String command = "find tagName personal tasks"; + // To check if the tasks are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_events_by_tag() { + String command = "find tagName buy events"; + // To check if event 4 is been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_by_invalid_tag() { + // To check if all tasks and events are still in the view + String command = "find tagName tester"; + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + assertEquals(console.getConsoleTextArea(), FindController.MESSAGE_NO_RESULT_FOUND); + } + + @Test + public void find_by_keyword() { + String command = "find buy"; + // To check if tasks and events are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_tasks_by_keyword() { + String command = "find buy tasks"; + // To check if tasks are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_events_by_keyword() { + String command = "find buy events"; + // To check if event4 is been filtered + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_by_invalid_keyword() { + String command = "find tester"; + // To check if all tasks and events are still in the view + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + assertEquals(console.getConsoleTextArea(), FindController.MESSAGE_NO_RESULT_FOUND); + } + + @Test + public void find_by_tasks_complete_status() { + console.runCommand("complete 1"); + String command = "find buy complete"; + // To check if task1 is been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_by_tassk_incomplete_status() { + String command = "find buy incomplete"; + // To check if tasks are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_by_events_current_status() { + String command = "find buy current"; + // To check if event3 is been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_by_events_over_status() { + String command = "find buy over"; + // To check if all tasks and events are still in the view + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + assertEquals(console.getConsoleTextArea(), FindController.MESSAGE_NO_RESULT_FOUND); + } + + @Test + public void find_by_single_date() { + String command = "find buy on today"; + // To check if task1 is been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_by_date_range() { + String command = "find buy from today"; + // To check if tasks and events are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_tasks_by_single_date() { + String command = "find buy tasks on today"; + + // To check if task1 is been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_tasks_by_date_range() { + String command = "find buy tasks from today to tmr"; + + // To check if all tasks are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_tasks_by_date_range_with_single_date() { + String command = "find buy tasks from today"; + // To check if all tasks are been filtered as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_events_by_single_date() { + String command = "find CS2103 events on tomorrow"; + // To check if event3 is been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_events_by_date_range_with_single_date() { + String command = "find buy events from today"; + // To check if event4 is been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_events_by_date_range() { + String command = "find CS2103 events from today to tmr"; + // To check if event3 is been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(FindController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_missingKeywords_disambiguate() { + String command = "find"; + console.runCommand(command); + + // To check if the consoleInputText matches the controller corrected syntax + String expectedDisambiguation = FindController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(FindController.MESSAGE_NO_KEYWORD_FOUND); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_invalidTaskSyntax_disambiguate() { + String command = "find buy task over"; + console.runCommand(command); + + // To check if the consoleInputText matches the controller corrected syntax + String expectedDisambiguation = FindController.FIND_TASK_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(FindController.MESSAGE_INVALID_TASK_STATUS); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_invalidEventSyntax_disambiguate() { + String command = "find buy event complete"; + console.runCommand(command); + + // To check if the consoleInputText matches the controller corrected syntax + String expectedDisambiguation = FindController.FIND_EVENT_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(FindController.MESSAGE_INVALID_EVENT_STATUS); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_with_invalid_single_date() { + String command = "find buy by todar"; + console.runCommand(command); + + // To check if the consoleInputText matches the controller corrected syntax + String expectedDisambiguation = FindController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(FindController.MESSAGE_NO_DATE_DETECTED); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_with_date_conflict() { + String command = "find buy by today from tmr"; + console.runCommand(command); + + // To check if the consoleInputText matches the controller corrected syntax + String expectedDisambiguation = FindController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(FindController.MESSAGE_DATE_CONFLICT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void find_with_invalid_date_range() { + String command = "find buy from today to tml"; + console.runCommand(command); + + // To check if the consoleInputText matches the controller corrected syntax + String expectedDisambiguation = FindController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(FindController.MESSAGE_NO_DATE_DETECTED); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } +} +``` +###### /java/seedu/todo/guitests/guihandles/SideBarHandle.java +``` java + */ +public class SideBarHandle extends GuiHandle { + + private static final String TAGLIST = "#sidebarTagsPlaceholder"; + + public SideBarHandle(GuiRobot guiRobot, Stage primaryStage, String stageTitle) { + super(guiRobot, primaryStage, stageTitle); + } + + /** + * Returns a TaskListDateItemHandle that corresponds to the name specified. + * If it doesn't exist, it returns null. + */ + public TagListItemHandle getTagListItem(String tagName) { + Optional tagItemNode = guiRobot.lookup(TAGLIST).queryAll().stream() + .filter(node -> new TagListItemHandle(guiRobot, primaryStage, node).getName().equals(tagName)) + .findFirst(); + + if (tagItemNode.isPresent()) { + return new TagListItemHandle(guiRobot, primaryStage, tagItemNode.get()); + } else { + return null; + } + } +} +``` +###### /java/seedu/todo/guitests/guihandles/TagListItemHandle.java +``` java + */ +public class TagListItemHandle extends GuiHandle { + + private static final String TAGLISTITEM_LABEL = "#labelText"; + private Node node; + + public TagListItemHandle(GuiRobot guiRobot, Stage primaryStage, Node node){ + super(guiRobot, primaryStage, null); + this.node = node; + } + + public String getName() { + return getStringFromText(TAGLISTITEM_LABEL, node); + } + +} +``` +###### /java/seedu/todo/guitests/GuiTest.java +``` java + * Utility method for testing if tag has been successfully added to the GUI side panel. + * This runs a command and checks if TagList contains tag that matches + * the tag that was just added. + * + * Assumption : No tags can have the same name + * + */ + protected void assertTaskTagVisibleAfterCmd(String command, Task taskToAdd) { + // Run the command in the console. + console.runCommand(command); + int tag_index = 0; + + // Get the Tag List + ArrayList taskTagList = taskToAdd.getTagList(); + + // Assumption each task only got 1 tag + String tagName = taskTagList.get(tag_index); + + // Check if tag exist in the side panel tag list + TagListItemHandle tagItem = sidebar.getTagListItem(tagName); + assertNotNull(tagItem); + + // Check if the tag found is equal to the tag name of the task + String tagItemName = tagItem.getName(); + assertEquals(tagItemName, tagName); + } + + /** +``` +###### /java/seedu/todo/guitests/GuiTest.java +``` java + * Utility method for testing if tag has been successfully removed from the GUI side panel. + * This runs a command and checks if TagList contains tag that matches + * the tag that was just removed. + * + * Assumption : No tags can have the same name + * + */ + protected void assertTaskTagNotVisibleAfterCmd(String command, Task taskToAdd) { + // Get the Tag List + ArrayList taskTagList = taskToAdd.getTagList(); + + // Get the tag name with assumption each task only got 1 tag + String tagName = getTagNameFromCommand(command); + + // Run the command in the console. + console.runCommand(command); + + // Check if tag exist in the side panel tag list + TagListItemHandle tagItem = sidebar.getTagListItem(tagName); + assertNull(tagItem); + + // Check if tag has been removed + int expected_tag_list_size = 0; + assertEquals(taskTagList.size(), expected_tag_list_size); + } + + /** +``` +###### /java/seedu/todo/guitests/GuiTest.java +``` java + * Utility method for testing if tag is not successfully added into the GUI side panel. + * This runs a command and checks if TagList contains tag that matches + * the tag that is attempt to be added. + * + * Assumption : No tags can have the same name + * + */ + protected void assertTaskTagListFull(String command, Task taskToAdd) { + // Get the Tag List + ArrayList taskTagList = taskToAdd.getTagList(); + + // Get the next tag name from command + String tagName = getTagNameFromCommand(command); + + // Run the command in the console. + console.runCommand(command); + int expected_tag_list_size = 20; + + // Check if tag exist in the side panel tag list + TagListItemHandle tagItem = sidebar.getTagListItem(tagName); + assertNull(tagItem); + + assertEquals(expected_tag_list_size, taskTagList.size()); + } + + /* +``` +###### /java/seedu/todo/guitests/GuiTest.java +``` java + * Extract out the tag name that is been parsed in the command + * + * Assumption only 1 tag name is provided and tag name wil be provided + * @return tagName + */ + private String getTagNameFromCommand(String command) { + int tagName_index = 2; + String tagName = StringUtil.splitStringBySpace(command)[tagName_index]; + assert tagName != null; + return tagName; + } + + /* +``` +###### /java/seedu/todo/guitests/GuiTest.java +``` java + * To format disambiguate message at console output text area + * + * @return formatted output + */ + protected String formatConsoleOutputTextArea(String expectedDisambiguateMessage) { + return String.format(Renderer.MESSAGE_DISAMBIGUATE + "\n\n%s", expectedDisambiguateMessage); + } +} +``` +###### /java/seedu/todo/guitests/ListCommandTest.java +``` java + */ +public class ListCommandTest extends GuiTest { +``` +###### /java/seedu/todo/guitests/ListCommandTest.java +``` java + @Test + public void list_all() { + String command = "list"; + // To check if all tasks and events are still in the view + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + String expectedOutputMessage = ListController.MESSAGE_LIST_SUCCESS; + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_tasks() { + String command = "list tasks"; + // To check if all tasks are been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_completed_tasks() { + console.runCommand("complete 1"); + String command = "list complete"; + // To check if task1 is been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_incomplete_tasks() { + String command = "list incomplete"; + // To check if all tasks are been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_events() { + String command = "list events"; + // To check if all events are been filtered out as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 2; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + + @Test + public void list_over_events() { + String command = "list over"; + // To check if all tasks events are still in the view + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + String expectedOutputMessage = ListController.MESSAGE_NO_RESULT_FOUND; + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_current_events() { + String command = "list current"; + // To check if all events are been filtered out as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 2; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_by_single_date() { + String command = "list today"; + // To check if task1 is been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_by_date_range() { + String command = "list from today"; + // To check if all tasks and events are been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 2; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_tasks_by_single_date() { + String command = "list tasks on today"; + // To check if task1 is been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 1; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_tasks_by_date_range_with_single_date() { + String command = "list tasks from today"; + // To check if all tasks are been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_tasks_by_date_range() { + String command = "list tasks from today to tmr"; + // To check if all tasks are been filtered out as expected + assertTaskVisibleAfterCmd(command, task1); + assertTaskVisibleAfterCmd(command, task2); + assertEventNotVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 2; + expectedNumOfEvents = 0; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_events_by_single_date() { + String command = "list events on tomorrow"; + // To check if event3 is been filtered as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventNotVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 1; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_events_by_date_range_with_single_date() { + String command = "list events from today"; + // To check if all events are been filtered out as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 2; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_events_by_date_range() { + String command = "list events from today to " + THE_DAY_AFTER_TOMORROW_STRING; + // To check if all events are been filtered out as expected + assertTaskNotVisibleAfterCmd(command, task1); + assertTaskNotVisibleAfterCmd(command, task2); + assertEventVisibleAfterCmd(command, event3); + assertEventVisibleAfterCmd(command, event4); + + // For console text area to check output message + expectedNumOfTasks = 0; + expectedNumOfEvents = 2; + String expectedOutputMessage = String.format(ListController.MESSAGE_RESULT_FOUND_FORMAT, + StringUtil.displayNumberOfTaskAndEventFoundWithPuralizer(expectedNumOfTasks, expectedNumOfEvents)); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_invalidTaskSyntax_disambiguate() { + String command = "list task over"; + console.runCommand(command); + // For console input text to check controller corrected syntax + String expectedDisambiguation = ListController.LIST_TASK_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(ListController.MESSAGE_INVALID_TASK_STATUS); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_invalidEventSyntax_disambiguate() { + String command = "list event complete"; + console.runCommand(command); + // For console input text to check controller corrected syntax + String expectedDisambiguation = ListController.LIST_EVENT_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(ListController.MESSAGE_INVALID_EVENT_STATUS); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_invalidDateSyntax_disambiguate_with_date_range() { + String command = "list by today to tml"; + console.runCommand(command); + // For console input text to check controller corrected syntax + String expectedDisambiguation = ListController.LIST_DATE_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(ListController.MESSAGE_DATE_CONFLICT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_invalidDateSyntax_disambiguate_with_single_date_by_keyword() { + String command = "list by todar"; + console.runCommand(command); + // For console input text to check controller corrected syntax + String expectedDisambiguation = ListController.LIST_DATE_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(ListController.MESSAGE_NO_DATE_DETECTED); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_invalidDateSyntax_disambiguate_with_single_date() { + String command = "list todar"; + console.runCommand(command); + // For console input text to check controller corrected syntax + String expectedDisambiguation = ListController.LIST_DATE_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(ListController.MESSAGE_NO_DATE_DETECTED); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_invalidDateSyntax_disambiguate_with_date_conflict() { + String command = "list today by tmr"; + console.runCommand(command); + // For console input text to check controller corrected syntax + String expectedDisambiguation = ListController.LIST_DATE_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(ListController.MESSAGE_DATE_CONFLICT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } + + @Test + public void list_invalidDateSyntax_disambiguate_with_date_conflict_by_status() { + String command = "list today over"; + console.runCommand(command); + // For console input text to check controller corrected syntax + String expectedDisambiguation = ListController.LIST_DATE_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguation); + + // For console text area to check error message + String expectedOutputMessage = formatConsoleOutputTextArea(ListController.MESSAGE_DATE_CONFLICT); + assertEquals(console.getConsoleTextArea(), expectedOutputMessage); + } +} +``` +###### /java/seedu/todo/guitests/TagControllerTest.java +``` java + */ +public class TagControllerTest extends GuiTest { +``` +###### /java/seedu/todo/guitests/TagControllerTest.java +``` java + @Test + public void tag_succcessfully() { + String command = "tag 1 personal"; + assertTaskTagVisibleAfterCmd(command, task); + assertEquals(console.getConsoleTextArea(), TagController.MESSAGE_TAG_SUCCESS); + } + + @Test + public void tag_with_duplicated_names() { + // To run the command + String command = "tag 1 personal"; + + assertTaskTagVisibleAfterCmd(command, task); + console.runCommand(command); + + // For console input + int tag_index = 1; + String expectedDisambiguationForConsoleInput = String.format(TagController.TAG_FORMAT, tag_index); + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(TagController.MESSAGE_TAG_NAME_EXIST); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void tag_when_tag_list_is_full() { + taskWithoutTag = generateTags(taskWithoutTag); + // To run Command + String command = "tag 1 personal"; + + assertTaskTagListFull(command, taskWithoutTag); + + // For console input + String expectedDisambiguationForConsoleInput = TagController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(TagController.MESSAGE_EXCEED_TAG_SIZE); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void tag_without_index() { + // To run command + String command = "tag"; + console.runCommand(command); + + // For console input + String expectedDisambiguationForConsoleInput = TagController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(TagController.MESSAGE_MISSING_INDEX_AND_TAG_NAME); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void tag_with_invalid_index_out_of_range() { + // To run command + String command = "tag 2"; + console.runCommand(command); + + // For console input + int tag_index_out_of_range = 2; + String expectedDisambiguationForConsoleInput = String.format(TagController.TAG_FORMAT, tag_index_out_of_range); + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(TagController.MESSAGE_INDEX_OUT_OF_RANGE); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void tag_with_invalid_index_as_alphabets() { + // To run command + String command = "tag personal"; + console.runCommand(command); + + // For console input + String expectedDisambiguationForConsoleInput = TagController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(TagController.MESSAGE_INDEX_NOT_NUMBER); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void tag_without_name() { + // To run command + String command = "tag 1"; + console.runCommand(command); + + // For console input + String expectedDisambiguationForConsoleInput = TagController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(TagController.MESSAGE_TAG_NAME_NOT_FOUND); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + private Task generateTags(Task task) { + for (int i = 0; i < task.getTagListLimit(); i ++) { + console.runCommand("tag 1 " + Integer.toString(i)); + task.addTag(Integer.toString(i)); + } + return task; + } +} +``` +###### /java/seedu/todo/guitests/UntagControllerTest.java +``` java + */ +public class UntagControllerTest extends GuiTest { +``` +###### /java/seedu/todo/guitests/UntagControllerTest.java +``` java + @Test + public void untag_succesfully() { + console.runCommand("tag 1 personal"); + String command = "untag 1 personal"; + assertTaskTagNotVisibleAfterCmd(command, taskWithoutTag); + } + + @Test + public void untag_task_with_invalid_name() { + // To run command + console.runCommand("tag 1 test"); + String command = "untag 1 personal"; + console.runCommand(command); + + // For console input + int tag_index = 1; + String expectedDisambiguationForConsoleInput = String.format(UntagController.UNTAG_FORMAT, tag_index); + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(UntagController.MESSAGE_TAG_NAME_EXIST); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void untag_without_name() { + // To run command + String command = "untag 1"; + console.runCommand(command); + + // For console input + String expectedDisambiguationForConsoleInput = UntagController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(UntagController.MESSAGE_TAG_NAME_NOT_FOUND); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void untag_without_index() { + // To run command + String command = "untag"; + console.runCommand(command); + + // For console input + String expectedDisambiguationForConsoleInput = UntagController.COMMAND_SYNTAX; + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(UntagController.MESSAGE_MISSING_INDEX_AND_TAG_NAME); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } + + @Test + public void untag_with_invalid_index() { + // To run command + String command = "untag 2"; + console.runCommand(command); + + // For console input + int index_out_of_range = 2; + String expectedDisambiguationForConsoleInput = String.format(UntagController.UNTAG_FORMAT, index_out_of_range); + assertEquals(console.getConsoleInputText(), expectedDisambiguationForConsoleInput); + + // For console text area to check error message + String expectedDisambiguationForConsoleTextArea = formatConsoleOutputTextArea(UntagController.MESSAGE_INDEX_OUT_OF_RANGE); + assertEquals(console.getConsoleTextArea(), expectedDisambiguationForConsoleTextArea); + } +} +```