From 495d2564e1e5309a94a2cb42ddbff40a3fc618fe Mon Sep 17 00:00:00 2001 From: rbth7e5 Date: Tue, 12 Feb 2019 20:46:37 +0800 Subject: [PATCH 1/4] add new command edit, supports name editing --- docs/UserGuide.adoc | 10 +++ .../addressbook/commands/EditCommand.java | 60 +++++++++++++++ src/seedu/addressbook/data/AddressBook.java | 5 ++ .../data/person/UniquePersonList.java | 16 ++++ src/seedu/addressbook/parser/Parser.java | 74 +++++++++++-------- test/expected.txt | 37 ++++++++++ test/input.txt | 17 +++++ .../addressbook/commands/EditCommandTest.java | 41 ++++++++++ 8 files changed, 230 insertions(+), 30 deletions(-) create mode 100644 src/seedu/addressbook/commands/EditCommand.java create mode 100644 test/java/seedu/addressbook/commands/EditCommandTest.java diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 4abb17e3e..0db1765fb 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -67,6 +67,16 @@ Examples: * `add John Doe p/98765432 e/johnd@gmail.com a/John street, block 123, #01-01` * `add Betsy Crowe pp/1234567 e/betsycrowe@gmail.com pa/Newgate Prison t/criminal t/friend` +== Editing a person: `edit` + +Edits a person in the address book. + +Format: `edit NAME n/NEW_NAME` + +Example: + +* `edit John Doe n/Johnny Doe` + +Edits John Doe's name to Johnny Doe + == Listing all persons : `list` Shows a list of all persons, along with their non-private details, in the address book. + diff --git a/src/seedu/addressbook/commands/EditCommand.java b/src/seedu/addressbook/commands/EditCommand.java new file mode 100644 index 000000000..280bbe3a7 --- /dev/null +++ b/src/seedu/addressbook/commands/EditCommand.java @@ -0,0 +1,60 @@ +package seedu.addressbook.commands; + +import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.*; + +public class EditCommand extends Command { + public static final String COMMAND_WORD = "edit"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits a person's name in the address book. " + + "Parameters: NAME n/NEW_NAME\n" + + "Example: " + COMMAND_WORD + + " John Doe n/Johnny Doe"; + + public static final String MESSAGE_SUCCESS = "%1$s is now called %2$s"; + public static final String MESSAGE_MISSING_PERSON = "This person does not exist in the address book"; + public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; + + private final Name toEdit; + private final Name toReplace; + + /** + * Convenience constructor using raw values. + * + * @throws IllegalValueException if any of the raw values are invalid + */ + public EditCommand(String name, String replacement) throws IllegalValueException { + this.toEdit = new Name(name); + this.toReplace = new Name(replacement); + } + + public EditCommand(Name toEdit, Name toReplace) { + this.toEdit = toEdit; + this.toReplace = toReplace; + } + + public Name getName() { + return toEdit; + } + + @Override + public CommandResult execute() { + try { + Person personToEdit = addressBook.getPerson(toEdit); + Person editedPerson = new Person( + toReplace, + personToEdit.getPhone(), + personToEdit.getEmail(), + personToEdit.getAddress(), + personToEdit.getTags() + ); + addressBook.removePerson(personToEdit); + addressBook.addPerson(editedPerson); + return new CommandResult(String.format(MESSAGE_SUCCESS, toEdit, toReplace)); + } catch (UniquePersonList.PersonNotFoundException pnfe) { + return new CommandResult(MESSAGE_MISSING_PERSON); + } catch (UniquePersonList.DuplicatePersonException dpe) { + return new CommandResult(MESSAGE_DUPLICATE_PERSON); + } + } +} diff --git a/src/seedu/addressbook/data/AddressBook.java b/src/seedu/addressbook/data/AddressBook.java index 537d35c89..2a1a3825b 100644 --- a/src/seedu/addressbook/data/AddressBook.java +++ b/src/seedu/addressbook/data/AddressBook.java @@ -1,5 +1,6 @@ package seedu.addressbook.data; +import seedu.addressbook.data.person.Name; import seedu.addressbook.data.person.Person; import seedu.addressbook.data.person.ReadOnlyPerson; import seedu.addressbook.data.person.UniquePersonList; @@ -38,6 +39,10 @@ public void addPerson(Person toAdd) throws DuplicatePersonException { allPersons.add(toAdd); } + public Person getPerson(Name name) throws PersonNotFoundException { + return allPersons.get(name); + } + /** * Returns true if an equivalent person exists in the address book. */ diff --git a/src/seedu/addressbook/data/person/UniquePersonList.java b/src/seedu/addressbook/data/person/UniquePersonList.java index d7acd8b4a..62ad6e53d 100644 --- a/src/seedu/addressbook/data/person/UniquePersonList.java +++ b/src/seedu/addressbook/data/person/UniquePersonList.java @@ -110,6 +110,22 @@ public void add(Person toAdd) throws DuplicatePersonException { internalList.add(toAdd); } + /** + * Get a person matching the input name + * + * @param name the name to be found + * @return the person found + * @throws PersonNotFoundException if no such person could be found in the list + */ + public Person get(Name name) throws PersonNotFoundException { + for (Person person: internalList) { + if (person.getName().equals(name)) { + return person; + } + } + throw new PersonNotFoundException(); + } + /** * Removes the equivalent person from the list. * diff --git a/src/seedu/addressbook/parser/Parser.java b/src/seedu/addressbook/parser/Parser.java index abddb3f45..6ba226d6e 100644 --- a/src/seedu/addressbook/parser/Parser.java +++ b/src/seedu/addressbook/parser/Parser.java @@ -11,17 +11,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.addressbook.commands.AddCommand; -import seedu.addressbook.commands.ClearCommand; -import seedu.addressbook.commands.Command; -import seedu.addressbook.commands.DeleteCommand; -import seedu.addressbook.commands.ExitCommand; -import seedu.addressbook.commands.FindCommand; -import seedu.addressbook.commands.HelpCommand; -import seedu.addressbook.commands.IncorrectCommand; -import seedu.addressbook.commands.ListCommand; -import seedu.addressbook.commands.ViewAllCommand; -import seedu.addressbook.commands.ViewCommand; +import seedu.addressbook.commands.*; import seedu.addressbook.data.exception.IllegalValueException; /** @@ -41,6 +31,10 @@ public class Parser { + " (?p?)a/(?
[^/]+)" + "(?(?: t/[^/]+)*)"); // variable number of tags + public static final Pattern PERSON_EDIT_ARGS_FORMAT = + Pattern.compile("(?[^/]+)" + + " n/(?[^/]+)"); + /** * Signals that the user input could not be parsed. @@ -73,33 +67,36 @@ public Command parseCommand(String userInput) { switch (commandWord) { - case AddCommand.COMMAND_WORD: - return prepareAdd(arguments); + case AddCommand.COMMAND_WORD: + return prepareAdd(arguments); - case DeleteCommand.COMMAND_WORD: - return prepareDelete(arguments); + case EditCommand.COMMAND_WORD: + return prepareEdit(arguments); - case ClearCommand.COMMAND_WORD: - return new ClearCommand(); + case DeleteCommand.COMMAND_WORD: + return prepareDelete(arguments); - case FindCommand.COMMAND_WORD: - return prepareFind(arguments); + case ClearCommand.COMMAND_WORD: + return new ClearCommand(); - case ListCommand.COMMAND_WORD: - return new ListCommand(); + case FindCommand.COMMAND_WORD: + return prepareFind(arguments); - case ViewCommand.COMMAND_WORD: - return prepareView(arguments); + case ListCommand.COMMAND_WORD: + return new ListCommand(); - case ViewAllCommand.COMMAND_WORD: - return prepareViewAll(arguments); + case ViewCommand.COMMAND_WORD: + return prepareView(arguments); - case ExitCommand.COMMAND_WORD: - return new ExitCommand(); + case ViewAllCommand.COMMAND_WORD: + return prepareViewAll(arguments); - case HelpCommand.COMMAND_WORD: // Fallthrough - default: - return new HelpCommand(); + case ExitCommand.COMMAND_WORD: + return new ExitCommand(); + + case HelpCommand.COMMAND_WORD: // Fallthrough + default: + return new HelpCommand(); } } @@ -156,6 +153,23 @@ private static Set getTagsFromArgs(String tagArguments) throws IllegalVa return new HashSet<>(tagStrings); } + private Command prepareEdit(String args) { + final Matcher matcher = PERSON_EDIT_ARGS_FORMAT.matcher(args.trim()); + // Validate arg string format + if (!matcher.matches()) { + return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE)); + } + try { + return new EditCommand( + matcher.group("name"), + + matcher.group("newName") + ); + } catch (IllegalValueException ive) { + return new IncorrectCommand(ive.getMessage()); + } + } + /** * Parses arguments in the context of the delete person command. diff --git a/test/expected.txt b/test/expected.txt index 56fe5fcac..022b3bc58 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -138,6 +138,43 @@ || Enter command: || [Command entered: add Esther Potato p/555555 e/esther@not.a.real.potato pa/555, epsilon street t/tubers t/starchy] || This person already exists in the address book || =================================================== +|| Enter command: || [Command entered: edit wrong args wrong args] +|| Invalid command format! +|| edit: Edits a person's name in the address book. Parameters: NAME n/NEW_NAME +|| Example: edit John Doe n/Johnny Doe +|| =================================================== +|| Enter command: || [Command entered: edit Valid Name Invalid Replacement] +|| Invalid command format! +|| edit: Edits a person's name in the address book. Parameters: NAME n/NEW_NAME +|| Example: edit John Doe n/Johnny Doe +|| =================================================== +|| Enter command: || [Command entered: edit Esther Potato n/Esther Tomato] +|| Esther Potato is now called Esther Tomato +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| 2. Betsy Choo Tags: [secretive] +|| 3. Charlie Dickson Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| 4. Dickson Ee Phone: 444444 Address: 444, delta street Tags: [friends] +|| 5. Esther Tomato Phone: 555555 Email: esther@not.a.real.potato Tags: [tubers][starchy] +|| +|| 5 persons listed! +|| =================================================== +|| Enter command: || [Command entered: edit Esther Tomato n/Esther Potato] +|| Esther Tomato is now called Esther Potato +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| 2. Betsy Choo Tags: [secretive] +|| 3. Charlie Dickson Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| 4. Dickson Ee Phone: 444444 Address: 444, delta street Tags: [friends] +|| 5. Esther Potato Phone: 555555 Email: esther@not.a.real.potato Tags: [tubers][starchy] +|| +|| 5 persons listed! +|| =================================================== +|| Enter command: || [Command entered: edit Nonexistent Person n/Existent Person] +|| This person does not exist in the address book +|| =================================================== || Enter command: || [Command entered: view] || Invalid command format! || view: Views the non-private details of the person identified by the index number in the last shown person listing. diff --git a/test/input.txt b/test/input.txt index eb8df81f8..136f9b844 100644 --- a/test/input.txt +++ b/test/input.txt @@ -54,6 +54,23 @@ # should not allow adding duplicate persons add Esther Potato p/555555 e/esther@not.a.real.potato pa/555, epsilon street t/tubers t/starchy +########################################################## +# test edit person command +########################################################## + + # should catch invalid args format + edit wrong args wrong args + edit Valid Name Invalid Replacement + + # should edit correctly and list non private information + edit Esther Potato n/Esther Tomato + list + edit Esther Tomato n/Esther Potato + list + + # should not allow editing person that does not exist + edit Nonexistent Person n/Existent Person + ########################################################## # test view/viewall persons command ########################################################## diff --git a/test/java/seedu/addressbook/commands/EditCommandTest.java b/test/java/seedu/addressbook/commands/EditCommandTest.java new file mode 100644 index 000000000..cfdeb5ecc --- /dev/null +++ b/test/java/seedu/addressbook/commands/EditCommandTest.java @@ -0,0 +1,41 @@ +package seedu.addressbook.commands; + +import org.junit.Test; +import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.Name; + +import static org.junit.Assert.fail; + +public class EditCommandTest { + @Test + public void editCommand_invalidName_throwsException() { + final String[] invalidNames = { "", " ", "[]\\[;]" }; + for (String name : invalidNames) { + assertConstructingInvalidEditCmdThrowsException(name, Name.EXAMPLE); + } + } + + @Test + public void editCommand_invalidReplacement_throwsException() { + final String[] invalidNames = { "", " ", "[]\\[;]" }; + for (String replacement : invalidNames) { + assertConstructingInvalidEditCmdThrowsException(Name.EXAMPLE, replacement); + } + } + + /** + * Asserts that attempting to construct an edit command with the supplied + * invalid data throws an IllegalValueException + */ + private void assertConstructingInvalidEditCmdThrowsException(String name, String replacement) { + try { + new EditCommand(name, replacement); + } catch (IllegalValueException e) { + return; + } + String error = String.format( + "An edit command was successfully constructed with invalid input: %s %s", + name, replacement); + fail(error); + } +} From 3dac185191d95df1f3773a24fd67cc6c703da6ef Mon Sep 17 00:00:00 2001 From: rbth7e5 Date: Tue, 12 Feb 2019 21:00:02 +0800 Subject: [PATCH 2/4] revert back importing commands individually --- src/seedu/addressbook/parser/Parser.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/seedu/addressbook/parser/Parser.java b/src/seedu/addressbook/parser/Parser.java index 6ba226d6e..5bd5a6709 100644 --- a/src/seedu/addressbook/parser/Parser.java +++ b/src/seedu/addressbook/parser/Parser.java @@ -11,7 +11,18 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.addressbook.commands.*; +import seedu.addressbook.commands.AddCommand; +import seedu.addressbook.commands.EditCommand; +import seedu.addressbook.commands.ClearCommand; +import seedu.addressbook.commands.Command; +import seedu.addressbook.commands.DeleteCommand; +import seedu.addressbook.commands.ExitCommand; +import seedu.addressbook.commands.FindCommand; +import seedu.addressbook.commands.HelpCommand; +import seedu.addressbook.commands.IncorrectCommand; +import seedu.addressbook.commands.ListCommand; +import seedu.addressbook.commands.ViewAllCommand; +import seedu.addressbook.commands.ViewCommand; import seedu.addressbook.data.exception.IllegalValueException; /** From c1a3267fdf095937ddac368b06057654e27c4924 Mon Sep 17 00:00:00 2001 From: rbth7e5 Date: Tue, 12 Feb 2019 21:23:31 +0800 Subject: [PATCH 3/4] update tests for help and parser --- .../addressbook/commands/HelpCommand.java | 1 + test/expected.txt | 2 ++ .../seedu/addressbook/parser/ParserTest.java | 29 ++++++++++++------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/seedu/addressbook/commands/HelpCommand.java b/src/seedu/addressbook/commands/HelpCommand.java index 9be217d89..2ee57448b 100644 --- a/src/seedu/addressbook/commands/HelpCommand.java +++ b/src/seedu/addressbook/commands/HelpCommand.java @@ -15,6 +15,7 @@ public class HelpCommand extends Command { public CommandResult execute() { return new CommandResult( AddCommand.MESSAGE_USAGE + + "\n" + EditCommand.MESSAGE_USAGE + "\n" + DeleteCommand.MESSAGE_USAGE + "\n" + ClearCommand.MESSAGE_USAGE + "\n" + FindCommand.MESSAGE_USAGE diff --git a/test/expected.txt b/test/expected.txt index 022b3bc58..7c0c743b8 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -9,6 +9,8 @@ || add: Adds a person to the address book. Contact details can be marked private by prepending 'p' to the prefix. || Parameters: NAME [p]p/PHONE [p]e/EMAIL [p]a/ADDRESS [t/TAG]... || Example: add John Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney +|| edit: Edits a person's name in the address book. Parameters: NAME n/NEW_NAME +|| Example: edit John Doe n/Johnny Doe || delete: Deletes the person identified by the index number used in the last person listing. || Parameters: INDEX || Example: delete 1 diff --git a/test/java/seedu/addressbook/parser/ParserTest.java b/test/java/seedu/addressbook/parser/ParserTest.java index 8b7259950..6bf9a0e8e 100644 --- a/test/java/seedu/addressbook/parser/ParserTest.java +++ b/test/java/seedu/addressbook/parser/ParserTest.java @@ -12,17 +12,7 @@ import org.junit.Before; import org.junit.Test; -import seedu.addressbook.commands.AddCommand; -import seedu.addressbook.commands.ClearCommand; -import seedu.addressbook.commands.Command; -import seedu.addressbook.commands.DeleteCommand; -import seedu.addressbook.commands.ExitCommand; -import seedu.addressbook.commands.FindCommand; -import seedu.addressbook.commands.HelpCommand; -import seedu.addressbook.commands.IncorrectCommand; -import seedu.addressbook.commands.ListCommand; -import seedu.addressbook.commands.ViewAllCommand; -import seedu.addressbook.commands.ViewCommand; +import seedu.addressbook.commands.*; import seedu.addressbook.data.exception.IllegalValueException; import seedu.addressbook.data.person.Address; import seedu.addressbook.data.person.Email; @@ -294,6 +284,23 @@ private static String convertPersonToAddCommandString(ReadOnlyPerson person) { return addCommand; } + /* + * Tests for edit person command ============================================================================== + */ + + @Test + public void parse_editCommandInvalidArgs_errorMessage() { + final String[] inputs = { + "edit", + "edit ", + "edit wrong args format", + // no name prefix + String.format("edit $s $s", Name.EXAMPLE, Name.EXAMPLE), + }; + final String resultMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE); + parseAndAssertIncorrectWithMessage(resultMessage, inputs); + } + /* * Utility methods ==================================================================================== */ From 9306fdba20de1fc614c8bca52d9601db561d24dc Mon Sep 17 00:00:00 2001 From: rbth7e5 Date: Tue, 12 Feb 2019 22:28:52 +0800 Subject: [PATCH 4/4] change parser test command imports to specific imports --- test/java/seedu/addressbook/parser/ParserTest.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/java/seedu/addressbook/parser/ParserTest.java b/test/java/seedu/addressbook/parser/ParserTest.java index 6bf9a0e8e..2997e6ba7 100644 --- a/test/java/seedu/addressbook/parser/ParserTest.java +++ b/test/java/seedu/addressbook/parser/ParserTest.java @@ -12,7 +12,18 @@ import org.junit.Before; import org.junit.Test; -import seedu.addressbook.commands.*; +import seedu.addressbook.commands.AddCommand; +import seedu.addressbook.commands.EditCommand; +import seedu.addressbook.commands.ClearCommand; +import seedu.addressbook.commands.Command; +import seedu.addressbook.commands.DeleteCommand; +import seedu.addressbook.commands.ExitCommand; +import seedu.addressbook.commands.FindCommand; +import seedu.addressbook.commands.HelpCommand; +import seedu.addressbook.commands.IncorrectCommand; +import seedu.addressbook.commands.ListCommand; +import seedu.addressbook.commands.ViewAllCommand; +import seedu.addressbook.commands.ViewCommand; import seedu.addressbook.data.exception.IllegalValueException; import seedu.addressbook.data.person.Address; import seedu.addressbook.data.person.Email;