diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java index c9abe4f5fb0..35f37c164c5 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/address/logic/LogicManager.java @@ -48,7 +48,7 @@ public CommandResult execute(String commandText) throws CommandException, ParseE logger.info("----------------[USER COMMAND][" + commandText + "]"); CommandResult commandResult; - Command command = addressBookParser.parseCommand(commandText); + Command command = addressBookParser.parse(commandText); commandResult = command.execute(model); model.getCommandHistory().pushCommand(command); model.addCommandToHistory(commandText); diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index adb44d06e4d..5891f6568c5 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -6,8 +6,12 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.logic.parser.CommandArgument.optionalMultiple; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandArgument; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.person.Person; @@ -18,20 +22,22 @@ public class AddCommand extends Command { public static final String COMMAND_WORD = "add"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. " - + "Parameters: " - + PREFIX_NAME + "NAME " - + PREFIX_PHONE + "PHONE " - + PREFIX_EMAIL + "EMAIL " - + PREFIX_ADDRESS + "ADDRESS " - + "[" + PREFIX_TAG + "TAG]...\n" - + "Example: " + COMMAND_WORD + " " - + PREFIX_NAME + "John Doe " - + PREFIX_PHONE + "98765432 " - + PREFIX_EMAIL + "johnd@example.com " - + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " - + PREFIX_TAG + "friends " - + PREFIX_TAG + "owesMoney"; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Adds a person to the address book.", + requiredSingle(PREFIX_NAME, "name"), + requiredSingle(PREFIX_PHONE, "phone"), + requiredSingle(PREFIX_EMAIL, "email"), + requiredSingle(PREFIX_ADDRESS, "address"), + optionalMultiple(PREFIX_TAG, "tag") + ).withExample( + CommandArgument.filled(PREFIX_NAME, "John Doe"), + CommandArgument.filled(PREFIX_PHONE, "98765432"), + CommandArgument.filled(PREFIX_EMAIL, "johnd@example.com"), + CommandArgument.filled(PREFIX_ADDRESS, "311, Clementi Ave 2, #02-25"), + CommandArgument.filled(PREFIX_TAG, "friends"), + CommandArgument.filled(PREFIX_TAG, "owesMoney") + ); public static final String MESSAGE_SUCCESS = "New person added: %1$s"; public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index 07004c85e7f..60b9ec717a3 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -4,6 +4,7 @@ import seedu.address.commons.core.Messages; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.AddressBook; import seedu.address.model.Model; import seedu.address.model.ReadOnlyAddressBook; @@ -15,8 +16,12 @@ public class ClearCommand extends Command { public static final String COMMAND_WORD = "clear"; public static final String MESSAGE_SUCCESS = "Address book has been cleared!"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Clears the address book. " - + "Parameters: none"; + + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Clears the address book." + ); + private ReadOnlyAddressBook oldAddressBook; @Override diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index 8d7c2f0cecb..ed0e0d9a63f 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -1,6 +1,9 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.List; import java.util.function.Predicate; @@ -8,6 +11,7 @@ import seedu.address.commons.core.Messages; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.person.Person; @@ -18,10 +22,13 @@ public class DeleteCommand extends Command { public static final String COMMAND_WORD = "delete"; - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the person identified by the index number used in the displayed person list.\n" - + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + COMMAND_WORD + " 1"; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Deletes the person identified by the index number used in the displayed person list.", + requiredSingle(PREFIX_PREAMBLE, "index") + ).withExample( + filled(PREFIX_PREAMBLE, "1") + ); public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index c29db8b65d4..52db3db624d 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -5,7 +5,12 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.optionalMultiple; +import static seedu.address.logic.parser.CommandArgument.optionalSingle; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; import java.util.Collections; @@ -18,6 +23,7 @@ import seedu.address.commons.core.index.Index; import seedu.address.commons.util.CollectionUtil; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.person.Address; import seedu.address.model.person.Email; @@ -32,19 +38,22 @@ public class EditCommand extends Command { public static final String COMMAND_WORD = "edit"; - - public static final String MESSAGE_USAGE = - COMMAND_WORD + ": Edits the details of the person identified " + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Edits the details of the person identified " + "by the index number used in the displayed person list. " - + "Existing values will be overwritten by the input values.\n" - + "Parameters: INDEX (must be a positive integer) " - + "[" + PREFIX_NAME + "NAME] " - + "[" + PREFIX_PHONE + "PHONE] " - + "[" + PREFIX_EMAIL + "EMAIL] " - + "[" + PREFIX_ADDRESS + "ADDRESS] " - + "[" + PREFIX_TAG + "TAG]...\n" - + "Example: " + COMMAND_WORD + " 1 " + PREFIX_PHONE - + "91234567 " + PREFIX_EMAIL + "johndoe@example.com"; + + "Existing values will be overwritten by the input values.", + requiredSingle(PREFIX_PREAMBLE, "index"), + optionalSingle(PREFIX_NAME, "name"), + optionalSingle(PREFIX_PHONE, "phone"), + optionalSingle(PREFIX_EMAIL, "email"), + optionalSingle(PREFIX_ADDRESS, "address"), + optionalMultiple(PREFIX_TAG, "tag") + ).withExample( + filled(PREFIX_PREAMBLE, "1"), + filled(PREFIX_PHONE, "91234567"), + filled(PREFIX_EMAIL, "johndoe@example.com") + ); public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; @@ -56,7 +65,7 @@ public class EditCommand extends Command { private Person editedPerson; /** - * @param index index of the person in the filtered person list to edit + * @param index index of the person in the filtered person list to edit * @param editPersonDescriptor details to edit the person with */ public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) { diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/seedu/address/logic/commands/ExitCommand.java index b34fc33d3f9..758e1b30ae2 100644 --- a/src/main/java/seedu/address/logic/commands/ExitCommand.java +++ b/src/main/java/seedu/address/logic/commands/ExitCommand.java @@ -1,5 +1,6 @@ package seedu.address.logic.commands; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; /** @@ -8,8 +9,11 @@ public class ExitCommand extends Command { public static final String COMMAND_WORD = "exit"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Exists TaskMaster2103. " - + "Parameters: none"; + + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Exits TaskMaster2103." + ); public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting TaskMaster2103 as requested ..."; diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index 134aabd644e..44e6d8ea68b 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindCommand.java @@ -1,11 +1,15 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.function.Predicate; import seedu.address.commons.core.Messages; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; @@ -15,13 +19,16 @@ * Keyword matching is case insensitive. */ public class FindCommand extends Command { - public static final String COMMAND_WORD = "find"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of " - + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" - + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" - + "Example: " + COMMAND_WORD + " alice bob charlie"; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Finds all persons whose names contain any of the specified keywords (case-insensitive)\n" + + "and displays them as a list with index numbers.", + requiredSingle(PREFIX_PREAMBLE, "KEYWORD [MORE_KEYWORDS]...") + ).withExample( + filled(PREFIX_PREAMBLE, "alice bob charlie") + ); private final NameContainsKeywordsPredicate predicate; diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/address/logic/commands/HelpCommand.java index bf824f91bd0..4f42bbaf3f3 100644 --- a/src/main/java/seedu/address/logic/commands/HelpCommand.java +++ b/src/main/java/seedu/address/logic/commands/HelpCommand.java @@ -1,5 +1,6 @@ package seedu.address.logic.commands; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; /** @@ -9,8 +10,10 @@ public class HelpCommand extends Command { public static final String COMMAND_WORD = "help"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows program usage instructions.\n" - + "Example: " + COMMAND_WORD; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Shows program usage instructions." + ); public static final String SHOWING_HELP_MESSAGE = "Opened help window."; diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java index 9a098fa8725..715ae9e50d0 100644 --- a/src/main/java/seedu/address/logic/commands/ListCommand.java +++ b/src/main/java/seedu/address/logic/commands/ListCommand.java @@ -6,6 +6,7 @@ import java.util.function.Predicate; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.person.Person; @@ -15,10 +16,12 @@ public class ListCommand extends Command { public static final String COMMAND_WORD = "list"; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Lists all persons in the address book." + ); public static final String MESSAGE_SUCCESS = "Listed all persons"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Lists all persons in the address book. " - + "Parameters: none"; private Predicate previousPredicate; diff --git a/src/main/java/seedu/address/logic/commands/RedoCommand.java b/src/main/java/seedu/address/logic/commands/RedoCommand.java index 8374b81e449..12dc6db618a 100644 --- a/src/main/java/seedu/address/logic/commands/RedoCommand.java +++ b/src/main/java/seedu/address/logic/commands/RedoCommand.java @@ -3,14 +3,18 @@ import java.util.Optional; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.storage.CommandHistory; public class RedoCommand extends Command { public static final String COMMAND_WORD = "redo"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Redoes the last executed command. \n" - + "Example: " + COMMAND_WORD; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Redoes the last executed command." + ); + public static final String MESSAGE_UNDO_SUCCESS = "Successfully redid: "; public static final String MESSAGE_NOT_UNDONE = "Cannot redo any further."; diff --git a/src/main/java/seedu/address/logic/commands/UndoCommand.java b/src/main/java/seedu/address/logic/commands/UndoCommand.java index e0046c520b3..2b613e7bc37 100644 --- a/src/main/java/seedu/address/logic/commands/UndoCommand.java +++ b/src/main/java/seedu/address/logic/commands/UndoCommand.java @@ -3,14 +3,17 @@ import java.util.Optional; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.storage.CommandHistory; public class UndoCommand extends Command { public static final String COMMAND_WORD = "undo"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Undoes the last executed command. \n" - + "Example: " + COMMAND_WORD; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + COMMAND_WORD, + "Undoes the last executed command." + ); public static final String MESSAGE_UNDO_SUCCESS = "Successfully undid: "; public static final String MESSAGE_NOT_UNDONE = "Cannot undo any further."; diff --git a/src/main/java/seedu/address/logic/commands/task/AddTaskCommand.java b/src/main/java/seedu/address/logic/commands/task/AddTaskCommand.java index 1ebb6a82c50..1e9a7284186 100644 --- a/src/main/java/seedu/address/logic/commands/task/AddTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/task/AddTaskCommand.java @@ -2,12 +2,18 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_CONTACT; import static seedu.address.logic.parser.CliSyntax.PREFIX_DESCRIPTION; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIMESTAMP; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.optionalMultiple; +import static seedu.address.logic.parser.CommandArgument.optionalSingle; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.TaskCommand; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.task.Task; @@ -18,16 +24,19 @@ public class AddTaskCommand extends TaskCommand { public static final String COMMAND_WORD = "add"; public static final String FULL_COMMAND_WORD = TaskCommand.COMMAND_WORD + " " + COMMAND_WORD; public static final String MESSAGE_SUCCESS = "New task added: %1$s"; - public static final String MESSAGE_USAGE = FULL_COMMAND_WORD - + ": Adds a task with a given title to the task list.\n" - + "Parameters: title (must be a non-empty string) " - + "[" + PREFIX_DESCRIPTION + "DESCRIPTION] " - + "[" + PREFIX_TIMESTAMP + "TIMESTAMP] " - + "[" + PREFIX_TAG + "TAG]...\n" - + "[" + PREFIX_CONTACT + "AB3 CONTACT]...\n" - + "Example: " + FULL_COMMAND_WORD + " Do homework " - + PREFIX_DESCRIPTION + "Physics assignment " - + PREFIX_TIMESTAMP + "25/12/2020"; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + FULL_COMMAND_WORD, + "Add a task with the given title field, and optionally a description, timestamp, tags and contacts.", + requiredSingle(PREFIX_PREAMBLE, "title"), + optionalSingle(PREFIX_DESCRIPTION, "description"), + optionalSingle(PREFIX_TIMESTAMP, "timestamp"), + optionalMultiple(PREFIX_TAG, "tag"), + optionalMultiple(PREFIX_CONTACT, "contact_name") + ).withExample( + filled(PREFIX_PREAMBLE, "Do homework"), + filled(PREFIX_DESCRIPTION, "Physics assignment"), + filled(PREFIX_TIMESTAMP, "25-12-2020") + ); private final Task task; diff --git a/src/main/java/seedu/address/logic/commands/task/DeleteTaskCommand.java b/src/main/java/seedu/address/logic/commands/task/DeleteTaskCommand.java index f7530c23a9f..c91b06264fe 100644 --- a/src/main/java/seedu/address/logic/commands/task/DeleteTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/task/DeleteTaskCommand.java @@ -1,15 +1,18 @@ package seedu.address.logic.commands.task; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.List; -import java.util.function.Predicate; import seedu.address.commons.core.Messages; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.TaskCommand; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.task.Task; @@ -20,10 +23,14 @@ public class DeleteTaskCommand extends TaskCommand { public static final String COMMAND_WORD = "delete"; public static final String FULL_COMMAND_WORD = TaskCommand.COMMAND_WORD + " " + COMMAND_WORD; public static final String MESSAGE_SUCCESS = "Deleted task: %1$s"; - public static final String MESSAGE_USAGE = FULL_COMMAND_WORD - + ": Deletes the task identified by the index number used in the displayed task list.\n" - + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + FULL_COMMAND_WORD + " 1"; + + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + FULL_COMMAND_WORD, + "Deletes the task identified by the index number used in the displayed task list.", + requiredSingle(PREFIX_PREAMBLE, "index") + ).withExample( + filled(PREFIX_PREAMBLE, "1") + ); private final Index targetIndex; @@ -71,7 +78,6 @@ public int hashCode() { @Override public CommandResult undo(Model model) throws CommandException { super.canUndo(); - Predicate predicate = model.getFilteredTaskPredicate(); model.insertTask(deletedTask, targetIndex.getZeroBased()); return new CommandResult(String.format(MESSAGE_SUCCESS, deletedTask)); } diff --git a/src/main/java/seedu/address/logic/commands/task/DoneTaskCommand.java b/src/main/java/seedu/address/logic/commands/task/DoneTaskCommand.java index 4a345044697..9785e948725 100644 --- a/src/main/java/seedu/address/logic/commands/task/DoneTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/task/DoneTaskCommand.java @@ -1,6 +1,9 @@ package seedu.address.logic.commands.task; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.List; @@ -9,6 +12,7 @@ import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.TaskCommand; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.task.Task; @@ -20,9 +24,14 @@ public class DoneTaskCommand extends TaskCommand { public static final String FULL_COMMAND_WORD = TaskCommand.COMMAND_WORD + " " + COMMAND_WORD; public static final String MESSAGE_SUCCESS = "Task completed: %1$s"; public static final String MESSAGE_UNDONE = "Task has been undone: %1$s"; - public static final String MESSAGE_USAGE = - FULL_COMMAND_WORD + ": Completes an existing task in the task list.\n" - + "Parameters: INDEX (must be a positive integer) " + "Example: " + FULL_COMMAND_WORD + " 1"; + + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + FULL_COMMAND_WORD, + "Completes an existing task in the displayed task list.", + requiredSingle(PREFIX_PREAMBLE, "index") + ).withExample( + filled(PREFIX_PREAMBLE, "1") + ); private final Index index; private Task completedTask; diff --git a/src/main/java/seedu/address/logic/commands/task/EditTaskCommand.java b/src/main/java/seedu/address/logic/commands/task/EditTaskCommand.java index d51f2422564..f9c27f2b938 100644 --- a/src/main/java/seedu/address/logic/commands/task/EditTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/task/EditTaskCommand.java @@ -2,9 +2,14 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_DESCRIPTION; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIMESTAMP; import static seedu.address.logic.parser.CliSyntax.PREFIX_TITLE; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.optionalMultiple; +import static seedu.address.logic.parser.CommandArgument.optionalSingle; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.Collections; import java.util.HashSet; @@ -18,6 +23,7 @@ import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.TaskCommand; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.tag.Tag; import seedu.address.model.task.Contact; @@ -28,20 +34,24 @@ * Edits the details of an existing task in the address book. */ public class EditTaskCommand extends TaskCommand { - public static final String COMMAND_WORD = "edit"; public static final String FULL_COMMAND_WORD = TaskCommand.COMMAND_WORD + " " + COMMAND_WORD; - public static final String MESSAGE_USAGE = - COMMAND_WORD + ": Edits the details of the task identified " - + "by the index number used in the displayed task list. " - + "Existing values will be overwritten by the input values.\n" - + "Parameters: INDEX (must be a positive integer) " - + "[" + PREFIX_TITLE + "TITLE] " - + "[" + PREFIX_DESCRIPTION + "DESCRIPTION] " - + "[" + PREFIX_TIMESTAMP + "TIMESTAMP] " - + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " - + FULL_COMMAND_WORD + " 1 " + PREFIX_DESCRIPTION - + "Physics assignment " + PREFIX_TIMESTAMP + "25/12/2020"; + + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + FULL_COMMAND_WORD, + "Edits the details of the task identified by the index number used in the displayed task list.\n" + + "Existing values will be overwritten by the input values.", + requiredSingle(PREFIX_PREAMBLE, "index"), + optionalSingle(PREFIX_TITLE, "title"), + optionalSingle(PREFIX_DESCRIPTION, "description"), + optionalSingle(PREFIX_TIMESTAMP, "timestamp"), + optionalMultiple(PREFIX_TAG, "tag") + ).withExample( + filled(PREFIX_PREAMBLE, "1"), + filled(PREFIX_DESCRIPTION, "Physics assignment"), + filled(PREFIX_TIMESTAMP, "25-12-2020") + ); + public static final String MESSAGE_EDIT_TASK_SUCCESS = "Edited Task: %1$s"; public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; diff --git a/src/main/java/seedu/address/logic/commands/task/FindTaskCommand.java b/src/main/java/seedu/address/logic/commands/task/FindTaskCommand.java index 6d4c7061856..b11c2373edb 100644 --- a/src/main/java/seedu/address/logic/commands/task/FindTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/task/FindTaskCommand.java @@ -1,6 +1,9 @@ package seedu.address.logic.commands.task; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.Optional; @@ -8,6 +11,7 @@ import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.TaskCommand; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.task.TaskContainsKeywordsPredicate; import seedu.address.model.task.filters.KeywordTaskFilter; @@ -19,11 +23,14 @@ public class FindTaskCommand extends TaskCommand { public static final String COMMAND_WORD = "find"; public static final String FULL_COMMAND_WORD = TaskCommand.COMMAND_WORD + " " + COMMAND_WORD; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all tasks whose names or description " - + "contain any of the specified keywords (case-insensitive) and displays them as a list with " - + "index numbers.\n" - + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" - + "Example: " + FULL_COMMAND_WORD + " CS2103 CS2106 PC3130"; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + FULL_COMMAND_WORD, + "Finds all tasks whose names or description contain any of the specified keywords (case-insensitive)\n" + + "and displays them as a list with index numbers.", + requiredSingle(PREFIX_PREAMBLE, "KEYWORD [MORE_KEYWORDS]...") + ).withExample( + filled(PREFIX_PREAMBLE, "CS2103 CS2106 PC3130") + ); private final TaskContainsKeywordsPredicate predicate; private TaskFilter prevPredicate; diff --git a/src/main/java/seedu/address/logic/commands/task/ListTaskCommand.java b/src/main/java/seedu/address/logic/commands/task/ListTaskCommand.java index 9c6f02362bf..cee7a0ff96f 100644 --- a/src/main/java/seedu/address/logic/commands/task/ListTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/task/ListTaskCommand.java @@ -4,12 +4,16 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_DONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_UNDONE; +import static seedu.address.logic.parser.CommandArgument.filled; +import static seedu.address.logic.parser.CommandArgument.optionalMultiple; +import static seedu.address.logic.parser.CommandArgument.optionalSingle; import java.util.List; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.TaskCommand; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.task.filters.TaskFilter; @@ -20,13 +24,17 @@ public class ListTaskCommand extends TaskCommand { public static final String COMMAND_WORD = "list"; public static final String FULL_COMMAND_WORD = TaskCommand.COMMAND_WORD + " " + COMMAND_WORD; public static final String MESSAGE_SUCCESS = "Task list updated"; - public static final String MESSAGE_USAGE = FULL_COMMAND_WORD - + ": Lists tasks matching the given search conditions.\n" - + "Parameters: " - + "[" + PREFIX_DONE + "] " - + "[" + PREFIX_UNDONE + "] " - + "[" + PREFIX_TAG + "TAG]...\n" - + "Example: " + FULL_COMMAND_WORD + " " + PREFIX_UNDONE + " " + PREFIX_TAG + "important"; + + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + FULL_COMMAND_WORD, + "List tasks matching the given search conditions.", + optionalSingle(PREFIX_DONE), + optionalSingle(PREFIX_UNDONE), + optionalMultiple(PREFIX_TAG, "tag") + ).withExample( + filled(PREFIX_UNDONE, ""), + filled(PREFIX_TAG, "important") + ); private final List taskFilters; diff --git a/src/main/java/seedu/address/logic/commands/task/PurgeTaskCommand.java b/src/main/java/seedu/address/logic/commands/task/PurgeTaskCommand.java index 1ff26839d73..6193d78e3d7 100644 --- a/src/main/java/seedu/address/logic/commands/task/PurgeTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/task/PurgeTaskCommand.java @@ -9,6 +9,7 @@ import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.TaskCommand; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.parser.CommandSpecification; import seedu.address.model.Model; import seedu.address.model.task.Task; import seedu.address.model.task.filters.TaskFilter; @@ -19,11 +20,13 @@ public class PurgeTaskCommand extends TaskCommand { public static final String COMMAND_WORD = "purge"; public static final String FULL_COMMAND_WORD = TaskCommand.COMMAND_WORD + " " + COMMAND_WORD; + public static final CommandSpecification COMMAND_SPECS = new CommandSpecification( + FULL_COMMAND_WORD, + "Purges all tasks in the displayed task list." + ); + public static final String MESSAGE_SUCCESS = "Tasks purged!"; public static final String MESSAGE_NO_TASK_TO_PURGE = "There are no tasks to purge."; - public static final String MESSAGE_USAGE = FULL_COMMAND_WORD - + ": Purges all tasks in the displayed task list.\n" - + "Example: " + FULL_COMMAND_WORD; private TreeMap deletedTasks; private ArrayList deletedFilters; diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 487915c3026..025814b080f 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -1,18 +1,15 @@ package seedu.address.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.AddCommand.COMMAND_SPECS; import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; -import static seedu.address.logic.parser.CommandArgument.optionalMultiple; -import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.Set; import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.parser.exceptions.IllegalPrefixException; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.Address; import seedu.address.model.person.Email; @@ -24,33 +21,24 @@ /** * Parses input arguments and creates a new AddCommand object */ -public class AddCommandParser implements Parser { +public class AddCommandParser extends ArgumentMultimapParser { + + public AddCommandParser() { + super(COMMAND_SPECS); + } /** * Parses the given {@code String} of arguments in the context of the AddCommand * and returns an AddCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ - public AddCommand parse(String args) throws ParseException { - ArgumentMultimap argMultimap; - try { - argMultimap = ArgumentTokenizer.tokenize(args, - requiredSingle(PREFIX_NAME), - requiredSingle(PREFIX_PHONE), - requiredSingle(PREFIX_EMAIL), - requiredSingle(PREFIX_ADDRESS), - optionalMultiple(PREFIX_TAG)); - } catch (IllegalPrefixException e) { - throw new ParseException(String.format(e.getMessage(), AddCommand.MESSAGE_USAGE)); - } catch (ParseException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); - } - - Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()); - Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()); - Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); - Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); - Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + public AddCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { + Name name = ArgumentParser.parseValue(PREFIX_NAME, ParserUtil::parseName, argMultimap, COMMAND_SPECS); + Phone phone = ArgumentParser.parseValue(PREFIX_PHONE, ParserUtil::parsePhone, argMultimap, COMMAND_SPECS); + Email email = ArgumentParser.parseValue(PREFIX_EMAIL, ParserUtil::parseEmail, argMultimap, COMMAND_SPECS); + Address address = ArgumentParser.parseValue(PREFIX_ADDRESS, ParserUtil::parseAddress, argMultimap, + COMMAND_SPECS); + Set tagList = ArgumentParser.parseAllValues(PREFIX_TAG, ParserUtil::parseTags, argMultimap, COMMAND_SPECS); Person person = new Person(name, phone, email, address, tagList); diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index a1b73a94541..19a68eb83bc 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -2,6 +2,7 @@ import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; +import static seedu.address.logic.commands.HelpCommand.COMMAND_SPECS; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -23,7 +24,7 @@ /** * Parses user input. */ -public class AddressBookParser { +public class AddressBookParser implements Parser { /** * Used for initial separation of command word and args. @@ -37,10 +38,10 @@ public class AddressBookParser { * @return the command based on the user input * @throws ParseException if the user input does not conform the expected format */ - public Command parseCommand(String userInput) throws ParseException { + public Command parse(String userInput) throws ParseException { final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(userInput.trim()); if (!matcher.matches()) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE)); + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, COMMAND_SPECS.getUsageMessage())); } final String commandWord = matcher.group("commandWord"); @@ -57,25 +58,25 @@ public Command parseCommand(String userInput) throws ParseException { return new DeleteCommandParser().parse(arguments); case ClearCommand.COMMAND_WORD: - return new NoArgumentCommandParser<>(ClearCommand.class, ClearCommand.MESSAGE_USAGE).parse(arguments); + return new NoArgumentCommandParser<>(ClearCommand.class, ClearCommand.COMMAND_SPECS).parse(arguments); case FindCommand.COMMAND_WORD: return new FindCommandParser().parse(arguments); case ListCommand.COMMAND_WORD: - return new NoArgumentCommandParser<>(ListCommand.class, ListCommand.MESSAGE_USAGE).parse(arguments); + return new NoArgumentCommandParser<>(ListCommand.class, ListCommand.COMMAND_SPECS).parse(arguments); case ExitCommand.COMMAND_WORD: - return new NoArgumentCommandParser<>(ExitCommand.class, ExitCommand.MESSAGE_USAGE).parse(arguments); + return new NoArgumentCommandParser<>(ExitCommand.class, ExitCommand.COMMAND_SPECS).parse(arguments); case HelpCommand.COMMAND_WORD: - return new NoArgumentCommandParser<>(HelpCommand.class, HelpCommand.MESSAGE_USAGE).parse(arguments); + return new NoArgumentCommandParser<>(HelpCommand.class, COMMAND_SPECS).parse(arguments); case UndoCommand.COMMAND_WORD: - return new NoArgumentCommandParser<>(UndoCommand.class, UndoCommand.MESSAGE_USAGE).parse(arguments); + return new NoArgumentCommandParser<>(UndoCommand.class, UndoCommand.COMMAND_SPECS).parse(arguments); case RedoCommand.COMMAND_WORD: - return new NoArgumentCommandParser<>(RedoCommand.class, RedoCommand.MESSAGE_USAGE).parse(arguments); + return new NoArgumentCommandParser<>(RedoCommand.class, RedoCommand.COMMAND_SPECS).parse(arguments); // Every command starting with "task" delegated to TaskCommandParser case TaskCommand.COMMAND_WORD: diff --git a/src/main/java/seedu/address/logic/parser/ArgumentMultimapParser.java b/src/main/java/seedu/address/logic/parser/ArgumentMultimapParser.java new file mode 100644 index 00000000000..c4f64a0d8ef --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/ArgumentMultimapParser.java @@ -0,0 +1,26 @@ +package seedu.address.logic.parser; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Represents a Parser that is able to parse user input into a {@code Command} of type {@code T}. + */ +public abstract class ArgumentMultimapParser implements Parser { + private final ArgumentTokenizer argumentTokenizer; + + public ArgumentMultimapParser(CommandSpecification specs) { + argumentTokenizer = new ArgumentTokenizer(specs); + } + + @Override + public T parse(String userInput) throws ParseException { + return parseArgumentMultimap(argumentTokenizer.tokenize(userInput)); + } + + /** + * Parses {@code userInput} into a command and returns it. + * @throws ParseException if {@code userInput} does not conform to the expected format + */ + public abstract T parseArgumentMultimap(ArgumentMultimap argumentMultimap) throws ParseException; +} diff --git a/src/main/java/seedu/address/logic/parser/ArgumentParser.java b/src/main/java/seedu/address/logic/parser/ArgumentParser.java new file mode 100644 index 00000000000..a713ce6c738 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/ArgumentParser.java @@ -0,0 +1,101 @@ +package seedu.address.logic.parser; + +import java.util.List; +import java.util.Optional; + +import seedu.address.logic.parser.exceptions.InvalidCommandArgumentFormatException; +import seedu.address.logic.parser.exceptions.ParseException; + +@FunctionalInterface +public interface ArgumentParser { + T parse(S argString) throws ParseException; + + + /** + * Parses a value from the given argument multimap matching the given prefix, supplied to the command specified by + * {@code specs}, using the given parser. + * Returns null if the value was not provided as an argument. + * + * @param prefix The prefix to obtain the argument from + * @param parser The function used to parse the function + * @param argMultimap The argument multimap containing all parsed arguments + * @param specs The specifications of the command to which the value is an argument of + * @param The type of the parsed argument + * @return a parsed value representing the parsed argument + * @throws ParseException If the parse throws a {@link ParseException} + */ + static T parseValue( + Prefix prefix, + ArgumentParser parser, + ArgumentMultimap argMultimap, + CommandSpecification specs + ) throws ParseException { + try { + assert argMultimap.contains(prefix); + return parser.parse(argMultimap.getValue(prefix).orElseThrow()); + } catch (ParseException e) { + throw new InvalidCommandArgumentFormatException(specs.getCommandArgumentWithPrefix(prefix), e.getMessage(), + specs); + } + } + + /** + * Parses an optional value from the given argument multimap matching the given prefix, supplied to the command + * specified by + * {@code specs}, using the given parser. + * Returns null if the value was not provided as an argument. + * + * @param prefix The prefix to obtain the argument from + * @param parser The function used to parse the function + * @param argMultimap The argument multimap containing all parsed arguments + * @param specs The specifications of the command to which the value is an argument of + * @param The type of the parsed argument + * @return an optional parsed value representing the parsed argument + * @throws ParseException If the parse throws a {@link ParseException} + */ + static Optional parseOptionalValue( + Prefix prefix, + ArgumentParser parser, + ArgumentMultimap argMultimap, + CommandSpecification specs + ) throws ParseException { + try { + if (argMultimap.getValue(prefix).isEmpty()) { + return Optional.empty(); + } else { + return Optional.of(parser.parse(argMultimap.getValue(prefix).get())); + } + } catch (ParseException e) { + throw new InvalidCommandArgumentFormatException(specs.getCommandArgumentWithPrefix(prefix), + e.getMessage(), specs); + } + } + + + /** + * Parses all values from the given argument multimap matching the given prefix, supplied to the command + * specified by {@code specs}, using the given parser. + * Returns null if the value was not provided as an argument. + * + * @param prefix The prefix to obtain the argument from + * @param parser The function used to parse the function + * @param argMultimap The argument multimap containing all parsed arguments + * @param specs The specifications of the command to which the value is an argument of + * @param The type of the parsed argument + * @return a value representing the parsed arguments + * @throws ParseException If the parse throws a {@link ParseException} + */ + static T parseAllValues( + Prefix prefix, + ArgumentParser, ? extends T> parser, + ArgumentMultimap argMultimap, + CommandSpecification specs + ) throws ParseException { + try { + return parser.parse(argMultimap.getAllValues(prefix)); + } catch (ParseException e) { + throw new InvalidCommandArgumentFormatException(specs.getCommandArgumentWithPrefix(prefix), + e.getMessage(), specs); + } + } +} diff --git a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java b/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java index 8ea4e712086..8b33277d3fc 100644 --- a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java +++ b/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java @@ -7,12 +7,11 @@ import java.util.regex.Matcher; import seedu.address.logic.parser.exceptions.ArgumentContainsSlashException; -import seedu.address.logic.parser.exceptions.MissingPreambleException; -import seedu.address.logic.parser.exceptions.MissingPrefixException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.logic.parser.exceptions.TooManyPrefixesException; +import seedu.address.logic.parser.exceptions.UnwantedCommandArgumentException; import seedu.address.logic.parser.exceptions.UnwantedPreambleException; -import seedu.address.logic.parser.exceptions.UnwantedPrefixException; /** * Tokenizes arguments string of the form: {@code preamble value value ...}
@@ -23,17 +22,31 @@ * in the above example.
*/ public class ArgumentTokenizer { + private final CommandSpecification specs; + private final List argumentList; + + /** + * Creates an ArgumentTokenizer that parses arguments specified by the given command specifications, + * @param specs The command specifications to parse arguments according to + */ + public ArgumentTokenizer(CommandSpecification specs) { + this.specs = specs; + argumentList = specs.getCommandArguments(); + } + + private CommandArgument getCommandArgumentWithPrefix(Prefix prefix) { + return Optional.ofNullable( + specs.getCommandArgumentWithPrefix(prefix)).orElseGet(() -> CommandArgument.unknown(prefix)); + } /** * Tokenizes an arguments string and returns an {@code ArgumentMultimap} object that maps prefixes to their * respective argument values. Only the given prefixes will be recognized in the arguments string. * * @param argsString Arguments string of the form: {@code preamble value value ...} - * @param arguments the arguments expected to appear in the argsString * @return ArgumentMultimap object that maps prefixes to their arguments */ - public static ArgumentMultimap tokenize(String argsString, CommandArgument... arguments) throws ParseException { - List argumentList = List.of(arguments); + public ArgumentMultimap tokenize(String argsString) throws ParseException { Matcher matcher = CliSyntax.PREFIX_PATTERN.matcher(argsString); ArgumentMultimap argumentMultimap = new ArgumentMultimap(); @@ -56,7 +69,7 @@ public static ArgumentMultimap tokenize(String argsString, CommandArgument... ar Prefix prefix = new Prefix(prefixString); if (value.contains("/")) { - throw new ArgumentContainsSlashException(prefix); + throw new ArgumentContainsSlashException(getCommandArgumentWithPrefix(prefix), specs); } argumentMultimap.put(prefix, value); } @@ -69,13 +82,13 @@ public static ArgumentMultimap tokenize(String argsString, CommandArgument... ar .filter(p -> !argumentMultimap.contains(p)) .findAny(); if (missingPrefix.isPresent()) { - throw new MissingPrefixException(missingPrefix.get()); + throw new MissingCommandArgumentException(getCommandArgumentWithPrefix(missingPrefix.get()), specs); } String preamble = argsString.substring(0, preambleEnd).trim(); if (preamble.contains("/")) { - throw new ArgumentContainsSlashException(PREFIX_PREAMBLE); + throw new ArgumentContainsSlashException(getCommandArgumentWithPrefix(PREFIX_PREAMBLE), specs); } // Check for unwanted preamble @@ -83,7 +96,7 @@ public static ArgumentMultimap tokenize(String argsString, CommandArgument... ar boolean isPreambleExpected = argumentList.stream().map(CommandArgument::getPrefix) .anyMatch(p -> p.equals(PREFIX_PREAMBLE)); if (!isPreambleExpected) { - throw new UnwantedPreambleException(preamble); + throw new UnwantedPreambleException(preamble, specs); } argumentMultimap.put(PREFIX_PREAMBLE, preamble); } else { @@ -93,7 +106,7 @@ public static ArgumentMultimap tokenize(String argsString, CommandArgument... ar .equals(PREFIX_PREAMBLE)); // Check for missing preamble if (isPreambleRequired) { - throw new MissingPreambleException(); + throw new MissingCommandArgumentException(getCommandArgumentWithPrefix(PREFIX_PREAMBLE), specs); } } @@ -103,10 +116,10 @@ public static ArgumentMultimap tokenize(String argsString, CommandArgument... ar .findFirst(); if (argument.isEmpty()) { // Argument not in expected list - throw new UnwantedPrefixException(prefix); + throw new UnwantedCommandArgumentException(getCommandArgumentWithPrefix(prefix), specs); } else { if (!argument.get().isMultiple() && argumentMultimap.getAllValues(prefix).size() > 1) { - throw new TooManyPrefixesException(prefix); + throw new TooManyPrefixesException(getCommandArgumentWithPrefix(prefix), specs); } } } diff --git a/src/main/java/seedu/address/logic/parser/CommandArgument.java b/src/main/java/seedu/address/logic/parser/CommandArgument.java index b17f5723cb6..424c3b51820 100644 --- a/src/main/java/seedu/address/logic/parser/CommandArgument.java +++ b/src/main/java/seedu/address/logic/parser/CommandArgument.java @@ -1,26 +1,57 @@ package seedu.address.logic.parser; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; + +import java.util.Optional; + public class CommandArgument { + private final String name; private final Prefix prefix; private final boolean isRequired; private final boolean isMultiple; - private CommandArgument(Prefix prefix, boolean isRequired, boolean isMultiple) { + protected CommandArgument(String name, Prefix prefix, boolean isRequired, boolean isMultiple) { + assert (name != null || !prefix.equals(PREFIX_PREAMBLE)); + this.name = name; this.prefix = prefix; this.isRequired = isRequired; this.isMultiple = isMultiple; } public static CommandArgument requiredSingle(Prefix prefix) { - return new CommandArgument(prefix, true, false); + return requiredSingle(prefix, null); + } + + public static CommandArgument requiredSingle(Prefix prefix, String name) { + return new CommandArgument(name, prefix, true, false); } public static CommandArgument optionalSingle(Prefix prefix) { - return new CommandArgument(prefix, false, false); + return optionalSingle(prefix, null); + } + + public static CommandArgument optionalSingle(Prefix prefix, String name) { + return new CommandArgument(name, prefix, false, false); } public static CommandArgument optionalMultiple(Prefix prefix) { - return new CommandArgument(prefix, false, true); + return optionalMultiple(prefix, null); + } + + public static CommandArgument optionalMultiple(Prefix prefix, String name) { + return new CommandArgument(name, prefix, false, true); + } + + public static CommandArgument unknown(Prefix prefix) { + return new CommandArgument(null, prefix, false, false); + } + + public static FilledCommandArgument filled(Prefix prefix, String value) { + return new FilledCommandArgument(prefix, value); + } + + public String getName() { + return name; } public Prefix getPrefix() { @@ -34,4 +65,19 @@ public boolean isRequired() { public boolean isMultiple() { return isMultiple; } + + @Override + public String toString() { + String baseString = prefix.getPrefix() + Optional.ofNullable(name).orElse(""); + if (isRequired) { + return baseString; + } else { + String optionalBaseString = "[" + baseString + "]"; + if (isMultiple) { + return optionalBaseString + "..."; + } else { + return optionalBaseString; + } + } + } } diff --git a/src/main/java/seedu/address/logic/parser/CommandSpecification.java b/src/main/java/seedu/address/logic/parser/CommandSpecification.java new file mode 100644 index 00000000000..87b4e48709f --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/CommandSpecification.java @@ -0,0 +1,62 @@ +package seedu.address.logic.parser; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class CommandSpecification { + private final String word; + private final String description; + private final List commandArguments; + private final List exampleCommands; + + /** + * Creates a specification of a command, with the word used to invoke the command, a description of the command, + * and a list of arguments to be supplied to the command. + * + * @param word The word used to invoke the command + * @param description The description of the command + * @param commandArguments The arguments to be supplied to the command + */ + public CommandSpecification(String word, String description, CommandArgument... commandArguments) { + this.word = word; + this.description = description; + this.commandArguments = List.of(commandArguments); + this.exampleCommands = new ArrayList<>(); + } + + /** + * Returns the command specification with an example of a command execution added to it. + * @param filledCommandArguments A list of filled arguments representing the example command + * @return The same command specification, with an example of a command execution added to it + */ + public CommandSpecification withExample(FilledCommandArgument... filledCommandArguments) { + String exampleCommand = word + " " + Arrays.stream(filledCommandArguments) + .map(FilledCommandArgument::toString) + .collect(Collectors.joining(" ")); + exampleCommands.add(exampleCommand); + return this; + } + + public List getCommandArguments() { + return commandArguments; + } + + public CommandArgument getCommandArgumentWithPrefix(Prefix prefix) { + return commandArguments.stream() + .filter(argument -> argument.getPrefix().equals(prefix)).findFirst().orElse(null); + } + + public String getUsageMessage() { + List lines = new ArrayList<>(); + lines.add(word + ": " + description); + lines.add(word + " " + getCommandArguments().stream().map(CommandArgument::toString) + .collect(Collectors.joining(" "))); + if (!exampleCommands.isEmpty()) { + lines.add("Examples:"); + lines.addAll(exampleCommands); + } + return String.join("\n", lines); + } +} diff --git a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java index 582e07bef94..197442d66bc 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java @@ -1,6 +1,7 @@ package seedu.address.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.DeleteCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.DeleteCommand; @@ -9,21 +10,15 @@ /** * Parses input arguments and creates a new DeleteCommand object */ -public class DeleteCommandParser implements Parser { +public class DeleteCommandParser extends ArgumentMultimapParser { + public DeleteCommandParser() { + super(COMMAND_SPECS); + } - /** - * Parses the given {@code String} of arguments in the context of the DeleteCommand - * and returns a DeleteCommand object for execution. - * @throws ParseException if the user input does not conform to the expected format - */ - public DeleteCommand parse(String args) throws ParseException { - try { - Index index = ParserUtil.parseIndex(args); - return new DeleteCommand(index); - } catch (ParseException pe) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), pe); - } + @Override + public DeleteCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { + Index index = ArgumentParser.parseValue(PREFIX_PREAMBLE, ParserUtil::parseIndex, argMultimap, COMMAND_SPECS); + return new DeleteCommand(index); } } diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index 6e6a2a6a92b..5c5660a1f37 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java @@ -1,17 +1,13 @@ package seedu.address.logic.parser; -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.commands.EditCommand.MESSAGE_USAGE; +import static seedu.address.logic.commands.EditCommand.COMMAND_SPECS; +import static seedu.address.logic.commands.EditCommand.MESSAGE_NOT_EDITED; import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; -import static seedu.address.logic.parser.CommandArgument.optionalMultiple; -import static seedu.address.logic.parser.CommandArgument.optionalSingle; -import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.Collection; import java.util.Collections; @@ -21,59 +17,45 @@ import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.logic.parser.exceptions.IllegalPrefixException; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.person.Address; +import seedu.address.model.person.Email; +import seedu.address.model.person.Name; +import seedu.address.model.person.Phone; import seedu.address.model.tag.Tag; /** * Parses input arguments and creates a new EditCommand object */ -public class EditCommandParser implements Parser { - - /** - * Parses the given {@code String} of arguments in the context of the EditCommand - * and returns an EditCommand object for execution. - * @throws ParseException if the user input does not conform the expected format - */ - public EditCommand parse(String args) throws ParseException { - requireNonNull(args); - ArgumentMultimap argMultimap; - Index index; +public class EditCommandParser extends ArgumentMultimapParser { + public EditCommandParser() { + super(COMMAND_SPECS); + } - try { - argMultimap = - ArgumentTokenizer.tokenize(args, - requiredSingle(PREFIX_PREAMBLE), - optionalSingle(PREFIX_NAME), - optionalSingle(PREFIX_PHONE), - optionalSingle(PREFIX_EMAIL), - optionalSingle(PREFIX_ADDRESS), - optionalMultiple(PREFIX_TAG)); + @Override + public EditCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { + EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); - index = ParserUtil.parseIndex(argMultimap.getPreamble()); - } catch (IllegalPrefixException e) { - throw new ParseException(String.format(e.getMessage(), MESSAGE_USAGE), e); - } catch (ParseException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - } + Index index = ArgumentParser.parseValue(PREFIX_PREAMBLE, ParserUtil::parseIndex, argMultimap, COMMAND_SPECS); + Optional name = ArgumentParser.parseOptionalValue(PREFIX_NAME, ParserUtil::parseName, argMultimap, + COMMAND_SPECS); + Optional phone = ArgumentParser.parseOptionalValue(PREFIX_PHONE, ParserUtil::parsePhone, argMultimap, + COMMAND_SPECS); + Optional email = ArgumentParser.parseOptionalValue(PREFIX_EMAIL, ParserUtil::parseEmail, argMultimap, + COMMAND_SPECS); + Optional
address = ArgumentParser.parseOptionalValue(PREFIX_ADDRESS, ParserUtil::parseAddress, + argMultimap, COMMAND_SPECS); + Optional> tags = ArgumentParser.parseAllValues(PREFIX_TAG, EditCommandParser::parseTagsForEdit, + argMultimap, COMMAND_SPECS); - EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); - if (argMultimap.getValue(PREFIX_NAME).isPresent()) { - editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get())); - } - if (argMultimap.getValue(PREFIX_PHONE).isPresent()) { - editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get())); - } - if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) { - editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get())); - } - if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) { - editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get())); - } - parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); + name.ifPresent(editPersonDescriptor::setName); + phone.ifPresent(editPersonDescriptor::setPhone); + email.ifPresent(editPersonDescriptor::setEmail); + address.ifPresent(editPersonDescriptor::setAddress); + tags.ifPresent(editPersonDescriptor::setTags); if (!editPersonDescriptor.isAnyFieldEdited()) { - throw new ParseException(EditCommand.MESSAGE_NOT_EDITED); + throw new ParseException(MESSAGE_NOT_EDITED + "\n" + COMMAND_SPECS.getUsageMessage()); } return new EditCommand(index, editPersonDescriptor); @@ -84,7 +66,7 @@ public EditCommand parse(String args) throws ParseException { * If {@code tags} contain only one element which is an empty string, it will be parsed into a * {@code Set} containing zero tags. */ - private Optional> parseTagsForEdit(Collection tags) throws ParseException { + private static Optional> parseTagsForEdit(Collection tags) throws ParseException { assert tags != null; if (tags.isEmpty()) { diff --git a/src/main/java/seedu/address/logic/parser/FilledCommandArgument.java b/src/main/java/seedu/address/logic/parser/FilledCommandArgument.java new file mode 100644 index 00000000000..a4c289ae3f1 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/FilledCommandArgument.java @@ -0,0 +1,12 @@ +package seedu.address.logic.parser; + +public class FilledCommandArgument extends CommandArgument { + protected FilledCommandArgument(Prefix prefix, String value) { + super(value, prefix, false, false); + } + + @Override + public String toString() { + return getPrefix().getPrefix() + getName(); + } +} diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index 4fb71f23103..5954fa3783c 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java @@ -1,6 +1,7 @@ package seedu.address.logic.parser; import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.FindCommand.COMMAND_SPECS; import java.util.Arrays; @@ -11,18 +12,22 @@ /** * Parses input arguments and creates a new FindCommand object */ -public class FindCommandParser implements Parser { +public class FindCommandParser extends ArgumentMultimapParser { + + public FindCommandParser() { + super(COMMAND_SPECS); + } /** * Parses the given {@code String} of arguments in the context of the FindCommand * and returns a FindCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ - public FindCommand parse(String args) throws ParseException { - String trimmedArgs = args.trim(); + public FindCommand parseArgumentMultimap(ArgumentMultimap argumentMultimap) throws ParseException { + String trimmedArgs = argumentMultimap.getPreamble(); if (trimmedArgs.isEmpty()) { throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, COMMAND_SPECS.getUsageMessage())); } String[] nameKeywords = trimmedArgs.split("\\s+"); diff --git a/src/main/java/seedu/address/logic/parser/NoArgumentCommandParser.java b/src/main/java/seedu/address/logic/parser/NoArgumentCommandParser.java index fc048aacfa0..c46590ab461 100644 --- a/src/main/java/seedu/address/logic/parser/NoArgumentCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/NoArgumentCommandParser.java @@ -1,32 +1,26 @@ package seedu.address.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; - import java.lang.reflect.InvocationTargetException; import seedu.address.logic.commands.Command; -import seedu.address.logic.parser.exceptions.IllegalPrefixException; import seedu.address.logic.parser.exceptions.ParseException; -public class NoArgumentCommandParser implements Parser { +public class NoArgumentCommandParser extends ArgumentMultimapParser { private final Class commandClass; - private final String commandUsage; /** * Creates a command parser that parses commands that do not accept any arguments. * Checks for validity of arguments by running provided arguments through {@link ArgumentTokenizer}. * - * @param commandClass The class of the command to create - * @param commandUsage The command usage text of the command + * @param specs The specifications of the command */ - public NoArgumentCommandParser(Class commandClass, String commandUsage) { + public NoArgumentCommandParser(Class commandClass, CommandSpecification specs) { + super(specs); this.commandClass = commandClass; - this.commandUsage = commandUsage; } @Override - public C parse(String args) throws ParseException { - assertEmptyArguments(args); + public C parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { try { return commandClass.getDeclaredConstructor().newInstance(); } catch (InstantiationException @@ -38,14 +32,4 @@ public C parse(String args) throws ParseException { return null; } } - - private void assertEmptyArguments(String args) throws ParseException { - try { - ArgumentTokenizer.tokenize(args); - } catch (IllegalPrefixException e) { - throw new ParseException(String.format(e.getMessage(), commandUsage)); - } catch (ParseException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, commandUsage)); - } - } } diff --git a/src/main/java/seedu/address/logic/parser/Parser.java b/src/main/java/seedu/address/logic/parser/Parser.java index 51c6cd44e83..06cc4940b21 100644 --- a/src/main/java/seedu/address/logic/parser/Parser.java +++ b/src/main/java/seedu/address/logic/parser/Parser.java @@ -3,11 +3,7 @@ import seedu.address.logic.commands.Command; import seedu.address.logic.parser.exceptions.ParseException; -/** - * Represents a Parser that is able to parse user input into a {@code Command} of type {@code T}. - */ public interface Parser { - /** * Parses {@code userInput} into a command and returns it. * @throws ParseException if {@code userInput} does not conform to the expected format diff --git a/src/main/java/seedu/address/logic/parser/TaskCommandParser.java b/src/main/java/seedu/address/logic/parser/TaskCommandParser.java index 78bd75a3f73..f39ec43deb9 100644 --- a/src/main/java/seedu/address/logic/parser/TaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/TaskCommandParser.java @@ -36,7 +36,8 @@ public class TaskCommandParser implements Parser { public TaskCommand parse(String userInput) throws ParseException { final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(userInput.trim()); if (!matcher.matches()) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE)); + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + HelpCommand.COMMAND_SPECS.getUsageMessage())); } final String commandWord = matcher.group("commandWord"); @@ -59,7 +60,7 @@ public TaskCommand parse(String userInput) throws ParseException { return new ListTaskCommandParser().parse(arguments); case PurgeTaskCommand.COMMAND_WORD: - return new NoArgumentCommandParser<>(PurgeTaskCommand.class, PurgeTaskCommand.FULL_COMMAND_WORD) + return new NoArgumentCommandParser<>(PurgeTaskCommand.class, PurgeTaskCommand.COMMAND_SPECS) .parse(arguments); case FindTaskCommand.COMMAND_WORD: diff --git a/src/main/java/seedu/address/logic/parser/exceptions/ArgumentContainsSlashException.java b/src/main/java/seedu/address/logic/parser/exceptions/ArgumentContainsSlashException.java index a57a9123035..cb55e3e6582 100644 --- a/src/main/java/seedu/address/logic/parser/exceptions/ArgumentContainsSlashException.java +++ b/src/main/java/seedu/address/logic/parser/exceptions/ArgumentContainsSlashException.java @@ -1,9 +1,10 @@ package seedu.address.logic.parser.exceptions; -import seedu.address.logic.parser.Prefix; +import seedu.address.logic.parser.CommandArgument; +import seedu.address.logic.parser.CommandSpecification; -public class ArgumentContainsSlashException extends IllegalPrefixException { - public ArgumentContainsSlashException(Prefix prefix) { - super(prefix, "Cannot have / in argument value"); +public class ArgumentContainsSlashException extends IllegalCommandArgumentException { + public ArgumentContainsSlashException(CommandArgument argument, CommandSpecification specs) { + super(String.format("Cannot have / in the value of %s.", argument.getName()), specs); } } diff --git a/src/main/java/seedu/address/logic/parser/exceptions/IllegalCommandArgumentException.java b/src/main/java/seedu/address/logic/parser/exceptions/IllegalCommandArgumentException.java new file mode 100644 index 00000000000..757fb68f748 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/exceptions/IllegalCommandArgumentException.java @@ -0,0 +1,9 @@ +package seedu.address.logic.parser.exceptions; + +import seedu.address.logic.parser.CommandSpecification; + +public abstract class IllegalCommandArgumentException extends ParseException { + protected IllegalCommandArgumentException(String argumentErrorMessage, CommandSpecification specs) { + super(argumentErrorMessage + "\n" + specs.getUsageMessage()); + } +} diff --git a/src/main/java/seedu/address/logic/parser/exceptions/IllegalPrefixException.java b/src/main/java/seedu/address/logic/parser/exceptions/IllegalPrefixException.java deleted file mode 100644 index 546074315b7..00000000000 --- a/src/main/java/seedu/address/logic/parser/exceptions/IllegalPrefixException.java +++ /dev/null @@ -1,16 +0,0 @@ -package seedu.address.logic.parser.exceptions; - -import seedu.address.logic.parser.Prefix; - -public class IllegalPrefixException extends ParseException { - private final Prefix prefix; - - protected IllegalPrefixException(Prefix prefix, String message) { - super(message); - this.prefix = prefix; - } - - public Prefix getPrefix() { - return prefix; - } -} diff --git a/src/main/java/seedu/address/logic/parser/exceptions/InvalidCommandArgumentFormatException.java b/src/main/java/seedu/address/logic/parser/exceptions/InvalidCommandArgumentFormatException.java new file mode 100644 index 00000000000..91e2e7ae935 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/exceptions/InvalidCommandArgumentFormatException.java @@ -0,0 +1,21 @@ +package seedu.address.logic.parser.exceptions; + +import seedu.address.logic.parser.CommandArgument; +import seedu.address.logic.parser.CommandSpecification; + +public class InvalidCommandArgumentFormatException extends IllegalCommandArgumentException { + /** + * Creates an exception representing the case where an argument to a given command has an invalid format. + * + * @param argument The argument with an invalid format + * @param argumentErrorMessage The error message associated with the parsing error + * @param specs The specifications of the command + */ + public InvalidCommandArgumentFormatException( + CommandArgument argument, + String argumentErrorMessage, + CommandSpecification specs + ) { + super(String.format("Error in format of %s: %s", argument.getName(), argumentErrorMessage), specs); + } +} diff --git a/src/main/java/seedu/address/logic/parser/exceptions/MissingCommandArgumentException.java b/src/main/java/seedu/address/logic/parser/exceptions/MissingCommandArgumentException.java new file mode 100644 index 00000000000..404f6994634 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/exceptions/MissingCommandArgumentException.java @@ -0,0 +1,10 @@ +package seedu.address.logic.parser.exceptions; + +import seedu.address.logic.parser.CommandArgument; +import seedu.address.logic.parser.CommandSpecification; + +public class MissingCommandArgumentException extends IllegalCommandArgumentException { + public MissingCommandArgumentException(CommandArgument argument, CommandSpecification specs) { + super(String.format("Missing required argument: %s.", argument), specs); + } +} diff --git a/src/main/java/seedu/address/logic/parser/exceptions/MissingPreambleException.java b/src/main/java/seedu/address/logic/parser/exceptions/MissingPreambleException.java deleted file mode 100644 index bf1cbe31aa4..00000000000 --- a/src/main/java/seedu/address/logic/parser/exceptions/MissingPreambleException.java +++ /dev/null @@ -1,9 +0,0 @@ -package seedu.address.logic.parser.exceptions; - -import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; - -public class MissingPreambleException extends IllegalPrefixException { - public MissingPreambleException() { - super(PREFIX_PREAMBLE, "Missing required preamble!\n%s"); - } -} diff --git a/src/main/java/seedu/address/logic/parser/exceptions/MissingPrefixException.java b/src/main/java/seedu/address/logic/parser/exceptions/MissingPrefixException.java deleted file mode 100644 index be5f774599e..00000000000 --- a/src/main/java/seedu/address/logic/parser/exceptions/MissingPrefixException.java +++ /dev/null @@ -1,9 +0,0 @@ -package seedu.address.logic.parser.exceptions; - -import seedu.address.logic.parser.Prefix; - -public class MissingPrefixException extends IllegalPrefixException { - public MissingPrefixException(Prefix prefix) { - super(prefix, String.format("Missing required prefix: %s\n", prefix) + "%s"); - } -} diff --git a/src/main/java/seedu/address/logic/parser/exceptions/TooManyPrefixesException.java b/src/main/java/seedu/address/logic/parser/exceptions/TooManyPrefixesException.java index f3d3d0db5cf..1065cbb6be1 100644 --- a/src/main/java/seedu/address/logic/parser/exceptions/TooManyPrefixesException.java +++ b/src/main/java/seedu/address/logic/parser/exceptions/TooManyPrefixesException.java @@ -1,9 +1,19 @@ package seedu.address.logic.parser.exceptions; -import seedu.address.logic.parser.Prefix; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; -public class TooManyPrefixesException extends IllegalPrefixException { - public TooManyPrefixesException(Prefix prefix) { - super(prefix, String.format("Too many arguments: %s!\n", prefix) + "%s"); +import seedu.address.logic.parser.CommandArgument; +import seedu.address.logic.parser.CommandSpecification; + +public class TooManyPrefixesException extends IllegalCommandArgumentException { + + /** + * Creates an exception representing the case where too many prefixes are supplied as arguments to a command. + * @param argument The argument with too many prefixes + * @param specs The specifications of the command + */ + public TooManyPrefixesException(CommandArgument argument, CommandSpecification specs) { + super(String.format("Too many arguments for the prefix %s.", argument.getPrefix()), specs); + assert !argument.getPrefix().equals(PREFIX_PREAMBLE); } } diff --git a/src/main/java/seedu/address/logic/parser/exceptions/UnwantedCommandArgumentException.java b/src/main/java/seedu/address/logic/parser/exceptions/UnwantedCommandArgumentException.java new file mode 100644 index 00000000000..fff5ce2b631 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/exceptions/UnwantedCommandArgumentException.java @@ -0,0 +1,10 @@ +package seedu.address.logic.parser.exceptions; + +import seedu.address.logic.parser.CommandArgument; +import seedu.address.logic.parser.CommandSpecification; + +public class UnwantedCommandArgumentException extends IllegalCommandArgumentException { + public UnwantedCommandArgumentException(CommandArgument argument, CommandSpecification specs) { + super(String.format("Unnecessary prefix %s present.", argument.getPrefix()), specs); + } +} diff --git a/src/main/java/seedu/address/logic/parser/exceptions/UnwantedPreambleException.java b/src/main/java/seedu/address/logic/parser/exceptions/UnwantedPreambleException.java index 1cd03101165..3cd6424e94e 100644 --- a/src/main/java/seedu/address/logic/parser/exceptions/UnwantedPreambleException.java +++ b/src/main/java/seedu/address/logic/parser/exceptions/UnwantedPreambleException.java @@ -1,9 +1,9 @@ package seedu.address.logic.parser.exceptions; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; +import seedu.address.logic.parser.CommandSpecification; -public class UnwantedPreambleException extends IllegalPrefixException { - public UnwantedPreambleException(String preamble) { - super(PREFIX_PREAMBLE, String.format("Unnecessary preamble present: %s\n", preamble) + "%s"); +public class UnwantedPreambleException extends IllegalCommandArgumentException { + public UnwantedPreambleException(String preamble, CommandSpecification specs) { + super(String.format("Unnecessary preamble with value \"%s\" present.", preamble), specs); } } diff --git a/src/main/java/seedu/address/logic/parser/exceptions/UnwantedPrefixException.java b/src/main/java/seedu/address/logic/parser/exceptions/UnwantedPrefixException.java deleted file mode 100644 index e31a6abfbbf..00000000000 --- a/src/main/java/seedu/address/logic/parser/exceptions/UnwantedPrefixException.java +++ /dev/null @@ -1,9 +0,0 @@ -package seedu.address.logic.parser.exceptions; - -import seedu.address.logic.parser.Prefix; - -public class UnwantedPrefixException extends IllegalPrefixException { - public UnwantedPrefixException(Prefix prefix) { - super(prefix, String.format("Unnecessary prefix present: %s\n", prefix) + "%s"); - } -} diff --git a/src/main/java/seedu/address/logic/parser/task/AddTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/task/AddTaskCommandParser.java index 1bb8abc5dc5..e3199dc519d 100644 --- a/src/main/java/seedu/address/logic/parser/task/AddTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/task/AddTaskCommandParser.java @@ -1,23 +1,18 @@ package seedu.address.logic.parser.task; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.task.AddTaskCommand.COMMAND_SPECS; import static seedu.address.logic.parser.CliSyntax.PREFIX_CONTACT; import static seedu.address.logic.parser.CliSyntax.PREFIX_DESCRIPTION; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIMESTAMP; -import static seedu.address.logic.parser.CommandArgument.optionalMultiple; -import static seedu.address.logic.parser.CommandArgument.optionalSingle; -import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.Set; import seedu.address.logic.commands.task.AddTaskCommand; import seedu.address.logic.parser.ArgumentMultimap; -import seedu.address.logic.parser.ArgumentTokenizer; -import seedu.address.logic.parser.Parser; +import seedu.address.logic.parser.ArgumentMultimapParser; +import seedu.address.logic.parser.ArgumentParser; import seedu.address.logic.parser.ParserUtil; -import seedu.address.logic.parser.exceptions.IllegalPrefixException; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.tag.Tag; import seedu.address.model.task.Contact; @@ -27,35 +22,20 @@ /** * Parses input arguments and creates a new AddTaskCommand object */ -public class AddTaskCommandParser implements Parser { - @Override - public AddTaskCommand parse(String args) throws ParseException { - ArgumentMultimap argMultimap; - try { - argMultimap = ArgumentTokenizer.tokenize(args, - requiredSingle(PREFIX_PREAMBLE), - optionalSingle(PREFIX_DESCRIPTION), - optionalSingle(PREFIX_TIMESTAMP), - optionalMultiple(PREFIX_TAG), - optionalMultiple(PREFIX_CONTACT) - ); - } catch (IllegalPrefixException e) { - throw new ParseException(String.format(e.getMessage(), AddTaskCommand.MESSAGE_USAGE)); - } catch (ParseException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTaskCommand.MESSAGE_USAGE)); - } +public class AddTaskCommandParser extends ArgumentMultimapParser { + public AddTaskCommandParser() { + super(COMMAND_SPECS); + } + @Override + public AddTaskCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { String title = argMultimap.getPreamble(); String description = argMultimap.getValue(PREFIX_DESCRIPTION).orElse(null); - - Timestamp timestamp; - if (argMultimap.getValue(PREFIX_TIMESTAMP).orElse(null) == null) { - timestamp = null; - } else { - timestamp = ParserUtil.parseTimestamp(argMultimap.getValue(PREFIX_TIMESTAMP).get()); - } - Set tags = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Set contacts = ParserUtil.parseContacts(argMultimap.getAllValues(PREFIX_CONTACT)); + Timestamp timestamp = ArgumentParser.parseOptionalValue(PREFIX_TIMESTAMP, ParserUtil::parseTimestamp, + argMultimap, COMMAND_SPECS).orElse(null); + Set tags = ArgumentParser.parseAllValues(PREFIX_TAG, ParserUtil::parseTags, argMultimap, COMMAND_SPECS); + Set contacts = ArgumentParser.parseAllValues(PREFIX_CONTACT, ParserUtil::parseContacts, argMultimap, + COMMAND_SPECS); return new AddTaskCommand(new Task(title, description, timestamp, tags, contacts)); } diff --git a/src/main/java/seedu/address/logic/parser/task/DeleteTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/task/DeleteTaskCommandParser.java index eec0dfb7599..603ad72a845 100644 --- a/src/main/java/seedu/address/logic/parser/task/DeleteTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/task/DeleteTaskCommandParser.java @@ -1,28 +1,24 @@ package seedu.address.logic.parser.task; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.task.DeleteTaskCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.task.DeleteTaskCommand; -import seedu.address.logic.parser.Parser; +import seedu.address.logic.parser.ArgumentMultimap; +import seedu.address.logic.parser.ArgumentMultimapParser; +import seedu.address.logic.parser.ArgumentParser; import seedu.address.logic.parser.ParserUtil; import seedu.address.logic.parser.exceptions.ParseException; -public class DeleteTaskCommandParser implements Parser { - /** - * Parses {@code userInput} into a new DeleteTaskCommand and returns it. - * - * @param userInput the input entered by the user - * @throws ParseException if {@code userInput} does not conform to the expected format - */ +public class DeleteTaskCommandParser extends ArgumentMultimapParser { + public DeleteTaskCommandParser() { + super(COMMAND_SPECS); + } + @Override - public DeleteTaskCommand parse(String userInput) throws ParseException { - try { - Index index = ParserUtil.parseIndex(userInput); - return new DeleteTaskCommand(index); - } catch (ParseException pe) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteTaskCommand.MESSAGE_USAGE), pe); - } + public DeleteTaskCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { + Index index = ArgumentParser.parseValue(PREFIX_PREAMBLE, ParserUtil::parseIndex, argMultimap, COMMAND_SPECS); + return new DeleteTaskCommand(index); } } diff --git a/src/main/java/seedu/address/logic/parser/task/DoneTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/task/DoneTaskCommandParser.java index ed4317ff957..ffa18754817 100644 --- a/src/main/java/seedu/address/logic/parser/task/DoneTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/task/DoneTaskCommandParser.java @@ -1,29 +1,27 @@ package seedu.address.logic.parser.task; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.task.DoneTaskCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.task.DoneTaskCommand; -import seedu.address.logic.parser.Parser; +import seedu.address.logic.parser.ArgumentMultimap; +import seedu.address.logic.parser.ArgumentMultimapParser; +import seedu.address.logic.parser.ArgumentParser; import seedu.address.logic.parser.ParserUtil; import seedu.address.logic.parser.exceptions.ParseException; /** * Parses input arguments and creates a new AddTaskCommand object */ -public class DoneTaskCommandParser implements Parser { - /** - * Parses the given {@code String} of arguments in the context of the DoneTaskCommand - * and returns a DoneTaskCommand object for execution. - * @throws ParseException if the user input does not conform the expected format - */ - public DoneTaskCommand parse(String args) throws ParseException { - try { - Index index = ParserUtil.parseIndex(args); - return new DoneTaskCommand(index); - } catch (ParseException pe) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, DoneTaskCommand.MESSAGE_USAGE), pe); - } +public class DoneTaskCommandParser extends ArgumentMultimapParser { + public DoneTaskCommandParser() { + super(COMMAND_SPECS); + } + + @Override + public DoneTaskCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { + Index index = ArgumentParser.parseValue(PREFIX_PREAMBLE, ParserUtil::parseIndex, argMultimap, COMMAND_SPECS); + return new DoneTaskCommand(index); } } diff --git a/src/main/java/seedu/address/logic/parser/task/EditTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/task/EditTaskCommandParser.java index 0b454d91507..d1d75f6db63 100644 --- a/src/main/java/seedu/address/logic/parser/task/EditTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/task/EditTaskCommandParser.java @@ -1,17 +1,12 @@ package seedu.address.logic.parser.task; -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.commands.task.EditTaskCommand.MESSAGE_USAGE; +import static seedu.address.logic.commands.task.EditTaskCommand.COMMAND_SPECS; import static seedu.address.logic.parser.CliSyntax.PREFIX_CONTACT; import static seedu.address.logic.parser.CliSyntax.PREFIX_DESCRIPTION; import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIMESTAMP; import static seedu.address.logic.parser.CliSyntax.PREFIX_TITLE; -import static seedu.address.logic.parser.CommandArgument.optionalMultiple; -import static seedu.address.logic.parser.CommandArgument.optionalSingle; -import static seedu.address.logic.parser.CommandArgument.requiredSingle; import java.util.Collection; import java.util.Collections; @@ -22,67 +17,47 @@ import seedu.address.logic.commands.task.EditTaskCommand; import seedu.address.logic.commands.task.EditTaskCommand.EditTaskDescriptor; import seedu.address.logic.parser.ArgumentMultimap; -import seedu.address.logic.parser.ArgumentTokenizer; -import seedu.address.logic.parser.Parser; +import seedu.address.logic.parser.ArgumentMultimapParser; +import seedu.address.logic.parser.ArgumentParser; import seedu.address.logic.parser.ParserUtil; -import seedu.address.logic.parser.exceptions.IllegalPrefixException; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.tag.Tag; import seedu.address.model.task.Contact; +import seedu.address.model.task.Timestamp; /** * Parses input arguments and creates a new EditTaskCommand object */ -public class EditTaskCommandParser implements Parser { +public class EditTaskCommandParser extends ArgumentMultimapParser { - /** - * Parses the given {@code String} of arguments in the context of the EditTaskCommand - * and returns an EditTaskCommand object for execution. - * @throws ParseException if the user input does not conform the expected format - */ - public EditTaskCommand parse(String args) throws ParseException { - requireNonNull(args); - ArgumentMultimap argMultimap; - try { - argMultimap = ArgumentTokenizer.tokenize(args, - requiredSingle(PREFIX_PREAMBLE), - optionalSingle(PREFIX_TITLE), - optionalSingle(PREFIX_DESCRIPTION), - optionalSingle(PREFIX_TIMESTAMP), - optionalMultiple(PREFIX_TAG), - optionalMultiple(PREFIX_CONTACT)); - } catch (IllegalPrefixException e) { - throw new ParseException(String.format(e.getMessage(), MESSAGE_USAGE)); - } catch (ParseException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - } - - Index index; - - try { - index = ParserUtil.parseIndex(argMultimap.getPreamble()); - } catch (ParseException pe) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditTaskCommand.MESSAGE_USAGE), pe); - } + public EditTaskCommandParser() { + super(COMMAND_SPECS); + } + @Override + public EditTaskCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { EditTaskDescriptor editTaskDescriptor = new EditTaskDescriptor(); - argMultimap.getValue(PREFIX_TITLE) - .map(ParserUtil::parseTitle) - .ifPresent(editTaskDescriptor::setTitle); - argMultimap.getValue(PREFIX_DESCRIPTION) - .map(ParserUtil::parseDescription) - .ifPresent(editTaskDescriptor::setDescription); - if (argMultimap.getValue(PREFIX_TIMESTAMP).orElse(null) != null) { - editTaskDescriptor.setTimestamp(ParserUtil.parseTimestamp(argMultimap.getValue(PREFIX_TIMESTAMP).get())); - } - parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)) - .ifPresent(editTaskDescriptor::setTags); - parseContactsForEdit(argMultimap.getAllValues(PREFIX_CONTACT)) - .ifPresent(editTaskDescriptor::setContacts); + Index index = ArgumentParser.parseValue(PREFIX_PREAMBLE, ParserUtil::parseIndex, argMultimap, COMMAND_SPECS); + Optional title = ArgumentParser.parseOptionalValue(PREFIX_TITLE, ParserUtil::parseTitle, argMultimap, + COMMAND_SPECS); + Optional description = ArgumentParser.parseOptionalValue(PREFIX_DESCRIPTION, + ParserUtil::parseDescription, argMultimap, COMMAND_SPECS); + Optional timestamp = ArgumentParser.parseOptionalValue(PREFIX_TIMESTAMP, + ParserUtil::parseTimestamp, argMultimap, COMMAND_SPECS); + Optional> tags = ArgumentParser.parseAllValues(PREFIX_TAG, EditTaskCommandParser::parseTagsForEdit, + argMultimap, COMMAND_SPECS); + Optional> contacts = ArgumentParser.parseAllValues(PREFIX_CONTACT, + EditTaskCommandParser::parseContactsForEdit, argMultimap, COMMAND_SPECS); + + title.ifPresent(editTaskDescriptor::setTitle); + description.ifPresent(editTaskDescriptor::setDescription); + timestamp.ifPresent(editTaskDescriptor::setTimestamp); + tags.ifPresent(editTaskDescriptor::setTags); + contacts.ifPresent(editTaskDescriptor::setContacts); if (!editTaskDescriptor.isAnyFieldEdited()) { - throw new ParseException(EditTaskCommand.MESSAGE_NOT_EDITED); + throw new ParseException(EditTaskCommand.MESSAGE_NOT_EDITED + "\n" + COMMAND_SPECS.getUsageMessage()); } return new EditTaskCommand(index, editTaskDescriptor); @@ -93,7 +68,7 @@ public EditTaskCommand parse(String args) throws ParseException { * If {@code tags} contain only one element which is an empty string, it will be parsed into a * {@code Set} containing zero tags. */ - private Optional> parseTagsForEdit(Collection tags) throws ParseException { + private static Optional> parseTagsForEdit(Collection tags) throws ParseException { assert tags != null; if (tags.isEmpty()) { @@ -108,7 +83,7 @@ private Optional> parseTagsForEdit(Collection tags) throws Pars * If {@code contacts} contain only one element which is an empty string, it will be parsed into a * {@code Set} containing zero contacts. */ - private Optional> parseContactsForEdit(Collection contacts) throws ParseException { + private static Optional> parseContactsForEdit(Collection contacts) throws ParseException { assert contacts != null; if (contacts.isEmpty()) { @@ -116,8 +91,8 @@ private Optional> parseContactsForEdit(Collection contacts) } Collection contactSet = contacts.size() == 1 && contacts.contains("") - ? Collections.emptySet() - : contacts; + ? Collections.emptySet() + : contacts; return Optional.of(ParserUtil.parseContacts(contactSet)); } } diff --git a/src/main/java/seedu/address/logic/parser/task/FindTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/task/FindTaskCommandParser.java index a6b8bfcf0fc..40e68cbae25 100644 --- a/src/main/java/seedu/address/logic/parser/task/FindTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/task/FindTaskCommandParser.java @@ -1,26 +1,23 @@ package seedu.address.logic.parser.task; -import static java.util.Objects.requireNonNull; +import static seedu.address.logic.commands.task.FindTaskCommand.COMMAND_SPECS; import java.util.Arrays; import seedu.address.logic.commands.task.FindTaskCommand; -import seedu.address.logic.parser.Parser; +import seedu.address.logic.parser.ArgumentMultimap; +import seedu.address.logic.parser.ArgumentMultimapParser; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.task.TaskContainsKeywordsPredicate; -public class FindTaskCommandParser implements Parser { - /** - * Parses {@code userInput} into a command and returns it. - * - * @param userInput the input entered by the user - * @throws ParseException if {@code userInput} does not conform to the expected format - */ - @Override - public FindTaskCommand parse(String userInput) throws ParseException { - requireNonNull(userInput); +public class FindTaskCommandParser extends ArgumentMultimapParser { + public FindTaskCommandParser() { + super(COMMAND_SPECS); + } - String trimmedArgs = userInput.trim(); + @Override + public FindTaskCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { + String trimmedArgs = argMultimap.getPreamble(); if (trimmedArgs.isEmpty()) { return new FindTaskCommand(TaskContainsKeywordsPredicate.SHOW_ALL_TASKS_PREDICATE); diff --git a/src/main/java/seedu/address/logic/parser/task/ListTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/task/ListTaskCommandParser.java index 8ef2c50d600..7bfd7e59798 100644 --- a/src/main/java/seedu/address/logic/parser/task/ListTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/task/ListTaskCommandParser.java @@ -1,11 +1,9 @@ package seedu.address.logic.parser.task; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.commands.task.ListTaskCommand.MESSAGE_USAGE; +import static seedu.address.logic.commands.task.ListTaskCommand.COMMAND_SPECS; import static seedu.address.logic.parser.CliSyntax.PREFIX_DONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_UNDONE; -import static seedu.address.logic.parser.CommandArgument.optionalSingle; import java.util.List; import java.util.Set; @@ -13,36 +11,26 @@ import seedu.address.logic.commands.task.ListTaskCommand; import seedu.address.logic.parser.ArgumentMultimap; -import seedu.address.logic.parser.ArgumentTokenizer; -import seedu.address.logic.parser.CommandArgument; -import seedu.address.logic.parser.Parser; +import seedu.address.logic.parser.ArgumentMultimapParser; +import seedu.address.logic.parser.ArgumentParser; import seedu.address.logic.parser.ParserUtil; -import seedu.address.logic.parser.exceptions.IllegalPrefixException; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.tag.Tag; import seedu.address.model.task.filters.TaskFilter; import seedu.address.model.task.filters.TaskFilters; -public class ListTaskCommandParser implements Parser { +public class ListTaskCommandParser extends ArgumentMultimapParser { + public ListTaskCommandParser() { + super(COMMAND_SPECS); + } + /** * Parses the given {@code String} of arguments in the context of the EditTaskCommand * and returns an EditTaskCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ - public ListTaskCommand parse(String args) throws ParseException { - ArgumentMultimap argMultimap; - try { - argMultimap = ArgumentTokenizer.tokenize(args, - optionalSingle(PREFIX_DONE), - optionalSingle(PREFIX_UNDONE), - CommandArgument.optionalMultiple(PREFIX_TAG)); - } catch (IllegalPrefixException e) { - throw new ParseException(String.format(e.getMessage(), MESSAGE_USAGE)); - } catch (ParseException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - } - - Set tags = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + public ListTaskCommand parseArgumentMultimap(ArgumentMultimap argMultimap) throws ParseException { + Set tags = ArgumentParser.parseAllValues(PREFIX_TAG, ParserUtil::parseTags, argMultimap, COMMAND_SPECS); List taskFilters = tags.stream().map(TaskFilters.FILTER_TAG).collect(Collectors.toList()); if (argMultimap.getValue(PREFIX_DONE).isPresent()) { @@ -54,7 +42,7 @@ public ListTaskCommand parse(String args) throws ParseException { } if (!argMultimap.getPreamble().isEmpty()) { - throw new ParseException(ListTaskCommand.MESSAGE_USAGE); + throw new ParseException(COMMAND_SPECS.getUsageMessage()); } return new ListTaskCommand(taskFilters); diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java index 3ee913c5940..9e3e109fc91 100644 --- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java @@ -1,6 +1,6 @@ package seedu.address.logic.parser; -import static seedu.address.logic.commands.AddCommand.MESSAGE_USAGE; +import static seedu.address.logic.commands.AddCommand.COMMAND_SPECS; import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB; import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; @@ -28,6 +28,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; import static seedu.address.testutil.TypicalPersons.AMY; @@ -36,7 +37,8 @@ import org.junit.jupiter.api.Test; import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.parser.exceptions.MissingPrefixException; +import seedu.address.logic.parser.exceptions.InvalidCommandArgumentFormatException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; import seedu.address.logic.parser.exceptions.TooManyPrefixesException; import seedu.address.logic.parser.exceptions.UnwantedPreambleException; import seedu.address.model.person.Address; @@ -61,22 +63,27 @@ public void parse_allFieldsPresent_success() { // multiple names - failure assertParseFailure(parser, NAME_DESC_AMY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, - String.format(new TooManyPrefixesException(PREFIX_NAME).getMessage(), MESSAGE_USAGE)); + new TooManyPrefixesException(CommandArgument.unknown(PREFIX_NAME), + COMMAND_SPECS).getMessage()); // multiple phones - failure assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_AMY + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, - String.format(new TooManyPrefixesException(PREFIX_PHONE).getMessage(), MESSAGE_USAGE)); + new TooManyPrefixesException(CommandArgument.unknown(PREFIX_PHONE), + COMMAND_SPECS).getMessage()); // multiple emails - failure assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_AMY + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, - String.format(new TooManyPrefixesException(PREFIX_EMAIL).getMessage(), MESSAGE_USAGE)); + new TooManyPrefixesException(CommandArgument.unknown(PREFIX_EMAIL), + COMMAND_SPECS).getMessage()); // multiple addresses - failure assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_AMY + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, - String.format(new TooManyPrefixesException(PREFIX_ADDRESS).getMessage(), MESSAGE_USAGE)); + new TooManyPrefixesException(CommandArgument.unknown(PREFIX_ADDRESS), + COMMAND_SPECS).getMessage()); + // multiple tags - all accepted Person expectedPersonMultipleTags = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND) @@ -97,54 +104,75 @@ public void parse_optionalFieldsMissing_success() { public void parse_compulsoryFieldMissing_failure() { // missing name prefix assertParseFailure(parser, VALID_NAME_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB, - String.format(new MissingPrefixException(PREFIX_NAME).getMessage(), MESSAGE_USAGE)); + new MissingCommandArgumentException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_NAME), + COMMAND_SPECS).getMessage()); // missing phone prefix assertParseFailure(parser, NAME_DESC_BOB + VALID_PHONE_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB, - String.format(new MissingPrefixException(PREFIX_PHONE).getMessage(), MESSAGE_USAGE)); + new MissingCommandArgumentException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PHONE), + COMMAND_SPECS).getMessage()); // missing email prefix assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + VALID_EMAIL_BOB + ADDRESS_DESC_BOB, - String.format(new MissingPrefixException(PREFIX_EMAIL).getMessage(), MESSAGE_USAGE)); + new MissingCommandArgumentException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_EMAIL), + COMMAND_SPECS).getMessage()); // missing address prefix assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + VALID_ADDRESS_BOB, - String.format(new MissingPrefixException(PREFIX_ADDRESS).getMessage(), MESSAGE_USAGE)); + new MissingCommandArgumentException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_ADDRESS), + COMMAND_SPECS).getMessage()); // all prefixes missing assertParseFailure(parser, VALID_NAME_BOB + VALID_PHONE_BOB + VALID_EMAIL_BOB + VALID_ADDRESS_BOB, - String.format(new MissingPrefixException(PREFIX_NAME).getMessage(), MESSAGE_USAGE)); + new MissingCommandArgumentException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_NAME), + COMMAND_SPECS).getMessage()); } @Test public void parse_invalidValue_failure() { // invalid name assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Name.MESSAGE_CONSTRAINTS); + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, + new InvalidCommandArgumentFormatException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_NAME), + Name.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage()); // invalid phone assertParseFailure(parser, NAME_DESC_BOB + INVALID_PHONE_DESC + EMAIL_DESC_BOB + ADDRESS_DESC_BOB - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Phone.MESSAGE_CONSTRAINTS); + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, + new InvalidCommandArgumentFormatException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PHONE), + Phone.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage()); // invalid email assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + INVALID_EMAIL_DESC + ADDRESS_DESC_BOB - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Email.MESSAGE_CONSTRAINTS); + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, + new InvalidCommandArgumentFormatException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_EMAIL), + Email.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage()); // invalid address assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC - + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Address.MESSAGE_CONSTRAINTS); + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, + new InvalidCommandArgumentFormatException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_ADDRESS), + Address.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage()); // invalid tag assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB - + INVALID_TAG_DESC + VALID_TAG_FRIEND, Tag.MESSAGE_CONSTRAINTS); + + INVALID_TAG_DESC + VALID_TAG_FRIEND, + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_TAG), + Tag.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage()); // two invalid values, only first invalid value reported assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC, - Name.MESSAGE_CONSTRAINTS); + + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_NAME), + Name.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage()); // non-empty preamble assertParseFailure(parser, PREAMBLE_NON_EMPTY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, - String.format(new UnwantedPreambleException(PREAMBLE_NON_EMPTY).getMessage(), MESSAGE_USAGE)); + new UnwantedPreambleException(PREAMBLE_NON_EMPTY, COMMAND_SPECS).getMessage()); } } diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index e5120da37c6..ff2f38f58cf 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -37,21 +37,21 @@ public class AddressBookParserTest { @Test public void parseCommand_add() throws Exception { Person person = new PersonBuilder().build(); - AddCommand command = (AddCommand) parser.parseCommand(PersonUtil.getAddCommand(person)); + AddCommand command = (AddCommand) parser.parse(PersonUtil.getAddCommand(person)); assertEquals(new AddCommand(person), command); } @Test public void parseCommand_clear() throws Exception { - assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD) instanceof ClearCommand); + assertTrue(parser.parse(ClearCommand.COMMAND_WORD) instanceof ClearCommand); assertThrows(ParseException.class, - String.format(new UnwantedPreambleException("3").getMessage(), ClearCommand.MESSAGE_USAGE), () -> - parser.parseCommand(ClearCommand.COMMAND_WORD + " 3")); + new UnwantedPreambleException("3", ClearCommand.COMMAND_SPECS).getMessage(), () -> + parser.parse(ClearCommand.COMMAND_WORD + " 3")); } @Test public void parseCommand_delete() throws Exception { - DeleteCommand command = (DeleteCommand) parser.parseCommand( + DeleteCommand command = (DeleteCommand) parser.parse( DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); } @@ -60,52 +60,52 @@ public void parseCommand_delete() throws Exception { public void parseCommand_edit() throws Exception { Person person = new PersonBuilder().build(); EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build(); - EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_WORD + " " + EditCommand command = (EditCommand) parser.parse(EditCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor)); assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command); } @Test public void parseCommand_exit() throws Exception { - assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD) instanceof ExitCommand); + assertTrue(parser.parse(ExitCommand.COMMAND_WORD) instanceof ExitCommand); assertThrows(ParseException.class, - String.format(new UnwantedPreambleException("3").getMessage(), ExitCommand.MESSAGE_USAGE), () -> - parser.parseCommand(ExitCommand.COMMAND_WORD + " 3")); + new UnwantedPreambleException("3", ExitCommand.COMMAND_SPECS).getMessage(), () -> + parser.parse(ExitCommand.COMMAND_WORD + " 3")); } @Test public void parseCommand_find() throws Exception { List keywords = Arrays.asList("foo", "bar", "baz"); - FindCommand command = (FindCommand) parser.parseCommand( + FindCommand command = (FindCommand) parser.parse( FindCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); } @Test public void parseCommand_help() throws Exception { - assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand); + assertTrue(parser.parse(HelpCommand.COMMAND_WORD) instanceof HelpCommand); assertThrows(ParseException.class, - String.format(new UnwantedPreambleException("3").getMessage(), HelpCommand.MESSAGE_USAGE), () -> - parser.parseCommand(HelpCommand.COMMAND_WORD + " 3")); + new UnwantedPreambleException("3", HelpCommand.COMMAND_SPECS).getMessage(), () -> + parser.parse(HelpCommand.COMMAND_WORD + " 3")); } @Test public void parseCommand_list() throws Exception { - assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD) instanceof ListCommand); + assertTrue(parser.parse(ListCommand.COMMAND_WORD) instanceof ListCommand); assertThrows(ParseException.class, - String.format(new UnwantedPreambleException("3").getMessage(), ListCommand.MESSAGE_USAGE), () -> - parser.parseCommand(ListCommand.COMMAND_WORD + " 3")); + new UnwantedPreambleException("3", ListCommand.COMMAND_SPECS).getMessage(), () -> + parser.parse(ListCommand.COMMAND_WORD + " 3")); } @Test public void parseCommand_unrecognisedInput_throwsParseException() { assertThrows(ParseException.class, - String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), () -> - parser.parseCommand("")); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.COMMAND_SPECS.getUsageMessage()), () -> + parser.parse("")); } @Test public void parseCommand_unknownCommand_throwsParseException() { - assertThrows(ParseException.class, MESSAGE_UNKNOWN_COMMAND, () -> parser.parseCommand("unknownCommand")); + assertThrows(ParseException.class, MESSAGE_UNKNOWN_COMMAND, () -> parser.parse("unknownCommand")); } } diff --git a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java b/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java index ba211afb181..24fb083682e 100644 --- a/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java +++ b/src/test/java/seedu/address/logic/parser/ArgumentTokenizerTest.java @@ -7,24 +7,25 @@ import org.junit.jupiter.api.Test; -import seedu.address.logic.parser.exceptions.MissingPrefixException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.logic.parser.exceptions.TooManyPrefixesException; +import seedu.address.logic.parser.exceptions.UnwantedCommandArgumentException; import seedu.address.logic.parser.exceptions.UnwantedPreambleException; -import seedu.address.logic.parser.exceptions.UnwantedPrefixException; public class ArgumentTokenizerTest { private static final Prefix prefix = new Prefix("p/"); @Test public void tokenize_expectingOptionalPreambleValidArguments_success() { + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null, + optionalSingle(PREFIX_PREAMBLE, "preambleName") + )); try { - ArgumentTokenizer.tokenize("", - optionalSingle(PREFIX_PREAMBLE)); - ArgumentTokenizer.tokenize("single", - optionalSingle(PREFIX_PREAMBLE)); - ArgumentTokenizer.tokenize("multiple words", - optionalSingle(PREFIX_PREAMBLE)); + tokenizer.tokenize(""); + tokenizer.tokenize("single"); + tokenizer.tokenize("multiple words"); } catch (ParseException e) { fail(e); } @@ -32,8 +33,10 @@ public void tokenize_expectingOptionalPreambleValidArguments_success() { @Test public void tokenize_expectingEmptyPreambleValidArguments_success() { + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null)); try { - ArgumentTokenizer.tokenize(""); + tokenizer.tokenize(""); } catch (ParseException e) { fail(e); } @@ -41,8 +44,10 @@ public void tokenize_expectingEmptyPreambleValidArguments_success() { @Test public void tokenize_expectingEmptyPreambleInvalidArguments_throwsUnwantedPrefixArguments() { + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null)); try { - ArgumentTokenizer.tokenize("single"); + tokenizer.tokenize("single"); fail(); } catch (UnwantedPreambleException ignored) { // This is expected @@ -50,7 +55,7 @@ public void tokenize_expectingEmptyPreambleInvalidArguments_throwsUnwantedPrefix fail(e); } try { - ArgumentTokenizer.tokenize("multiple words"); + tokenizer.tokenize("multiple words"); fail(); } catch (UnwantedPreambleException ignored) { // This is expected @@ -61,12 +66,15 @@ public void tokenize_expectingEmptyPreambleInvalidArguments_throwsUnwantedPrefix @Test public void tokenize_expectingOptionalSingleValidArguments_success() { - CommandArgument argument = optionalSingle(prefix); + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null, + optionalSingle(prefix) + )); try { - ArgumentTokenizer.tokenize(prefix.getPrefix(), argument); - ArgumentTokenizer.tokenize(prefix.getPrefix() + " space", argument); - ArgumentTokenizer.tokenize(prefix.getPrefix() + "single", argument); - ArgumentTokenizer.tokenize(prefix.getPrefix() + "multiple words", argument); + tokenizer.tokenize(prefix.getPrefix()); + tokenizer.tokenize(prefix.getPrefix() + " space"); + tokenizer.tokenize(prefix.getPrefix() + "single"); + tokenizer.tokenize(prefix.getPrefix() + "multiple words"); } catch (ParseException e) { fail(e); } @@ -74,17 +82,20 @@ public void tokenize_expectingOptionalSingleValidArguments_success() { @Test public void tokenize_expectingOptionalSingleInvalidArguments_throwsException() { - CommandArgument argument = optionalSingle(prefix); + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null, + optionalSingle(prefix) + )); try { - ArgumentTokenizer.tokenize("", argument); - } catch (MissingPrefixException ignored) { + tokenizer.tokenize(""); + } catch (MissingCommandArgumentException ignored) { // This is expected } catch (ParseException e) { fail(e); } try { - ArgumentTokenizer.tokenize(prefix.getPrefix() + "first " + prefix.getPrefix() + "second", argument); + tokenizer.tokenize(prefix.getPrefix() + "first " + prefix.getPrefix() + "second"); } catch (TooManyPrefixesException ignored) { // This is expected } catch (ParseException e) { @@ -94,10 +105,13 @@ public void tokenize_expectingOptionalSingleInvalidArguments_throwsException() { @Test public void tokenize_expectingRequiredSingleValidArguments_success() { - CommandArgument argument = requiredSingle(prefix); + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null, + requiredSingle(prefix) + )); try { - ArgumentTokenizer.tokenize(prefix.getPrefix(), argument); - ArgumentTokenizer.tokenize(prefix.getPrefix() + "first", argument); + tokenizer.tokenize(prefix.getPrefix()); + tokenizer.tokenize(prefix.getPrefix() + "first"); } catch (ParseException e) { fail(e); } @@ -105,16 +119,19 @@ public void tokenize_expectingRequiredSingleValidArguments_success() { @Test public void tokenize_expectingRequiredSingleInvalidArguments_throwsException() { - CommandArgument argument = requiredSingle(prefix); + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null, + requiredSingle(prefix) + )); try { - ArgumentTokenizer.tokenize("", argument); - } catch (MissingPrefixException ignored) { + tokenizer.tokenize(""); + } catch (MissingCommandArgumentException ignored) { // This is expected } catch (ParseException e) { fail(e); } try { - ArgumentTokenizer.tokenize(prefix.getPrefix() + "first " + prefix.getPrefix() + "second", argument); + tokenizer.tokenize(prefix.getPrefix() + "first " + prefix.getPrefix() + "second"); } catch (TooManyPrefixesException ignored) { // This is expected } catch (ParseException e) { @@ -124,16 +141,18 @@ public void tokenize_expectingRequiredSingleInvalidArguments_throwsException() { @Test public void tokenize_unexpectedArgument_throwUnwantedArgumentException() { + ArgumentTokenizer tokenizer = new ArgumentTokenizer(new CommandSpecification( + null, null)); try { - ArgumentTokenizer.tokenize(prefix.getPrefix()); - } catch (UnwantedPrefixException ignored) { + tokenizer.tokenize(prefix.getPrefix()); + } catch (UnwantedCommandArgumentException ignored) { // This is expected } catch (ParseException e) { fail(e); } try { - ArgumentTokenizer.tokenize(prefix.getPrefix() + "first " + prefix.getPrefix() + "second"); - } catch (UnwantedPrefixException ignored) { + tokenizer.tokenize(prefix.getPrefix() + "first " + prefix.getPrefix() + "second"); + } catch (UnwantedCommandArgumentException ignored) { // This is expected } catch (ParseException e) { fail(e); diff --git a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java index 27eaec84450..681600a345e 100644 --- a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java @@ -1,6 +1,7 @@ package seedu.address.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.DeleteCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; @@ -8,6 +9,7 @@ import org.junit.jupiter.api.Test; import seedu.address.logic.commands.DeleteCommand; +import seedu.address.logic.parser.exceptions.InvalidCommandArgumentFormatException; /** * As we are only doing white-box testing, our test cases do not cover path variations @@ -18,6 +20,9 @@ */ public class DeleteCommandParserTest { + private static final String MESSAGE_INVALID_INDEX = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), + ParserUtil.MESSAGE_INVALID_INDEX, COMMAND_SPECS).getMessage(); private DeleteCommandParser parser = new DeleteCommandParser(); @Test @@ -27,6 +32,6 @@ public void parse_validArgs_returnsDeleteCommand() { @Test public void parse_invalidArgs_throwsParseException() { - assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); + assertParseFailure(parser, "a", MESSAGE_INVALID_INDEX); } } diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java index a4706120d0a..4d88a25d72d 100644 --- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java @@ -1,6 +1,5 @@ package seedu.address.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC; @@ -20,7 +19,13 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.address.logic.commands.EditCommand.COMMAND_SPECS; +import static seedu.address.logic.commands.EditCommand.MESSAGE_NOT_EDITED; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; @@ -33,9 +38,10 @@ import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; -import seedu.address.logic.parser.exceptions.MissingPreambleException; +import seedu.address.logic.parser.exceptions.InvalidCommandArgumentFormatException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; import seedu.address.logic.parser.exceptions.TooManyPrefixesException; -import seedu.address.logic.parser.exceptions.UnwantedPrefixException; +import seedu.address.logic.parser.exceptions.UnwantedCommandArgumentException; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -44,63 +50,89 @@ import seedu.address.testutil.EditPersonDescriptorBuilder; public class EditCommandParserTest { - + private static final String MESSAGE_INVALID_NAME = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_NAME), + Name.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_INVALID_PHONE = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PHONE), + Phone.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_INVALID_EMAIL = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_EMAIL), + Email.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_INVALID_TAG = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_TAG), + Tag.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_INVALID_ADDRESS = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_ADDRESS), + Address.MESSAGE_CONSTRAINTS, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_INVALID_INDEX = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), + ParserUtil.MESSAGE_INVALID_INDEX, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_NOT_EDITED = + EditCommand.MESSAGE_NOT_EDITED + "\n" + COMMAND_SPECS.getUsageMessage(); private static final String TAG_EMPTY = " " + PREFIX_TAG; - private static final String MESSAGE_INVALID_FORMAT = - String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE); - private final EditCommandParser parser = new EditCommandParser(); @Test public void parse_missingParts_failure() { // no index specified - assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_INDEX); // no field specified - assertParseFailure(parser, "1", EditCommand.MESSAGE_NOT_EDITED); + assertParseFailure(parser, "1", MESSAGE_NOT_EDITED); // no index and no field specified assertParseFailure(parser, "", - String.format(new MissingPreambleException().getMessage(), EditCommand.MESSAGE_USAGE)); + new MissingCommandArgumentException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), COMMAND_SPECS).getMessage()); } @Test public void parse_invalidPreamble_failure() { // negative index - assertParseFailure(parser, "-5" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, "-5" + NAME_DESC_AMY, MESSAGE_INVALID_INDEX); // zero index - assertParseFailure(parser, "0" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, "0" + NAME_DESC_AMY, MESSAGE_INVALID_INDEX); // invalid arguments being parsed as preamble - assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_INDEX); // invalid prefix assertParseFailure(parser, "1 i/ string", - String.format(new UnwantedPrefixException(new Prefix("i/")).getMessage(), EditCommand.MESSAGE_USAGE)); + new UnwantedCommandArgumentException( + CommandArgument.unknown(new Prefix("i/")), COMMAND_SPECS).getMessage()); } @Test public void parse_invalidValue_failure() { - assertParseFailure(parser, "1" + INVALID_NAME_DESC, Name.MESSAGE_CONSTRAINTS); // invalid name - assertParseFailure(parser, "1" + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS); // invalid phone - assertParseFailure(parser, "1" + INVALID_EMAIL_DESC, Email.MESSAGE_CONSTRAINTS); // invalid email - assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, Address.MESSAGE_CONSTRAINTS); // invalid address - assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag - + // invalid name + assertParseFailure(parser, "1" + INVALID_NAME_DESC, MESSAGE_INVALID_NAME); + // invalid phone + assertParseFailure(parser, "1" + INVALID_PHONE_DESC, MESSAGE_INVALID_PHONE); + // invalid email + assertParseFailure(parser, "1" + INVALID_EMAIL_DESC, MESSAGE_INVALID_EMAIL); + // invalid address + assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, MESSAGE_INVALID_ADDRESS); + // invalid tag + assertParseFailure(parser, "1" + INVALID_TAG_DESC, MESSAGE_INVALID_TAG); // invalid phone followed by valid email - assertParseFailure(parser, "1" + INVALID_PHONE_DESC + EMAIL_DESC_AMY, Phone.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + INVALID_PHONE_DESC + EMAIL_DESC_AMY, MESSAGE_INVALID_PHONE); // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Person} being edited, // parsing it together with a valid tag results in error - assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_DESC_HUSBAND + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS); - assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_EMPTY + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS); - assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_DESC_HUSBAND + TAG_EMPTY, + MESSAGE_INVALID_TAG); + assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_EMPTY + TAG_DESC_HUSBAND, + MESSAGE_INVALID_TAG); + assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND, + MESSAGE_INVALID_TAG); // multiple invalid values, but only the first invalid value is captured - assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_EMAIL_DESC + VALID_ADDRESS_AMY + VALID_PHONE_AMY, - Name.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, + "1" + INVALID_NAME_DESC + INVALID_EMAIL_DESC + VALID_ADDRESS_AMY + VALID_PHONE_AMY, + MESSAGE_INVALID_NAME); } @Test @@ -170,7 +202,7 @@ public void parse_repeatedFields_failure() { + TAG_DESC_FRIEND + PHONE_DESC_AMY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND; assertParseFailure(parser, userInput, - String.format(new TooManyPrefixesException(PREFIX_PHONE).getMessage(), EditCommand.MESSAGE_USAGE)); + new TooManyPrefixesException(CommandArgument.unknown(PREFIX_PHONE), COMMAND_SPECS).getMessage()); } @Test diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java index 70f4f0e79c4..a5658005b91 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java @@ -1,6 +1,7 @@ package seedu.address.logic.parser; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.FindCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; @@ -9,15 +10,17 @@ import org.junit.jupiter.api.Test; import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; import seedu.address.model.person.NameContainsKeywordsPredicate; public class FindCommandParserTest { - - private FindCommandParser parser = new FindCommandParser(); + private final FindCommandParser parser = new FindCommandParser(); @Test public void parse_emptyArg_throwsParseException() { - assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); + assertParseFailure(parser, " ", + new MissingCommandArgumentException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), COMMAND_SPECS).getMessage()); } @Test diff --git a/src/test/java/seedu/address/logic/parser/task/AddTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/task/AddTaskCommandParserTest.java index 83bb0bba77a..8feff5a5ac5 100644 --- a/src/test/java/seedu/address/logic/parser/task/AddTaskCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/task/AddTaskCommandParserTest.java @@ -7,24 +7,28 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_CAREER; import static seedu.address.logic.commands.CommandTestUtil.VALID_TIMESTAMP_REPORT; import static seedu.address.logic.commands.CommandTestUtil.VALID_TITLE_REPORT; +import static seedu.address.logic.commands.task.AddTaskCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; import org.junit.jupiter.api.Test; import seedu.address.logic.commands.task.AddTaskCommand; -import seedu.address.logic.parser.exceptions.MissingPreambleException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; import seedu.address.model.task.Task; import seedu.address.testutil.TaskBuilder; public class AddTaskCommandParserTest { + private static final String MESSAGE_MISSING_PREAMBLE = + new MissingCommandArgumentException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), COMMAND_SPECS).getMessage(); private final AddTaskCommandParser parser = new AddTaskCommandParser(); @Test void parse_emptyArguments_failure() { - assertParseFailure(parser, "", - String.format(new MissingPreambleException().getMessage(), AddTaskCommand.MESSAGE_USAGE)); + assertParseFailure(parser, "", MESSAGE_MISSING_PREAMBLE); } @Test diff --git a/src/test/java/seedu/address/logic/parser/task/DeleteTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/task/DeleteTaskCommandParserTest.java index 21d80f793e1..4a66be4f95e 100644 --- a/src/test/java/seedu/address/logic/parser/task/DeleteTaskCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/task/DeleteTaskCommandParserTest.java @@ -1,7 +1,7 @@ package seedu.address.logic.parser.task; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.commands.task.DeleteTaskCommand.MESSAGE_USAGE; +import static seedu.address.logic.commands.task.DeleteTaskCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; @@ -9,28 +9,38 @@ import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.task.DeleteTaskCommand; +import seedu.address.logic.parser.ParserUtil; +import seedu.address.logic.parser.exceptions.InvalidCommandArgumentFormatException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; public class DeleteTaskCommandParserTest { + private static final String MESSAGE_INVALID_INDEX = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), + ParserUtil.MESSAGE_INVALID_INDEX, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_MISSING_PREAMBLE = + new MissingCommandArgumentException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), COMMAND_SPECS).getMessage(); final DeleteTaskCommandParser parser = new DeleteTaskCommandParser(); @Test public void parse_noIndex_failure() { - assertParseFailure(parser, "", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + assertParseFailure(parser, "", MESSAGE_MISSING_PREAMBLE); } @Test public void parse_nonIntegerIndex_failure() { assertParseFailure(parser, "1.1", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + MESSAGE_INVALID_INDEX); assertParseFailure(parser, "hello", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + MESSAGE_INVALID_INDEX); } @Test public void parse_nonPositiveIndex_failure() { assertParseFailure(parser, "-1", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - assertParseFailure(parser, "0", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + MESSAGE_INVALID_INDEX); + assertParseFailure(parser, "0", + MESSAGE_INVALID_INDEX); } @Test diff --git a/src/test/java/seedu/address/logic/parser/task/DoneTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/task/DoneTaskCommandParserTest.java index 57fef08410e..15e597d08a2 100644 --- a/src/test/java/seedu/address/logic/parser/task/DoneTaskCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/task/DoneTaskCommandParserTest.java @@ -1,7 +1,7 @@ package seedu.address.logic.parser.task; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.commands.task.DoneTaskCommand.MESSAGE_USAGE; +import static seedu.address.logic.commands.task.DoneTaskCommand.COMMAND_SPECS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; @@ -9,26 +9,35 @@ import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.task.DoneTaskCommand; +import seedu.address.logic.parser.ParserUtil; +import seedu.address.logic.parser.exceptions.InvalidCommandArgumentFormatException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; public class DoneTaskCommandParserTest { + private static final String MESSAGE_MISSING_PREAMBLE = + new MissingCommandArgumentException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), COMMAND_SPECS).getMessage(); + private static final String MESSAGE_INVALID_INDEX = + new InvalidCommandArgumentFormatException( + COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), + ParserUtil.MESSAGE_INVALID_INDEX, COMMAND_SPECS).getMessage(); final DoneTaskCommandParser parser = new DoneTaskCommandParser(); @Test public void parse_noIndex_failure() { - assertParseFailure(parser, "", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + assertParseFailure(parser, "", MESSAGE_MISSING_PREAMBLE); } @Test public void parse_nonIntegerIndex_failure() { - assertParseFailure(parser, "1.1", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - assertParseFailure(parser, "hello", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + assertParseFailure(parser, "1.1", MESSAGE_INVALID_INDEX); + assertParseFailure(parser, "hello", MESSAGE_INVALID_INDEX); } @Test public void parse_nonPositiveIndex_failure() { - assertParseFailure(parser, "-1", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - assertParseFailure(parser, "0", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + assertParseFailure(parser, "-1", MESSAGE_INVALID_INDEX); + assertParseFailure(parser, "0", MESSAGE_INVALID_INDEX); } @Test diff --git a/src/test/java/seedu/address/logic/parser/task/EditTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/task/EditTaskCommandParserTest.java index 9ce6141222c..f1ef3504127 100644 --- a/src/test/java/seedu/address/logic/parser/task/EditTaskCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/task/EditTaskCommandParserTest.java @@ -1,6 +1,5 @@ package seedu.address.logic.parser.task; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.commands.CommandTestUtil.DESCRIPTION_DESC_REPORT; import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_CAREER; import static seedu.address.logic.commands.CommandTestUtil.TIMESTAMP_DESC_REPORT; @@ -9,9 +8,10 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_CAREER; import static seedu.address.logic.commands.CommandTestUtil.VALID_TIMESTAMP_REPORT; import static seedu.address.logic.commands.CommandTestUtil.VALID_TITLE_REPORT; +import static seedu.address.logic.commands.task.EditTaskCommand.COMMAND_SPECS; import static seedu.address.logic.commands.task.EditTaskCommand.EditTaskDescriptor; import static seedu.address.logic.commands.task.EditTaskCommand.MESSAGE_NOT_EDITED; -import static seedu.address.logic.commands.task.EditTaskCommand.MESSAGE_USAGE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PREAMBLE; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; @@ -19,28 +19,38 @@ import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.task.EditTaskCommand; -import seedu.address.logic.parser.exceptions.MissingPreambleException; +import seedu.address.logic.parser.ParserUtil; +import seedu.address.logic.parser.exceptions.InvalidCommandArgumentFormatException; +import seedu.address.logic.parser.exceptions.MissingCommandArgumentException; import seedu.address.testutil.EditTaskDescriptorBuilder; public class EditTaskCommandParserTest { + private static final String MESSAGE_MISSING_PREAMBLE = + new MissingCommandArgumentException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), + COMMAND_SPECS).getMessage(); + private static final String MESSAGE_INVALID_INDEX = + new InvalidCommandArgumentFormatException(COMMAND_SPECS.getCommandArgumentWithPrefix(PREFIX_PREAMBLE), + ParserUtil.MESSAGE_INVALID_INDEX, COMMAND_SPECS).getMessage(); + private static final String MESSAGE_NOT_EDITED = + EditTaskCommand.MESSAGE_NOT_EDITED + "\n" + COMMAND_SPECS.getUsageMessage(); + final EditTaskCommandParser parser = new EditTaskCommandParser(); @Test public void parse_emptyArguments_failure() { - assertParseFailure(parser, "", String.format(new MissingPreambleException().getMessage(), MESSAGE_USAGE)); + assertParseFailure(parser, "", MESSAGE_MISSING_PREAMBLE); } @Test public void parse_nonIntegerIndex_failure() { - assertParseFailure(parser, "1.1", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - assertParseFailure(parser, "hello", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + assertParseFailure(parser, "1.1", MESSAGE_INVALID_INDEX); + assertParseFailure(parser, "hello", MESSAGE_INVALID_INDEX); } @Test public void parse_nonPositiveIndex_failure() { - assertParseFailure(parser, "-1", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); - assertParseFailure(parser, "0", String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE)); + assertParseFailure(parser, "-1", MESSAGE_INVALID_INDEX); + assertParseFailure(parser, "0", MESSAGE_INVALID_INDEX); } @Test diff --git a/src/test/java/seedu/address/logic/parser/task/ListTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/task/ListTaskCommandParserTest.java index 80d779a6929..bc9254277ff 100644 --- a/src/test/java/seedu/address/logic/parser/task/ListTaskCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/task/ListTaskCommandParserTest.java @@ -1,6 +1,6 @@ package seedu.address.logic.parser.task; -import static seedu.address.logic.commands.task.ListTaskCommand.MESSAGE_USAGE; +import static seedu.address.logic.commands.task.ListTaskCommand.COMMAND_SPECS; import static seedu.address.logic.parser.CliSyntax.PREFIX_DONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CliSyntax.PREFIX_UNDONE; @@ -20,6 +20,7 @@ public class ListTaskCommandParserTest { private final ListTaskCommandParser parser = new ListTaskCommandParser(); + @Test void parse_emptyArguments_noTaskFilters() { assertParseSuccess(parser, "", new ListTaskCommand(new ArrayList<>())); @@ -47,6 +48,7 @@ void parse_showTag_showTaggedTasks() { @Test void parse_withPreamble_failure() { assertParseFailure(parser, " preamble", - String.format(new UnwantedPreambleException("preamble").getMessage(), MESSAGE_USAGE)); + String.format(new UnwantedPreambleException("preamble", COMMAND_SPECS).getMessage(), + COMMAND_SPECS.getUsageMessage())); } }